better factor out lr table writes
This commit is contained in:
parent
534a29b7ba
commit
d67e12a825
3 changed files with 14 additions and 9 deletions
|
|
@ -130,10 +130,10 @@ static inline bool has_conflicts(HLRTable *table)
|
||||||
return !h_slist_empty(table->inadeq);
|
return !h_slist_empty(table->inadeq);
|
||||||
}
|
}
|
||||||
|
|
||||||
// place a new entry in tbl; records conflicts in tbl->inadeq
|
// place a new terminal entry in tbl; records conflicts in tbl->inadeq
|
||||||
// returns 0 on success, -1 on conflict
|
// returns 0 on success, -1 on conflict
|
||||||
// ignores forall entries
|
// ignores forall entries
|
||||||
int h_lrtable_put(HLRTable *tbl, size_t state, HCFChoice *x, HLRAction *action)
|
static int terminal_put(HLRTable *tbl, size_t state, HCFChoice *x, HLRAction *action)
|
||||||
{
|
{
|
||||||
HLRAction *prev = h_hashtable_get(tbl->rows[state], x);
|
HLRAction *prev = h_hashtable_get(tbl->rows[state], x);
|
||||||
if(prev && prev != action) {
|
if(prev && prev != action) {
|
||||||
|
|
@ -257,7 +257,7 @@ int h_lalr_compile(HAllocator* mm__, HParser* parser, const void* params)
|
||||||
if(fs->end_branch) {
|
if(fs->end_branch) {
|
||||||
HCFChoice *terminal = h_arena_malloc(arena, sizeof(HCFChoice));
|
HCFChoice *terminal = h_arena_malloc(arena, sizeof(HCFChoice));
|
||||||
terminal->type = HCF_END;
|
terminal->type = HCF_END;
|
||||||
if(h_lrtable_put(table, state, terminal, action) < 0)
|
if(terminal_put(table, state, terminal, action) < 0)
|
||||||
inadeq = true;
|
inadeq = true;
|
||||||
}
|
}
|
||||||
H_FOREACH(fs->char_branches, void *key, HStringMap *m)
|
H_FOREACH(fs->char_branches, void *key, HStringMap *m)
|
||||||
|
|
@ -268,7 +268,7 @@ int h_lalr_compile(HAllocator* mm__, HParser* parser, const void* params)
|
||||||
terminal->type = HCF_CHAR;
|
terminal->type = HCF_CHAR;
|
||||||
terminal->chr = key_char((HCharKey)key);
|
terminal->chr = key_char((HCharKey)key);
|
||||||
|
|
||||||
if(h_lrtable_put(table, state, terminal, action) < 0)
|
if(terminal_put(table, state, terminal, action) < 0)
|
||||||
inadeq = true;
|
inadeq = true;
|
||||||
H_END_FOREACH // lookahead character
|
H_END_FOREACH // lookahead character
|
||||||
} H_END_FOREACH // enhanced production
|
} H_END_FOREACH // enhanced production
|
||||||
|
|
|
||||||
|
|
@ -120,12 +120,10 @@ HHashValue h_hash_transition(const void *p);
|
||||||
|
|
||||||
HLRDFA *h_lr0_dfa(HCFGrammar *g);
|
HLRDFA *h_lr0_dfa(HCFGrammar *g);
|
||||||
HLRTable *h_lr0_table(HCFGrammar *g, const HLRDFA *dfa);
|
HLRTable *h_lr0_table(HCFGrammar *g, const HLRDFA *dfa);
|
||||||
int h_lrtable_put(HLRTable *tbl, size_t state, HCFChoice *x, HLRAction *action);
|
|
||||||
|
|
||||||
int h_lalr_compile(HAllocator* mm__, HParser* parser, const void* params);
|
int h_lalr_compile(HAllocator* mm__, HParser* parser, const void* params);
|
||||||
void h_lalr_free(HParser *parser);
|
void h_lalr_free(HParser *parser);
|
||||||
|
|
||||||
const HLRAction *h_lr_lookup(const HLRTable *table, size_t state, const HCFChoice *symbol);
|
|
||||||
const HLRAction *h_lrengine_action(const HLREngine *engine);
|
const HLRAction *h_lrengine_action(const HLREngine *engine);
|
||||||
void h_lrengine_step(HLREngine *engine, const HLRAction *action);
|
void h_lrengine_step(HLREngine *engine, const HLRAction *action);
|
||||||
HParseResult *h_lrengine_result(HLREngine *engine);
|
HParseResult *h_lrengine_result(HLREngine *engine);
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,14 @@ HLRDFA *h_lr0_dfa(HCFGrammar *g)
|
||||||
|
|
||||||
/* LR(0) table generation */
|
/* LR(0) table generation */
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void put_shift(HLRTable *table, size_t state, const HCFChoice *symbol,
|
||||||
|
size_t nextstate)
|
||||||
|
{
|
||||||
|
HLRAction *action = h_shift_action(table->arena, nextstate);
|
||||||
|
h_hashtable_put(table->rows[state], symbol, action);
|
||||||
|
}
|
||||||
|
|
||||||
HLRTable *h_lr0_table(HCFGrammar *g, const HLRDFA *dfa)
|
HLRTable *h_lr0_table(HCFGrammar *g, const HLRDFA *dfa)
|
||||||
{
|
{
|
||||||
HAllocator *mm__ = g->mm__;
|
HAllocator *mm__ = g->mm__;
|
||||||
|
|
@ -174,15 +182,14 @@ HLRTable *h_lr0_table(HCFGrammar *g, const HLRDFA *dfa)
|
||||||
// add dummy shift entry for the start symbol so h_lrengine_step can always
|
// add dummy shift entry for the start symbol so h_lrengine_step can always
|
||||||
// find a shift.
|
// find a shift.
|
||||||
// NB: nextstate=0 is used for the "victory condition" by h_lrengine_result.
|
// NB: nextstate=0 is used for the "victory condition" by h_lrengine_result.
|
||||||
h_hashtable_put(table->rows[0], g->start, h_shift_action(arena, 0));
|
put_shift(table, 0, g->start, 0);
|
||||||
|
|
||||||
// add shift entries
|
// add shift entries
|
||||||
for(HSlistNode *x = dfa->transitions->head; x; x = x->next) {
|
for(HSlistNode *x = dfa->transitions->head; x; x = x->next) {
|
||||||
// for each transition x-A->y, add "shift, goto y" to table entry (x,A)
|
// for each transition x-A->y, add "shift, goto y" to table entry (x,A)
|
||||||
HLRTransition *t = x->elem;
|
HLRTransition *t = x->elem;
|
||||||
|
|
||||||
HLRAction *action = h_shift_action(arena, t->to);
|
put_shift(table, t->from, t->symbol, t->to);
|
||||||
h_hashtable_put(table->rows[t->from], t->symbol, action);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add reduce entries, record inadequate states
|
// add reduce entries, record inadequate states
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue