diff options
-rwxr-xr-x | build.sh | 13 | ||||
-rw-r--r-- | clr-table.c | 9 | ||||
-rw-r--r-- | compile_flags.txt | 5 | ||||
-rw-r--r-- | demos/generate-parser.c | 64 | ||||
-rw-r--r-- | demos/instant-parser.c | 13 | ||||
-rw-r--r-- | demos/sample-files/defs.c | 48 | ||||
-rw-r--r-- | demos/sample-files/parser-skeleton.c | 30 | ||||
-rw-r--r-- | lr-parser.c | 10 | ||||
-rw-r--r-- | parts/grammar.h | 14 | ||||
-rw-r--r-- | parts/symbol.h | 11 | ||||
-rw-r--r-- | parts/table.h | 7 | ||||
-rw-r--r-- | parts/toklist.h | 4 | ||||
-rw-r--r-- | parts/util-tables.h | 4 | ||||
-rw-r--r-- | slr-table.c | 9 | ||||
-rw-r--r-- | util-tables.c | 10 |
15 files changed, 188 insertions, 63 deletions
@@ -28,8 +28,7 @@ function leak # cc clr-table "-D_CLR_TABLE_STANDALONE -D_LAZY_LALR" # cc lr-parser -D_LR_PARSER_STANDALONE # cc demos/instant-parser -cc demos/generate-parser -shared demos/sample-files/defs + # leak lexer # leak recursive-ascent @@ -39,4 +38,12 @@ shared demos/sample-files/defs # leak clr-table # leak lr-parser # leak instant-parser -leak "generate-parser bin/defs.so" + +#--------------------------------------------------------------------------------------------------# + +cc demos/generate-parser +shared demos/sample-files/defs + +leak "generate-parser bin/defs.so" > bin/generated.c +cc demos/sample-files/parser-skeleton # this includes bin/generated.c +leak parser-skeleton diff --git a/clr-table.c b/clr-table.c index 37b2cd6..82f553d 100644 --- a/clr-table.c +++ b/clr-table.c @@ -268,12 +268,12 @@ 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; } +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 grammar.h #define PROD(LHS, _, ...) {LHS, (symbol[]){__VA_ARGS__}, sizeof((symbol[]){__VA_ARGS__})/sizeof(symbol)} -struct production grammar[] = { +static struct production _grammar[] = { #if (CHOOSE_GRAMMAR == 0) PROD(EP, ->, E, END_INPUT), PROD(E, -->, L, EQUAL, R), @@ -289,7 +289,8 @@ struct production grammar[] = { #endif }; -const size_t total_productions = sizeof(grammar)/sizeof(*grammar); +struct production *grammar = _grammar; +size_t total_productions = sizeof(_grammar)/sizeof(*_grammar); // implement util-tables.h #include "util-tables.c" diff --git a/compile_flags.txt b/compile_flags.txt new file mode 100644 index 0000000..d56e238 --- /dev/null +++ b/compile_flags.txt @@ -0,0 +1,5 @@ +-Wall +-Wextra +-Wpedantic +-I. +-g 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 <stdio.h> +#include <stdlib.h> #include <dlfcn.h> -#include <parts/table.h> - -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 <stdio.h> #include <stddef.h> -#include <parts/table.h> +#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 <stdio.h> +#include <stdlib.h> + +#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(); +} diff --git a/lr-parser.c b/lr-parser.c index 2358164..9f7ea24 100644 --- a/lr-parser.c +++ b/lr-parser.c @@ -1,6 +1,9 @@ #include <stdio.h> #include <stdlib.h> +// TODO: check erros and fail safely and +// see connection with the lexer + // Requirements #include "parts/symbol.h" #include "parts/grammar.h" @@ -74,11 +77,11 @@ enum symbol { size_t total_symbols = SYMBOLS_END; -int symbol_is_valid(symbol s) { return s < SYMBOLS_END; } +IMPLEMENT_FUNCPTR(int, symbol_is_valid, (symbol s), { return s < SYMBOLS_END; }) // implement 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), @@ -89,7 +92,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); // implement table.h struct action **table = (struct action *([])){ diff --git a/parts/grammar.h b/parts/grammar.h index 328f88e..a02a99e 100644 --- a/parts/grammar.h +++ b/parts/grammar.h @@ -5,9 +5,9 @@ extern struct production { symbol LHS; symbol *RHS; size_t nRHS; -} grammar[]; +} *grammar; -extern const size_t total_productions; +extern size_t total_productions; void grammar_print() { @@ -18,5 +18,15 @@ void grammar_print() printf("\n"); } } +void grammar_print_cstyle() + +{ + for(size_t i = 0; i < total_productions; i++) { + printf("{%d, (symbol[]){", grammar[i].LHS); + for(size_t j = 0; j < grammar[i].nRHS; j++) + printf("%d, ", grammar[i].RHS[j]); + printf("}, %zu},\n", grammar[i].nRHS); + } +} #endif diff --git a/parts/symbol.h b/parts/symbol.h index 5f865ec..2e9c30c 100644 --- a/parts/symbol.h +++ b/parts/symbol.h @@ -5,8 +5,13 @@ typedef unsigned int symbol; extern size_t total_symbols; // extern char *symbol_to_str[] ... -extern int symbol_is_terminal(symbol s); -extern int symbol_is_input_end(symbol s); -extern int symbol_is_valid(symbol s); +extern int (*symbol_is_terminal)(symbol s); +extern int (*symbol_is_input_end)(symbol s); +extern int (*symbol_is_valid)(symbol s); + +// helper macro +#define IMPLEMENT_FUNCPTR(type, name, args, ...) \ + type __##name args __VA_ARGS__ \ + type (*name) args = __##name; #endif diff --git a/parts/table.h b/parts/table.h index 23c61dc..44d1e12 100644 --- a/parts/table.h +++ b/parts/table.h @@ -12,12 +12,13 @@ extern struct action { extern size_t table_states; -extern int table_fill(); -extern void table_free(); +/*extern*/ int table_fill(); +/*extern*/ void table_free(); void table_print(); void table_print_cstyle(); #include "symbol.h" + void table_print() { printf(" "); @@ -40,7 +41,7 @@ void table_print() void table_print_cstyle() { for(size_t i = 0; i < table_states; i++) { - printf("{"); + printf("(struct action[]){"); for(size_t sym = 0; sym < total_symbols; sym++) printf("{%d, %zu},", table[i][sym].type, table[i][sym].arg); printf("},\n"); diff --git a/parts/toklist.h b/parts/toklist.h index 9a7b8ce..a6fe68d 100644 --- a/parts/toklist.h +++ b/parts/toklist.h @@ -3,7 +3,7 @@ #include "symbol.h" -extern symbol toklist_eat(); -extern symbol toklist_peek(); +/*extern*/ symbol toklist_eat(); +/*extern*/ symbol toklist_peek(); #endif diff --git a/parts/util-tables.h b/parts/util-tables.h index 66ecab5..6e173cf 100644 --- a/parts/util-tables.h +++ b/parts/util-tables.h @@ -5,7 +5,7 @@ extern int **follow; extern int **first; -extern void util_tables_fill(); -extern void util_tables_free(); +/*extern*/ void util_tables_fill(); +/*extern*/ void util_tables_free(); #endif diff --git a/slr-table.c b/slr-table.c index d5f4505..9bcdc3e 100644 --- a/slr-table.c +++ b/slr-table.c @@ -227,12 +227,12 @@ 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; } +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 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), @@ -243,7 +243,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); // implement util-tables.h #include "util-tables.c" diff --git a/util-tables.c b/util-tables.c index 09df914..507153d 100644 --- a/util-tables.c +++ b/util-tables.c @@ -121,13 +121,9 @@ enum symbol { size_t total_symbols = SYMBOLS_END; -int symbol_is_terminal(symbol s) { return s < E; } -int symbol_is_nonterminal(symbol s) { return s >= E; } -int symbol_is_input_end(symbol s) { return s == END_INPUT; } - // implement 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), @@ -137,8 +133,8 @@ struct production grammar[] = { PROD(N, -->, N0), PROD(N, -->, N1), }; - -const size_t total_productions = sizeof(grammar)/sizeof(*grammar); +struct production *grammar = _grammar; +size_t total_productions = sizeof(_grammar)/sizeof(*_grammar); int main(void) { |