diff options
Diffstat (limited to 'clr-table.c')
-rw-r--r-- | clr-table.c | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/clr-table.c b/clr-table.c index fb68826..ca23799 100644 --- a/clr-table.c +++ b/clr-table.c @@ -1,9 +1,9 @@ #include <stdio.h> #include <stdlib.h> #include <stdint.h> +#include <setjmp.h> -// TODO: idk but a good parser should just exit(1) -// like in itemset_handle() +// TODO: handle conflicts (itemset_insert returns 2 on table problem) #ifndef XCALLOC_IMPLEMENTED #define XCALLOC_IMPLEMENTED @@ -25,8 +25,7 @@ static struct action *__table[TABLE_CAP]; struct action **table = __table; size_t table_states = 0; -int table_fill(); -void table_free(); +static jmp_buf fail_jmpbuf; static void table_allocate() { for(size_t i = 0; i < TABLE_CAP; i++) table[i] = xcalloc(total_symbols, sizeof(*table[i])); } static void table_deallocate() { for(size_t i = 0; i < TABLE_CAP; i++) free(table[i]); } @@ -98,7 +97,7 @@ static size_t itemset_handle(struct item *set, size_t nset) // 2. add set to seen_sets if(nseen_sets >= SEEN_SETS_CAP) { fprintf(stderr, "ERROR: SEEN_SET_CAP exceeded\n"); - exit(1); + longjmp(fail_jmpbuf, 1); } seen_sets[nseen_sets].items = xcalloc(nset, sizeof(*set)); @@ -114,12 +113,12 @@ static size_t itemset_handle(struct item *set, size_t nset) #endif if(new_state >= TABLE_CAP) { fprintf(stderr, "ERROR: TABLE_CAP exceeded\n"); - exit(1); + longjmp(fail_jmpbuf, 1); } if(itemset_insert(new_state, set, nset)) { fprintf(stderr, "ERROR: itemset_insert failed\n"); - exit(1); + longjmp(fail_jmpbuf, 1); } return new_state; @@ -247,16 +246,18 @@ static int table_insert(size_t state, symbol sym, struct action a) return 0; } -int table_fill() +IMPLEMENT_FUNCPTR(int, table_fill, ()) { table_allocate(); + // Possible bug: wrong lookahead for kernel item of state, // but it may not really matter - itemset_handle((struct item[]){{0, 0, 0}}, 1); - return 0; + int r = setjmp(fail_jmpbuf); + if(r == 0) itemset_handle((struct item[]){{0, 0, 0}}, 1); + return r; } -void table_free() +IMPLEMENT_FUNCPTR(void, table_free, ()) { seen_sets_free(); table_deallocate(); @@ -285,8 +286,8 @@ enum symbol { 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_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)} @@ -314,18 +315,17 @@ size_t total_productions = sizeof(_grammar)/sizeof(*_grammar); int main(void) { + int r = 0; + util_tables_fill(); - table_fill(); + if((r = table_fill())) goto cleanup; table_print(); - for(size_t i = 0; i < nseen_sets; i++) - { - printf("\nSTATE: %zu\n", i); - itemset_print(seen_sets[i].items, seen_sets[i].nitems); - } +cleanup: table_free(); util_tables_free(); + return r; } #endif |