aboutsummaryrefslogtreecommitdiff
path: root/parts
diff options
context:
space:
mode:
Diffstat (limited to 'parts')
-rw-r--r--parts/grammar.h12
-rw-r--r--parts/symbol.h6
-rw-r--r--parts/table.h82
3 files changed, 89 insertions, 11 deletions
diff --git a/parts/grammar.h b/parts/grammar.h
index d1bf176..4505b1a 100644
--- a/parts/grammar.h
+++ b/parts/grammar.h
@@ -3,10 +3,20 @@
#include <stddef.h> // size_t
+enum precedence_flag {
+ PRECEDENCE_NO_ASSOC,
+ PRECEDENCE_RIGHT_ASSOC,
+ PRECEDENCE_LEFT_ASSOC,
+};
+
+#define PRECEDENCE_NUM(prec) ((prec) >> 2)
+#define PRECEDENCE_FLAG(prec) ((prec) & 0x3)
+
extern struct production {
symbol LHS;
symbol *RHS;
size_t nRHS;
+ unsigned int precedence;
} *grammar;
extern size_t total_productions;
@@ -29,7 +39,7 @@ void grammar_print_cstyle()
printf("{%d, (symbol[]){", grammar[i].LHS);
for(size_t j = 0; j < grammar[i].nRHS; j++)
printf("%d, ", grammar[i].RHS[j]);
- printf("}, %zu},\n", grammar[i].nRHS);
+ printf("}, %zu, %d},\n", grammar[i].nRHS, grammar[i].precedence);
}
}
diff --git a/parts/symbol.h b/parts/symbol.h
index 2190eca..c7314f4 100644
--- a/parts/symbol.h
+++ b/parts/symbol.h
@@ -11,10 +11,6 @@ extern int (*symbol_is_terminal)(symbol s);
extern int (*symbol_is_input_end)(symbol s);
extern int (*symbol_is_valid)(symbol s);
-// helper macro
-#define IMPLEMENT_FUNCPTR(type, name, args) \
- type __##name args; \
- type (*name) args = __##name; \
- type __##name args
+#include "util/util.h" //temp
#endif
diff --git a/parts/table.h b/parts/table.h
index f3099fe..ff4601f 100644
--- a/parts/table.h
+++ b/parts/table.h
@@ -2,13 +2,21 @@
#define TABLE_H
#include <stddef.h> // size_t
+#include "util/util.h"
+
+#define ACTION_TYPE(X) \
+ X(ACTION_NOT_SET) \
+ X(ACTION_SHIFT) \
+ X(ACTION_GOTO) \
+ X(ACTION_REDUCE) \
+ X(ACTION_ACCEPT)
+
+const char * const action_type_to_char[] = {
+ ACTION_TYPE(X_TO_STR)
+};
extern struct action {
- enum action_type {
- ACTION_NOT_SET = 0, ACTION_SHIFT,
- ACTION_GOTO, ACTION_REDUCE,
- ACTION_ACCEPT
- } type;
+ enum action_type { ACTION_TYPE(X_TO_ENUM) } type;
size_t arg;
} **table;
@@ -19,6 +27,7 @@ extern void (*table_free)();
void table_print();
void table_print_cstyle();
+int table_insert(size_t state, symbol sym, struct action a); // should it be here??
#include "symbol.h"
@@ -51,4 +60,67 @@ void table_print_cstyle()
}
}
+#include "grammar.h"
+int table_insert(size_t state, symbol sym, struct action a)
+{
+ struct action *tbl_a = &table[state][sym];
+ struct action *new_a = &a;
+
+ if(tbl_a->type == new_a->type && tbl_a->arg == new_a->arg) return 0;
+ if(tbl_a->type == ACTION_NOT_SET) {
+ *tbl_a = *new_a;
+ return 0;
+ }
+
+ int r = 0, report = 0, set_tbl_a = 0,
+ reduce_reduce = 0, shift_reduce = 0;
+ struct action *shift_a;
+
+ if((tbl_a->type == ACTION_REDUCE && new_a->type == ACTION_REDUCE)) reduce_reduce = 1;
+ else if((tbl_a->type == ACTION_REDUCE && new_a->type == ACTION_SHIFT)) { shift_reduce = 1;
+ shift_a = new_a;
+ } else if((tbl_a->type == ACTION_SHIFT && new_a->type == ACTION_REDUCE)) { shift_reduce = 1;
+ shift_a = tbl_a;
+ }
+
+#define prec_num(a) PRECEDENCE_NUM(grammar[(a)->arg].precedence)
+#define prec_flag(a) PRECEDENCE_FLAG(grammar[(a)->arg].precedence)
+
+ if(reduce_reduce || shift_reduce) {
+ if(prec_num(tbl_a) == 0 || prec_num(new_a) == 0) report = 1;
+
+ if(prec_num(tbl_a) > prec_num(new_a)) set_tbl_a = 0;
+ else if(prec_num(tbl_a) < prec_num(new_a)) set_tbl_a = 1;
+ else if(reduce_reduce) {
+ report = 1;
+ if(new_a->arg > tbl_a->arg) set_tbl_a = 1;
+ } else {
+ if(prec_flag(tbl_a) == PRECEDENCE_NO_ASSOC && tbl_a->arg == new_a->arg) {
+ report = 1; r = 2;
+ } else if(prec_flag(shift_a) == PRECEDENCE_LEFT_ASSOC) {
+ if(shift_a == tbl_a) set_tbl_a = 1; // favor reduce
+ }else {
+ if(shift_a == new_a) set_tbl_a = 1; // favor shift
+ }
+ }
+ } else {
+ r = 1; report = 1;
+ }
+
+ if(report) {
+ struct action *a0 = (set_tbl_a) ? new_a: tbl_a;
+ struct action *a1 = (set_tbl_a) ? tbl_a: new_a;
+
+ fprintf(stderr, "REPORT: table collission on state '%zu' sym '%d'\n", state, sym);
+ fprintf(stderr, "\t%s resolve: {%s %zu} %s {%s %zu}\n",
+ (r == 0) ? "SUCCESSFULLY" : "COULD NOT",
+ action_type_to_char[a0->type], a0->arg,
+ (r == 0) ? "over" : "vs",
+ action_type_to_char[a1->type], a1->arg);
+ }
+
+ if(!r && set_tbl_a) *tbl_a = *new_a;
+ return r;
+}
+
#endif