From 55c9a3d9c51fb752e89c85f49987a124c35acc88 Mon Sep 17 00:00:00 2001 From: "Sven M. Hallberg" <pesco@khjk.org> Date: Wed, 19 Jun 2013 17:20:53 +0200 Subject: [PATCH] add stub GLR backend with h_glr_parse() a copy of h_lr_parse() --- src/Makefile | 3 +- src/backends/glr.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++ src/backends/lr.h | 1 + src/hammer.c | 1 + src/hammer.h | 4 +- src/internal.h | 1 + src/t_parser.c | 38 +++++++++++++++++++ 7 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 src/backends/glr.c diff --git a/src/Makefile b/src/Makefile index 380436ae..9ce6d9f8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -27,9 +27,10 @@ PARSERS := \ BACKENDS := \ packrat \ + regex \ llk \ lalr \ - regex + glr HAMMER_PARTS := \ bitreader.o \ diff --git a/src/backends/glr.c b/src/backends/glr.c new file mode 100644 index 00000000..c57ffd6b --- /dev/null +++ b/src/backends/glr.c @@ -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; +} diff --git a/src/backends/lr.h b/src/backends/lr.h index 13e10d41..f766d5b7 100644 --- a/src/backends/lr.h +++ b/src/backends/lr.h @@ -131,6 +131,7 @@ const HLRAction *h_lrengine_action(HLREngine *engine, HInputStream *stream); 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); +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_lrstate(FILE *f, const HCFGrammar *g, diff --git a/src/hammer.c b/src/hammer.c index 7d5b4e90..7fc80dba 100644 --- a/src/hammer.c +++ b/src/hammer.c @@ -31,6 +31,7 @@ static HParserBackendVTable *backends[PB_MAX + 1] = { &h__regex_backend_vtable, &h__llk_backend_vtable, &h__lalr_backend_vtable, + &h__glr_backend_vtable, }; diff --git a/src/hammer.h b/src/hammer.h index a5ebcfff..67fb8e4b 100644 --- a/src/hammer.h +++ b/src/hammer.h @@ -37,8 +37,8 @@ typedef enum HParserBackend_ { PB_REGULAR, PB_LLk, PB_LALR, - PB_GLR, // Not Implemented - PB_MAX = PB_LALR + PB_GLR, + PB_MAX = PB_GLR } HParserBackend; typedef enum HTokenType_ { diff --git a/src/internal.h b/src/internal.h index 2f3018df..d8b221a7 100644 --- a/src/internal.h +++ b/src/internal.h @@ -220,6 +220,7 @@ struct HBitWriter_ { extern HParserBackendVTable h__packrat_backend_vtable; extern HParserBackendVTable h__llk_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. diff --git a/src/t_parser.c b/src/t_parser.c index a0e4040b..57486cdc 100644 --- a/src/t_parser.c +++ b/src/t_parser.c @@ -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/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/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); } -- GitLab