diff --git a/src/runtime/c/pgf/parser.cxx b/src/runtime/c/pgf/parser.cxx index c9eacea09..187567e87 100644 --- a/src/runtime/c/pgf/parser.cxx +++ b/src/runtime/c/pgf/parser.cxx @@ -6,7 +6,7 @@ //#define DEBUG_STATE_CREATION #define DEBUG_AUTOMATON #define DEBUG_PARSER -//#define DEBUG_GENERATOR +#define DEBUG_GENERATOR struct PgfLRTableMaker::CCat { CCat *parent; @@ -678,29 +678,74 @@ void PgfLRTableMaker::symbol(State *state, Fold fold, Item *item, PgfSymbol sym) } case PgfSymbolKS::tag: { auto symks = ref::untagged(sym); + + size_t sym_idx_2 = item->sym_idx+1; + while (sym_idx_2 < item->seq->syms.len) { + if (ref::get_tag(item->seq->syms.data[sym_idx_2]) != PgfSymbolKS::tag) + break; + sym_idx_2++; + } + if (fold == PROBE) { item->ccat->productive = true; + if (item->sym_idx > 0 || sym_idx_2 < item->seq->syms.len) { + print_item(item); + item->ccat->register_item(item); + } } else { auto &next_state = state->tokens[Key3(item->seq,item->sym_idx)]; if (next_state == NULL) { next_state = new State; } - while (item->sym_idx < item->seq->syms.len) { - if (ref::get_tag(item->seq->syms.data[item->sym_idx]) != PgfSymbolKS::tag) - break; - item->sym_idx++; - } + item = new (item) Item; + item->sym_idx = sym_idx_2; item->stk_size++; next_state->push_item(item); } break; } + case PgfSymbolKP::tag: { + if (fold == PROBE) { + item->ccat->productive = true; + item->ccat->register_item(item); + } else { + auto symkp = ref::untagged(sym); + for (size_t i = 0; i < symkp->alts.len; i++) { + Item *new_item = new (item) Item; new_item->sym_idx++; + ref form = symkp->alts.data[i].form; + if (form->syms.len == 0) { + process(state, fold, new_item); + } else { + auto &next_state = state->tokens[Key3(form,0)]; + if (next_state == NULL) { + next_state = new State; + } + new_item->stk_size++; + next_state->push_item(new_item); + } + } + + Item *new_item = new (item) Item; new_item->sym_idx++; + ref form = symkp->default_form; + if (form->syms.len == 0) { + process(state, fold, new_item); + } else { + auto &next_state = state->tokens[Key3(form,0)]; + if (next_state == NULL) { + next_state = new State; + } + new_item->stk_size++; + next_state->push_item(new_item); + } + } + } case PgfSymbolBIND::tag: { if (fold != PROBE) { if (state->bind_state == NULL) { state->bind_state = new State; } + item = new (item) Item; item->sym_idx++; item->stk_size++; state->bind_state->push_item(item); @@ -712,6 +757,7 @@ void PgfLRTableMaker::symbol(State *state, Fold fold, Item *item, PgfSymbol sym) if (fold != PROBE) { // SOFT_BIND && SOFT_SPACE also allow a space + item = new (item) Item(); item->sym_idx++; process(state,fold,item); diff --git a/src/runtime/c/pgf/parser.h b/src/runtime/c/pgf/parser.h index f005cc196..4312ca5c5 100644 --- a/src/runtime/c/pgf/parser.h +++ b/src/runtime/c/pgf/parser.h @@ -74,6 +74,7 @@ class PGF_INTERNAL_DECL PgfLRTableMaker typedef enum { INIT, PROBE, REPEAT } Fold; void process(State *state, Fold fold, Item *item); + void syntagma(State *state, Fold fold, Item *item, ref seq, size_t sym_idx); void symbol(State *state, Fold fold, Item *item, PgfSymbol sym); template diff --git a/src/runtime/c/pgf/reader.cxx b/src/runtime/c/pgf/reader.cxx index f0a8b8366..0c82a4d61 100644 --- a/src/runtime/c/pgf/reader.cxx +++ b/src/runtime/c/pgf/reader.cxx @@ -753,8 +753,8 @@ ref PgfReader::read_concrete() auto printnames = read_namespace(&PgfReader::read_printname); concrete->printnames = printnames; -// PgfLRTableMaker maker(abstract, concrete); -// concrete->lrtable = maker.make(); + PgfLRTableMaker maker(abstract, concrete); + concrete->lrtable = maker.make(); return concrete; }