add stub GLR backend with h_glr_parse() a copy of h_lr_parse()
This commit is contained in:
parent
54ba62bfb7
commit
55c9a3d9c5
7 changed files with 138 additions and 3 deletions
|
|
@ -27,9 +27,10 @@ PARSERS := \
|
||||||
|
|
||||||
BACKENDS := \
|
BACKENDS := \
|
||||||
packrat \
|
packrat \
|
||||||
|
regex \
|
||||||
llk \
|
llk \
|
||||||
lalr \
|
lalr \
|
||||||
regex
|
glr
|
||||||
|
|
||||||
HAMMER_PARTS := \
|
HAMMER_PARTS := \
|
||||||
bitreader.o \
|
bitreader.o \
|
||||||
|
|
|
||||||
93
src/backends/glr.c
Normal file
93
src/backends/glr.c
Normal file
|
|
@ -0,0 +1,93 @@
|
||||||
|
#include "lr.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* GLR driver */
|
||||||
|
|
||||||
|
HParseResult *h_glr_parse(HAllocator* mm__, const HParser* parser, HInputStream* stream)
|
||||||
|
{
|
||||||
|
HLRTable *table = parser->backend_data;
|
||||||
|
if(!table)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
HArena *arena = h_new_arena(mm__, 0); // will hold the results
|
||||||
|
HArena *tarena = h_new_arena(mm__, 0); // tmp, deleted after parse
|
||||||
|
HLREngine *engine = h_lrengine_new(arena, tarena, table);
|
||||||
|
|
||||||
|
// iterate engine to completion
|
||||||
|
while(h_lrengine_step(engine, h_lrengine_action(engine, stream)));
|
||||||
|
|
||||||
|
HParseResult *result = h_lrengine_result(engine);
|
||||||
|
if(!result)
|
||||||
|
h_delete_arena(arena);
|
||||||
|
h_delete_arena(tarena);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
HParserBackendVTable h__glr_backend_vtable = {
|
||||||
|
.compile = h_lalr_compile,
|
||||||
|
.parse = h_glr_parse,
|
||||||
|
.free = h_lalr_free
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// dummy!
|
||||||
|
int test_glr(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
E -> E '-' T
|
||||||
|
| T
|
||||||
|
T -> '(' E ')'
|
||||||
|
| 'n' -- also try [0-9] for the charset paths
|
||||||
|
*/
|
||||||
|
|
||||||
|
HParser *n = h_ch('n');
|
||||||
|
HParser *E = h_indirect();
|
||||||
|
HParser *T = h_choice(h_sequence(h_ch('('), E, h_ch(')'), NULL), n, NULL);
|
||||||
|
HParser *E_ = h_choice(h_sequence(E, h_ch('-'), T, NULL), T, NULL);
|
||||||
|
h_bind_indirect(E, E_);
|
||||||
|
HParser *p = E;
|
||||||
|
|
||||||
|
printf("\n==== G R A M M A R ====\n");
|
||||||
|
HCFGrammar *g = h_cfgrammar(&system_allocator, p);
|
||||||
|
if(g == NULL) {
|
||||||
|
fprintf(stderr, "h_cfgrammar failed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
h_pprint_grammar(stdout, g, 0);
|
||||||
|
|
||||||
|
printf("\n==== D F A ====\n");
|
||||||
|
HLRDFA *dfa = h_lr0_dfa(g);
|
||||||
|
if(dfa)
|
||||||
|
h_pprint_lrdfa(stdout, g, dfa, 0);
|
||||||
|
else
|
||||||
|
fprintf(stderr, "h_lalr_dfa failed\n");
|
||||||
|
|
||||||
|
printf("\n==== L R ( 0 ) T A B L E ====\n");
|
||||||
|
HLRTable *table0 = h_lr0_table(g, dfa);
|
||||||
|
if(table0)
|
||||||
|
h_pprint_lrtable(stdout, g, table0, 0);
|
||||||
|
else
|
||||||
|
fprintf(stderr, "h_lr0_table failed\n");
|
||||||
|
h_lrtable_free(table0);
|
||||||
|
|
||||||
|
printf("\n==== L A L R T A B L E ====\n");
|
||||||
|
if(h_compile(p, PB_GLR, NULL)) {
|
||||||
|
fprintf(stderr, "does not compile\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
h_pprint_lrtable(stdout, g, (HLRTable *)p->backend_data, 0);
|
||||||
|
|
||||||
|
printf("\n==== P A R S E R E S U L T ====\n");
|
||||||
|
HParseResult *res = h_parse(p, (uint8_t *)"n-(n-((n)))-n", 13);
|
||||||
|
if(res)
|
||||||
|
h_pprint(stdout, res->ast, 0, 2);
|
||||||
|
else
|
||||||
|
printf("no parse\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -131,6 +131,7 @@ const HLRAction *h_lrengine_action(HLREngine *engine, HInputStream *stream);
|
||||||
bool h_lrengine_step(HLREngine *engine, const HLRAction *action);
|
bool h_lrengine_step(HLREngine *engine, const HLRAction *action);
|
||||||
HParseResult *h_lrengine_result(HLREngine *engine);
|
HParseResult *h_lrengine_result(HLREngine *engine);
|
||||||
HParseResult *h_lr_parse(HAllocator* mm__, const HParser* parser, HInputStream* stream);
|
HParseResult *h_lr_parse(HAllocator* mm__, const HParser* parser, HInputStream* stream);
|
||||||
|
HParseResult *h_glr_parse(HAllocator* mm__, const HParser* parser, HInputStream* stream);
|
||||||
|
|
||||||
void h_pprint_lritem(FILE *f, const HCFGrammar *g, const HLRItem *item);
|
void h_pprint_lritem(FILE *f, const HCFGrammar *g, const HLRItem *item);
|
||||||
void h_pprint_lrstate(FILE *f, const HCFGrammar *g,
|
void h_pprint_lrstate(FILE *f, const HCFGrammar *g,
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ static HParserBackendVTable *backends[PB_MAX + 1] = {
|
||||||
&h__regex_backend_vtable,
|
&h__regex_backend_vtable,
|
||||||
&h__llk_backend_vtable,
|
&h__llk_backend_vtable,
|
||||||
&h__lalr_backend_vtable,
|
&h__lalr_backend_vtable,
|
||||||
|
&h__glr_backend_vtable,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,8 @@ typedef enum HParserBackend_ {
|
||||||
PB_REGULAR,
|
PB_REGULAR,
|
||||||
PB_LLk,
|
PB_LLk,
|
||||||
PB_LALR,
|
PB_LALR,
|
||||||
PB_GLR, // Not Implemented
|
PB_GLR,
|
||||||
PB_MAX = PB_LALR
|
PB_MAX = PB_GLR
|
||||||
} HParserBackend;
|
} HParserBackend;
|
||||||
|
|
||||||
typedef enum HTokenType_ {
|
typedef enum HTokenType_ {
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,7 @@ struct HBitWriter_ {
|
||||||
extern HParserBackendVTable h__packrat_backend_vtable;
|
extern HParserBackendVTable h__packrat_backend_vtable;
|
||||||
extern HParserBackendVTable h__llk_backend_vtable;
|
extern HParserBackendVTable h__llk_backend_vtable;
|
||||||
extern HParserBackendVTable h__lalr_backend_vtable;
|
extern HParserBackendVTable h__lalr_backend_vtable;
|
||||||
|
extern HParserBackendVTable h__glr_backend_vtable;
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
// TODO(thequux): Set symbol visibility for these functions so that they aren't exported.
|
// TODO(thequux): Set symbol visibility for these functions so that they aren't exported.
|
||||||
|
|
|
||||||
|
|
@ -585,4 +585,42 @@ void register_parser_tests(void) {
|
||||||
g_test_add_data_func("/core/parser/lalr/ignore", GINT_TO_POINTER(PB_LALR), test_ignore);
|
g_test_add_data_func("/core/parser/lalr/ignore", GINT_TO_POINTER(PB_LALR), test_ignore);
|
||||||
g_test_add_data_func("/core/parser/lalr/leftrec", GINT_TO_POINTER(PB_LALR), test_leftrec);
|
g_test_add_data_func("/core/parser/lalr/leftrec", GINT_TO_POINTER(PB_LALR), test_leftrec);
|
||||||
g_test_add_data_func("/core/parser/lalr/rightrec", GINT_TO_POINTER(PB_LALR), test_rightrec);
|
g_test_add_data_func("/core/parser/lalr/rightrec", GINT_TO_POINTER(PB_LALR), test_rightrec);
|
||||||
|
|
||||||
|
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);
|
||||||
|
g_test_add_data_func("/core/parser/glr/ch_range", GINT_TO_POINTER(PB_GLR), test_ch_range);
|
||||||
|
g_test_add_data_func("/core/parser/glr/int64", GINT_TO_POINTER(PB_GLR), test_int64);
|
||||||
|
g_test_add_data_func("/core/parser/glr/int32", GINT_TO_POINTER(PB_GLR), test_int32);
|
||||||
|
g_test_add_data_func("/core/parser/glr/int16", GINT_TO_POINTER(PB_GLR), test_int16);
|
||||||
|
g_test_add_data_func("/core/parser/glr/int8", GINT_TO_POINTER(PB_GLR), test_int8);
|
||||||
|
g_test_add_data_func("/core/parser/glr/uint64", GINT_TO_POINTER(PB_GLR), test_uint64);
|
||||||
|
g_test_add_data_func("/core/parser/glr/uint32", GINT_TO_POINTER(PB_GLR), test_uint32);
|
||||||
|
g_test_add_data_func("/core/parser/glr/uint16", GINT_TO_POINTER(PB_GLR), test_uint16);
|
||||||
|
g_test_add_data_func("/core/parser/glr/uint8", GINT_TO_POINTER(PB_GLR), test_uint8);
|
||||||
|
g_test_add_data_func("/core/parser/glr/int_range", GINT_TO_POINTER(PB_GLR), test_int_range);
|
||||||
|
#if 0
|
||||||
|
g_test_add_data_func("/core/parser/glr/float64", GINT_TO_POINTER(PB_GLR), test_float64);
|
||||||
|
g_test_add_data_func("/core/parser/glr/float32", GINT_TO_POINTER(PB_GLR), test_float32);
|
||||||
|
#endif
|
||||||
|
g_test_add_data_func("/core/parser/glr/whitespace", GINT_TO_POINTER(PB_GLR), test_whitespace);
|
||||||
|
g_test_add_data_func("/core/parser/glr/left", GINT_TO_POINTER(PB_GLR), test_left);
|
||||||
|
g_test_add_data_func("/core/parser/glr/right", GINT_TO_POINTER(PB_GLR), test_right);
|
||||||
|
g_test_add_data_func("/core/parser/glr/middle", GINT_TO_POINTER(PB_GLR), test_middle);
|
||||||
|
g_test_add_data_func("/core/parser/glr/action", GINT_TO_POINTER(PB_GLR), test_action);
|
||||||
|
g_test_add_data_func("/core/parser/glr/in", GINT_TO_POINTER(PB_GLR), test_in);
|
||||||
|
g_test_add_data_func("/core/parser/glr/not_in", GINT_TO_POINTER(PB_GLR), test_not_in);
|
||||||
|
g_test_add_data_func("/core/parser/glr/end_p", GINT_TO_POINTER(PB_GLR), test_end_p);
|
||||||
|
g_test_add_data_func("/core/parser/glr/nothing_p", GINT_TO_POINTER(PB_GLR), test_nothing_p);
|
||||||
|
g_test_add_data_func("/core/parser/glr/sequence", GINT_TO_POINTER(PB_GLR), test_sequence);
|
||||||
|
g_test_add_data_func("/core/parser/glr/choice", GINT_TO_POINTER(PB_GLR), test_choice);
|
||||||
|
g_test_add_data_func("/core/parser/glr/many", GINT_TO_POINTER(PB_GLR), test_many);
|
||||||
|
g_test_add_data_func("/core/parser/glr/many1", GINT_TO_POINTER(PB_GLR), test_many1);
|
||||||
|
g_test_add_data_func("/core/parser/glr/optional", GINT_TO_POINTER(PB_GLR), test_optional);
|
||||||
|
g_test_add_data_func("/core/parser/glr/sepBy", GINT_TO_POINTER(PB_GLR), test_sepBy);
|
||||||
|
g_test_add_data_func("/core/parser/glr/sepBy1", GINT_TO_POINTER(PB_GLR), test_sepBy1);
|
||||||
|
g_test_add_data_func("/core/parser/glr/epsilon_p", GINT_TO_POINTER(PB_GLR), test_epsilon_p);
|
||||||
|
g_test_add_data_func("/core/parser/glr/attr_bool", GINT_TO_POINTER(PB_GLR), test_attr_bool);
|
||||||
|
g_test_add_data_func("/core/parser/glr/ignore", GINT_TO_POINTER(PB_GLR), test_ignore);
|
||||||
|
g_test_add_data_func("/core/parser/glr/leftrec", GINT_TO_POINTER(PB_GLR), test_leftrec);
|
||||||
|
g_test_add_data_func("/core/parser/glr/rightrec", GINT_TO_POINTER(PB_GLR), test_rightrec);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue