diff options
-rwxr-xr-x | build.sh | 16 | ||||
-rw-r--r-- | clr-table.c | 27 | ||||
-rw-r--r-- | parts/grammar.h | 4 | ||||
-rw-r--r-- | parts/table.h | 52 |
4 files changed, 66 insertions, 33 deletions
@@ -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; } |