diff options
author | Anas Nashif <anas.nashif@intel.com> | 2012-10-29 18:06:41 -0700 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2012-10-29 18:06:41 -0700 |
commit | e83b5dbc94116983df1ec99d4f02cc8640f63da5 (patch) | |
tree | ded816253288526577640cf23faa5ccaa2ed2d0d /mkpar.c | |
download | byacc-e83b5dbc94116983df1ec99d4f02cc8640f63da5.tar.gz byacc-e83b5dbc94116983df1ec99d4f02cc8640f63da5.tar.bz2 byacc-e83b5dbc94116983df1ec99d4f02cc8640f63da5.zip |
Imported Upstream version 20100216upstream/20100216
Diffstat (limited to 'mkpar.c')
-rw-r--r-- | mkpar.c | 393 |
1 files changed, 393 insertions, 0 deletions
@@ -0,0 +1,393 @@ +/* $Id: mkpar.c,v 1.10 2009/10/27 10:50:13 tom Exp $ */ + +#include "defs.h" + +static action *add_reduce(action *actions, int ruleno, int symbol); +static action *add_reductions(int stateno, action *actions); +static action *get_shifts(int stateno); +static action *parse_actions(int stateno); +static int sole_reduction(int stateno); +static void defreds(void); +static void find_final_state(void); +static void free_action_row(action *p); +static void remove_conflicts(void); +static void total_conflicts(void); +static void unused_rules(void); + +action **parser; + +int SRexpect; +int RRexpect; + +int SRtotal; +int RRtotal; + +Value_t *SRconflicts; +Value_t *RRconflicts; +Value_t *defred; +Value_t *rules_used; +Value_t nunused; +Value_t final_state; + +static Value_t SRcount; +static Value_t RRcount; + +void +make_parser(void) +{ + int i; + + parser = NEW2(nstates, action *); + for (i = 0; i < nstates; i++) + parser[i] = parse_actions(i); + + find_final_state(); + remove_conflicts(); + unused_rules(); + if (SRtotal + RRtotal > 0) + total_conflicts(); + defreds(); +} + +static action * +parse_actions(int stateno) +{ + action *actions; + + actions = get_shifts(stateno); + actions = add_reductions(stateno, actions); + return (actions); +} + +static action * +get_shifts(int stateno) +{ + action *actions, *temp; + shifts *sp; + Value_t *to_state2; + Value_t i, k; + Value_t symbol; + + actions = 0; + sp = shift_table[stateno]; + if (sp) + { + to_state2 = sp->shift; + for (i = (Value_t) (sp->nshifts - 1); i >= 0; i--) + { + k = to_state2[i]; + symbol = accessing_symbol[k]; + if (ISTOKEN(symbol)) + { + temp = NEW(action); + temp->next = actions; + temp->symbol = symbol; + temp->number = k; + temp->prec = symbol_prec[symbol]; + temp->action_code = SHIFT; + temp->assoc = symbol_assoc[symbol]; + actions = temp; + } + } + } + return (actions); +} + +static action * +add_reductions(int stateno, action *actions) +{ + int i, j, m, n; + int ruleno, tokensetsize; + unsigned *rowp; + + tokensetsize = WORDSIZE(ntokens); + m = lookaheads[stateno]; + n = lookaheads[stateno + 1]; + for (i = m; i < n; i++) + { + ruleno = LAruleno[i]; + rowp = LA + i * tokensetsize; + for (j = ntokens - 1; j >= 0; j--) + { + if (BIT(rowp, j)) + actions = add_reduce(actions, ruleno, j); + } + } + return (actions); +} + +static action * +add_reduce(action *actions, + int ruleno, + int symbol) +{ + action *temp, *prev, *next; + + prev = 0; + for (next = actions; next && next->symbol < symbol; next = next->next) + prev = next; + + while (next && next->symbol == symbol && next->action_code == SHIFT) + { + prev = next; + next = next->next; + } + + while (next && next->symbol == symbol && + next->action_code == REDUCE && next->number < ruleno) + { + prev = next; + next = next->next; + } + + temp = NEW(action); + temp->next = next; + temp->symbol = (Value_t) symbol; + temp->number = (Value_t) ruleno; + temp->prec = rprec[ruleno]; + temp->action_code = REDUCE; + temp->assoc = rassoc[ruleno]; + + if (prev) + prev->next = temp; + else + actions = temp; + + return (actions); +} + +static void +find_final_state(void) +{ + int goal, i; + Value_t *to_state2; + shifts *p; + + p = shift_table[0]; + to_state2 = p->shift; + goal = ritem[1]; + for (i = p->nshifts - 1; i >= 0; --i) + { + final_state = to_state2[i]; + if (accessing_symbol[final_state] == goal) + break; + } +} + +static void +unused_rules(void) +{ + int i; + action *p; + + rules_used = (Value_t *) MALLOC((unsigned)nrules * sizeof(Value_t)); + if (rules_used == 0) + no_space(); + + for (i = 0; i < nrules; ++i) + rules_used[i] = 0; + + for (i = 0; i < nstates; ++i) + { + for (p = parser[i]; p; p = p->next) + { + if (p->action_code == REDUCE && p->suppressed == 0) + rules_used[p->number] = 1; + } + } + + nunused = 0; + for (i = 3; i < nrules; ++i) + if (!rules_used[i]) + ++nunused; + + if (nunused) + { + if (nunused == 1) + fprintf(stderr, "%s: 1 rule never reduced\n", myname); + else + fprintf(stderr, "%s: %d rules never reduced\n", myname, nunused); + } +} + +static void +remove_conflicts(void) +{ + int i; + int symbol; + action *p, *pref = 0; + + SRtotal = 0; + RRtotal = 0; + SRconflicts = NEW2(nstates, Value_t); + RRconflicts = NEW2(nstates, Value_t); + for (i = 0; i < nstates; i++) + { + SRcount = 0; + RRcount = 0; + symbol = -1; + for (p = parser[i]; p; p = p->next) + { + if (p->symbol != symbol) + { + pref = p; + symbol = p->symbol; + } + else if (i == final_state && symbol == 0) + { + SRcount++; + p->suppressed = 1; + } + else if (pref->action_code == SHIFT) + { + if (pref->prec > 0 && p->prec > 0) + { + if (pref->prec < p->prec) + { + pref->suppressed = 2; + pref = p; + } + else if (pref->prec > p->prec) + { + p->suppressed = 2; + } + else if (pref->assoc == LEFT) + { + pref->suppressed = 2; + pref = p; + } + else if (pref->assoc == RIGHT) + { + p->suppressed = 2; + } + else + { + pref->suppressed = 2; + p->suppressed = 2; + } + } + else + { + SRcount++; + p->suppressed = 1; + } + } + else + { + RRcount++; + p->suppressed = 1; + } + } + SRtotal += SRcount; + RRtotal += RRcount; + SRconflicts[i] = SRcount; + RRconflicts[i] = RRcount; + } +} + +static void +total_conflicts(void) +{ + fprintf(stderr, "%s: ", myname); + if (SRtotal == 1) + fprintf(stderr, "1 shift/reduce conflict"); + else if (SRtotal > 1) + fprintf(stderr, "%d shift/reduce conflicts", SRtotal); + + if (SRtotal && RRtotal) + fprintf(stderr, ", "); + + if (RRtotal == 1) + fprintf(stderr, "1 reduce/reduce conflict"); + else if (RRtotal > 1) + fprintf(stderr, "%d reduce/reduce conflicts", RRtotal); + + fprintf(stderr, ".\n"); + + if (SRexpect >= 0 && SRtotal != SRexpect) + { + fprintf(stderr, "%s: ", myname); + fprintf(stderr, "expected %d shift/reduce conflict%s.\n", + SRexpect, PLURAL(SRexpect)); + exit_code = EXIT_FAILURE; + } + if (RRexpect >= 0 && RRtotal != RRexpect) + { + fprintf(stderr, "%s: ", myname); + fprintf(stderr, "expected %d reduce/reduce conflict%s.\n", + RRexpect, PLURAL(RRexpect)); + exit_code = EXIT_FAILURE; + } +} + +static int +sole_reduction(int stateno) +{ + int count, ruleno; + action *p; + + count = 0; + ruleno = 0; + for (p = parser[stateno]; p; p = p->next) + { + if (p->action_code == SHIFT && p->suppressed == 0) + return (0); + else if (p->action_code == REDUCE && p->suppressed == 0) + { + if (ruleno > 0 && p->number != ruleno) + return (0); + if (p->symbol != 1) + ++count; + ruleno = p->number; + } + } + + if (count == 0) + return (0); + return (ruleno); +} + +static void +defreds(void) +{ + int i; + + defred = NEW2(nstates, Value_t); + for (i = 0; i < nstates; i++) + defred[i] = (Value_t) sole_reduction(i); +} + +static void +free_action_row(action *p) +{ + action *q; + + while (p) + { + q = p->next; + FREE(p); + p = q; + } +} + +void +free_parser(void) +{ + int i; + + for (i = 0; i < nstates; i++) + free_action_row(parser[i]); + + FREE(parser); +} + +#ifdef NO_LEAKS +void +mkpar_leaks(void) +{ + DO_FREE(defred); + DO_FREE(rules_used); + DO_FREE(SRconflicts); + DO_FREE(RRconflicts); +} +#endif |