aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild.sh2
-rw-r--r--clr-table.c142
-rw-r--r--fusion.c27
-rw-r--r--lr-parser.c52
-rw-r--r--parts/grammar.h22
-rw-r--r--parts/symbol.h12
-rw-r--r--parts/table.h50
-rw-r--r--parts/toklist.h9
-rw-r--r--parts/util-tables.h8
-rw-r--r--slr-table.c112
-rw-r--r--util-tables.c18
11 files changed, 254 insertions, 200 deletions
diff --git a/build.sh b/build.sh
index 2680884..464d86a 100755
--- a/build.sh
+++ b/build.sh
@@ -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
+ */
diff --git a/fusion.c b/fusion.c
index 1e4579f..3dc7dba 100644
--- a/fusion.c
+++ b/fusion.c
@@ -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)