diff options
-rwxr-xr-x | build.sh | 2 | ||||
-rw-r--r-- | clr-table.c | 142 | ||||
-rw-r--r-- | fusion.c | 27 | ||||
-rw-r--r-- | lr-parser.c | 52 | ||||
-rw-r--r-- | parts/grammar.h | 22 | ||||
-rw-r--r-- | parts/symbol.h | 12 | ||||
-rw-r--r-- | parts/table.h | 50 | ||||
-rw-r--r-- | parts/toklist.h | 9 | ||||
-rw-r--r-- | parts/util-tables.h | 8 | ||||
-rw-r--r-- | slr-table.c | 112 | ||||
-rw-r--r-- | util-tables.c | 18 |
11 files changed, 254 insertions, 200 deletions
@@ -19,7 +19,7 @@ function leak # cc util-tables -D_UTIL_TABLES_STANDALONE # cc slr-table -D_SLR_TABLE_STANDALONE # cc clr-table -D_CLR_TABLE_STANDALONE -# cc lr-parser -D_LR_PARSER_STANDALONE -std=gnu99 +# cc lr-parser -D_LR_PARSER_STANDALONE cc fusion # leak lexer diff --git a/clr-table.c b/clr-table.c index b6bd47b..68ce3a4 100644 --- a/clr-table.c +++ b/clr-table.c @@ -8,49 +8,24 @@ void *xcalloc(size_t n, size_t size) { void *addr = calloc(n, size); return addr extern void *xcalloc(size_t n, size_t size); #endif -typedef unsigned int symbol; -extern const size_t total_symbols; +// Requirements +#include "parts/symbol.h" +#include "parts/grammar.h" +#include "parts/util-tables.h" -extern int symbol_is_terminal(symbol s); -extern int symbol_is_input_end(symbol s); - -extern struct production { - symbol LHS; - symbol *RHS; - size_t nRHS; -} grammar[]; -extern const size_t total_productions; - -void grammar_print() -{ - for(size_t i = 0; i < total_productions; i++) { - printf("%d --> ", grammar[i].LHS); - for(size_t j = 0; j < grammar[i].nRHS; j++) - printf("%d ", grammar[i].RHS[j]); - printf("\n"); - } -} - -extern int **first; -extern int **follow; - -struct action { - enum action_type { - ACTION_NOT_SET = 0, ACTION_SHIFT, - ACTION_GOTO, ACTION_REDUCE, - ACTION_ACCEPT - } type; - size_t arg; -}; +// Implements +#include "parts/table.h" #define TABLE_CAP 64 struct action *table[TABLE_CAP]; size_t table_states = 0; -void table_allocate() { for(size_t i = 0; i < TABLE_CAP; i++) table[i] = xcalloc(total_symbols, sizeof(*table[i])); } -void table_free() { for(size_t i = 0; i < TABLE_CAP; i++) free(table[i]); } -int table_insert(size_t state, symbol sym, struct action a); -void table_print(); +int table_fill(); +void table_free(); + +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]); } +static int table_insert(size_t state, symbol sym, struct action a); struct item { size_t prod_idx; @@ -58,7 +33,7 @@ struct item { symbol lookahead; }; -int item_eq(struct item *i1, struct item *i2) { return (i1->dot == i2->dot && i1->prod_idx == i2->prod_idx && i1->lookahead == i2->lookahead) ? 1 : 0; } +static int item_eq(struct item *i1, struct item *i2) { return (i1->dot == i2->dot && i1->prod_idx == i2->prod_idx && i1->lookahead == i2->lookahead) ? 1 : 0; } #define SEEN_SETS_CAP 64 static struct { @@ -68,12 +43,12 @@ static struct { } seen_sets[SEEN_SETS_CAP]; static size_t nseen_sets; -void seen_sets_free() { for(size_t i = 0; i < nseen_sets; i++) free(seen_sets[i].items);} +static void seen_sets_free() { for(size_t i = 0; i < nseen_sets; i++) free(seen_sets[i].items);} -size_t itemset_handle(struct item *set, size_t nset); -int itemset_insert(size_t state, struct item *initial_set, size_t ninitial); -size_t itemset_closure(struct item *in_set, size_t nin, struct item *out_set, size_t nout); -void itemset_print(struct item *set, size_t nset) +static size_t itemset_handle(struct item *set, size_t nset); +static int itemset_insert(size_t state, struct item *initial_set, size_t ninitial); +static size_t itemset_closure(struct item *in_set, size_t nin, struct item *out_set, size_t nout); +static void itemset_print(struct item *set, size_t nset) { printf("{"); for(size_t i = 0; i < nset; i++) @@ -81,7 +56,7 @@ void itemset_print(struct item *set, size_t nset) printf("}\n"); } -size_t itemset_handle(struct item *set, size_t nset) +static size_t itemset_handle(struct item *set, size_t nset) { // 1. is set in seen_sets for(size_t i = 0; i < nseen_sets; i++) { @@ -125,7 +100,7 @@ size_t itemset_handle(struct item *set, size_t nset) #define CLOSURE_SET_CAP 64 #define GOTO_SET_CAP 32 -int itemset_insert(size_t state, struct item *initial_set, size_t ninitial) +static int itemset_insert(size_t state, struct item *initial_set, size_t ninitial) { struct item closure_set[CLOSURE_SET_CAP]; @@ -179,7 +154,7 @@ int itemset_insert(size_t state, struct item *initial_set, size_t ninitial) return 0; } -size_t itemset_closure(struct item *in_set, size_t nin, struct item *out_set, size_t nout_max) +static size_t itemset_closure(struct item *in_set, size_t nin, struct item *out_set, size_t nout_max) { size_t nout = nin; @@ -226,7 +201,7 @@ cleanup: return nout; } -int table_insert(size_t state, symbol sym, struct action a) +static int table_insert(size_t state, symbol sym, struct action a) { if(table[state][sym].type != ACTION_NOT_SET) { fprintf(stderr, "TABLE COLLISION on state '%zu' sym '%d'\n", state, sym); @@ -240,31 +215,28 @@ int table_insert(size_t state, symbol sym, struct action a) return 0; } -void table_print() +int table_fill() { - printf(" "); - for(size_t sym = 0; sym < total_symbols; sym++) printf("%2zu ", sym); - printf("\n"); - - char action_to_char[] = {[ACTION_SHIFT] = 's', [ACTION_REDUCE] = 'r', [ACTION_GOTO] = 'g'}; - for(size_t i = 0; i < table_states; i++) { - printf("%2zu ", i); - for(size_t sym = 0; sym < total_symbols; sym++) - if(table[i][sym].type == ACTION_ACCEPT) printf(" a "); - else if(table[i][sym].type) printf("%c%-2zu ", action_to_char[table[i][sym].type], table[i][sym].arg); - else printf(" "); - printf("\n"); - } + 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; } -#ifdef _CLR_TABLE_STANDALONE +void table_free() +{ + seen_sets_free(); + table_deallocate(); +} -#include "util-tables.c" +#ifdef _CLR_TABLE_STANDALONE #ifndef CHOOSE_GRAMMAR -#define CHOOSE_GRAMMAR 1 // 0 or 1 +#define CHOOSE_GRAMMAR 0 // 0 or 1 #endif +// implement symbol.h enum symbol { #if (CHOOSE_GRAMMAR == 0) ID, EQUAL, STAR, @@ -284,6 +256,7 @@ const 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 grammar.h #define PROD(LHS, _, ...) {LHS, (symbol[]){__VA_ARGS__}, sizeof((symbol[]){__VA_ARGS__})/sizeof(symbol)} struct production grammar[] = { #if (CHOOSE_GRAMMAR == 0) @@ -303,17 +276,50 @@ struct production grammar[] = { const size_t total_productions = sizeof(grammar)/sizeof(*grammar); +// implement util-tables.h +#include "util-tables.c" + int main(void) { util_tables_fill(); - table_allocate(); - - itemset_handle((struct item[]){{0, 0, END_INPUT}}, 1); + table_fill(); + table_print(); - seen_sets_free(); table_free(); util_tables_free(); } #endif + +/* +---+------------------------+ + * | - | 0 1 2 3 4 5 | + * +---+------------------------+ + * | 0 | s1 s2 g4 g5 | + * | 1 | s1 s2 g3 | + * | 2 | r3 r3 | + * | 3 | r2 r2 | + * | 4 | a | + * | 5 | s6 s7 g9 | + * | 6 | s6 s7 g8 | + * | 7 | r3 | + * | 8 | r2 | + * | 9 | r1 | + * +---+------------------------+ + + 0 1 2 3 4 5 6 7 + 0 s1 s2 g5 g6 g13 + 1 r4 r4 + 2 s1 s2 g3 g4 + 3 r5 r5 + 4 r3 r3 + 5 a + 6 s7 r5 + 7 s8 s9 g10 g12 + 8 r4 + 9 s8 s9 g10 g11 +10 r5 +11 r3 +12 r1 +13 r2 + */ @@ -1,10 +1,7 @@ #include <stdio.h> #include <stdlib.h> -#include "util-tables.c" -#include "slr-table.c" -#include "lr-parser.c" - +#include "parts/symbol.h" enum symbol { PLUS = 0, MINUS, @@ -23,6 +20,7 @@ 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; } +#include "parts/grammar.h" #define PROD(LHS, _, ...) {LHS, (symbol[]){__VA_ARGS__}, sizeof((symbol[]){__VA_ARGS__})/sizeof(symbol)} struct production grammar[] = { PROD(EP, ->, E, END_INPUT), @@ -37,22 +35,25 @@ struct production grammar[] = { const size_t total_productions = sizeof(grammar)/sizeof(*grammar); -symbol toklist[] = {N0, PLUS, N1, MINUS, N0, N0, END_INPUT}; -symbol *tok = toklist; +#include "parts/toklist.h" +static symbol toklist[] = {N0, PLUS, N1, MINUS, N0, END_INPUT}; +static symbol *tok = toklist; -symbol toklist_eat() { return *(tok++); } -symbol toklist_peek() { return *tok; } +symbol toklist_eat() { return *(tok++); } // unsafe +symbol toklist_peek() { return *tok; } // unsafe + +#include "slr-table.c" +#include "util-tables.c" +#include "lr-parser.c" int main(void) { util_tables_fill(); - table_allocate(); - - itemset_handle((struct item[]){{0, 0}}, 1); + table_fill(); - lr_parser() && (exit(1), 1); + int r = 0; + r = lr_parser(); - seen_sets_free(); table_free(); util_tables_free(); diff --git a/lr-parser.c b/lr-parser.c index 3b0ecb7..41cc45b 100644 --- a/lr-parser.c +++ b/lr-parser.c @@ -1,42 +1,17 @@ #include <stdio.h> #include <stdlib.h> -typedef unsigned int symbol; -// extern const size_t total_symbols; - -// extern int symbol_is_terminal(symbol s); -// extern int symbol_is_input_end(symbol s); -extern int symbol_is_valid(symbol s); - -extern struct production { - symbol LHS; - symbol *RHS; - size_t nRHS; -} grammar[]; -extern const size_t total_productions; -// extern void grammar_print(); - -struct action { - enum action_type { - ACTION_NOT_SET = 0, ACTION_SHIFT, - ACTION_GOTO, ACTION_REDUCE, - ACTION_ACCEPT - } type; - size_t arg; -}; - -extern struct action *table[]; -extern size_t table_states; -// extern void table_print(); - -extern symbol toklist_eat(); -extern symbol toklist_peek(); +// Requirements +#include "parts/symbol.h" +#include "parts/grammar.h" +#include "parts/table.h" +#include "parts/toklist.h" typedef int stack_item; #define STACK_CAP 128 -stack_item stack_bottom[STACK_CAP]; -stack_item *stack_head = stack_bottom; +static stack_item stack_bottom[STACK_CAP]; +static stack_item *stack_head = stack_bottom; int lr_parser() { @@ -84,6 +59,7 @@ int lr_parser() #ifdef _LR_PARSER_STANDALONE +// implement symbol.h enum symbol { PLUS = 0, MINUS, @@ -100,6 +76,7 @@ const size_t total_symbols = SYMBOLS_END; 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[] = { PROD(EP, ->, E, END_INPUT), @@ -114,6 +91,7 @@ struct production grammar[] = { const size_t total_productions = sizeof(grammar)/sizeof(*grammar); +// implement table.h struct action *table[] = { (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},}, @@ -129,13 +107,15 @@ struct action *table[] = { (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},}, }; + size_t table_states = 13; -symbol toklist[] = {N0, PLUS, N1, END_INPUT}; -symbol *tok = toklist; +// implement toklist +static symbol toklist[] = {N0, PLUS, N1, END_INPUT}; +static symbol *tok = toklist; -symbol toklist_eat() { return *(tok++); } -symbol toklist_peek() { return *tok; } +symbol toklist_eat() { return *(tok++); } // unsafe +symbol toklist_peek() { return *tok; } // unsafe int main(void) { diff --git a/parts/grammar.h b/parts/grammar.h new file mode 100644 index 0000000..328f88e --- /dev/null +++ b/parts/grammar.h @@ -0,0 +1,22 @@ +#ifndef GRAMMAR_H +#define GRAMMAR_H + +extern struct production { + symbol LHS; + symbol *RHS; + size_t nRHS; +} grammar[]; + +extern const size_t total_productions; + +void grammar_print() +{ + for(size_t i = 0; i < total_productions; i++) { + printf("%d --> ", grammar[i].LHS); + for(size_t j = 0; j < grammar[i].nRHS; j++) + printf("%d ", grammar[i].RHS[j]); + printf("\n"); + } +} + +#endif diff --git a/parts/symbol.h b/parts/symbol.h new file mode 100644 index 0000000..d3cb5cd --- /dev/null +++ b/parts/symbol.h @@ -0,0 +1,12 @@ +#ifndef SYMBOL_H +#define SYMBOL_H + +typedef unsigned int symbol; +extern const 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); + +#endif diff --git a/parts/table.h b/parts/table.h new file mode 100644 index 0000000..3b54312 --- /dev/null +++ b/parts/table.h @@ -0,0 +1,50 @@ +#ifndef TABLE_H +#define TABLE_H + +extern struct action { + enum action_type { + ACTION_NOT_SET = 0, ACTION_SHIFT, + ACTION_GOTO, ACTION_REDUCE, + ACTION_ACCEPT + } type; + size_t arg; +} *table[]; + +extern size_t table_states; + +extern int table_fill(); +extern void table_free(); +void table_print(); +void table_print_cstyle(); + +#include "symbol.h" +void table_print() +{ + printf(" "); + for(size_t sym = 0; sym < total_symbols; sym++) printf("%2zu ", sym); + printf("\n"); + + char action_to_char[] = {[ACTION_SHIFT] = 's', [ACTION_REDUCE] = 'r', [ACTION_GOTO] = 'g'}; + for(size_t i = 0; i < table_states; i++) { + printf("%2zu ", i); + for(size_t sym = 0; sym < total_symbols; sym++) + if(table[i][sym].type == ACTION_ACCEPT) printf(" a "); + else if(table[i][sym].type) printf("%c%-2zu ", action_to_char[table[i][sym].type], table[i][sym].arg); + else printf(" "); + printf("\n"); + } + + +} + +void table_print_cstyle() +{ + for(size_t i = 0; i < table_states; i++) { + printf("{"); + for(size_t sym = 0; sym < total_symbols; sym++) + printf("{%d, %zu},", table[i][sym].type, table[i][sym].arg); + printf("},\n"); + } +} + +#endif diff --git a/parts/toklist.h b/parts/toklist.h new file mode 100644 index 0000000..b6fd10d --- /dev/null +++ b/parts/toklist.h @@ -0,0 +1,9 @@ +#ifndef TOKLIST_H +#define TOKLIST_H + +#include "symbol.h" + +extern symbol toklist_eat(); +extern symbol toklist_peek(); + +#endif diff --git a/parts/util-tables.h b/parts/util-tables.h new file mode 100644 index 0000000..a6d788a --- /dev/null +++ b/parts/util-tables.h @@ -0,0 +1,8 @@ +#ifndef UTIL_TABLES_H +#define UTIL_TABLES_H + +// extern int *nullable +extern int **follow; +extern int **first; + +#endif diff --git a/slr-table.c b/slr-table.c index 39e95ae..76399d7 100644 --- a/slr-table.c +++ b/slr-table.c @@ -8,55 +8,31 @@ void *xcalloc(size_t n, size_t size) { void *addr = calloc(n, size); return addr extern void *xcalloc(size_t n, size_t size); #endif -typedef unsigned int symbol; -extern const size_t total_symbols; +// Requirements +#include "parts/symbol.h" +#include "parts/grammar.h" +#include "parts/util-tables.h" -extern int symbol_is_terminal(symbol s); -extern int symbol_is_input_end(symbol s); - -extern struct production { - symbol LHS; - symbol *RHS; - size_t nRHS; -} grammar[]; -extern const size_t total_productions; - -void grammar_print() -{ - for(size_t i = 0; i < total_productions; i++) { - printf("%d --> ", grammar[i].LHS); - for(size_t j = 0; j < grammar[i].nRHS; j++) - printf("%d ", grammar[i].RHS[j]); - printf("\n"); - } -} - -extern int **follow; - -struct action { - enum action_type { - ACTION_NOT_SET = 0, ACTION_SHIFT, - ACTION_GOTO, ACTION_REDUCE, - ACTION_ACCEPT - } type; - size_t arg; -}; +// Implements +#include "parts/table.h" #define TABLE_CAP 64 struct action *table[TABLE_CAP]; size_t table_states = 0; -void table_allocate() { for(size_t i = 0; i < TABLE_CAP; i++) table[i] = xcalloc(total_symbols, sizeof(*table[i])); } -void table_free() { for(size_t i = 0; i < TABLE_CAP; i++) free(table[i]); } -int table_insert(size_t state, symbol sym, struct action a); -void table_print(); +int table_fill(); +void table_free(); + +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]); } +static int table_insert(size_t state, symbol sym, struct action a); struct item { size_t prod_idx; size_t dot; }; -int item_eq(struct item *i1, struct item *i2) { return (i1->dot == i2->dot && i1->prod_idx == i2->prod_idx) ? 1 : 0; } +static int item_eq(struct item *i1, struct item *i2) { return (i1->dot == i2->dot && i1->prod_idx == i2->prod_idx) ? 1 : 0; } #define SEEN_SETS_CAP 64 static struct { @@ -66,12 +42,12 @@ static struct { } seen_sets[SEEN_SETS_CAP]; static size_t nseen_sets; -void seen_sets_free() { for(size_t i = 0; i < nseen_sets; i++) free(seen_sets[i].items);} +static void seen_sets_free() { for(size_t i = 0; i < nseen_sets; i++) free(seen_sets[i].items);} -size_t itemset_handle(struct item *set, size_t nset); -int itemset_insert(size_t state, struct item *initial_set, size_t ninitial); -size_t itemset_closure(struct item *in_set, size_t nin, struct item *out_set, size_t nout); -void itemset_print(struct item *set, size_t nset) +static size_t itemset_handle(struct item *set, size_t nset); +static int itemset_insert(size_t state, struct item *initial_set, size_t ninitial); +static size_t itemset_closure(struct item *in_set, size_t nin, struct item *out_set, size_t nout); +static void itemset_print(struct item *set, size_t nset) { printf("{"); for(size_t i = 0; i < nset; i++) @@ -79,7 +55,7 @@ void itemset_print(struct item *set, size_t nset) printf("}\n"); } -size_t itemset_handle(struct item *set, size_t nset) +static size_t itemset_handle(struct item *set, size_t nset) { // 1. is set in seen_sets for(size_t i = 0; i < nseen_sets; i++) { @@ -123,7 +99,7 @@ size_t itemset_handle(struct item *set, size_t nset) #define CLOSURE_SET_CAP 64 #define GOTO_SET_CAP 32 -int itemset_insert(size_t state, struct item *initial_set, size_t ninitial) +static int itemset_insert(size_t state, struct item *initial_set, size_t ninitial) { struct item closure_set[CLOSURE_SET_CAP]; @@ -177,7 +153,7 @@ int itemset_insert(size_t state, struct item *initial_set, size_t ninitial) return 0; } -size_t itemset_closure(struct item *in_set, size_t nin, struct item *out_set, size_t nout_max) +static size_t itemset_closure(struct item *in_set, size_t nin, struct item *out_set, size_t nout_max) { size_t nout = nin; @@ -206,7 +182,7 @@ cleanup: return nout; } -int table_insert(size_t state, symbol sym, struct action a) +static int table_insert(size_t state, symbol sym, struct action a) { if(table[state][sym].type != ACTION_NOT_SET) { fprintf(stderr, "TABLE COLLISION on state '%zu' sym '%d'\n", state, sym); @@ -220,34 +196,22 @@ int table_insert(size_t state, symbol sym, struct action a) return 0; } -void table_print() +int table_fill() { - printf(" "); - for(size_t sym = 0; sym < total_symbols; sym++) printf("%2zu ", sym); - printf("\n"); - - char action_to_char[] = {[ACTION_SHIFT] = 's', [ACTION_REDUCE] = 'r', [ACTION_GOTO] = 'g'}; - for(size_t i = 0; i < table_states; i++) { - printf("%2zu ", i); - for(size_t sym = 0; sym < total_symbols; sym++) - if(table[i][sym].type == ACTION_ACCEPT) printf(" a "); - else if(table[i][sym].type) printf("%c%-2zu ", action_to_char[table[i][sym].type], table[i][sym].arg); - else printf(" "); - printf("\n"); - } + table_allocate(); + itemset_handle((struct item[]){{0, 0}}, 1); + return 0; +} - // for(size_t i = 0; i < table_states; i++) { - // printf("{"); - // for(size_t sym = 0; sym < total_symbols; sym++) - // printf("{%d, %d},", table[i][sym].type, table[i][sym].arg); - // printf("},\n"); - // } +void table_free() +{ + seen_sets_free(); + table_deallocate(); } #ifdef _SLR_TABLE_STANDALONE -#include "util-tables.c" - +// implement symbol.h enum symbol { PLUS = 0, MINUS, @@ -265,6 +229,7 @@ const 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 grammar.h #define PROD(LHS, _, ...) {LHS, (symbol[]){__VA_ARGS__}, sizeof((symbol[]){__VA_ARGS__})/sizeof(symbol)} struct production grammar[] = { PROD(EP, ->, E, END_INPUT), @@ -279,15 +244,16 @@ struct production grammar[] = { const size_t total_productions = sizeof(grammar)/sizeof(*grammar); +// implement util-tables.h +#include "util-tables.c" + int main(void) { util_tables_fill(); - table_allocate(); - - itemset_handle((struct item[]){{0, 0}}, 1); + table_fill(); + table_print(); - - seen_sets_free(); + table_free(); util_tables_free(); } diff --git a/util-tables.c b/util-tables.c index 0bd227d..83a015c 100644 --- a/util-tables.c +++ b/util-tables.c @@ -9,19 +9,15 @@ void *xcalloc(size_t n, size_t size) { void *addr = calloc(n, size); return addr extern void *xcalloc(size_t n, size_t size); #endif -typedef unsigned int symbol; -extern const size_t total_symbols; +// Requirements +#include "parts/symbol.h" +#include "parts/grammar.h" -extern struct production { - symbol LHS; - symbol *RHS; - size_t nRHS; -} grammar[]; -extern const size_t total_productions; +// Implements +#include "parts/util-tables.h" int **follow; int **first; -// int *nullable; void util_tables_fill() { @@ -110,6 +106,7 @@ void util_tables_print() #ifdef _UTIL_TABLES_STANDALONE +// implement symbol.h enum symbol { PLUS = 0, MINUS, @@ -121,12 +118,14 @@ enum symbol { EP, E, T, N, SYMBOLS_END, }; + const 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[] = { PROD(EP, ->, E, END_INPUT), @@ -138,6 +137,7 @@ struct production grammar[] = { PROD(N, -->, N0), PROD(N, -->, N1), }; + const size_t total_productions = sizeof(grammar)/sizeof(*grammar); int main(void) |