diff --git a/src/Makefile b/src/Makefile index 7fac881ae0882fb0d436005d65dd63125914af4c..1a2bff3530ed897f50814fdfae949ff7d8ef635b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -28,6 +28,7 @@ PARSERS := \ BACKENDS := \ packrat \ llk \ + lalr \ regex HAMMER_PARTS := \ diff --git a/src/backends/lalr.c b/src/backends/lalr.c new file mode 100644 index 0000000000000000000000000000000000000000..22cd3890ded111238ba9c3bbff5b1fbebf6d5548 --- /dev/null +++ b/src/backends/lalr.c @@ -0,0 +1,86 @@ +#include <assert.h> +#include "../internal.h" +#include "../cfgrammar.h" +#include "../parsers/parser_internal.h" + + + +void h_lalr_free(HParser *parser) +{ + // XXX free data structures + parser->backend_data = NULL; + parser->backend = PB_PACKRAT; +} + + +/* LALR table generation */ + +int h_lalr_compile(HAllocator* mm__, HParser* parser, const void* params) +{ + return -1; +} + + +/* LR driver */ + +HParseResult *h_lr_parse(HAllocator* mm__, const HParser* parser, HInputStream* stream) +{ + return NULL; +} + + + + +HParserBackendVTable h__lalr_backend_vtable = { + .compile = h_lalr_compile, + .parse = h_lr_parse, + .free = h_lalr_free +}; + + + + +// dummy! +int test_lalr(void) +{ + /* for k=2: + + S -> A | B + A -> X Y a + B -> Y b + X -> x | '' + Y -> y -- for k=3 use "yy" + */ + + // XXX make LALR example + HParser *X = h_optional(h_ch('x')); + HParser *Y = h_sequence(h_ch('y'), h_ch('y'), NULL); + HParser *A = h_sequence(X, Y, h_ch('a'), NULL); + HParser *B = h_sequence(Y, h_ch('b'), NULL); + HParser *p = h_choice(A, B, NULL); + + HCFGrammar *g = h_cfgrammar(&system_allocator, p); + + if(g == NULL) { + fprintf(stderr, "h_cfgrammar failed\n"); + return 1; + } + + h_pprint_grammar(stdout, g, 0); + // print states of the LR(0) automaton + // print LALR(1) table + + if(h_compile(p, PB_LALR, NULL)) { + fprintf(stderr, "does not compile\n"); + return 2; + } + + + HParseResult *res = h_parse(p, (uint8_t *)"xyya", 4); + if(res) + h_pprint(stdout, res->ast, 0, 2); + else + printf("no parse\n"); + + return 0; +} diff --git a/src/hammer.c b/src/hammer.c index 5f94142908f48f86a0dde79ccd376c2625063635..7d5b4e90b2edd224f6f28a57d0b65bacf2de94b7 100644 --- a/src/hammer.c +++ b/src/hammer.c @@ -30,6 +30,7 @@ static HParserBackendVTable *backends[PB_MAX + 1] = { &h__packrat_backend_vtable, &h__regex_backend_vtable, &h__llk_backend_vtable, + &h__lalr_backend_vtable, }; diff --git a/src/hammer.h b/src/hammer.h index 455684cc92edbfbf9b9352625e373ca408f61261..a5ebcfff640bd33ba4459b1b59ea106033cb5eb2 100644 --- a/src/hammer.h +++ b/src/hammer.h @@ -34,11 +34,11 @@ typedef struct HParseState_ HParseState; typedef enum HParserBackend_ { PB_MIN = 0, PB_PACKRAT = PB_MIN, // PB_MIN is always the default. - PB_REGULAR, // - PB_LLk, // - PB_LALR, // Not Implemented + PB_REGULAR, + PB_LLk, + PB_LALR, PB_GLR, // Not Implemented - PB_MAX = PB_LLk + PB_MAX = PB_LALR } HParserBackend; typedef enum HTokenType_ { diff --git a/src/internal.h b/src/internal.h index 926bf02a6e54da52cf193443a12d0e3c7547ef35..01861f5e70189dedb3313a0db28f1ddf02f3c9a1 100644 --- a/src/internal.h +++ b/src/internal.h @@ -219,6 +219,7 @@ struct HBitWriter_ { // Backends {{{ extern HParserBackendVTable h__packrat_backend_vtable; extern HParserBackendVTable h__llk_backend_vtable; +extern HParserBackendVTable h__lalr_backend_vtable; // }}} // TODO(thequux): Set symbol visibility for these functions so that they aren't exported.