/** * \post: * - \c result = a new \c bitset of size \c ::nritems such that any bit \c i * is set iff <tt>ritem[i]</tt> is a nonterminal after which all ritems in * the same RHS are nullable nonterminals. In other words, the follows of * a goto on <tt>ritem[i]</tt> include the lookahead set of the item. */ static bitset ielr_compute_ritem_sees_lookahead_set (void) { bitset result = bitset_create (nritems, BITSET_FIXED); unsigned int i = nritems-1; while (i>0) { --i; while (!item_number_is_rule_number (ritem[i]) && ISVAR (ritem[i]) && nullable [item_number_as_symbol_number (ritem[i]) - ntokens]) bitset_set (result, i--); if (!item_number_is_rule_number (ritem[i]) && ISVAR (ritem[i])) bitset_set (result, i--); while (!item_number_is_rule_number (ritem[i]) && i>0) --i; } if (trace_flag & trace_ielr) { fprintf (stderr, "ritem_sees_lookahead_set:\n"); debug_bitset (result); fprintf (stderr, "\n"); } return result; }
void set_EFF(void) { unsigned *row; int symbol; short *sp; int rowsize; int i; int rule; rowsize = WORDSIZE(nvars); EFF = NEW2(nvars * rowsize, unsigned); row = EFF; for (i = start_symbol; i < nsyms; i++) { sp = derives[i]; for (rule = *sp; rule > 0; rule = *++sp) { symbol = ritem[rrhs[rule]]; if (ISVAR(symbol)) { symbol -= start_symbol; SETBIT(row, symbol); } } row += rowsize; } reflexive_transitive_closure(EFF, nvars); #ifdef DEBUG print_EFF(); #endif }
static void set_EFF(void) { register unsigned *row; register Yshort symbol; register Yshort *sp; register int rowsize; register int i; register int rule; rowsize = WORDSIZE(nvars); EFF = NEW2(nvars * rowsize, EFF[0]); row = EFF; for (i = start_symbol; i < nsyms; ++i) { sp = derives[i]; for (rule = *sp; rule > 0; rule = *++sp) { symbol = ritem[rrhs[rule]]; if (ISVAR(symbol)) { symbol -= start_symbol; SETBIT(row, symbol); } } row += rowsize; } reflexive_transitive_closure(EFF, nvars); if (tflag > 1) print_EFF(); }
initialize_LA() { register int i; register int j; register int count; register reductions *rp; register shifts *sp; register short *np; consistent = NEW2(nstates, char); lookaheads = NEW2(nstates + 1, short); count = 0; for (i = 0; i < nstates; i++) { register int j; lookaheads[i] = count; rp = reduction_table[i]; sp = shift_table[i]; if (rp && (rp->nreds > 1 || (sp && ! ISVAR(accessing_symbol[sp->shifts[0]])))) count += rp->nreds; else consistent[i] = 1; if (sp) for (j = 0; j < sp->nshifts; j++) { if (accessing_symbol[sp->shifts[j]] == error_token_number) { consistent[i] = 0; break; } } } lookaheads[nstates] = count; LA = NEW2(count * tokensetsize, unsigned); LAruleno = NEW2(count, short); lookback = NEW2(count, shorts *); np = LAruleno; for (i = 0; i < nstates; i++) { if (!consistent[i]) { if (rp = reduction_table[i]) for (j = 0; j < rp->nreds; j++) *np++ = rp->rules[j]; } } }
static void nonterminals_reduce (void) { /* Map the nonterminals to their new index: useful first, useless afterwards. Kept for later report. */ symbol_number *nontermmap = xnmalloc (nvars, sizeof *nontermmap); symbol_number n = ntokens; symbol_number i; for (i = ntokens; i < nsyms; i++) if (bitset_test (V, i)) nontermmap[i - ntokens] = n++; for (i = ntokens; i < nsyms; i++) if (!bitset_test (V, i)) { nontermmap[i - ntokens] = n++; if (symbols[i]->status != used) complain (&symbols[i]->location, Wother, _("nonterminal useless in grammar: %s"), symbols[i]->tag); } /* Shuffle elements of tables indexed by symbol number. */ { symbol **symbols_sorted = xnmalloc (nvars, sizeof *symbols_sorted); for (i = ntokens; i < nsyms; i++) symbols[i]->number = nontermmap[i - ntokens]; for (i = ntokens; i < nsyms; i++) symbols_sorted[nontermmap[i - ntokens] - ntokens] = symbols[i]; for (i = ntokens; i < nsyms; i++) symbols[i] = symbols_sorted[i - ntokens]; free (symbols_sorted); } { rule_number r; for (r = 0; r < nrules; ++r) { item_number *rhsp; for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp) if (ISVAR (*rhsp)) *rhsp = symbol_number_as_item_number (nontermmap[*rhsp - ntokens]); } accept->number = nontermmap[accept->number - ntokens]; } nsyms -= nuseless_nonterminals; nvars -= nuseless_nonterminals; free (nontermmap); }
static bool useful_production (rule_number r, bitset N0) { item_number *rhsp; /* A production is useful if all of the nonterminals in its appear in the set of useful nonterminals. */ for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp) if (ISVAR (*rhsp) && !bitset_test (N0, *rhsp - ntokens)) return false; return true; }
void initialize_LA (void) { register int i; register int j; register int count; register reductions *rp; register shifts *sp; register short *np; consistent = NEW2(nstates, char); lookaheads = NEW2(nstates + 1, short); count = 0; for (i = 0; i < nstates; i++) { register int k; lookaheads[i] = count; rp = reduction_table[i]; sp = shift_table[i]; if (rp && (rp->nreds > 1 || (sp && ! ISVAR(accessing_symbol[sp->shifts[0]])))) count += rp->nreds; else consistent[i] = 1; if (sp) for (k = 0; k < sp->nshifts; k++) { if (accessing_symbol[sp->shifts[k]] == error_token_number) { consistent[i] = 0; break; } } } lookaheads[nstates] = count; if (count == 0) { LA = NEW2(1 * tokensetsize, unsigned); LAruleno = NEW2(1, short); lookback = NEW2(1, shorts *); }
static void print_gotos (int stateno) { int i, k; int as; Value_t * to_state2; shifts * sp; putc ('\n', verbose_file); sp = shift_table[stateno]; to_state2 = sp->shift; for (i = 0; i < sp->nshifts; ++i) { k = to_state2[i]; as = accessing_symbol[k]; if (ISVAR (as)) fprintf (verbose_file, "\t%s goto %d\n", symbol_name[as], k); } }
void print_gotos(int stateno) { register int i, k; register int as; register Yshort *to_state; register shifts *sp; BtYacc_putc('\n', verbose_file); sp = shift_table[stateno]; to_state = sp->shift; for (i = 0; i < sp->nshifts; ++i) { k = to_state[i]; as = accessing_symbol[k]; if (ISVAR(as)) BtYacc_printf(verbose_file, "\t%s goto %d\n", symbol_name[as], k); } }
void print_actions(int stateno) { register action *p; register shifts *sp; register int as; if (stateno == final_state) BtYacc_puts("\t$end accept\n", verbose_file); p = parser[stateno]; if (p) { print_shifts(p); print_reductions(p, defred[stateno]); } sp = shift_table[stateno]; if (sp && sp->nshifts > 0) { as = accessing_symbol[sp->shift[sp->nshifts - 1]]; if (ISVAR(as)) print_gotos(stateno); } if (tflag > 1) { BtYacc_puts("\n\n------------ action dump ---------------\n", verbose_file); for (p = parser[stateno]; p; p = p->next) { BtYacc_printf(verbose_file, "\t%-30s %6s %5d ~ prec %3d, assoc: %3d (%%%-10s), suppress: %d\n", symbol_name[p->symbol], (p->action_code == SHIFT ? "shift" : "reduce"), (p->action_code == SHIFT ? p->number : p->number - 2), p->prec, p->assoc, get_symbol_assoc_str(p->assoc), p->suppressed); } BtYacc_puts("----------------------------------------\n\n", verbose_file); } }
void print_actions(int stateno) { action *p; shifts *sp; int as; if (stateno == final_state) fprintf(verbose_file, "\t$end accept\n"); p = parser[stateno]; if (p) { print_shifts(p); print_reductions(p, defred[stateno]); } sp = shift_table[stateno]; if (sp && sp->nshifts > 0) { as = accessing_symbol[sp->shift[sp->nshifts - 1]]; if (ISVAR(as)) print_gotos(stateno); } }
void closure(short *nucleus,int n) { int ruleno; unsigned word; unsigned mask; short *csp; unsigned *dsp; unsigned *rsp; int rulesetsize; short *csend; unsigned *rsend; int symbol; int itemno; rulesetsize = WORDSIZE(nrules); rsp = ruleset; rsend = ruleset + rulesetsize; for (rsp = ruleset; rsp < rsend; rsp++) *rsp = 0; csend = nucleus + n; for (csp = nucleus; csp < csend; ++csp) { symbol = ritem[*csp]; if (ISVAR(symbol)) { dsp = first_derives + symbol * rulesetsize; rsp = ruleset; while (rsp < rsend) *rsp++ |= *dsp++; } } ruleno = 0; itemsetend = itemset; csp = nucleus; for (rsp = ruleset; rsp < rsend; ++rsp) { word = *rsp; if (word == 0) ruleno += BITS_PER_WORD; else { mask = 1; while (mask) { if (word & mask) { itemno = rrhs[ruleno]; while (csp < csend && *csp < itemno) *itemsetend++ = *csp++; *itemsetend++ = itemno; while (csp < csend && *csp == itemno) ++csp; } mask <<= 1; ++ruleno; } } } while (csp < csend) *itemsetend++ = *csp++; #ifdef DEBUG print_closure(n); #endif }
void set_conflicts (int state) { register int i; register int k; register shifts *shiftp; register unsigned *fp2; register unsigned *fp3; register unsigned *fp4; register unsigned *fp1; register int symbol; if (consistent[state]) return; for (i = 0; i < tokensetsize; i++) lookaheadset[i] = 0; shiftp = shift_table[state]; if (shiftp) { k = shiftp->nshifts; for (i = 0; i < k; i++) { symbol = accessing_symbol[shiftp->shifts[i]]; if (ISVAR(symbol)) break; SETBIT(lookaheadset, symbol); } } k = lookaheads[state + 1]; fp4 = lookaheadset + tokensetsize; /* loop over all rules which require lookahead in this state */ /* first check for shift-reduce conflict, and try to resolve using precedence */ for (i = lookaheads[state]; i < k; i++) if (rprec[LAruleno[i]]) { fp1 = LA + i * tokensetsize; fp2 = fp1; fp3 = lookaheadset; while (fp3 < fp4) { if (*fp2++ & *fp3++) { resolve_sr_conflict(state, i); break; } } } /* loop over all rules which require lookahead in this state */ /* Check for conflicts not resolved above. */ for (i = lookaheads[state]; i < k; i++) { fp1 = LA + i * tokensetsize; fp2 = fp1; fp3 = lookaheadset; while (fp3 < fp4) { if (*fp2++ & *fp3++) { conflicts[state] = 1; any_conflicts = 1; } } fp2 = fp1; fp3 = lookaheadset; while (fp3 < fp4) *fp3++ |= *fp2++; } }
void print_reductions (int state) { register int i; register int j; register int k; register unsigned *fp1; register unsigned *fp2; register unsigned *fp3; register unsigned *fp4; register int rule; register int symbol; register unsigned mask; register int m; register int n; register int default_LA; register int default_rule = 0; register int cmax; register int count; register shifts *shiftp; register errs *errp; int nodefault = 0; for (i = 0; i < tokensetsize; i++) shiftset[i] = 0; shiftp = shift_table[state]; if (shiftp) { k = shiftp->nshifts; for (i = 0; i < k; i++) { if (! shiftp->shifts[i]) continue; symbol = accessing_symbol[shiftp->shifts[i]]; if (ISVAR(symbol)) break; /* if this state has a shift for the error token, don't use a default rule. */ if (symbol == error_token_number) nodefault = 1; SETBIT(shiftset, symbol); } } errp = err_table[state]; if (errp) { k = errp->nerrs; for (i = 0; i < k; i++) { if (! errp->errs[i]) continue; symbol = errp->errs[i]; SETBIT(shiftset, symbol); } } m = lookaheads[state]; n = lookaheads[state + 1]; if (n - m == 1 && ! nodefault) { default_rule = LAruleno[m]; fp1 = LA + m * tokensetsize; fp2 = shiftset; fp3 = lookaheadset; fp4 = lookaheadset + tokensetsize; while (fp3 < fp4) *fp3++ = *fp1++ & *fp2++; mask = 1; fp3 = lookaheadset; for (i = 0; i < ntokens; i++) { if (mask & *fp3) fprintf(foutput, _(" %-4s\t[reduce using rule %d (%s)]\n"), tags[i], default_rule, tags[rlhs[default_rule]]); mask <<= 1; if (mask == 0) { mask = 1; fp3++; } } fprintf(foutput, _(" $default\treduce using rule %d (%s)\n\n"), default_rule, tags[rlhs[default_rule]]); } else if (n - m >= 1) { cmax = 0; default_LA = -1; fp4 = lookaheadset + tokensetsize; if (! nodefault) for (i = m; i < n; i++) { fp1 = LA + i * tokensetsize; fp2 = shiftset; fp3 = lookaheadset; while (fp3 < fp4) *fp3++ = *fp1++ & (~(*fp2++)); count = 0; mask = 1; fp3 = lookaheadset; for (j = 0; j < ntokens; j++) { if (mask & *fp3) count++; mask <<= 1; if (mask == 0) { mask = 1; fp3++; } } if (count > cmax) { cmax = count; default_LA = i; default_rule = LAruleno[i]; } fp2 = shiftset; fp3 = lookaheadset; while (fp3 < fp4) *fp2++ |= *fp3++; } for (i = 0; i < tokensetsize; i++) shiftset[i] = 0; if (shiftp) { k = shiftp->nshifts; for (i = 0; i < k; i++) { if (! shiftp->shifts[i]) continue; symbol = accessing_symbol[shiftp->shifts[i]]; if (ISVAR(symbol)) break; SETBIT(shiftset, symbol); } } mask = 1; fp1 = LA + m * tokensetsize; fp2 = shiftset; for (i = 0; i < ntokens; i++) { int defaulted = 0; if (mask & *fp2) count = 1; else count = 0; fp3 = fp1; for (j = m; j < n; j++) { if (mask & *fp3) { if (count == 0) { if (j != default_LA) { rule = LAruleno[j]; fprintf(foutput, _(" %-4s\treduce using rule %d (%s)\n"), tags[i], rule, tags[rlhs[rule]]); } else defaulted = 1; count++; } else { if (defaulted) { rule = LAruleno[default_LA]; fprintf(foutput, _(" %-4s\treduce using rule %d (%s)\n"), tags[i], rule, tags[rlhs[rule]]); defaulted = 0; } rule = LAruleno[j]; fprintf(foutput, _(" %-4s\t[reduce using rule %d (%s)]\n"), tags[i], rule, tags[rlhs[rule]]); } } fp3 += tokensetsize; } mask <<= 1; if (mask == 0) { mask = 1; /* We tried incrementing just fp1, and just fp2; both seem wrong. It seems necessary to increment both in sync. */ fp1++; fp2++; } } if (default_LA >= 0) { fprintf(foutput, _(" $default\treduce using rule %d (%s)\n"), default_rule, tags[rlhs[default_rule]]); } putc('\n', foutput); } }
void closure(Value_t *nucleus, int n) { unsigned ruleno; unsigned word; unsigned i; Value_t *csp; unsigned *dsp; unsigned *rsp; int rulesetsize; Value_t *csend; unsigned *rsend; int symbol; Value_t itemno; rulesetsize = WORDSIZE(nrules); rsend = ruleset + rulesetsize; for (rsp = ruleset; rsp < rsend; rsp++) *rsp = 0; csend = nucleus + n; for (csp = nucleus; csp < csend; ++csp) { symbol = ritem[*csp]; if (ISVAR(symbol)) { dsp = first_derives + symbol * rulesetsize; rsp = ruleset; while (rsp < rsend) *rsp++ |= *dsp++; } } ruleno = 0; itemsetend = itemset; csp = nucleus; for (rsp = ruleset; rsp < rsend; ++rsp) { word = *rsp; if (word) { for (i = 0; i < BITS_PER_WORD; ++i) { if (word & (unsigned)(1 << i)) { itemno = rrhs[ruleno + i]; while (csp < csend && *csp < itemno) *itemsetend++ = *csp++; *itemsetend++ = itemno; while (csp < csend && *csp == itemno) ++csp; } } } ruleno += BITS_PER_WORD; } while (csp < csend) *itemsetend++ = *csp++; #ifdef DEBUG print_closure(n); #endif }
static void initialize_F(void) { int i; int j; int k; shifts *sp; Value_t *edge; unsigned *rowp; Value_t *rp; Value_t **reads; int nedges; int stateno; int symbol; int nwords; nwords = ngotos * tokensetsize; F = NEW2(nwords, unsigned); reads = NEW2(ngotos, Value_t *); edge = NEW2(ngotos + 1, Value_t); nedges = 0; rowp = F; for (i = 0; i < ngotos; i++) { stateno = to_state[i]; sp = shift_table[stateno]; if (sp) { k = sp->nshifts; for (j = 0; j < k; j++) { symbol = accessing_symbol[sp->shift[j]]; if (ISVAR(symbol)) break; SETBIT(rowp, symbol); } for (; j < k; j++) { symbol = accessing_symbol[sp->shift[j]]; if (nullable[symbol]) edge[nedges++] = map_goto(stateno, symbol); } if (nedges) { reads[i] = rp = NEW2(nedges + 1, Value_t); for (j = 0; j < nedges; j++) rp[j] = edge[j]; rp[nedges] = -1; nedges = 0; } } rowp += tokensetsize; } SETBIT(F, 0); digraph(reads); for (i = 0; i < ngotos; i++) { if (reads[i]) FREE(reads[i]); } FREE(reads); FREE(edge); }
static void build_relations(void) { int i; int j; int k; Value_t *rulep; Value_t *rp; shifts *sp; int length; int nedges; int done_flag; Value_t state1; Value_t stateno; int symbol1; int symbol2; Value_t *shortp; Value_t *edge; Value_t *states; Value_t **new_includes; includes = NEW2(ngotos, Value_t *); edge = NEW2(ngotos + 1, Value_t); states = NEW2(maxrhs + 1, Value_t); for (i = 0; i < ngotos; i++) { nedges = 0; state1 = from_state[i]; symbol1 = accessing_symbol[to_state[i]]; for (rulep = derives[symbol1]; *rulep >= 0; rulep++) { length = 1; states[0] = state1; stateno = state1; for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++) { symbol2 = *rp; sp = shift_table[stateno]; k = sp->nshifts; for (j = 0; j < k; j++) { stateno = sp->shift[j]; if (accessing_symbol[stateno] == symbol2) break; } states[length++] = stateno; } add_lookback_edge(stateno, *rulep, i); length--; done_flag = 0; while (!done_flag) { done_flag = 1; rp--; if (ISVAR(*rp)) { stateno = states[--length]; edge[nedges++] = map_goto(stateno, *rp); if (nullable[*rp] && length > 0) done_flag = 0; } } } if (nedges) { includes[i] = shortp = NEW2(nedges + 1, Value_t); for (j = 0; j < nedges; j++) shortp[j] = edge[j]; shortp[nedges] = -1; } } new_includes = transpose(includes, ngotos); for (i = 0; i < ngotos; i++) if (includes[i]) FREE(includes[i]); FREE(includes); includes = new_includes; FREE(edge); FREE(states); }
void count_sr_conflicts (int state) { register int i; register int k; register int mask; register shifts *shiftp; register unsigned *fp1; register unsigned *fp2; register unsigned *fp3; register int symbol; src_count = 0; shiftp = shift_table[state]; if (!shiftp) return; for (i = 0; i < tokensetsize; i++) { shiftset[i] = 0; lookaheadset[i] = 0; } k = shiftp->nshifts; for (i = 0; i < k; i++) { if (! shiftp->shifts[i]) continue; symbol = accessing_symbol[shiftp->shifts[i]]; if (ISVAR(symbol)) break; SETBIT(shiftset, symbol); } k = lookaheads[state + 1]; fp3 = lookaheadset + tokensetsize; for (i = lookaheads[state]; i < k; i++) { fp1 = LA + i * tokensetsize; fp2 = lookaheadset; while (fp2 < fp3) *fp2++ |= *fp1++; } fp1 = shiftset; fp2 = lookaheadset; while (fp2 < fp3) *fp2++ &= *fp1++; mask = 1; fp2 = lookaheadset; for (i = 0; i < ntokens; i++) { if (mask & *fp2) src_count++; mask <<= 1; if (mask == 0) { mask = 1; fp2++; } } }