refactoring in preparation for engine merging
This commit is contained in:
parent
8bc3b93e95
commit
bf9c9b5f7a
3 changed files with 57 additions and 27 deletions
|
|
@ -43,6 +43,44 @@ HLREngine *fork_engine(const HLREngine *engine)
|
||||||
return eng2;
|
return eng2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void stow_engine(HSlist *engines, HLREngine *engine)
|
||||||
|
{
|
||||||
|
// XXX switch to one engine per state, and do the merge here
|
||||||
|
h_slist_push(engines, engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const HLRAction *handle_conflict(HSlist *engines, const HLREngine *engine,
|
||||||
|
const HSlist *branches)
|
||||||
|
{
|
||||||
|
// there should be at least two conflicting actions
|
||||||
|
assert(branches->head);
|
||||||
|
assert(branches->head->next); // this is just a consistency check
|
||||||
|
|
||||||
|
// fork a new engine for all but the first action
|
||||||
|
for(HSlistNode *x=branches->head->next; x; x=x->next) {
|
||||||
|
HLRAction *act = x->elem;
|
||||||
|
HLREngine *eng = fork_engine(engine);
|
||||||
|
|
||||||
|
// perform one step and add to list
|
||||||
|
h_lrengine_step(eng, act);
|
||||||
|
stow_engine(engines, eng);
|
||||||
|
}
|
||||||
|
|
||||||
|
// return first action for use with original engine
|
||||||
|
return branches->head->elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HLREngine *handle_demerge(HSlist *engines, HLREngine *engine,
|
||||||
|
const HLRAction *reduce)
|
||||||
|
{
|
||||||
|
return engine; // XXX
|
||||||
|
|
||||||
|
for(size_t i=0; i<reduce->production.length; i++) {
|
||||||
|
// XXX if stack hits bottom, demerge
|
||||||
|
}
|
||||||
|
// XXX call step and stow on the newly-created engines
|
||||||
|
}
|
||||||
|
|
||||||
HParseResult *h_glr_parse(HAllocator* mm__, const HParser* parser, HInputStream* stream)
|
HParseResult *h_glr_parse(HAllocator* mm__, const HParser* parser, HInputStream* stream)
|
||||||
{
|
{
|
||||||
HLRTable *table = parser->backend_data;
|
HLRTable *table = parser->backend_data;
|
||||||
|
|
@ -60,12 +98,11 @@ HParseResult *h_glr_parse(HAllocator* mm__, const HParser* parser, HInputStream*
|
||||||
for(HSlistNode **x = &engines->head; *x; ) {
|
for(HSlistNode **x = &engines->head; *x; ) {
|
||||||
HLREngine *engine = (*x)->elem;
|
HLREngine *engine = (*x)->elem;
|
||||||
|
|
||||||
// check for terminated engines
|
// remove engine from list; it may come back in below
|
||||||
if(engine->run) {
|
*x = (*x)->next; // advance x, removing the current element
|
||||||
x = &(*x)->next; // advance x with no change
|
|
||||||
} else {
|
|
||||||
*x = (*x)->next; // advance x, removing the current element
|
|
||||||
|
|
||||||
|
// drop those engines that have terminated
|
||||||
|
if(!engine->run) {
|
||||||
// check for parse success
|
// check for parse success
|
||||||
HParseResult *res = h_lrengine_result(engine);
|
HParseResult *res = h_lrengine_result(engine);
|
||||||
if(res)
|
if(res)
|
||||||
|
|
@ -76,29 +113,19 @@ HParseResult *h_glr_parse(HAllocator* mm__, const HParser* parser, HInputStream*
|
||||||
|
|
||||||
const HLRAction *action = h_lrengine_action(engine);
|
const HLRAction *action = h_lrengine_action(engine);
|
||||||
|
|
||||||
// fork engine on conflicts
|
// handle forks and demerges (~> spawn engines)
|
||||||
if(action && action->type == HLR_CONFLICT) {
|
if(action) {
|
||||||
const HSlist *branches = action->branches;
|
if(action->type == HLR_CONFLICT) {
|
||||||
|
// fork engine on conflicts
|
||||||
// there should be at least two conflicting actions
|
action = handle_conflict(engines, engine, action->branches);
|
||||||
assert(branches->head);
|
} else if(action->type == HLR_REDUCE) {
|
||||||
assert(branches->head->next);
|
// demerge as needed to ensure that stacks are deep enough
|
||||||
|
engine = handle_demerge(engines, engine, action);
|
||||||
// save first action for use with old engine below
|
}
|
||||||
action = branches->head->elem;
|
|
||||||
|
|
||||||
// fork a new engine for all the other actions
|
|
||||||
for(HSlistNode *x=branches->head->next; x; x=x->next) {
|
|
||||||
HLRAction *act = x->elem;
|
|
||||||
HLREngine *eng = fork_engine(engine);
|
|
||||||
|
|
||||||
// perform one step and add to list
|
|
||||||
h_lrengine_step(eng, act);
|
|
||||||
h_slist_push(engines, eng);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h_lrengine_step(engine, action);
|
h_lrengine_step(engine, action);
|
||||||
|
stow_engine(engines, engine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -209,6 +209,7 @@ HLREngine *h_lrengine_new(HArena *arena, HArena *tarena, const HLRTable *table,
|
||||||
engine->run = true;
|
engine->run = true;
|
||||||
engine->stack = h_slist_new(tarena);
|
engine->stack = h_slist_new(tarena);
|
||||||
engine->input = *stream;
|
engine->input = *stream;
|
||||||
|
engine->merged = NULL;
|
||||||
engine->arena = arena;
|
engine->arena = arena;
|
||||||
engine->tarena = tarena;
|
engine->tarena = tarena;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,8 +74,10 @@ typedef struct HLREngine_ {
|
||||||
HSlist *stack; // holds pairs: (saved state, semantic value)
|
HSlist *stack; // holds pairs: (saved state, semantic value)
|
||||||
HInputStream input;
|
HInputStream input;
|
||||||
|
|
||||||
HArena *arena; // will hold the results
|
HSlist *merged; // saved ancestor engines that merged to form this one
|
||||||
HArena *tarena; // tmp, deleted after parse
|
|
||||||
|
HArena *arena; // will hold the results
|
||||||
|
HArena *tarena; // tmp, deleted after parse
|
||||||
} HLREngine;
|
} HLREngine;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue