diff options
Diffstat (limited to 'mkpar.c')
-rw-r--r-- | mkpar.c | 27 |
1 files changed, 23 insertions, 4 deletions
@@ -1,7 +1,18 @@ -/* $Id: mkpar.c,v 1.12 2012/05/26 00:42:18 tom Exp $ */ +/* $Id: mkpar.c,v 1.14 2014/04/01 23:05:37 tom Exp $ */ #include "defs.h" +#define NotSuppressed(p) ((p)->suppressed == 0) + +#if defined(YYBTYACC) +#define MaySuppress(p) ((backtrack ? ((p)->suppressed <= 1) : (p)->suppressed == 0)) + /* suppress the preferred action => enable backtracking */ +#define StartBacktrack(p) if (backtrack && (p) != NULL && NotSuppressed(p)) (p)->suppressed = 1 +#else +#define MaySuppress(p) ((p)->suppressed == 0) +#define StartBacktrack(p) /*nothing */ +#endif + static action *add_reduce(action *actions, int ruleno, int symbol); static action *add_reductions(int stateno, action *actions); static action *get_shifts(int stateno); @@ -190,7 +201,7 @@ unused_rules(void) { for (p = parser[i]; p; p = p->next) { - if (p->action_code == REDUCE && p->suppressed == 0) + if ((p->action_code == REDUCE) && MaySuppress(p)) rules_used[p->number] = 1; } } @@ -225,17 +236,23 @@ remove_conflicts(void) SRcount = 0; RRcount = 0; symbol = -1; +#if defined(YYBTYACC) + pref = NULL; +#endif for (p = parser[i]; p; p = p->next) { if (p->symbol != symbol) { + /* the first parse action for each symbol is the preferred action */ pref = p; symbol = p->symbol; } + /* following conditions handle multiple, i.e., conflicting, parse actions */ else if (i == final_state && symbol == 0) { SRcount++; p->suppressed = 1; + StartBacktrack(pref); } else if (pref != 0 && pref->action_code == SHIFT) { @@ -269,12 +286,14 @@ remove_conflicts(void) { SRcount++; p->suppressed = 1; + StartBacktrack(pref); } } else { RRcount++; p->suppressed = 1; + StartBacktrack(pref); } } SRtotal += SRcount; @@ -329,9 +348,9 @@ sole_reduction(int stateno) ruleno = 0; for (p = parser[stateno]; p; p = p->next) { - if (p->action_code == SHIFT && p->suppressed == 0) + if (p->action_code == SHIFT && MaySuppress(p)) return (0); - else if (p->action_code == REDUCE && p->suppressed == 0) + else if ((p->action_code == REDUCE) && MaySuppress(p)) { if (ruleno > 0 && p->number != ruleno) return (0); |