static int count_sr_conflicts (state *s) { int i; int src_count = 0; transitions *trans = s->transitions; reductions *reds = s->reductions; if (!trans) return 0; bitset_zero (lookahead_set); bitset_zero (shift_set); FOR_EACH_SHIFT (trans, i) bitset_set (shift_set, TRANSITION_SYMBOL (trans, i)); for (i = 0; i < reds->num; ++i) bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]); bitset_and (lookahead_set, lookahead_set, shift_set); src_count = bitset_count (lookahead_set); return src_count; }
static rule * state_default_rule (state *s) { reductions *reds = s->reductions; rule *default_rule = NULL; int cmax = 0; int i; /* No need for a look-ahead. */ if (s->consistent) return reds->rules[0]; /* 1. Each reduction is possibly masked by the look-ahead tokens on which we shift (S/R conflicts)... */ bitset_zero (shift_set); { transitions *trans = s->transitions; FOR_EACH_SHIFT (trans, i) { /* If this state has a shift for the error token, don't use a default rule. */ if (TRANSITION_IS_ERROR (trans, i)) return NULL; bitset_set (shift_set, TRANSITION_SYMBOL (trans, i)); } } /* 2. Each reduction is possibly masked by the look-ahead tokens on which we raise an error (due to %nonassoc). */ { errs *errp = s->errs; for (i = 0; i < errp->num; i++) if (errp->symbols[i]) bitset_set (shift_set, errp->symbols[i]->number); } for (i = 0; i < reds->num; ++i) { int count = 0; /* How many non-masked look-ahead tokens are there for this reduction? */ bitset_andn (look_ahead_set, reds->look_ahead_tokens[i], shift_set); count = bitset_count (look_ahead_set); if (count > cmax) { cmax = count; default_rule = reds->rules[i]; } /* 3. And finally, each reduction is possibly masked by previous reductions (in R/R conflicts, we keep the first reductions). */ bitset_or (shift_set, shift_set, reds->look_ahead_tokens[i]); } return default_rule; }
/* Zero a vector of bitsets. */ void bitsetv_zero (bitsetv bsetv) { bitset_bindex i; for (i = 0; bsetv[i]; i++) bitset_zero (bsetv[i]); }
static void no_reduce_bitset_init (state const *s, bitset *no_reduce_set) { int n; *no_reduce_set = bitset_create (ntokens, BITSET_FIXED); bitset_zero (*no_reduce_set); FOR_EACH_SHIFT (s->transitions, n) bitset_set (*no_reduce_set, TRANSITION_SYMBOL (s->transitions, n)); for (n = 0; n < s->errs->num; ++n) if (s->errs->symbols[n]) bitset_set (*no_reduce_set, s->errs->symbols[n]->content->number); }
static void set_conflicts (state *s, symbol **errors) { int i; transitions *trans = s->transitions; reductions *reds = s->reductions; int nerrs = 0; if (s->consistent) return; bitset_zero (lookahead_set); FOR_EACH_SHIFT (trans, i) bitset_set (lookahead_set, TRANSITION_SYMBOL (trans, i)); /* Loop over all rules which require lookahead in this state. First check for shift-reduce conflict, and try to resolve using precedence. */ for (i = 0; i < reds->num; ++i) if (reds->rules[i]->prec && reds->rules[i]->prec->prec && !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set)) resolve_sr_conflict (s, i, errors, &nerrs); if (nerrs) { /* Some tokens have been explicitly made errors. Allocate a permanent errs structure for this state, to record them. */ state_errs_set (s, nerrs, errors); } if (obstack_object_size (&solved_conflicts_obstack)) { obstack_1grow (&solved_conflicts_obstack, '\0'); s->solved_conflicts = obstack_finish (&solved_conflicts_obstack); } if (obstack_object_size (&solved_conflicts_xml_obstack)) { obstack_1grow (&solved_conflicts_xml_obstack, '\0'); s->solved_conflicts_xml = obstack_finish (&solved_conflicts_xml_obstack); } /* Loop over all rules which require lookahead in this state. Check for conflicts not resolved above. */ for (i = 0; i < reds->num; ++i) { if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set)) conflicts[s->number] = 1; bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]); } }
static int damap_addrset_flush_locked(damap_t *damapp) { dam_t *mapp = (dam_t *)damapp; int idx; ASSERT(mapp); ASSERT(mutex_owned(&mapp->dam_lock)); if (mapp->dam_rptmode != DAMAP_REPORT_FULLSET) { return (DAM_EINVAL); } DTRACE_PROBE2(damap__addrset__flush__locked__enter, char *, mapp->dam_name, dam_t *, mapp); if (mapp->dam_flags & DAM_SETADD) { DTRACE_PROBE2(damap__addrset__flush__locked__reset, char *, mapp->dam_name, dam_t *, mapp); /* * cancel stabilization timeout */ dam_sched_timeout(NULL, mapp, 0); DAM_INCR_STAT(mapp, dam_jitter); /* * clear pending reports */ for (idx = 1; idx < mapp->dam_high; idx++) { if (DAM_IN_REPORT(mapp, idx)) { dam_addr_report_release(mapp, idx); } } bitset_zero(&mapp->dam_report_set); mapp->dam_flags &= ~DAM_SETADD; cv_signal(&mapp->dam_sync_cv); }
static void print_reductions (FILE *out, int level, state *s) { transitions *trans = s->transitions; reductions *reds = s->reductions; rule *default_reduction = NULL; int report = false; int i, j; if (reds->num == 0) { xml_puts (out, level, "<reductions/>"); return; } if (yydefact[s->number] != 0) default_reduction = &rules[yydefact[s->number] - 1]; bitset_zero (no_reduce_set); FOR_EACH_SHIFT (trans, i) bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i)); for (i = 0; i < s->errs->num; ++i) if (s->errs->symbols[i]) bitset_set (no_reduce_set, s->errs->symbols[i]->number); if (default_reduction) report = true; if (reds->lookahead_tokens) for (i = 0; i < ntokens; i++) { bool count = bitset_test (no_reduce_set, i); for (j = 0; j < reds->num; ++j) if (bitset_test (reds->lookahead_tokens[j], i)) { if (! count) { if (reds->rules[j] != default_reduction) report = true; count = true; } else { report = true; } } } /* Nothing to report. */ if (!report) { xml_puts (out, level, "<reductions/>"); return; } xml_puts (out, level, "<reductions>"); /* Report lookahead tokens (or $default) and reductions. */ if (reds->lookahead_tokens) for (i = 0; i < ntokens; i++) { bool defaulted = false; bool count = bitset_test (no_reduce_set, i); for (j = 0; j < reds->num; ++j) if (bitset_test (reds->lookahead_tokens[j], i)) { if (! count) { if (reds->rules[j] != default_reduction) print_reduction (out, level + 1, symbols[i]->tag, reds->rules[j], true); else defaulted = true; count = true; } else { if (defaulted) print_reduction (out, level + 1, symbols[i]->tag, default_reduction, true); defaulted = false; print_reduction (out, level + 1, symbols[i]->tag, reds->rules[j], false); } } } if (default_reduction) print_reduction (out, level + 1, "$default", default_reduction, true); xml_puts (out, level, "</reductions>"); }
/** * \pre: * - \c ritem_sees_lookahead_set was computed by * \c ielr_compute_ritem_sees_lookahead_set. * \post: * - Each of \c *edgesp and \c *edge_countsp is a new array of size * \c ::ngotos. * - <tt>(*edgesp)[i]</tt> points to a \c goto_number array of size * <tt>(*edge_countsp)[i]+1</tt>. * - In such a \c goto_number array, the last element is \c ::END_NODE. * - All remaining elements are the indices of the gotos to which there is an * internal follow edge from goto \c i. * - There is an internal follow edge from goto \c i to goto \c j iff both: * - The from states of gotos \c i and \c j are the same. * - The transition nonterminal for goto \c i appears as the first RHS * symbol of at least one production for which both: * - The LHS is the transition symbol of goto \c j. * - All other RHS symbols are nullable nonterminals. * - In other words, the follows of goto \c i include the follows of * goto \c j and it's an internal edge because the from states are the * same. */ static void ielr_compute_internal_follow_edges (bitset ritem_sees_lookahead_set, goto_number ***edgesp, int **edge_countsp) { *edgesp = xnmalloc (ngotos, sizeof **edgesp); *edge_countsp = xnmalloc (ngotos, sizeof **edge_countsp); { bitset sources = bitset_create (ngotos, BITSET_FIXED); goto_number i; for (i = 0; i < ngotos; ++i) (*edge_countsp)[i] = 0; for (i = 0; i < ngotos; ++i) { int nsources = 0; { rule **rulep; for (rulep = derives[states[to_state[i]]->accessing_symbol - ntokens]; *rulep; ++rulep) { /* If there is at least one RHS symbol, if the first RHS symbol is a nonterminal, and if all remaining RHS symbols (if any) are nullable nonterminals, create an edge from the LHS symbol's goto to the first RHS symbol's goto such that the RHS symbol's goto will be the source of the edge after the eventual relation_transpose below. Unlike in ielr_compute_always_follows, I use a bitset for edges rather than an array because it is possible that multiple RHS's with the same first symbol could fit and thus that we could end up with redundant edges. With the possibility of redundant edges, it's hard to know ahead of time how large to make such an array. Another possible redundancy is that source and destination might be the same goto. Eliminating all these possible redundancies now might possibly help performance a little. I have not proven any of this, but I'm guessing the bitset shouldn't entail much of a performance penalty, if any. */ if (bitset_test (ritem_sees_lookahead_set, (*rulep)->rhs - ritem)) { goto_number source = map_goto (from_state[i], item_number_as_symbol_number (*(*rulep)->rhs)); if (i != source && !bitset_test (sources, source)) { bitset_set (sources, source); ++nsources; ++(*edge_countsp)[source]; } } } } if (nsources == 0) (*edgesp)[i] = NULL; else { (*edgesp)[i] = xnmalloc (nsources + 1, sizeof *(*edgesp)[i]); { bitset_iterator biter_source; bitset_bindex source; int j = 0; BITSET_FOR_EACH (biter_source, sources, source, 0) (*edgesp)[i][j++] = source; } (*edgesp)[i][nsources] = END_NODE; } bitset_zero (sources); } bitset_free (sources); } relation_transpose (edgesp, ngotos); if (trace_flag & trace_ielr) { fprintf (stderr, "internal_follow_edges:\n"); relation_print (*edgesp, ngotos, stderr); } }
static void print_reductions (FILE *out, state *s) { transitions *trans = s->transitions; reductions *reds = s->reductions; rule *default_rule = NULL; size_t width = 0; int i, j; if (reds->num == 0) return; default_rule = state_default_rule (s); bitset_zero (shift_set); FOR_EACH_SHIFT (trans, i) bitset_set (shift_set, TRANSITION_SYMBOL (trans, i)); /* Compute the width of the look-ahead token column. */ if (default_rule) width = strlen (_("$default")); if (reds->look_ahead_tokens) for (i = 0; i < ntokens; i++) { bool count = bitset_test (shift_set, i); for (j = 0; j < reds->num; ++j) if (bitset_test (reds->look_ahead_tokens[j], i)) { if (! count) { if (reds->rules[j] != default_rule) max_length (&width, symbols[i]->tag); count = true; } else { max_length (&width, symbols[i]->tag); } } } /* Nothing to report. */ if (!width) return; fputc ('\n', out); width += 2; /* Report look-ahead tokens (or $default) and reductions. */ if (reds->look_ahead_tokens) for (i = 0; i < ntokens; i++) { bool defaulted = false; bool count = bitset_test (shift_set, i); for (j = 0; j < reds->num; ++j) if (bitset_test (reds->look_ahead_tokens[j], i)) { if (! count) { if (reds->rules[j] != default_rule) print_reduction (out, width, symbols[i]->tag, reds->rules[j], true); else defaulted = true; count = true; } else { if (defaulted) print_reduction (out, width, symbols[i]->tag, default_rule, true); defaulted = false; print_reduction (out, width, symbols[i]->tag, reds->rules[j], false); } } } if (default_rule) print_reduction (out, width, _("$default"), default_rule, true); }
static void print_reductions (FILE *out, state *s) { transitions *trans = s->transitions; reductions *reds = s->reductions; rule *default_reduction = NULL; size_t width = 0; int i, j; bool default_reduction_only = true; if (reds->num == 0) return; if (yydefact[s->number] != 0) default_reduction = &rules[yydefact[s->number] - 1]; bitset_zero (no_reduce_set); FOR_EACH_SHIFT (trans, i) bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i)); for (i = 0; i < s->errs->num; ++i) if (s->errs->symbols[i]) bitset_set (no_reduce_set, s->errs->symbols[i]->number); /* Compute the width of the lookahead token column. */ if (default_reduction) width = strlen (_("$default")); if (reds->lookahead_tokens) for (i = 0; i < ntokens; i++) { bool count = bitset_test (no_reduce_set, i); for (j = 0; j < reds->num; ++j) if (bitset_test (reds->lookahead_tokens[j], i)) { if (! count) { if (reds->rules[j] != default_reduction) max_length (&width, symbols[i]->tag); count = true; } else { max_length (&width, symbols[i]->tag); } } } /* Nothing to report. */ if (!width) return; fputc ('\n', out); width += 2; /* Report lookahead tokens (or $default) and reductions. */ if (reds->lookahead_tokens) for (i = 0; i < ntokens; i++) { bool defaulted = false; bool count = bitset_test (no_reduce_set, i); if (count) default_reduction_only = false; for (j = 0; j < reds->num; ++j) if (bitset_test (reds->lookahead_tokens[j], i)) { if (! count) { if (reds->rules[j] != default_reduction) { default_reduction_only = false; print_reduction (out, width, symbols[i]->tag, reds->rules[j], true); } else defaulted = true; count = true; } else { default_reduction_only = false; if (defaulted) print_reduction (out, width, symbols[i]->tag, default_reduction, true); defaulted = false; print_reduction (out, width, symbols[i]->tag, reds->rules[j], false); } } } if (default_reduction) { char *default_reductions = muscle_percent_define_get ("lr.default-reductions"); print_reduction (out, width, _("$default"), default_reduction, true); aver (0 == strcmp (default_reductions, "most") || (0 == strcmp (default_reductions, "consistent") && default_reduction_only) || (reds->num == 1 && reds->rules[0]->number == 0)); free (default_reductions); } }