go back to storing engines in lists
This commit is contained in:
parent
67681a119a
commit
66809ceeda
1 changed files with 28 additions and 35 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "lr.h"
|
#include "lr.h"
|
||||||
|
|
||||||
static bool glr_step(HParseResult **result, HLREngine **engines,
|
static bool glr_step(HParseResult **result, HSlist *engines,
|
||||||
HLREngine *engine, const HLRAction *action);
|
HLREngine *engine, const HLRAction *action);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -73,7 +73,7 @@ static inline HLREngine *respawn(HLREngine *eng, HSlist *stack)
|
||||||
}
|
}
|
||||||
|
|
||||||
static HLREngine *
|
static HLREngine *
|
||||||
demerge(HParseResult **result, HLREngine **engines,
|
demerge(HParseResult **result, HSlist *engines,
|
||||||
HLREngine *engine, const HLRAction *action, size_t depth)
|
HLREngine *engine, const HLRAction *action, size_t depth)
|
||||||
{
|
{
|
||||||
// no-op on engines that are not merged
|
// no-op on engines that are not merged
|
||||||
|
|
@ -126,7 +126,7 @@ HLREngine *fork_engine(const HLREngine *engine)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const HLRAction *
|
static const HLRAction *
|
||||||
handle_conflict(HParseResult **result, HLREngine **engines,
|
handle_conflict(HParseResult **result, HSlist *engines,
|
||||||
const HLREngine *engine, const HSlist *branches)
|
const HLREngine *engine, const HSlist *branches)
|
||||||
{
|
{
|
||||||
// there should be at least two conflicting actions
|
// there should be at least two conflicting actions
|
||||||
|
|
@ -149,7 +149,7 @@ handle_conflict(HParseResult **result, HLREngine **engines,
|
||||||
|
|
||||||
/* GLR driver */
|
/* GLR driver */
|
||||||
|
|
||||||
static bool glr_step(HParseResult **result, HLREngine **engines,
|
static bool glr_step(HParseResult **result, HSlist *engines,
|
||||||
HLREngine *engine, const HLRAction *action)
|
HLREngine *engine, const HLRAction *action)
|
||||||
{
|
{
|
||||||
// handle forks and demerges (~> spawn engines)
|
// handle forks and demerges (~> spawn engines)
|
||||||
|
|
@ -167,11 +167,17 @@ static bool glr_step(HParseResult **result, HLREngine **engines,
|
||||||
bool run = h_lrengine_step(engine, action);
|
bool run = h_lrengine_step(engine, action);
|
||||||
|
|
||||||
if(run) {
|
if(run) {
|
||||||
// store engine in the array, merge if necessary
|
// store engine in the list, merge if necessary
|
||||||
if(engines[engine->state] == NULL)
|
HSlistNode *x;
|
||||||
engines[engine->state] = engine;
|
for(x=engines->head; x; x=x->next) {
|
||||||
else
|
HLREngine *eng = x->elem;
|
||||||
engines[engine->state] = lrengine_merge(engines[engine->state], engine);
|
if(eng->state == engine->state) {
|
||||||
|
x->elem = lrengine_merge(eng, engine);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!x) // no merge happened
|
||||||
|
h_slist_push(engines, engine);
|
||||||
} else if(engine->state == HLR_SUCCESS) {
|
} else if(engine->state == HLR_SUCCESS) {
|
||||||
// save the result
|
// save the result
|
||||||
*result = h_lrengine_result(engine);
|
*result = h_lrengine_result(engine);
|
||||||
|
|
@ -189,40 +195,27 @@ HParseResult *h_glr_parse(HAllocator* mm__, const HParser* parser, HInputStream*
|
||||||
HArena *arena = h_new_arena(mm__, 0); // will hold the results
|
HArena *arena = h_new_arena(mm__, 0); // will hold the results
|
||||||
HArena *tarena = h_new_arena(mm__, 0); // tmp, deleted after parse
|
HArena *tarena = h_new_arena(mm__, 0); // tmp, deleted after parse
|
||||||
|
|
||||||
// allocate engine arrays (can hold one engine per state)
|
// allocate engine lists (will hold one engine per state)
|
||||||
// these are swapped each iteration
|
// these are swapped each iteration
|
||||||
HLREngine **engines = h_arena_malloc(tarena, table->nrows * sizeof(HLREngine *));
|
HSlist *engines = h_slist_new(tarena);
|
||||||
HLREngine **engback = h_arena_malloc(tarena, table->nrows * sizeof(HLREngine *));
|
HSlist *engback = h_slist_new(tarena);
|
||||||
|
|
||||||
assert(table->nrows > 0);
|
|
||||||
for(size_t i=0; i<table->nrows; i++) {
|
|
||||||
engines[i] = NULL;
|
|
||||||
engback[i] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create initial engine
|
// create initial engine
|
||||||
engines[0] = h_lrengine_new(arena, tarena, table, stream);
|
h_slist_push(engines, h_lrengine_new(arena, tarena, table, stream));
|
||||||
assert(engines[0]->state == 0);
|
|
||||||
|
|
||||||
HParseResult *result = NULL;
|
HParseResult *result = NULL;
|
||||||
size_t engines_left = 1;
|
while(result == NULL && !h_slist_empty(engines)) {
|
||||||
while(engines_left && result == NULL) {
|
assert(h_slist_empty(engback));
|
||||||
engines_left = 0;
|
|
||||||
|
|
||||||
for(size_t i=0; i<table->nrows; i++) {
|
|
||||||
HLREngine *engine = engines[i];
|
|
||||||
if(engine == NULL)
|
|
||||||
continue;
|
|
||||||
engines[i] = NULL; // cleared for next iteration
|
|
||||||
|
|
||||||
// step all engines
|
// step all engines
|
||||||
bool run = glr_step(&result, engback, engine, h_lrengine_action(engine));
|
while(!h_slist_empty(engines)) {
|
||||||
if(run)
|
HLREngine *engine = h_slist_pop(engines);
|
||||||
engines_left++;
|
const HLRAction *action = h_lrengine_action(engine);
|
||||||
|
glr_step(&result, engback, engine, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
// swap the arrays
|
// swap the lists
|
||||||
HLREngine **tmp = engines;
|
HSlist *tmp = engines;
|
||||||
engines = engback;
|
engines = engback;
|
||||||
engback = tmp;
|
engback = tmp;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue