don't even touch the right stack on piggy-back shifts

This commit is contained in:
Sven M. Hallberg 2013-06-21 15:31:37 +02:00
parent 7cd143c0c4
commit bf3e3c162e

View file

@ -269,7 +269,6 @@ bool h_lrengine_step(HLREngine *engine, const HLRAction *action)
assert(action->type == HLR_SHIFT || action->type == HLR_REDUCE); assert(action->type == HLR_SHIFT || action->type == HLR_REDUCE);
if(action->type == HLR_REDUCE) { if(action->type == HLR_REDUCE) {
assert(action->type == HLR_REDUCE);
size_t len = action->production.length; size_t len = action->production.length;
HCFChoice *symbol = action->production.lhs; HCFChoice *symbol = action->production.lhs;
@ -306,21 +305,24 @@ bool h_lrengine_step(HLREngine *engine, const HLRAction *action)
if(symbol->action) if(symbol->action)
value = (HParsedToken *)symbol->action(make_result(arena, value)); value = (HParsedToken *)symbol->action(make_result(arena, value));
// push result (value, symbol) onto the right stack
h_slist_push(right, value);
h_slist_push(right, symbol);
// this is LR, building a right-most derivation bottom-up, so no reduce can // this is LR, building a right-most derivation bottom-up, so no reduce can
// follow a reduce. we can also assume no conflict follows for GLR if we // follow a reduce. we can also assume no conflict follows for GLR if we
// use LALR tables, because only terminal symbols (lookahead) get reduces. // use LALR tables, because only terminal symbols (lookahead) get reduces.
action = h_lr_lookup(engine->table, engine->state, symbol); const HLRAction *next = h_lr_lookup(engine->table, engine->state, symbol);
if(action == NULL) if(next) {
return false; // no handle after reduce; terminate assert(next->type == HLR_SHIFT);
assert(action->type == HLR_SHIFT);
}
// this could be the original action, or a shift piggy-backed onto reduce // piggy-back the shift onto here, never touching the right stack
if(action->type == HLR_SHIFT) { h_slist_push(left, (void *)(uintptr_t)engine->state);
h_slist_push(left, value);
engine->state = next->nextstate;
} else {
// fallback
h_slist_push(right, value);
h_slist_push(right, symbol);
}
} else {
assert(action->type == HLR_SHIFT);
h_slist_push(left, (void *)(uintptr_t)engine->state); h_slist_push(left, (void *)(uintptr_t)engine->state);
h_slist_drop(right); // symbol (discard) h_slist_drop(right); // symbol (discard)
h_slist_push(left, h_slist_drop(right)); // semantic value h_slist_push(left, h_slist_drop(right)); // semantic value