aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild.sh30
-rw-r--r--clr-table.c42
-rw-r--r--demos/generate-parser.c54
-rw-r--r--demos/sample-files/arithmetic-defs.c49
-rw-r--r--demos/sample-files/arithmetic-skeleton.c62
-rw-r--r--demos/sample-files/calc-defs.c40
-rw-r--r--demos/sample-files/calc-skeleton.c12
-rw-r--r--lr-parser.c5
-rw-r--r--parts/grammar.h12
-rw-r--r--parts/precedence.h17
-rw-r--r--parts/table.h41
-rw-r--r--slr-table.c7
-rw-r--r--util-tables.c1
13 files changed, 172 insertions, 200 deletions
diff --git a/build.sh b/build.sh
index b4c62c8..aa0c308 100755
--- a/build.sh
+++ b/build.sh
@@ -24,7 +24,7 @@ function shared
function leak
{
- log valgrind --leak-check=full --show-leak-kinds=all -s bin/$1 $2
+ log valgrind --leak-check=full --show-leak-kinds=all -s bin/$1 "$2"
}
# cc util/dict -D_DICT_STANDALONE
@@ -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,21 +59,15 @@ leak lalr-table
#--------------------------------------------------------------------------------------------------#
-# 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 demos/sample-files/lalr-defs
-
-# --- Arithemitc example ---
-# shared demos/sample-files/arithmetic-defs
-# leak "generate-parser -t lalr-table bin/arithmetic-defs.so"
-# cc demos/sample-files/arithmetic-skeleton "" parser
-# leak parser "0-1+(1+0)-1+0"
+shared slr-table
+shared clr-table
+shared clr-table -D_LAZY_LALR lalr-table
+shared demos/sample-files/lalr-defs
# --- 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 "13*10+9 - (54*(10+8))"
diff --git a/clr-table.c b/clr-table.c
index 7b7e057..af39441 100644
--- a/clr-table.c
+++ b/clr-table.c
@@ -15,6 +15,7 @@ extern void *xcalloc(size_t n, size_t size);
// Requirements
#include "parts/symbol.h"
#include "parts/grammar.h"
+#include "parts/precedence.h"
#include "parts/util-tables.h"
// Implements
@@ -259,14 +260,14 @@ enum symbol {
EP, E, L, R,
SYMBOLS_END,
#else
- IF, ELSE, N, PLUS, TIMES, EQUAL,
- END_INPUT,
- EP, E, STMT,
- SYMBOLS_END
// SC, SD,
// END_INPUT,
// EP, E, C,
// SYMBOLS_END
+ IF, ELSE, N, PLUS, TIMES, EQUAL,
+ END_INPUT,
+ EP, E, STMT,
+ SYMBOLS_END
#endif
};
@@ -276,8 +277,7 @@ 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(P, LHS, _, ...) {LHS, (symbol[]){__VA_ARGS__}, sizeof((symbol[]){__VA_ARGS__})/sizeof(symbol), P}
+#define PROD(LHS, _, ...) {LHS, (symbol[]){__VA_ARGS__}, sizeof((symbol[]){__VA_ARGS__})/sizeof(symbol)}
static struct production _grammar[] = {
#if (CHOOSE_GRAMMAR == 0)
PROD(EP, ->, E, END_INPUT),
@@ -291,20 +291,34 @@ static struct production _grammar[] = {
// 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),
+ PROD(EP, ->, E, END_INPUT),
+ PROD(E, -->, STMT),
+ PROD(STMT, -->, IF, STMT),
+ PROD(STMT, -->, IF, STMT, ELSE, STMT),
+ PROD(STMT, -->, N),
+ PROD(STMT, -->, STMT, PLUS, STMT),
+ PROD(STMT, -->, STMT, EQUAL, STMT),
+ PROD(STMT, -->, STMT, TIMES, STMT),
#endif
};
struct production *grammar = _grammar;
size_t total_productions = sizeof(_grammar)/sizeof(*_grammar);
+// implement precedence.h
+#define c(...) __builtin_constant_p(__VA_ARGS__)
+int *precedence_symbol = (int[]){
+ [PLUS] = PRECEDENCE_SET(2, PRECEDENCE_LEFT_ASSOC),
+ [EQUAL] = PRECEDENCE_SET(1, PRECEDENCE_LEFT_ASSOC),
+ [TIMES] = PRECEDENCE_SET(3, PRECEDENCE_LEFT_ASSOC),
+};
+
+int *precedence_production = (int[]){
+ [5] = PRECEDENCE_SET(2, PRECEDENCE_LEFT_ASSOC),
+ [6] = PRECEDENCE_SET(1, PRECEDENCE_LEFT_ASSOC),
+ [7] = PRECEDENCE_SET(3, PRECEDENCE_LEFT_ASSOC),
+};
+
// implement util-tables.h
#include "util-tables.c"
diff --git a/demos/generate-parser.c b/demos/generate-parser.c
index fad3b93..23201fa 100644
--- a/demos/generate-parser.c
+++ b/demos/generate-parser.c
@@ -21,6 +21,19 @@ size_t total_productions;
char **semantic_action_str;
+#include "parts/precedence.h"
+int *precedence_symbol;
+int *precedence_production;
+
+struct precedence_def{
+ int flag;
+ int *list;
+ size_t nlist;
+} *precedence_defs;
+size_t nprecedence_defs;
+void precedence_tables_fill();
+void precedence_tables_free();
+
#include "parts/table.h"
struct action **table;
size_t table_states;
@@ -29,6 +42,7 @@ void (*table_free)();
#include "util-tables.c"
+
void *xdlsym(void *handle, char *sym)
{
void *r = dlsym(handle, sym);
@@ -106,7 +120,10 @@ int main(int argc, char **argv)
GET_VARIABLE(grammar, def_handle);
GET_VARIABLE(total_productions, def_handle);
GET_VARIABLE(semantic_action_str, def_handle);
+ GET_VARIABLE(precedence_defs, def_handle);
+ GET_VARIABLE(nprecedence_defs, def_handle);
+ precedence_tables_fill();
util_tables_fill();
int r = 0;
@@ -131,6 +148,13 @@ int main(int argc, char **argv)
printf("};\n");
printf("size_t table_states = %zu;\n", table_states);
+ printf("int *precedence_symbol = (int[]){");
+ for(size_t i = 0; i < total_symbols; i++) printf("%d, ", precedence_symbol[i]);
+ printf("};\n");
+ printf("int *precedence_production = (int[]){");
+ for(size_t i = 0; i < total_productions; i++) printf("%d, ", precedence_production[i]);
+ printf("};\n");
+
for(size_t i = 0; i < total_productions; i++) {
printf("#define A(n) (*(stack_head-3*%zu+3*n-1))\n", grammar[i].nRHS-1);
printf("int __prod%zu_action(int *stack_head)\n", i);
@@ -150,8 +174,38 @@ int main(int argc, char **argv)
cleanup:
table_free();
+ precedence_tables_free();
util_tables_free();
+
dlclose(table_handle);
dlclose(def_handle);
return r;
}
+
+void precedence_tables_fill()
+{
+ precedence_symbol = calloc(total_symbols, sizeof(*precedence_symbol));
+ precedence_production = calloc(total_productions, sizeof(*precedence_production));
+
+ for(size_t i = 0; i < nprecedence_defs; i++)
+ for(size_t j = 0; j < precedence_defs[i].nlist; j++)
+ if(precedence_defs[i].flag >= 0)
+ precedence_symbol[precedence_defs[i].list[j]] = PRECEDENCE_SET(precedence_defs[i].flag, i+1);
+ else
+ precedence_production[precedence_defs[i].list[j]] = PRECEDENCE_SET(~precedence_defs[i].flag, i+1);
+
+ for(size_t i = 0; i < total_productions; i++) {
+ if(precedence_production[i]) continue;
+
+ for(size_t j = 0; j < grammar[i].nRHS; j++)
+ if(precedence_symbol[grammar[i].RHS[j]]) {
+ precedence_production[i] = precedence_symbol[grammar[i].RHS[j]];
+ break;
+ }
+ }
+}
+void precedence_tables_free()
+{
+ free(precedence_symbol);
+ free(precedence_production);
+}
diff --git a/demos/sample-files/arithmetic-defs.c b/demos/sample-files/arithmetic-defs.c
deleted file mode 100644
index 9a0db22..0000000
--- a/demos/sample-files/arithmetic-defs.c
+++ /dev/null
@@ -1,49 +0,0 @@
-#include <stdio.h>
-#include <stddef.h>
-
-#include "parts/symbol.h"
-enum symbol {
- PLUS = 0,
- MINUS,
- LPAREN,
- RPAREN,
- N0, N1,
- END_INPUT,
-
- EP, E, T, N,
- SYMBOLS_END,
-};
-
-size_t total_symbols = SYMBOLS_END;
-
-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_FUNCPTR(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)}
-static struct production _grammar[] = {
- PROD(EP, ->, E, END_INPUT),
- PROD(E, -->, E, PLUS, T),
- PROD(E, -->, E, MINUS, T),
- PROD(E, -->, T),
- PROD(T, -->, LPAREN, E, RPAREN),
- PROD(T, -->, N),
- PROD(N, -->, N0),
- PROD(N, -->, N1),
-};
-
-struct production *grammar = _grammar;
-size_t total_productions = sizeof(_grammar)/sizeof(*_grammar);
-
-// #include "???.h"
-char **semantic_action_str = (char *([])){
- "v = A(0);",
- "v = A(0) + A(2);",
- "v = A(0) - A(2);",
- "v = A(0);",
- "v = A(1);",
- "v = A(0);",
- "v = 0;",
- "v = 1;",
-};
diff --git a/demos/sample-files/arithmetic-skeleton.c b/demos/sample-files/arithmetic-skeleton.c
deleted file mode 100644
index ef5ec2f..0000000
--- a/demos/sample-files/arithmetic-skeleton.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <stdio.h>ae
-#include <stdlib.h>
-
-#include "lr-parser.c"
-#include "bin/generated.c"
-
-#include "parts/toklist.h"
-
-enum symbol {
- PLUS = 0,
- MINUS,
- LPAREN,
- RPAREN,
- N0, N1,
- END_INPUT,
-
- EP, E, T, N,
- SYMBOLS_END,
-};
-
-struct token {
- symbol s;
-};
-
-static inline struct token *char_to_token(char c)
-{
- static struct token t;
-
- switch(c) {
- case '+': t = (struct token){PLUS}; break;
- case '-': t = (struct token){MINUS}; break;
- case '(': t = (struct token){LPAREN}; break;
- case ')': t = (struct token){RPAREN}; break;
- case '0': t = (struct token){N0}; break;
- case '1': t = (struct token){N1}; break;
- case 0 : t = (struct token){END_INPUT}; break;
- default: fprintf(stderr, "ERROR: Unknown character '%c'\n", c); exit(1);
- }
-
- return &t;
-}
-
-static char *input;
-
-symbol token_sym(struct token *t) { return t->s; }
-int token_val(struct token *t) { return 0; }
-struct token *toklist_eat() { return char_to_token(*(input++)); } // unsafe
-struct token *toklist_peek() { return char_to_token(*input); } // unsafe
-
-int main(int argc, char **argv)
-{
- if(argc != 2) {
- fprintf(stderr, "ERROR: Not enough arguments\n");
- return 1;
- }
-
- input = argv[1];
-
- printf("INPUT: '%s'\n", input);
- printf("OUTPUT: %d\n", lr_parser());
- return 0;
-}
diff --git a/demos/sample-files/calc-defs.c b/demos/sample-files/calc-defs.c
index 656ab1c..7321a88 100644
--- a/demos/sample-files/calc-defs.c
+++ b/demos/sample-files/calc-defs.c
@@ -2,12 +2,9 @@
#include "parts/symbol.h"
enum symbol {
- PLUS = 0,
- MINUS,
- LPAREN,
- RPAREN,
- NUM,
- END_INPUT,
+ PLUS, MINUS, TIMES,
+ LPAREN, RPAREN,
+ NUM, END_INPUT,
EP, E, T,
SYMBOLS_END,
@@ -20,14 +17,14 @@ IMPLEMENT_FUNCPTR(int, symbol_is_input_end, (symbol s)) { return s == END_INPUT;
IMPLEMENT_FUNCPTR(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), 0}
+#define PROD(LHS, _, ...) {LHS, (symbol[]){__VA_ARGS__}, sizeof((symbol[]){__VA_ARGS__})/sizeof(symbol)}
static struct production _grammar[] = {
PROD(EP, ->, E, END_INPUT),
- PROD(E, -->, E, PLUS, T),
- PROD(E, -->, E, MINUS, T),
- PROD(E, -->, T),
- PROD(T, -->, LPAREN, E, RPAREN),
- PROD(T, -->, NUM),
+ PROD(E, -->, E, PLUS, E),
+ PROD(E, -->, E, MINUS, E),
+ PROD(E, -->, E, TIMES, E),
+ PROD(E, -->, LPAREN, E, RPAREN),
+ PROD(E, -->, NUM),
};
struct production *grammar = _grammar;
@@ -38,7 +35,24 @@ char **semantic_action_str = (char *([])){
"v = A(0);",
"v = A(0) + A(2);",
"v = A(0) - A(2);",
- "v = A(0);",
+ "v = A(0) * A(2);",
"v = A(1);",
"v = A(0);",
};
+
+#include "parts/precedence.h"
+
+struct precedence_def {
+ int flag;
+ int *list;
+ size_t nlist;
+};
+#define PREC(f, ...) {f, (int[]){__VA_ARGS__}, sizeof((int[]){__VA_ARGS__})/sizeof(int)}
+struct precedence_def _precedence_defs[] = {
+ PREC(PRECEDENCE_LEFT_ASSOC, MINUS, PLUS),
+ PREC(PRECEDENCE_LEFT_ASSOC, TIMES),
+ PREC(PRECEDENCE_LEFT_ASSOC, LPAREN, RPAREN),
+};
+
+struct precedence_def *precedence_defs = _precedence_defs;
+size_t nprecedence_defs = sizeof(_precedence_defs)/sizeof(*_precedence_defs);
diff --git a/demos/sample-files/calc-skeleton.c b/demos/sample-files/calc-skeleton.c
index 2108999..b0cbf00 100644
--- a/demos/sample-files/calc-skeleton.c
+++ b/demos/sample-files/calc-skeleton.c
@@ -9,12 +9,9 @@
// header file by the parser generator
#include "parts/symbol.h"
enum symbol {
- PLUS = 0,
- MINUS,
- LPAREN,
- RPAREN,
- NUM,
- END_INPUT,
+ PLUS, MINUS, TIMES,
+ LPAREN, RPAREN,
+ NUM, END_INPUT,
EP, E, T,
SYMBOLS_END,
@@ -27,7 +24,7 @@ static struct token {
static inline int issep(char c)
{
- return isspace(c) || c == '\0' || c == '(' || c == ')' || c == '+' || c == '-';
+ return isspace(c) || c == '\0' || c == '(' || c == ')' || c == '+' || c == '-' || c == '*';;
}
static inline int tillsep(char *str)
@@ -61,6 +58,7 @@ static char *next_token(char *str)
case ')': tok.s = RPAREN; break;
case '-': tok.s = MINUS; break;
case '+': tok.s = PLUS; break;
+ case '*': tok.s = TIMES; break;
}
} else if(c0 >= '0' && c0 <= '9') { // num
tok.s = NUM;
diff --git a/lr-parser.c b/lr-parser.c
index 827b502..799276d 100644
--- a/lr-parser.c
+++ b/lr-parser.c
@@ -93,7 +93,7 @@ size_t total_symbols = SYMBOLS_END;
IMPLEMENT_FUNCPTR(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), 0}
+#define PROD(LHS, _, ...) {LHS, (symbol[]){__VA_ARGS__}, sizeof((symbol[]){__VA_ARGS__})/sizeof(symbol)}
static struct production _grammar[] = {
PROD(EP, ->, E, END_INPUT),
PROD(E, -->, E, PLUS, T),
@@ -105,6 +105,9 @@ static struct production _grammar[] = {
PROD(N, -->, N1),
};
+int *precedence_symbol = (int[]){0};
+int *precedence_production = (int[]){0};
+
struct production *grammar = _grammar;
size_t total_productions = sizeof(_grammar)/sizeof(*_grammar);
diff --git a/parts/grammar.h b/parts/grammar.h
index 594e61e..d1bf176 100644
--- a/parts/grammar.h
+++ b/parts/grammar.h
@@ -3,20 +3,10 @@
#include <stddef.h> // size_t
-enum precedence_flag {
- PRECEDENCE_LEFT_ASSOC,
- PRECEDENCE_RIGHT_ASSOC,
- PRECEDENCE_NO_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;
@@ -39,7 +29,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, %d},\n", grammar[i].nRHS, grammar[i].precedence);
+ printf("}, %zu},\n", grammar[i].nRHS);
}
}
diff --git a/parts/precedence.h b/parts/precedence.h
new file mode 100644
index 0000000..37e54c6
--- /dev/null
+++ b/parts/precedence.h
@@ -0,0 +1,17 @@
+#ifndef PRECEDENCE_H
+#define PRECEDENCE_H
+
+enum precedence_flag {
+ PRECEDENCE_LEFT_ASSOC,
+ PRECEDENCE_RIGHT_ASSOC,
+ // PRECEDENCE_NO_ASSOC,
+};
+
+#define PRECEDENCE_SET(num, flag) (((num) << 1 /*2*/) | (flag))
+#define PRECEDENCE_NUM(prec) ((prec) >> 2)
+#define PRECEDENCE_FLAG(prec) ((prec) & 0x3)
+
+extern int *precedence_symbol;
+extern int *precedence_production;
+
+#endif
diff --git a/parts/table.h b/parts/table.h
index 01a6bbf..efd19bb 100644
--- a/parts/table.h
+++ b/parts/table.h
@@ -62,6 +62,8 @@ void table_print_cstyle()
}
#include "grammar.h"
+#include "precedence.h"
+
int table_insert(size_t state, symbol sym, struct action a)
{
struct action *tbl_a = &table[state][sym];
@@ -75,7 +77,7 @@ 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,
- shift_p, reduce_p, tbl_is_reduce;
+ tbl_is_reduce, shift_p, reduce_p;
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;
@@ -84,45 +86,36 @@ int table_insert(size_t state, symbol sym, struct action 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;
+ report = 1;
+ shift_p = precedence_symbol[sym];
+ reduce_p = (tbl_is_reduce)
+ ? precedence_production[tbl_a->arg]
+ : precedence_production[new_a->arg];
}
-#define prec_num(a) PRECEDENCE_NUM(grammar[(a)->arg].precedence)
-#define prec_flag(a) PRECEDENCE_FLAG(grammar[(a)->arg].precedence)
+#define prec_num(a) PRECEDENCE_NUM(precedence_production[(a)->arg])
+#define prec_flag(a) PRECEDENCE_FLAG(precedence_production[(a)->arg])
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 {
- report = 1;
+ else { report = 1;
if(new_a->arg > tbl_a->arg) set_tbl_a = 1;
}
} 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; }
- }
+ else if(PRECEDENCE_NUM(reduce_p) > PRECEDENCE_NUM(shift_p)) favor_shift = 0;
+ 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 { favor_shift = 1, report = 1; }
- if(favor_shift && tbl_is_reduce || !favor_shift && !tbl_is_reduce) set_tbl_a = 1;
+ if((favor_shift && tbl_is_reduce) || (!favor_shift && !tbl_is_reduce)) set_tbl_a = 1;
} else {
r = 1; report = 1;
}
diff --git a/slr-table.c b/slr-table.c
index ac90755..d9f289c 100644
--- a/slr-table.c
+++ b/slr-table.c
@@ -14,6 +14,7 @@ extern void *xcalloc(size_t n, size_t size);
// Requirements
#include "parts/symbol.h"
#include "parts/grammar.h"
+#include "parts/precedence.h"
#include "parts/util-tables.h"
// Implements
@@ -221,7 +222,7 @@ 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)}
static struct production _grammar[] = {
PROD(EP, ->, E, END_INPUT),
PROD(E, -->, E, PLUS, T),
@@ -236,6 +237,10 @@ static struct production _grammar[] = {
struct production *grammar = _grammar;
size_t total_productions = sizeof(_grammar)/sizeof(*_grammar);
+// implement precedence.h
+int *precedence_symbol = (int[]){0};
+int *precedence_production = (int[]){0};
+
// implement util-tables.h
#include "util-tables.c"
diff --git a/util-tables.c b/util-tables.c
index cfebf68..aa89359 100644
--- a/util-tables.c
+++ b/util-tables.c
@@ -133,6 +133,7 @@ static struct production _grammar[] = {
PROD(N, -->, N0),
PROD(N, -->, N1),
};
+
struct production *grammar = _grammar;
size_t total_productions = sizeof(_grammar)/sizeof(*_grammar);