From f2bef76fb369d4c9c3e53dca60eb78b75bb02d97 Mon Sep 17 00:00:00 2001 From: kartofen Date: Thu, 3 Jul 2025 19:11:36 +0300 Subject: working more or less parser generator (no semantic action, so pretty much useless --- demos/generate-parser.c | 64 +++++++++++++++++++++++++++++++----- demos/instant-parser.c | 13 +++++--- demos/sample-files/defs.c | 48 +++++++++++++++++---------- demos/sample-files/parser-skeleton.c | 30 +++++++++++++++++ 4 files changed, 125 insertions(+), 30 deletions(-) create mode 100644 demos/sample-files/parser-skeleton.c (limited to 'demos') diff --git a/demos/generate-parser.c b/demos/generate-parser.c index b0a769d..fc022be 100644 --- a/demos/generate-parser.c +++ b/demos/generate-parser.c @@ -1,11 +1,37 @@ #include +#include #include -#include - -struct action **table; -size_t table_states; +#include "parts/symbol.h" +#include "parts/table.h" size_t total_symbols; +int (*symbol_is_terminal)(symbol s); +int (*symbol_is_input_end)(symbol s); +int (*symbol_is_valid)(symbol s); + +#include "parts/grammar.h" + +struct production *grammar; +size_t total_productions; + +#include "util-tables.c" + +// _LAZY_LALR on clr does not work?? +#include "slr-table.c" + +void *xdlsym(void *handle, char *sym) +{ + void *r = dlsym(handle, sym); + if(!r) { + fprintf(stderr, "ERROR: Symbol \"%s\" was not found\n", sym); + exit(1); + } + return r; +} + + +#define GET_VARIABLE(var, handle) \ + var = *(typeof(&var))xdlsym(handle, #var) int main(int argc, char **argv) { @@ -13,13 +39,35 @@ int main(int argc, char **argv) void *handle = dlopen(argv[1], RTLD_LAZY); if(!handle) { puts(dlerror()); return 1; } + + GET_VARIABLE(total_symbols, handle); + GET_VARIABLE(symbol_is_terminal, handle); + GET_VARIABLE(symbol_is_input_end, handle); + GET_VARIABLE(symbol_is_valid, handle); + GET_VARIABLE(grammar, handle); + GET_VARIABLE(total_productions, handle); + + util_tables_fill(); + table_fill() && (exit(1), 1); - table = *(typeof(&table))dlsym(handle, "table"); - table_states = *(typeof(&table_states))dlsym(handle, "table_states"); - total_symbols = *(typeof(&total_symbols))dlsym(handle, "total_symbols"); + printf("size_t total_symbols = %zu;\n", total_symbols); + printf("IMPLEMENT_FUNCPTR(int, symbol_is_valid, (symbol s), {return s >= 0 && s < total_symbols;})\n"); - table_print(); + printf("struct production _grammar[] = {\n"); + grammar_print_cstyle(); + printf("};\n"); + printf("struct production *grammar = _grammar;"); + printf("size_t total_productions = %zu;\n", total_productions); + + printf("struct action **table = (struct action *([])){\n", table_states, total_symbols); + table_print_cstyle(); + printf("};\n"); + printf("size_t table_states = %zu;\n", table_states); + + table_free(); + util_tables_free(); + dlclose(handle); return 0; } diff --git a/demos/instant-parser.c b/demos/instant-parser.c index 3a82b07..57d1f2f 100644 --- a/demos/instant-parser.c +++ b/demos/instant-parser.c @@ -16,13 +16,13 @@ enum symbol { size_t total_symbols = SYMBOLS_END; -int symbol_is_terminal(symbol s) { return s < EP; } -int symbol_is_input_end(symbol s) { return s == END_INPUT; } -int symbol_is_valid(symbol s) { return s < SYMBOLS_END; } +IMPLEMENT_FUNCPTR(int, symbol_is_terminal, (symbol s), { return s < EP; }) +IMPLEMENT_FUNCPTR(int, symbol_is_input_end, (symbol s), { return s == END_INPUT; }) +IMPLEMENT_FUNCPTR(int, symbol_is_valid,(symbol s), { return s < SYMBOLS_END; }) #include "parts/grammar.h" #define PROD(LHS, _, ...) {LHS, (symbol[]){__VA_ARGS__}, sizeof((symbol[]){__VA_ARGS__})/sizeof(symbol)} -struct production grammar[] = { +static struct production _grammar[] = { PROD(EP, ->, E, END_INPUT), PROD(E, -->, E, PLUS, T), PROD(E, -->, E, MINUS, T), @@ -33,7 +33,8 @@ struct production grammar[] = { PROD(N, -->, N1), }; -const size_t total_productions = sizeof(grammar)/sizeof(*grammar); +struct production *grammar = _grammar; +size_t total_productions = sizeof(_grammar)/sizeof(*_grammar); #include "parts/toklist.h" static symbol toklist[] = {N0, PLUS, N1, MINUS, N0, END_INPUT}; @@ -51,6 +52,8 @@ int main(void) util_tables_fill(); table_fill(); + table_print(); + int r = 0; r = lr_parser(); diff --git a/demos/sample-files/defs.c b/demos/sample-files/defs.c index 797c86d..92d6837 100644 --- a/demos/sample-files/defs.c +++ b/demos/sample-files/defs.c @@ -1,23 +1,37 @@ #include #include -#include +#include "parts/symbol.h" +enum symbol { + PLUS = 0, + MINUS, + LPAREN, + RPAREN, + N0, N1, + END_INPUT, -struct action **table = (struct action *([])){ - (struct action[]){{0, 0},{0, 0},{1, 1},{0, 0},{1, 2},{1, 3},{0, 0},{0, 0},{2, 12},{2, 11},{2, 7},}, - (struct action[]){{0, 0},{0, 0},{1, 1},{0, 0},{1, 2},{1, 3},{0, 0},{0, 0},{2, 4},{2, 11},{2, 7},}, - (struct action[]){{3, 6},{3, 6},{0, 0},{3, 6},{0, 0},{0, 0},{3, 6},{0, 0},{0, 0},{0, 0},{0, 0},}, - (struct action[]){{3, 7},{3, 7},{0, 0},{3, 7},{0, 0},{0, 0},{3, 7},{0, 0},{0, 0},{0, 0},{0, 0},}, - (struct action[]){{1, 5},{1, 8},{0, 0},{1, 10},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},}, - (struct action[]){{0, 0},{0, 0},{1, 1},{0, 0},{1, 2},{1, 3},{0, 0},{0, 0},{0, 0},{2, 6},{2, 7},}, - (struct action[]){{3, 1},{3, 1},{0, 0},{3, 1},{0, 0},{0, 0},{3, 1},{0, 0},{0, 0},{0, 0},{0, 0},}, - (struct action[]){{3, 5},{3, 5},{0, 0},{3, 5},{0, 0},{0, 0},{3, 5},{0, 0},{0, 0},{0, 0},{0, 0},}, - (struct action[]){{0, 0},{0, 0},{1, 1},{0, 0},{1, 2},{1, 3},{0, 0},{0, 0},{0, 0},{2, 9},{2, 7},}, - (struct action[]){{3, 2},{3, 2},{0, 0},{3, 2},{0, 0},{0, 0},{3, 2},{0, 0},{0, 0},{0, 0},{0, 0},}, - (struct action[]){{3, 4},{3, 4},{0, 0},{3, 4},{0, 0},{0, 0},{3, 4},{0, 0},{0, 0},{0, 0},{0, 0},}, - (struct action[]){{3, 3},{3, 3},{0, 0},{3, 3},{0, 0},{0, 0},{3, 3},{0, 0},{0, 0},{0, 0},{0, 0},}, - (struct action[]){{1, 5},{1, 8},{0, 0},{0, 0},{0, 0},{0, 0},{4, 0},{0, 0},{0, 0},{0, 0},{0, 0},}, + EP, E, T, N, + SYMBOLS_END, }; -size_t total_symbols = 10; -size_t table_states = 13; +size_t total_symbols = SYMBOLS_END; + +IMPLEMENT_FUNCPTR(int, symbol_is_terminal, (symbol s), { return s < EP; }) +IMPLEMENT_FUNCPTR(int, symbol_is_input_end, (symbol s), { return s == END_INPUT; }) +IMPLEMENT_FUNCPTR(int, symbol_is_valid,(symbol s), { return s < SYMBOLS_END; }) + +#include "parts/grammar.h" +#define PROD(LHS, _, ...) {LHS, (symbol[]){__VA_ARGS__}, sizeof((symbol[]){__VA_ARGS__})/sizeof(symbol)} +static struct production _grammar[] = { + PROD(EP, ->, E, END_INPUT), + PROD(E, -->, E, PLUS, T), + PROD(E, -->, E, MINUS, T), + PROD(E, -->, T), + PROD(T, -->, LPAREN, E, RPAREN), + PROD(T, -->, N), + PROD(N, -->, N0), + PROD(N, -->, N1), +}; + +struct production *grammar = _grammar; +size_t total_productions = sizeof(_grammar)/sizeof(*_grammar); diff --git a/demos/sample-files/parser-skeleton.c b/demos/sample-files/parser-skeleton.c new file mode 100644 index 0000000..facbc1b --- /dev/null +++ b/demos/sample-files/parser-skeleton.c @@ -0,0 +1,30 @@ +#include +#include + +#include "lr-parser.c" +#include "bin/generated.c" + +#include "parts/toklist.h" + +enum symbol { + PLUS = 0, + MINUS, + LPAREN, + RPAREN, + N0, N1, + END_INPUT, + + EP, E, T, N, + SYMBOLS_END, +}; + +static symbol toklist[] = {N0, PLUS, N1, END_INPUT}; +static symbol *tok = toklist; + +symbol toklist_eat() { return *(tok++); } // unsafe +symbol toklist_peek() { return *tok; } // unsafe + +int main(void) +{ + return lr_parser(); +} -- cgit v1.2.3