1
0
forked from GitHub/gf-core

complete the linearization of pre

This commit is contained in:
krangelov
2021-12-03 11:29:01 +01:00
parent baf78528d3
commit df82e1e7ca
4 changed files with 85 additions and 6 deletions

View File

@@ -44,6 +44,7 @@ PgfLinearizer::PgfLinearizer(ref<PgfConcr> 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<PgfText> 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<Vector<PgfSymbol>> syms)
{
ref<Vector<PgfHypo>> hypos = node->lin->absfun->type->hypos;
@@ -223,6 +260,8 @@ void PgfLinearizer::linearize(PgfLinearizationOutputIface *out, TreeNode *node,
case PgfSymbolKS::tag: {
auto sym_ks = ref<PgfSymbolKS>::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<PgfSymbolKP>::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;
}
}

View File

@@ -49,6 +49,18 @@ class PGF_INTERNAL_DECL PgfLinearizer : public PgfUnmarshaller {
bool capit;
bool allcapit;
struct PreStack {
PreStack *next;
TreeNode *node;
ref<PgfSymbolKP> 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<Vector<PgfSymbol>> syms);
void linearize(PgfLinearizationOutputIface *out, TreeNode *node, size_t lindex);

View File

@@ -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)
{

View File

@@ -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);