aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild.sh16
-rw-r--r--clr-table.c27
-rw-r--r--parts/grammar.h4
-rw-r--r--parts/table.h52
4 files changed, 66 insertions, 33 deletions
diff --git a/build.sh b/build.sh
index c909bce..b4c62c8 100755
--- a/build.sh
+++ b/build.sh
@@ -48,8 +48,8 @@ function leak
# cc clr-table -D_CLR_TABLE_STANDALONE
# leak clr-table
-# cc clr-table "-D_CLR_TABLE_STANDALONE -D_LAZY_LALR" lalr-table
-# leak lalr-table
+cc clr-table "-D_CLR_TABLE_STANDALONE -D_LAZY_LALR" lalr-table
+leak lalr-table
# cc lr-parser -D_LR_PARSER_STANDALONE
# leak lr-parser
@@ -59,11 +59,11 @@ function leak
#--------------------------------------------------------------------------------------------------#
-cc demos/generate-parser "-rdynamic"
+# cc demos/generate-parser "-rdynamic"
# shared slr-table
# shared clr-table
-shared clr-table -D_LAZY_LALR lalr-table
+# shared clr-table -D_LAZY_LALR lalr-table
# shared demos/sample-files/lalr-defs
# --- Arithemitc example ---
@@ -73,7 +73,7 @@ shared clr-table -D_LAZY_LALR lalr-table
# leak parser "0-1+(1+0)-1+0"
# --- Calc example ---
-shared demos/sample-files/calc-defs
-leak "generate-parser -t lalr-table bin/calc-defs.so"
-cc demos/sample-files/calc-skeleton "" parser
-leak parser "4237-100+(17498+70)-1321+82910"
+# shared demos/sample-files/calc-defs
+# leak "generate-parser -t lalr-table bin/calc-defs.so"
+# cc demos/sample-files/calc-skeleton "" parser
+# leak parser "4237-100+(17498+70)-1321+82910"
diff --git a/clr-table.c b/clr-table.c
index 8f09ef1..7b7e057 100644
--- a/clr-table.c
+++ b/clr-table.c
@@ -259,10 +259,14 @@ enum symbol {
EP, E, L, R,
SYMBOLS_END,
#else
- SC, SD,
+ IF, ELSE, N, PLUS, TIMES, EQUAL,
END_INPUT,
- EP, E, C,
+ EP, E, STMT,
SYMBOLS_END
+ // SC, SD,
+ // END_INPUT,
+ // EP, E, C,
+ // SYMBOLS_END
#endif
};
@@ -272,7 +276,8 @@ 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), 0}
+// #define PROD(LHS, _, ...) {LHS, (symbol[]){__VA_ARGS__}, sizeof((symbol[]){__VA_ARGS__})/sizeof(symbol), 0}
+#define PROD(P, LHS, _, ...) {LHS, (symbol[]){__VA_ARGS__}, sizeof((symbol[]){__VA_ARGS__})/sizeof(symbol), P}
static struct production _grammar[] = {
#if (CHOOSE_GRAMMAR == 0)
PROD(EP, ->, E, END_INPUT),
@@ -282,10 +287,18 @@ static struct production _grammar[] = {
PROD(L, -->, ID),
PROD(R, -->, L),
#else
- PROD(EP, ->, E, END_INPUT),
- PROD(E, -->, C, C),
- PROD(C, -->, SC, C),
- PROD(C, -->, SD),
+ // PROD(EP, ->, E, END_INPUT),
+ // PROD(E, -->, C, C),
+ // PROD(C, -->, SC, C),
+ // PROD(C, -->, SD),
+ PROD(0, EP, ->, E, END_INPUT),
+ PROD(0, E, -->, STMT),
+ PROD(0, STMT, -->, IF, STMT),
+ PROD(0, STMT, -->, IF, STMT, ELSE, STMT),
+ PROD(0, STMT, -->, N),
+ PROD((2 << 2) | (PRECEDENCE_LEFT_ASSOC), STMT, -->, STMT, PLUS, STMT),
+ PROD((1 << 2) | (PRECEDENCE_NO_ASSOC), STMT, -->, STMT, EQUAL, STMT),
+ PROD((3 << 2) | (PRECEDENCE_LEFT_ASSOC), STMT, -->, STMT, TIMES, STMT),
#endif
};
diff --git a/parts/grammar.h b/parts/grammar.h
index 4505b1a..594e61e 100644
--- a/parts/grammar.h
+++ b/parts/grammar.h
@@ -4,9 +4,9 @@
#include <stddef.h> // size_t
enum precedence_flag {
- PRECEDENCE_NO_ASSOC,
- PRECEDENCE_RIGHT_ASSOC,
PRECEDENCE_LEFT_ASSOC,
+ PRECEDENCE_RIGHT_ASSOC,
+ PRECEDENCE_NO_ASSOC,
};
#define PRECEDENCE_NUM(prec) ((prec) >> 2)
diff --git a/parts/table.h b/parts/table.h
index ff4601f..01a6bbf 100644
--- a/parts/table.h
+++ b/parts/table.h
@@ -9,7 +9,8 @@
X(ACTION_SHIFT) \
X(ACTION_GOTO) \
X(ACTION_REDUCE) \
- X(ACTION_ACCEPT)
+ X(ACTION_ACCEPT) \
+ X(ACTION_ERROR)
const char * const action_type_to_char[] = {
ACTION_TYPE(X_TO_STR)
@@ -37,7 +38,7 @@ void table_print()
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'};
+ char action_to_char[] = {[ACTION_SHIFT] = 's', [ACTION_REDUCE] = 'r', [ACTION_GOTO] = 'g', [ACTION_ERROR] = 'e'};
for(size_t i = 0; i < table_states; i++) {
printf("%2zu ", i);
for(size_t sym = 0; sym < total_symbols; sym++)
@@ -73,36 +74,55 @@ int table_insert(size_t state, symbol sym, struct action a)
}
int r = 0, report = 0, set_tbl_a = 0,
- reduce_reduce = 0, shift_reduce = 0;
- struct action *shift_a;
+ reduce_reduce = 0, shift_reduce = 0,
+ shift_p, reduce_p, tbl_is_reduce;
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;
+ tbl_is_reduce = 1;
} else if((tbl_a->type == ACTION_SHIFT && new_a->type == ACTION_REDUCE)) { shift_reduce = 1;
- shift_a = tbl_a;
+ tbl_is_reduce = 0;
+ }
+
+ // bad hack to get precedence of the symbol
+ if(shift_reduce) {
+ for(size_t i = 0; i < total_productions; i++)
+ for(size_t j = 0; j < grammar[i].nRHS; j++)
+ if(grammar[i].RHS[j] == sym) {
+ shift_p = grammar[i].precedence;
+ goto out;
+ }
+ out:
+ if(tbl_is_reduce) reduce_p = grammar[tbl_a->arg].precedence;
+ else reduce_p = grammar[new_a->arg].precedence;
}
#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(reduce_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) {
+ else {
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 if(shift_reduce) {
+ int favor_shift = 0;
+ if(shift_p == 0 || reduce_p == 0) { favor_shift = 1; report = 1; }
+ else if(PRECEDENCE_NUM(shift_p) > PRECEDENCE_NUM(reduce_p)) favor_shift = 1;
+ else if(PRECEDENCE_NUM(reduce_p) > PRECEDENCE_NUM(shift_p)) favor_shift = 1;
+ else {
+ if(PRECEDENCE_FLAG(shift_p) == PRECEDENCE_LEFT_ASSOC) favor_shift = 1;
+ else if(PRECEDENCE_FLAG(shift_p) == PRECEDENCE_RIGHT_ASSOC) favor_shift = 0;
+ // else if(PRECEDENCE_FLAG(shift_p) == PRECEDENCE_NO_ASSOC &&
+ // PRECEDENCE_FLAG(reduce_p) == PRECEDENCE_NO_ASSOC) { set_tbl_a = 1; a.type = ACTION_ERROR; a.arg = 0; }
+ else { favor_shift = 1, report = 1; }
+ }
+
+ if(favor_shift && tbl_is_reduce || !favor_shift && !tbl_is_reduce) set_tbl_a = 1;
} else {
r = 1; report = 1;
}