diff options
-rw-r--r-- | src/gram.c | 15 | ||||
-rw-r--r-- | src/reduce.c | 34 | ||||
-rw-r--r-- | tests/sets.at | 60 |
3 files changed, 85 insertions, 24 deletions
@@ -237,27 +237,28 @@ grammar_dump (FILE *out, const char *title) fprintf (out, "Rules\n-----\n\n"); { + /* Reduced number, then original number in the sources. */ fprintf (out, - "Num (Prec, Assoc, Useful, Ritem Range) Lhs" - " -> Rhs (Ritem range) [Num]\n"); - for (rule_number i = 0; i < nrules + nuseless_productions; i++) + "Num (Num, Prec, Assoc, Useful, UselessChain, Ritem Range)" + " Lhs -> Rhs (Ritem range)\n"); + for (rule_number i = 0; i < nrules + nuseless_productions; ++i) { rule const *rule_i = &rules[i]; unsigned const rhs_itemno = rule_i->rhs - ritem; unsigned length = rule_rhs_length (rule_i); - fprintf (out, "%3d (%2d, %2d, %2d, %2u-%2u) %2d ->", + fprintf (out, "%3d (%3d, %2d, %2d, %2s, %2u-%2u) %2d ->", + item_number_as_rule_number (rule_i->rhs[length]), i, rule_i->prec ? rule_i->prec->prec : 0, rule_i->prec ? rule_i->prec->assoc : 0, - rule_i->useful, + rule_i->useful ? "t" : "f", rhs_itemno, rhs_itemno + length - 1, rule_i->lhs->number); /* Dumped the RHS. */ for (item_number *rhsp = rule_i->rhs; 0 <= *rhsp; ++rhsp) fprintf (out, " %3d", *rhsp); - fprintf (out, " [%d]\n", - item_number_as_rule_number (rule_i->rhs[length+1])); + fputc ('\n', out); } } fprintf (out, "\n\n"); diff --git a/src/reduce.c b/src/reduce.c index 56a90754..574e9b07 100644 --- a/src/reduce.c +++ b/src/reduce.c @@ -378,23 +378,23 @@ reduce_grammar (void) inaccessable_symbols (); /* Did we reduce something? */ - if (!nuseless_nonterminals && !nuseless_productions) - return; - - reduce_print (); - - if (!bitset_test (N, accept->content->number - ntokens)) - complain (&startsymbol_location, fatal, - _("start symbol %s does not derive any sentence"), - startsymbol->tag); - - /* First reduce the nonterminals, as they renumber themselves in the - whole grammar. If you change the order, nonterms would be - renumbered only in the reduced grammar. */ - if (nuseless_nonterminals) - nonterminals_reduce (); - if (nuseless_productions) - reduce_grammar_tables (); + if (nuseless_nonterminals || nuseless_productions) + { + reduce_print (); + + if (!bitset_test (N, accept->content->number - ntokens)) + complain (&startsymbol_location, fatal, + _("start symbol %s does not derive any sentence"), + startsymbol->tag); + + /* First reduce the nonterminals, as they renumber themselves in the + whole grammar. If you change the order, nonterms would be + renumbered only in the reduced grammar. */ + if (nuseless_nonterminals) + nonterminals_reduce (); + if (nuseless_productions) + reduce_grammar_tables (); + } if (trace_flag & trace_grammar) { diff --git a/tests/sets.at b/tests/sets.at index 7cd254a9..01339c22 100644 --- a/tests/sets.at +++ b/tests/sets.at @@ -300,3 +300,63 @@ AT_CHECK([sed -n ' 0, [expout]) AT_CLEANUP + + + +## ----------------- ## +## Reduced Grammar. ## +## ----------------- ## + +# Check information about the grammar, once reduced. + +AT_SETUP([Reduced Grammar]) + +AT_DATA([input.y], +[[%% +expr: expr "+" term | term +term: term "*" fact | fact +fact: "num" +]]) + +AT_BISON_CHECK([[--trace=grammar -o input.c input.y]], [], [], +[[Reduced Grammar + +ntokens = 6, nvars = 4, nsyms = 10, nrules = 6, nritems = 17 + +Variables +--------- + +Value Sprec Sassoc Tag + 6 0 0 $accept + 7 0 0 expr + 8 0 0 term + 9 0 0 fact + + +Rules +----- + +Num (Num, Prec, Assoc, Useful, UselessChain, Ritem Range) Lhs -> Rhs (Ritem range) + 0 ( 0, 0, 0, t, 0- 1) 6 -> 7 0 + 1 ( 1, 0, 0, t, 3- 5) 7 -> 7 3 8 + 2 ( 2, 0, 0, t, 7- 7) 7 -> 8 + 3 ( 3, 0, 0, t, 9-11) 8 -> 8 4 9 + 4 ( 4, 0, 0, t, 13-13) 8 -> 9 + 5 ( 5, 0, 0, t, 15-15) 9 -> 5 + + +Rules interpreted +----------------- + +0 $accept: expr $end +1 expr: expr "+" term +2 expr: term +3 term: term "*" fact +4 term: fact +5 fact: "num" + + +reduced input.y defines 6 terminals, 4 nonterminals, and 6 productions. +]]) + +AT_CLEANUP |