aboutsummaryrefslogtreecommitdiff
path: root/slr-table.c
diff options
context:
space:
mode:
Diffstat (limited to 'slr-table.c')
-rw-r--r--slr-table.c112
1 files changed, 39 insertions, 73 deletions
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();
}