From df82e1e7ca2b690c925fc9fa8f5cc8b9f36b041c Mon Sep 17 00:00:00 2001 From: krangelov Date: Fri, 3 Dec 2021 11:29:01 +0100 Subject: [PATCH] complete the linearization of pre --- src/runtime/c/pgf/linearizer.cxx | 62 ++++++++++++++++++++++++++++---- src/runtime/c/pgf/linearizer.h | 12 +++++++ src/runtime/c/pgf/text.cxx | 14 ++++++++ src/runtime/c/pgf/text.h | 3 ++ 4 files changed, 85 insertions(+), 6 deletions(-) diff --git a/src/runtime/c/pgf/linearizer.cxx b/src/runtime/c/pgf/linearizer.cxx index 42d2050f3..300b6153e 100644 --- a/src/runtime/c/pgf/linearizer.cxx +++ b/src/runtime/c/pgf/linearizer.cxx @@ -44,6 +44,7 @@ PgfLinearizer::PgfLinearizer(ref concr, PgfMarshaller *m) { this->args = NULL; this->capit = false; this->allcapit = false; + this->pre_stack = NULL; }; PgfLinearizer::~PgfLinearizer() @@ -53,6 +54,12 @@ PgfLinearizer::~PgfLinearizer() delete first; first = next; } + + while (pre_stack != NULL) { + PreStack *next = pre_stack->next; + delete pre_stack; + pre_stack = next; + } } bool PgfLinearizer::resolve() @@ -164,6 +171,36 @@ void PgfLinearizer::reverse_and_label() } } +void PgfLinearizer::flush_pre_stack(PgfLinearizationOutputIface *out, PgfText *token) +{ + while (pre_stack != NULL) { + PreStack *pre = pre_stack; + pre_stack = pre->next; + + for (size_t i = 0; i < pre->sym_kp->alts.len; i++) { + PgfAlternative *alt = &pre->sym_kp->alts.data[i]; + for (size_t j = 0; j < alt->prefixes->len; j++) { + ref prefix = *vector_elem(alt->prefixes,j); + if (textstarts(token, &(*prefix))) { + linearize(out, pre->node, alt->form); + goto done; + } + } + } + + linearize(out, pre->node, pre->sym_kp->default_form); + + done: + if (pre->bind) + out->symbol_bind(); + + capit = pre->capit; + allcapit = pre->allcapit; + + delete pre; + } +} + void PgfLinearizer::linearize(PgfLinearizationOutputIface *out, TreeNode *node, ref> syms) { ref> hypos = node->lin->absfun->type->hypos; @@ -223,6 +260,8 @@ void PgfLinearizer::linearize(PgfLinearizationOutputIface *out, TreeNode *node, case PgfSymbolKS::tag: { auto sym_ks = ref::untagged(sym); + flush_pre_stack(out, &sym_ks->token); + if (capit) { PgfText *cap = (PgfText *) alloca(sizeof(PgfText)+sym_ks->token.size+6); @@ -269,14 +308,19 @@ void PgfLinearizer::linearize(PgfLinearizationOutputIface *out, TreeNode *node, } case PgfSymbolKP::tag: { auto sym_kp = ref::untagged(sym); - linearize(out, node, sym_kp->default_form); + PreStack *pre = new PreStack(); + pre->next = pre_stack; + pre->node = node; + pre->sym_kp = sym_kp; + pre_stack = pre; break; } case PgfSymbolBIND::tag: - out->symbol_bind(); - break; case PgfSymbolSOFTBIND::tag: - out->symbol_bind(); + if (pre_stack == NULL) + out->symbol_bind(); + else + pre_stack->bind = true; break; case PgfSymbolNE::tag: out->symbol_ne(); @@ -285,10 +329,16 @@ void PgfLinearizer::linearize(PgfLinearizationOutputIface *out, TreeNode *node, // Nothing to do break; case PgfSymbolCAPIT::tag: - capit = true; + if (pre_stack == NULL) + capit = true; + else + pre_stack->capit = true; break; case PgfSymbolALLCAPIT::tag: - allcapit = true; + if (pre_stack == NULL) + allcapit = true; + else + pre_stack->allcapit = true; break; } } diff --git a/src/runtime/c/pgf/linearizer.h b/src/runtime/c/pgf/linearizer.h index 7cac25cb1..e4a8fa366 100644 --- a/src/runtime/c/pgf/linearizer.h +++ b/src/runtime/c/pgf/linearizer.h @@ -49,6 +49,18 @@ class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller { bool capit; bool allcapit; + struct PreStack { + PreStack *next; + TreeNode *node; + ref sym_kp; + bool bind; + bool capit; + bool allcapit; + }; + + PreStack *pre_stack; + void flush_pre_stack(PgfLinearizationOutputIface *out, PgfText *token); + void linearize(PgfLinearizationOutputIface *out, TreeNode *node, ref> syms); void linearize(PgfLinearizationOutputIface *out, TreeNode *node, size_t lindex); diff --git a/src/runtime/c/pgf/text.cxx b/src/runtime/c/pgf/text.cxx index f9dfff3d7..9d10a66f8 100644 --- a/src/runtime/c/pgf/text.cxx +++ b/src/runtime/c/pgf/text.cxx @@ -16,6 +16,20 @@ int textcmp(PgfText *t1, PgfText *t2) } } +PGF_INTERNAL +bool textstarts(PgfText *t, PgfText *prefix) +{ + if (t->size < prefix->size) + return false; + + for (size_t i = 0; i < prefix->size; i++) { + if (t->text[i] != prefix->text[i]) + return false; + } + + return true; +} + PGF_INTERNAL PgfText* textdup(PgfText *t1) { diff --git a/src/runtime/c/pgf/text.h b/src/runtime/c/pgf/text.h index 9b48b3d8e..639ef88ae 100644 --- a/src/runtime/c/pgf/text.h +++ b/src/runtime/c/pgf/text.h @@ -4,6 +4,9 @@ PGF_INTERNAL_DECL int textcmp(PgfText *t1, PgfText *t2); +PGF_INTERNAL_DECL +bool textstarts(PgfText *t, PgfText *prefix); + PGF_INTERNAL_DECL PgfText* textdup(PgfText *t1);