forked from GitHub/gf-core
complete the linearization of pre
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user