+
+/*----------------------------------------------------------.
+| Return the default rule of this STATE if it has one, NULL |
+| otherwise. |
+`----------------------------------------------------------*/
+
+static rule_t *
+state_default_rule_compute (state_t *state)
+{
+ reductions_t *redp = state->reductions;
+ rule_t *default_rule = NULL;
+ int cmax = 0;
+ int i;
+
+ /* No need for a lookahead. */
+ if (state->consistent)
+ return &rules[redp->rules[0]];
+
+ /* 1. Each reduction is possibly masked by the lookaheads on which
+ we shift (S/R conflicts)... */
+ bitset_zero (shiftset);
+ {
+ shifts_t *shiftp = state->shifts;
+ for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
+ if (!SHIFT_IS_DISABLED (shiftp, i))
+ {
+ /* If this state has a shift for the error token, don't use a
+ default rule. */
+ if (SHIFT_IS_ERROR (shiftp, i))
+ return NULL;
+ bitset_set (shiftset, SHIFT_SYMBOL (shiftp, i));
+ }
+ }
+
+ /* 2. Each reduction is possibly masked by the lookaheads on which
+ we raise an error (due to %nonassoc). */
+ {
+ errs_t *errp = state->errs;
+ for (i = 0; i < errp->nerrs; i++)
+ if (errp->errs[i])
+ bitset_set (shiftset, errp->errs[i]);
+ }
+
+ for (i = 0; i < state->nlookaheads; ++i)
+ {
+ int count = 0;
+
+ /* How many non-masked lookaheads are there for this reduction?
+ */
+ bitset_andn (lookaheadset, state->lookaheads[i], shiftset);
+ count = bitset_count (lookaheadset);
+
+ if (count > cmax)
+ {
+ cmax = count;
+ default_rule = state->lookaheads_rule[i];
+ }
+
+ /* 3. And finally, each reduction is possibly masked by previous
+ reductions (in R/R conflicts, we keep the first reductions).
+ */
+ bitset_or (shiftset, shiftset, state->lookaheads[i]);
+ }
+
+ return default_rule;
+}
+
+
+/*----------------------------------------------------.
+| Report on OUT the reduction actions of this STATE. |
+`----------------------------------------------------*/
+
+static void
+print_reductions (FILE *out, state_t *state)
+{
+ int i;
+ shifts_t *shiftp = state->shifts;
+ reductions_t *redp = state->reductions;
+ rule_t *default_rule = NULL;
+
+ if (redp->nreds == 0)
+ return;
+
+ default_rule = state_default_rule_compute (state);
+
+ bitset_zero (shiftset);
+ for (i = 0; i < shiftp->nshifts && SHIFT_IS_SHIFT (shiftp, i); i++)
+ if (!SHIFT_IS_DISABLED (shiftp, i))
+ bitset_set (shiftset, SHIFT_SYMBOL (shiftp, i));
+
+ for (i = 0; i < ntokens; i++)
+ {
+ int j;
+ int defaulted = 0;
+ int count = bitset_test (shiftset, i);
+
+ for (j = 0; j < state->nlookaheads; ++j)
+ if (bitset_test (state->lookaheads[j], i))
+ {
+ if (count == 0)
+ {
+ if (state->lookaheads_rule[j] != default_rule)
+ fprintf (out,
+ _(" %-4s\treduce using rule %d (%s)\n"),
+ symbol_tag_get (symbols[i]),
+ state->lookaheads_rule[j]->number - 1,
+ symbol_tag_get_n (state->lookaheads_rule[j]->lhs, 1));
+ else
+ defaulted = 1;
+ count++;
+ }
+ else
+ {
+ if (defaulted)
+ fprintf (out,
+ _(" %-4s\treduce using rule %d (%s)\n"),
+ symbol_tag_get (symbols[i]),
+ default_rule->number - 1,
+ symbol_tag_get_n (default_rule->lhs, 1));
+ defaulted = 0;
+ fprintf (out,
+ _(" %-4s\t[reduce using rule %d (%s)]\n"),
+ symbol_tag_get (symbols[i]),
+ state->lookaheads_rule[j]->number - 1,
+ symbol_tag_get_n (state->lookaheads_rule[j]->lhs, 1));
+ }
+ }
+ }
+
+ if (default_rule)
+ fprintf (out, _(" $default\treduce using rule %d (%s)\n"),
+ default_rule->number - 1,
+ symbol_tag_get (default_rule->lhs));
+ fputc ('\n', out);
+}
+
+
+/*--------------------------------------------------------------.
+| Report on OUT all the actions (shifts, gotos, reductions, and |
+| explicit erros from %nonassoc) of STATE. |
+`--------------------------------------------------------------*/
+