add iterative API to LALR backend
This commit is contained in:
parent
ff55937e00
commit
caf00006f3
4 changed files with 67 additions and 5 deletions
|
|
@ -346,7 +346,10 @@ void h_lalr_free(HParser *parser)
|
|||
HParserBackendVTable h__lalr_backend_vtable = {
|
||||
.compile = h_lalr_compile,
|
||||
.parse = h_lr_parse,
|
||||
.free = h_lalr_free
|
||||
.free = h_lalr_free,
|
||||
.parse_start = h_lr_parse_start,
|
||||
.parse_chunk = h_lr_parse_chunk,
|
||||
.parse_finish = h_lr_parse_finish
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -199,15 +199,14 @@ bool h_lrtable_row_empty(const HLRTable *table, size_t i)
|
|||
|
||||
/* LR driver */
|
||||
|
||||
HLREngine *h_lrengine_new(HArena *arena, HArena *tarena, const HLRTable *table,
|
||||
const HInputStream *stream)
|
||||
static
|
||||
HLREngine *h_lrengine_new_(HArena *arena, HArena *tarena, const HLRTable *table)
|
||||
{
|
||||
HLREngine *engine = h_arena_malloc(tarena, sizeof(HLREngine));
|
||||
|
||||
engine->table = table;
|
||||
engine->state = 0;
|
||||
engine->stack = h_slist_new(tarena);
|
||||
engine->input = *stream;
|
||||
engine->merged[0] = NULL;
|
||||
engine->merged[1] = NULL;
|
||||
engine->arena = arena;
|
||||
|
|
@ -216,6 +215,14 @@ HLREngine *h_lrengine_new(HArena *arena, HArena *tarena, const HLRTable *table,
|
|||
return engine;
|
||||
}
|
||||
|
||||
HLREngine *h_lrengine_new(HArena *arena, HArena *tarena, const HLRTable *table,
|
||||
const HInputStream *stream)
|
||||
{
|
||||
HLREngine *engine = h_lrengine_new_(arena, tarena, table);
|
||||
engine->input = *stream;
|
||||
return engine;
|
||||
}
|
||||
|
||||
static const HLRAction *
|
||||
terminal_lookup(const HLREngine *engine, const HInputStream *stream)
|
||||
{
|
||||
|
|
@ -352,7 +359,7 @@ HParseResult *h_lrengine_result(HLREngine *engine)
|
|||
assert(!h_slist_empty(engine->stack));
|
||||
HParsedToken *tok = engine->stack->head->elem;
|
||||
HParseResult *res = make_result(engine->arena, tok);
|
||||
res->bit_length = engine->input.index * 8;
|
||||
res->bit_length = (engine->input.pos + engine->input.index) * 8;
|
||||
return res;
|
||||
} else {
|
||||
return NULL;
|
||||
|
|
@ -379,7 +386,53 @@ HParseResult *h_lr_parse(HAllocator* mm__, const HParser* parser, HInputStream*
|
|||
return result;
|
||||
}
|
||||
|
||||
void h_lr_parse_start(HSuspendedParser *s)
|
||||
{
|
||||
HLRTable *table = s->parser->backend_data;
|
||||
assert(table != NULL);
|
||||
|
||||
HArena *arena = h_new_arena(s->mm__, 0); // will hold the results
|
||||
HArena *tarena = h_new_arena(s->mm__, 0); // tmp, deleted after parse
|
||||
HLREngine *engine = h_lrengine_new_(arena, tarena, table);
|
||||
|
||||
s->backend_state = engine;
|
||||
}
|
||||
|
||||
bool h_lr_parse_chunk(HSuspendedParser* s, HInputStream *stream)
|
||||
{
|
||||
HLREngine *engine = s->backend_state;
|
||||
engine->input = *stream;
|
||||
|
||||
bool run = true;
|
||||
while(run) {
|
||||
// check input against table to determine which action to take
|
||||
const HLRAction *action = h_lrengine_action(engine);
|
||||
if(action == NEED_INPUT) {
|
||||
// XXX assume lookahead 1
|
||||
assert(engine->input.length - engine->input.index == 0);
|
||||
break;
|
||||
}
|
||||
|
||||
// execute action
|
||||
run = h_lrengine_step(engine, action);
|
||||
if(engine->input.overrun && !engine->input.last_chunk)
|
||||
break;
|
||||
}
|
||||
|
||||
*stream = engine->input;
|
||||
return !run; // done if engine no longer running
|
||||
}
|
||||
|
||||
HParseResult *h_lr_parse_finish(HSuspendedParser *s)
|
||||
{
|
||||
HLREngine *engine = s->backend_state;
|
||||
|
||||
HParseResult *result = h_lrengine_result(engine);
|
||||
if(!result)
|
||||
h_delete_arena(engine->arena);
|
||||
h_delete_arena(engine->tarena);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Pretty-printers */
|
||||
|
||||
|
|
|
|||
|
|
@ -134,6 +134,9 @@ const HLRAction *h_lrengine_action(const HLREngine *engine);
|
|||
bool h_lrengine_step(HLREngine *engine, const HLRAction *action);
|
||||
HParseResult *h_lrengine_result(HLREngine *engine);
|
||||
HParseResult *h_lr_parse(HAllocator* mm__, const HParser* parser, HInputStream* stream);
|
||||
void h_lr_parse_start(HSuspendedParser *s);
|
||||
bool h_lr_parse_chunk(HSuspendedParser* s, HInputStream *stream);
|
||||
HParseResult *h_lr_parse_finish(HSuspendedParser *s);
|
||||
HParseResult *h_glr_parse(HAllocator* mm__, const HParser* parser, HInputStream* stream);
|
||||
|
||||
void h_pprint_lritem(FILE *f, const HCFGrammar *g, const HLRItem *item);
|
||||
|
|
|
|||
|
|
@ -883,6 +883,9 @@ void register_parser_tests(void) {
|
|||
g_test_add_data_func("/core/parser/lalr/leftrec-ne", GINT_TO_POINTER(PB_LALR), test_leftrec_ne);
|
||||
g_test_add_data_func("/core/parser/lalr/rightrec", GINT_TO_POINTER(PB_LALR), test_rightrec);
|
||||
g_test_add_data_func("/core/parser/lalr/result_length", GINT_TO_POINTER(PB_LALR), test_result_length);
|
||||
g_test_add_data_func("/core/parser/lalr/iterative", GINT_TO_POINTER(PB_LALR), test_iterative);
|
||||
g_test_add_data_func("/core/parser/lalr/iterative/lookahead", GINT_TO_POINTER(PB_LALR), test_iterative_lookahead);
|
||||
g_test_add_data_func("/core/parser/lalr/iterative/result_length", GINT_TO_POINTER(PB_LALR), test_iterative_result_length);
|
||||
|
||||
g_test_add_data_func("/core/parser/glr/token", GINT_TO_POINTER(PB_GLR), test_token);
|
||||
g_test_add_data_func("/core/parser/glr/ch", GINT_TO_POINTER(PB_GLR), test_ch);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue