In the XML output, list useless and unused symbols and rules with the

useful ones and add a "usefulness" attribute.  Discussed starting at
<http://lists.gnu.org/archive/html/bison-patches/2007-09/msg00017.html>.
* src/gram.c (grammar_rules_partial_print_xml): Remove.
(grammar_rules_print_xml): Print all rules instead of just those
useful in the grammar, and add a "usefulness" attribute.
* src/gram.h (grammar_rules_partial_print_xml): Remove prototype.
* src/print-xml.c (print_rules_useless_in_parser): Remove.
(print_grammar): Print all nonterminals instead of just useful ones,
and add a "usefulness" attribute to nonterminals and terminals.
(print_xml): Don't print a separate "reductions" or
"rules-useless-in-parser" element.
* src/reduce.c (reduce_output): Use reduce_token_unused_in_grammar.
(reduce_xml): Remove.
(reduce_token_unused_in_grammar): New.
(reduce_nonterminal_useless_in_grammar): New.
* src/reduce.h (reduce_xml): Remove prototype.
(reduce_token_unused_in_grammar): Add prototype.
(reduce_nonterminal_useless_in_grammar): Add prototype.
* data/xslt/xml2text.xsl: Update for XML changes.
* data/xslt/xml2xhtml.xsl: Update for XML changes.
* tests/reduce.at (Useless Terminals): Update output.
(Useless Rules): Update output.
(Reduced Automaton): Update output.

Say "Terminals unused in grammar" instead of "Unused terminals".
* NEWS (2.3a+): Update.
* doc/bison.texinfo (Understanding): Update example output.
* src/reduce.c (reduce_output): Implement.
* data/xslt/xml2text.xsl: Implement.
* data/xslt/xml2xhtml.xsl: Implement.
This commit is contained in:
Joel E. Denny
2007-11-24 19:41:25 +00:00
parent 1bb2bd75f0
commit d80fb37a26
11 changed files with 267 additions and 269 deletions

View File

@@ -1,3 +1,37 @@
2007-11-24 Joel E. Denny <jdenny@ces.clemson.edu>
In the XML output, list useless and unused symbols and rules with the
useful ones and add a "usefulness" attribute. Discussed starting at
<http://lists.gnu.org/archive/html/bison-patches/2007-09/msg00017.html>.
* src/gram.c (grammar_rules_partial_print_xml): Remove.
(grammar_rules_print_xml): Print all rules instead of just those
useful in the grammar, and add a "usefulness" attribute.
* src/gram.h (grammar_rules_partial_print_xml): Remove prototype.
* src/print-xml.c (print_rules_useless_in_parser): Remove.
(print_grammar): Print all nonterminals instead of just useful ones,
and add a "usefulness" attribute to nonterminals and terminals.
(print_xml): Don't print a separate "reductions" or
"rules-useless-in-parser" element.
* src/reduce.c (reduce_output): Use reduce_token_unused_in_grammar.
(reduce_xml): Remove.
(reduce_token_unused_in_grammar): New.
(reduce_nonterminal_useless_in_grammar): New.
* src/reduce.h (reduce_xml): Remove prototype.
(reduce_token_unused_in_grammar): Add prototype.
(reduce_nonterminal_useless_in_grammar): Add prototype.
* data/xslt/xml2text.xsl: Update for XML changes.
* data/xslt/xml2xhtml.xsl: Update for XML changes.
* tests/reduce.at (Useless Terminals): Update output.
(Useless Rules): Update output.
(Reduced Automaton): Update output.
Say "Terminals unused in grammar" instead of "Unused terminals".
* NEWS (2.3a+): Update.
* doc/bison.texinfo (Understanding): Update example output.
* src/reduce.c (reduce_output): Implement.
* data/xslt/xml2text.xsl: Implement.
* data/xslt/xml2xhtml.xsl: Implement.
2007-11-18 Joel E. Denny <jdenny@ces.clemson.edu>
Accept --report-file=FILE to override the default `.output' filename.

7
NEWS
View File

@@ -41,9 +41,10 @@ Changes in version 2.3a+ (????-??-??):
%defines "parser.h"
* When reporting useless rules and nonterminals, Bison now employs the term
"useless in grammar" instead of "useless" and employs the term "useless in
parser" instead of "never reduced".
* When reporting useless rules, useless nonterminals, and unused terminals,
Bison now employs the terms "useless in grammar" instead of "useless",
"useless in parser" instead of "never reduced", and "unused in grammar"
instead of "unused".
* Unreachable State Removal

View File

@@ -36,73 +36,95 @@
</xsl:template>
<xsl:template match="bison-xml-report">
<xsl:apply-templates select="reductions"/>
<xsl:apply-templates select="rules-useless-in-parser"/>
<xsl:apply-templates select="grammar" mode="reductions"/>
<xsl:apply-templates select="grammar" mode="useless-in-parser"/>
<xsl:apply-templates select="automaton" mode="conflicts"/>
<xsl:apply-templates select="grammar"/>
<xsl:apply-templates select="automaton"/>
</xsl:template>
<xsl:template match="rules-useless-in-parser">
<xsl:if test="rule">
<xsl:text>Rules useless in parser due to conflicts&#10;</xsl:text>
<xsl:apply-templates select="rule">
<xsl:with-param name="pad" select="'3'"/>
</xsl:apply-templates>
<xsl:text>&#10;&#10;</xsl:text>
</xsl:if>
<xsl:template match="grammar" mode="reductions">
<xsl:apply-templates select="nonterminals" mode="useless-in-grammar"/>
<xsl:apply-templates select="terminals" mode="unused-in-grammar"/>
<xsl:apply-templates select="rules" mode="useless-in-grammar"/>
</xsl:template>
<xsl:template match="reductions">
<xsl:apply-templates select="useless-in-grammar/nonterminals"/>
<xsl:apply-templates select="unused/terminals"/>
<xsl:apply-templates select="useless-in-grammar/rules"/>
</xsl:template>
<xsl:template match="useless-in-grammar/nonterminals">
<xsl:if test="nonterminal">
<xsl:template match="nonterminals" mode="useless-in-grammar">
<xsl:if test="nonterminal[@usefulness='useless-in-grammar']">
<xsl:text>Nonterminals useless in grammar&#10;&#10;</xsl:text>
<xsl:for-each select="nonterminal">
<xsl:for-each select="nonterminal[@usefulness='useless-in-grammar']">
<xsl:text> </xsl:text>
<xsl:value-of select="."/>
<xsl:value-of select="@name"/>
<xsl:text>&#10;</xsl:text>
</xsl:for-each>
<xsl:text>&#10;&#10;</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="useless-in-grammar/rules">
<xsl:if test="rule">
<xsl:template match="terminals" mode="unused-in-grammar">
<xsl:if test="terminal[@usefulness='unused-in-grammar']">
<xsl:text>Terminals unused in grammar&#10;&#10;</xsl:text>
<xsl:for-each select="terminal[@usefulness='unused-in-grammar']">
<xsl:sort select="@symbol-number" data-type="number"/>
<xsl:text> </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text>&#10;</xsl:text>
</xsl:for-each>
<xsl:text>&#10;&#10;</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="rules" mode="useless-in-grammar">
<xsl:variable name="set" select="rule[@usefulness='useless-in-grammar']"/>
<xsl:if test="$set">
<xsl:text>Rules useless in grammar&#10;</xsl:text>
<xsl:apply-templates select="rule">
<xsl:with-param name="pad" select="'3'"/>
</xsl:apply-templates>
<xsl:call-template name="style-rule-set">
<xsl:with-param name="rule-set" select="$set"/>
</xsl:call-template>
<xsl:text>&#10;&#10;</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="unused/terminals">
<xsl:if test="terminal">
<xsl:text>Terminals which are not used&#10;&#10;</xsl:text>
<xsl:for-each select="terminal">
<xsl:text> </xsl:text>
<xsl:value-of select="."/>
<xsl:text>&#10;</xsl:text>
</xsl:for-each>
<xsl:template match="grammar" mode="useless-in-parser">
<xsl:variable
name="set" select="rules/rule[@usefulness='useless-in-parser']"
/>
<xsl:if test="$set">
<xsl:text>Rules useless in parser due to conflicts&#10;</xsl:text>
<xsl:call-template name="style-rule-set">
<xsl:with-param name="rule-set" select="$set"/>
</xsl:call-template>
<xsl:text>&#10;&#10;</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="grammar">
<xsl:text>Grammar&#10;</xsl:text>
<xsl:apply-templates select="rules/rule">
<xsl:with-param name="pad" select="'3'"/>
</xsl:apply-templates>
<xsl:call-template name="style-rule-set">
<xsl:with-param
name="rule-set" select="rules/rule[@usefulness!='useless-in-grammar']"
/>
</xsl:call-template>
<xsl:text>&#10;&#10;</xsl:text>
<xsl:apply-templates select="terminals"/>
<xsl:apply-templates select="nonterminals"/>
</xsl:template>
<xsl:template name="style-rule-set">
<xsl:param name="rule-set"/>
<xsl:for-each select="$rule-set">
<xsl:apply-templates select=".">
<xsl:with-param name="pad" select="'3'"/>
<xsl:with-param name="prev-lhs">
<xsl:if test="position()>1">
<xsl:variable name="position" select="position()"/>
<xsl:value-of select="$rule-set[$position - 1]/lhs"/>
</xsl:if>
</xsl:with-param>
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
<xsl:template match="grammar/terminals">
<xsl:text>Terminals, with rules where they appear&#10;&#10;</xsl:text>
<xsl:apply-templates select="terminal"/>
@@ -111,7 +133,7 @@
<xsl:template match="grammar/nonterminals">
<xsl:text>Nonterminals, with rules where they appear&#10;&#10;</xsl:text>
<xsl:apply-templates select="nonterminal"/>
<xsl:apply-templates select="nonterminal[@usefulness!='useless-in-grammar']"/>
</xsl:template>
<xsl:template match="terminal">
@@ -293,8 +315,7 @@
<xsl:param name="point"/>
<xsl:param name="lookaheads"/>
<xsl:if test="$itemset != 'true'
and not(preceding-sibling::rule[1]/lhs[text()] = lhs[text()])">
<xsl:if test="$itemset != 'true' and not($prev-lhs = lhs[text()])">
<xsl:text>&#10;</xsl:text>
</xsl:if>
@@ -307,8 +328,7 @@
<!-- LHS -->
<xsl:choose>
<xsl:when test="$itemset != 'true'
and preceding-sibling::rule[1]/lhs[text()] = lhs[text()]">
<xsl:when test="$itemset != 'true' and $prev-lhs = lhs[text()]">
<xsl:call-template name="lpad">
<xsl:with-param name="str" select="'|'"/>
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 1"/>

View File

@@ -109,9 +109,9 @@
<a href="#reductions">Reductions</a>
<ul class="lower-alpha">
<li><a href="#nonterminals_useless_in_grammar">Nonterminals useless in grammar</a></li>
<li><a href="#unused_terminals">Unused terminals</a></li>
<li><a href="#terminals_unused_in_grammar">Terminals unused in grammar</a></li>
<li><a href="#rules_useless_in_grammar">Rules useless in grammar</a></li>
<xsl:if test="rules-useless-in-parser/rule">
<xsl:if test="grammar/rules/rule[@usefulness='useless-in-parser']">
<li><a href="#rules_useless_in_parser">Rules useless in parser due to conflicts</a></li>
</xsl:if>
</ul>
@@ -127,89 +127,127 @@
</li>
<li><a href="#automaton">Automaton</a></li>
</ul>
<xsl:apply-templates select="reductions"/>
<xsl:apply-templates select="rules-useless-in-parser"/>
<xsl:apply-templates select="grammar" mode="reductions"/>
<xsl:apply-templates select="grammar" mode="useless-in-parser"/>
<xsl:apply-templates select="automaton" mode="conflicts"/>
<xsl:apply-templates select="grammar"/>
<xsl:apply-templates select="automaton"/>
</xsl:template>
<xsl:template match="rules-useless-in-parser">
<xsl:if test="rule">
<xsl:template match="grammar" mode="reductions">
<h2>
<a name="reductions"/>
<xsl:text> Reductions</xsl:text>
</h2>
<xsl:apply-templates select="nonterminals" mode="useless-in-grammar"/>
<xsl:apply-templates select="terminals" mode="unused-in-grammar"/>
<xsl:apply-templates select="rules" mode="useless-in-grammar"/>
</xsl:template>
<xsl:template match="nonterminals" mode="useless-in-grammar">
<h3>
<a name="nonterminals_useless_in_grammar"/>
<xsl:text> Nonterminals useless in grammar</xsl:text>
</h3>
<xsl:text>&#10;&#10;</xsl:text>
<xsl:if test="nonterminal[@usefulness='useless-in-grammar']">
<p class="pre">
<xsl:for-each select="nonterminal[@usefulness='useless-in-grammar']">
<xsl:text> </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text>&#10;</xsl:text>
</xsl:for-each>
<xsl:text>&#10;&#10;</xsl:text>
</p>
</xsl:if>
</xsl:template>
<xsl:template match="terminals" mode="unused-in-grammar">
<h3>
<a name="terminals_unused_in_grammar"/>
<xsl:text> Terminals unused in grammar</xsl:text>
</h3>
<xsl:text>&#10;&#10;</xsl:text>
<xsl:if test="terminal[@usefulness='unused-in-grammar']">
<p class="pre">
<xsl:for-each select="terminal[@usefulness='unused-in-grammar']">
<xsl:sort select="@symbol-number" data-type="number"/>
<xsl:text> </xsl:text>
<xsl:value-of select="@name"/>
<xsl:text>&#10;</xsl:text>
</xsl:for-each>
<xsl:text>&#10;&#10;</xsl:text>
</p>
</xsl:if>
</xsl:template>
<xsl:template match="rules" mode="useless-in-grammar">
<h3>
<a name="rules_useless_in_grammar"/>
<xsl:text> Rules useless in grammar</xsl:text>
</h3>
<xsl:text>&#10;</xsl:text>
<xsl:variable name="set" select="rule[@usefulness='useless-in-grammar']"/>
<xsl:if test="$set">
<p class="pre">
<xsl:call-template name="style-rule-set">
<xsl:with-param name="rule-set" select="$set"/>
</xsl:call-template>
<xsl:text>&#10;&#10;</xsl:text>
</p>
</xsl:if>
</xsl:template>
<xsl:template match="grammar" mode="useless-in-parser">
<xsl:variable
name="set" select="rules/rule[@usefulness='useless-in-parser']"
/>
<xsl:if test="$set">
<h2>
<a name="rules_useless_in_parser"/>
<xsl:text> Rules useless in parser due to conflicts</xsl:text>
</h2>
<xsl:text>&#10;</xsl:text>
<p class="pre">
<xsl:apply-templates select="rule">
<xsl:with-param name="pad" select="'3'"/>
</xsl:apply-templates>
<xsl:call-template name="style-rule-set">
<xsl:with-param name="rule-set" select="$set"/>
</xsl:call-template>
</p>
<xsl:text>&#10;&#10;</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="reductions">
<xsl:template match="grammar">
<h2>
<a name="reductions"/>
<xsl:text> Reductions</xsl:text>
<a name="grammar"/>
<xsl:text> Grammar</xsl:text>
</h2>
<xsl:apply-templates select="useless-in-grammar/nonterminals"/>
<xsl:apply-templates select="unused/terminals"/>
<xsl:apply-templates select="useless-in-grammar/rules"/>
</xsl:template>
<xsl:template match="useless-in-grammar/nonterminals">
<h3>
<a name="nonterminals_useless_in_grammar"/>
<xsl:text> Nonterminals useless in grammar</xsl:text>
</h3>
<xsl:text>&#10;&#10;</xsl:text>
<xsl:if test="nonterminal">
<p class="pre">
<xsl:for-each select="nonterminal">
<xsl:text> </xsl:text>
<xsl:value-of select="."/>
<xsl:text>&#10;</xsl:text>
</xsl:for-each>
<xsl:text>&#10;&#10;</xsl:text>
</p>
</xsl:if>
</xsl:template>
<xsl:template match="useless-in-grammar/rules">
<h3>
<a name="rules_useless_in_grammar"/>
<xsl:text> Rules useless in grammar</xsl:text>
</h3>
<xsl:text>&#10;</xsl:text>
<xsl:if test="rule">
<p class="pre">
<xsl:apply-templates select="rule">
<xsl:with-param name="pad" select="'3'"/>
</xsl:apply-templates>
<xsl:text>&#10;&#10;</xsl:text>
</p>
</xsl:if>
<p class="pre">
<xsl:call-template name="style-rule-set">
<xsl:with-param
name="rule-set" select="rules/rule[@usefulness!='useless-in-grammar']"
/>
</xsl:call-template>
</p>
<xsl:text>&#10;&#10;</xsl:text>
<xsl:apply-templates select="terminals"/>
<xsl:apply-templates select="nonterminals"/>
</xsl:template>
<xsl:template match="unused/terminals">
<h3>
<a name="unused_terminals"/>
<xsl:text> Terminals which are not used</xsl:text>
</h3>
<xsl:text>&#10;&#10;</xsl:text>
<xsl:if test="terminal">
<p class="pre">
<xsl:for-each select="terminal">
<xsl:text> </xsl:text>
<xsl:value-of select="."/>
<xsl:text>&#10;</xsl:text>
</xsl:for-each>
<xsl:text>&#10;&#10;</xsl:text>
</p>
</xsl:if>
<xsl:template name="style-rule-set">
<xsl:param name="rule-set"/>
<xsl:for-each select="$rule-set">
<xsl:apply-templates select=".">
<xsl:with-param name="pad" select="'3'"/>
<xsl:with-param name="prev-lhs">
<xsl:if test="position()>1">
<xsl:variable name="position" select="position()"/>
<xsl:value-of select="$rule-set[$position - 1]/lhs"/>
</xsl:if>
</xsl:with-param>
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
<xsl:template match="automaton" mode="conflicts">
@@ -260,22 +298,6 @@
</xsl:if>
</xsl:template>
<xsl:template match="grammar">
<h2>
<a name="grammar"/>
<xsl:text> Grammar</xsl:text>
</h2>
<xsl:text>&#10;</xsl:text>
<p class="pre">
<xsl:apply-templates select="rules/rule">
<xsl:with-param name="pad" select="'3'"/>
</xsl:apply-templates>
</p>
<xsl:text>&#10;&#10;</xsl:text>
<xsl:apply-templates select="terminals"/>
<xsl:apply-templates select="nonterminals"/>
</xsl:template>
<xsl:template match="grammar/terminals">
<h3>
<a name="terminals"/>
@@ -295,7 +317,9 @@
</h3>
<xsl:text>&#10;&#10;</xsl:text>
<p class="pre">
<xsl:apply-templates select="nonterminal"/>
<xsl:apply-templates
select="nonterminal[@usefulness!='useless-in-grammar']"
/>
</p>
</xsl:template>
@@ -446,8 +470,7 @@
<xsl:param name="point"/>
<xsl:param name="lookaheads"/>
<xsl:if test="$itemset != 'true'
and not(preceding-sibling::rule[1]/lhs[text()] = lhs[text()])">
<xsl:if test="$itemset != 'true' and not($prev-lhs = lhs[text()])">
<xsl:text>&#10;</xsl:text>
</xsl:if>
@@ -483,8 +506,7 @@
<!-- LHS -->
<xsl:choose>
<xsl:when test="$itemset != 'true'
and preceding-sibling::rule[1]/lhs[text()] = lhs[text()]">
<xsl:when test="$itemset != 'true' and $prev-lhs = lhs[text()]">
<xsl:call-template name="lpad">
<xsl:with-param name="str" select="'|'"/>
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>

View File

@@ -7197,14 +7197,14 @@ State 11 conflicts: 4 shift/reduce
The next section reports useless tokens, nonterminal and rules. Useless
nonterminals and rules are removed in order to produce a smaller parser,
but useless tokens are preserved, since they might be used by the
scanner (note the difference between ``useless'' and ``not used''
scanner (note the difference between ``useless'' and ``unused''
below):
@example
Useless nonterminals:
Nonterminals useless in grammar:
useless
Terminals which are not used:
Terminals unused in grammar:
STR
Rules useless in grammar:

View File

@@ -196,36 +196,6 @@ grammar_rules_partial_print (FILE *out, const char *title,
fputs ("\n\n", out);
}
void
grammar_rules_partial_print_xml (FILE *out, int level, bool rtag,
rule_filter filter)
{
rule_number r;
bool first = true;
for (r = 0; r < nrules + nuseless_productions; r++)
{
if (filter && !filter (&rules[r]))
continue;
if (rtag && first)
xml_puts (out, level + 1, "<rules>");
first = false;
xml_printf (out, level + 2, "<rule number=\"%d\">",
rules[r].number);
rule_lhs_print_xml (&rules[r], out, level + 3);
rule_rhs_print_xml (&rules[r], out, level + 3);
xml_puts (out, level + 2, "</rule>");
}
if (rtag)
{
if (!first)
xml_puts (out, level + 1, "</rules>");
else
xml_puts (out, level + 1, "<rules/>");
}
}
void
grammar_rules_print (FILE *out)
{
@@ -235,7 +205,33 @@ grammar_rules_print (FILE *out)
void
grammar_rules_print_xml (FILE *out, int level)
{
grammar_rules_partial_print_xml (out, level, true, rule_useful_in_grammar_p);
rule_number r;
bool first = true;
for (r = 0; r < nrules + nuseless_productions; r++)
{
if (first)
xml_puts (out, level + 1, "<rules>");
first = false;
{
char const *usefulness;
if (rule_useless_in_grammar_p (&rules[r]))
usefulness = "useless-in-grammar";
else if (rule_useless_in_parser_p (&rules[r]))
usefulness = "useless-in-parser";
else
usefulness = "useful";
xml_printf (out, level + 2, "<rule number=\"%d\" usefulness=\"%s\">",
rules[r].number, usefulness);
}
rule_lhs_print_xml (&rules[r], out, level + 3);
rule_rhs_print_xml (&rules[r], out, level + 3);
xml_puts (out, level + 2, "</rule>");
}
if (!first)
xml_puts (out, level + 1, "</rules>");
else
xml_puts (out, level + 1, "<rules/>");
}
void

View File

@@ -254,11 +254,10 @@ size_t ritem_longest_rhs (void);
/* Print the grammar's rules that match FILTER on OUT under TITLE. */
void grammar_rules_partial_print (FILE *out, const char *title,
rule_filter filter);
void grammar_rules_partial_print_xml (FILE *out, int level, bool rtag,
rule_filter filter);
/* Print the grammar's useful rules on OUT. */
void grammar_rules_print (FILE *out);
/* Print all of the grammar's rules with a "usefulness" attribute. */
void grammar_rules_print_xml (FILE *out, int level);
/* Dump the grammar. */

View File

@@ -51,35 +51,6 @@ struct escape_buf
static struct escape_buf escape_bufs[2];
/*--------------------------------.
| Print rules useless in parser. |
`--------------------------------*/
static void
print_rules_useless_in_parser (FILE *out, int level)
{
rule_number r;
bool count = false;
for (r = 0; r < nrules + nuseless_productions; r++)
{
if (rule_useless_in_parser_p (&rules[r]))
{
count = true;
break;
}
}
if (count) {
xml_puts (out, level, "<rules-useless-in-parser>");
grammar_rules_partial_print_xml (out, level - 1,
false, rule_useless_in_parser_p);
xml_puts (out, level, "</rules-useless-in-parser>");
}
else
xml_puts (out, level, "<rules-useless-in-parser/>");
}
/*--------------------------------.
| Report information on a state. |
`--------------------------------*/
@@ -430,8 +401,10 @@ print_grammar (FILE *out, int level)
xml_printf (out, level + 2,
"<terminal symbol-number=\"%d\" token-number=\"%d\""
" name=\"%s\">",
token_translations[i], i, xml_escape (tag));
" name=\"%s\" usefulness=\"%s\">",
token_translations[i], i, xml_escape (tag),
reduce_token_unused_in_grammar (token_translations[i])
? "unused-in-grammar" : "useful");
for (r = 0; r < nrules; r++)
for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
@@ -446,7 +419,7 @@ print_grammar (FILE *out, int level)
/* Nonterminals */
xml_puts (out, level + 1, "<nonterminals>");
for (i = ntokens; i < nsyms; i++)
for (i = ntokens; i < nsyms + nuseless_nonterminals; i++)
{
int left_count = 0, right_count = 0;
rule_number r;
@@ -466,8 +439,11 @@ print_grammar (FILE *out, int level)
}
xml_printf (out, level + 2,
"<nonterminal symbol-number=\"%d\" name=\"%s\">",
i, xml_escape (tag));
"<nonterminal symbol-number=\"%d\" name=\"%s\""
" usefulness=\"%s\">",
i, xml_escape (tag),
reduce_nonterminal_useless_in_grammar (i)
? "useless-in-grammar" : "useful");
if (left_count > 0)
{
@@ -584,12 +560,6 @@ print_xml (void)
xml_printf (out, level + 1, "<filename>%s</filename>",
xml_escape (grammar_file));
/* print reductions */
reduce_xml (out, level + 1);
/* print rules useless in parser */
print_rules_useless_in_parser (out, level + 1);
/* print grammar */
print_grammar (out, level + 1);

View File

@@ -358,10 +358,10 @@ reduce_output (FILE *out)
bool b = false;
int i;
for (i = 0; i < ntokens; i++)
if (!bitset_test (V, i) && !bitset_test (V1, i))
if (reduce_token_unused_in_grammar (i))
{
if (!b)
fprintf (out, "%s\n\n", _("Terminals which are not used"));
fprintf (out, "%s\n\n", _("Terminals unused in grammar"));
b = true;
fprintf (out, " %s\n", symbols[i]->tag);
}
@@ -375,64 +375,6 @@ reduce_output (FILE *out)
}
/*--------------------------------------------------------------.
| Output the detailed results of the reductions. For FILE.xml. |
`---------------------------------------------------------------*/
void
reduce_xml (FILE *out, int level)
{
fputc ('\n', out);
xml_puts (out, level, "<reductions>");
xml_puts (out, level + 1, "<useless-in-grammar>");
if (nuseless_nonterminals > 0)
{
int i;
xml_puts (out, level + 2, "<nonterminals>");
for (i = 0; i < nuseless_nonterminals; ++i)
xml_printf (out, level + 3,
"<nonterminal>%s</nonterminal>",
symbols[nsyms + i]->tag);
xml_puts (out, level + 2, "</nonterminals>");
}
else
xml_puts (out, level + 2, "<nonterminals/>");
if (nuseless_productions > 0)
grammar_rules_partial_print_xml (out, level + 1, true,
rule_useless_in_grammar_p);
else
xml_puts (out, level + 2, "<rules/>");
xml_puts (out, level + 1, "</useless-in-grammar>");
xml_puts (out, level + 1, "<unused>");
{
bool b = false;
int i;
for (i = 0; i < ntokens; i++)
if (!bitset_test (V, i) && !bitset_test (V1, i))
{
if (!b)
xml_puts (out, level + 2, "<terminals>");
b = true;
xml_printf (out, level + 3,
"<terminal>%s</terminal>",
xml_escape (symbols[i]->tag));
}
if (b)
xml_puts (out, level + 2, "</terminals>");
else
xml_puts (out, level + 2, "<terminals/>");
}
xml_puts (out, level + 1, "</unused>");
xml_puts (out, level, "</reductions>");
fputc ('\n', out);
}
/*-------------------------------.
| Report the results to STDERR. |
`-------------------------------*/
@@ -506,6 +448,19 @@ reduce_grammar (void)
}
}
bool
reduce_token_unused_in_grammar (symbol_number i)
{
aver (i < ntokens);
return !bitset_test (V, i) && !bitset_test (V1, i);
}
bool
reduce_nonterminal_useless_in_grammar (symbol_number i)
{
aver (ntokens <= i && i < nsyms + nuseless_nonterminals);
return nsyms <= i;
}
/*-----------------------------------------------------------.
| Free the global sets used to compute the reduced grammar. |

View File

@@ -22,7 +22,8 @@
void reduce_grammar (void);
void reduce_output (FILE *out);
void reduce_xml (FILE *out, int level);
bool reduce_token_unused_in_grammar (symbol_number i);
bool reduce_nonterminal_useless_in_grammar (symbol_number i);
void reduce_free (void);
extern symbol_number nuseless_nonterminals;

View File

@@ -45,7 +45,7 @@ exp: useful;
AT_CHECK([[bison input.y]])
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
[[Terminals which are not used
[[Terminals unused in grammar
useless1
useless2
useless3
@@ -174,7 +174,7 @@ AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
useless7
useless8
useless9
Terminals which are not used
Terminals unused in grammar
'1'
'2'
'3'
@@ -249,7 +249,7 @@ AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
[[Nonterminals useless in grammar
not_reachable
non_productive
Terminals which are not used
Terminals unused in grammar
useless_token
Rules useless in grammar
2 exp: non_productive