#include #include #include #define DEFUALT_PATH "./bin" #define DEFUALT_TYPE "lalr-table" #include "parts/symbol.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; char **semantic_action_str; #include "parts/table.h" struct action **table; size_t table_states; int (*table_fill)(); void (*table_free)(); #include "util-tables.c" void *xdlsym(void *handle, char *sym) { void *r = dlsym(handle, sym); if(!r) { fprintf(stderr, "ERROR: Symbol '%s' was not found\n", sym); dlclose(handle); exit(1); } return r; } #define GET_VARIABLE(var, handle) \ var = *(typeof(&var))xdlsym(handle, #var) char *modpath(char *name) { static char fullpath[128]; char *path = getenv("GENERATE_PARSER_PATH"); if(!path) path = DEFUALT_PATH; snprintf(fullpath, 128, "%s/%s.so", path, name); return fullpath; } int main(int argc, char **argv) { if(argc < 2) return -1; void *table_handle; void *def_handle; if(argc == 2) { table_handle = dlopen(modpath(DEFUALT_TYPE), RTLD_LAZY); if(!table_handle) { fputs(dlerror(), stderr); return 1; } def_handle = dlopen(argv[1], RTLD_LAZY); if(!def_handle) { fputs(dlerror(), stderr); return 1; } } else if(argc == 4 && argv[1][0] == '-' && argv[1][1] == 't') { table_handle = dlopen(modpath(argv[2]), RTLD_LAZY); if(!table_handle) { fputs(dlerror(), stderr); return 1; } def_handle = dlopen(argv[3], RTLD_LAZY); if(!def_handle) { fputs(dlerror(), stderr); return 1; } } else return -1; GET_VARIABLE(table, table_handle); GET_VARIABLE(table_states, table_handle); GET_VARIABLE(table_fill, table_handle); GET_VARIABLE(table_free, table_handle); GET_VARIABLE(total_symbols, def_handle); GET_VARIABLE(symbol_is_terminal, def_handle); GET_VARIABLE(symbol_is_input_end, def_handle); GET_VARIABLE(symbol_is_valid, def_handle); GET_VARIABLE(grammar, def_handle); GET_VARIABLE(total_productions, def_handle); GET_VARIABLE(semantic_action_str, def_handle); util_tables_fill(); int r = 0; if((r = table_fill())) { fprintf(stderr, "ERROR: Table couldn't be generated\n"); goto cleanup; } printf("size_t total_symbols = %zu;\n", total_symbols); printf("IMPLEMENT_FUNCPTR(int, symbol_is_valid, (symbol s)) {return s < total_symbols;}\n"); 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_print_cstyle(); printf("};\n"); printf("size_t table_states = %zu;\n", table_states); for(size_t i = 0; i < total_productions; i++) { printf("#define A(n) (*(stack_head-3*%zu+3*n-1))\n", grammar[i].nRHS-1); printf("int __prod%zu_action(int *stack_head)\n", i); printf("{ int v;\n"); printf(semantic_action_str[i]); printf("return v; }\n"); printf("#undef A\n"); } printf("typedef int (*semantic_action_fn)(int *stack_head);\n"); printf("semantic_action_fn *semantic_actions = (semantic_action_fn[]){\n"); for(size_t i = 0; i < total_productions; i++) printf("__prod%zu_action, ", i); printf("};"); cleanup: table_free(); util_tables_free(); dlclose(table_handle); dlclose(def_handle); return r; }