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> 2007-11-18 Joel E. Denny <jdenny@ces.clemson.edu>
Accept --report-file=FILE to override the default `.output' filename. 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" %defines "parser.h"
* When reporting useless rules and nonterminals, Bison now employs the term * When reporting useless rules, useless nonterminals, and unused terminals,
"useless in grammar" instead of "useless" and employs the term "useless in Bison now employs the terms "useless in grammar" instead of "useless",
parser" instead of "never reduced". "useless in parser" instead of "never reduced", and "unused in grammar"
instead of "unused".
* Unreachable State Removal * Unreachable State Removal

View File

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

View File

@@ -109,9 +109,9 @@
<a href="#reductions">Reductions</a> <a href="#reductions">Reductions</a>
<ul class="lower-alpha"> <ul class="lower-alpha">
<li><a href="#nonterminals_useless_in_grammar">Nonterminals useless in grammar</a></li> <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> <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> <li><a href="#rules_useless_in_parser">Rules useless in parser due to conflicts</a></li>
</xsl:if> </xsl:if>
</ul> </ul>
@@ -127,89 +127,127 @@
</li> </li>
<li><a href="#automaton">Automaton</a></li> <li><a href="#automaton">Automaton</a></li>
</ul> </ul>
<xsl:apply-templates select="reductions"/> <xsl:apply-templates select="grammar" mode="reductions"/>
<xsl:apply-templates select="rules-useless-in-parser"/> <xsl:apply-templates select="grammar" mode="useless-in-parser"/>
<xsl:apply-templates select="automaton" mode="conflicts"/> <xsl:apply-templates select="automaton" mode="conflicts"/>
<xsl:apply-templates select="grammar"/> <xsl:apply-templates select="grammar"/>
<xsl:apply-templates select="automaton"/> <xsl:apply-templates select="automaton"/>
</xsl:template> </xsl:template>
<xsl:template match="rules-useless-in-parser"> <xsl:template match="grammar" mode="reductions">
<xsl:if test="rule"> <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> <h2>
<a name="rules_useless_in_parser"/> <a name="rules_useless_in_parser"/>
<xsl:text> Rules useless in parser due to conflicts</xsl:text> <xsl:text> Rules useless in parser due to conflicts</xsl:text>
</h2> </h2>
<xsl:text>&#10;</xsl:text> <xsl:text>&#10;</xsl:text>
<p class="pre"> <p class="pre">
<xsl:apply-templates select="rule"> <xsl:call-template name="style-rule-set">
<xsl:with-param name="pad" select="'3'"/> <xsl:with-param name="rule-set" select="$set"/>
</xsl:apply-templates> </xsl:call-template>
</p> </p>
<xsl:text>&#10;&#10;</xsl:text> <xsl:text>&#10;&#10;</xsl:text>
</xsl:if> </xsl:if>
</xsl:template> </xsl:template>
<xsl:template match="reductions"> <xsl:template match="grammar">
<h2> <h2>
<a name="reductions"/> <a name="grammar"/>
<xsl:text> Reductions</xsl:text> <xsl:text> Grammar</xsl:text>
</h2> </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:text>&#10;</xsl:text>
<xsl:if test="rule"> <p class="pre">
<p class="pre"> <xsl:call-template name="style-rule-set">
<xsl:apply-templates select="rule"> <xsl:with-param
<xsl:with-param name="pad" select="'3'"/> name="rule-set" select="rules/rule[@usefulness!='useless-in-grammar']"
</xsl:apply-templates> />
<xsl:text>&#10;&#10;</xsl:text> </xsl:call-template>
</p> </p>
</xsl:if> <xsl:text>&#10;&#10;</xsl:text>
<xsl:apply-templates select="terminals"/>
<xsl:apply-templates select="nonterminals"/>
</xsl:template> </xsl:template>
<xsl:template match="unused/terminals"> <xsl:template name="style-rule-set">
<h3> <xsl:param name="rule-set"/>
<a name="unused_terminals"/> <xsl:for-each select="$rule-set">
<xsl:text> Terminals which are not used</xsl:text> <xsl:apply-templates select=".">
</h3> <xsl:with-param name="pad" select="'3'"/>
<xsl:text>&#10;&#10;</xsl:text> <xsl:with-param name="prev-lhs">
<xsl:if test="terminal"> <xsl:if test="position()>1">
<p class="pre"> <xsl:variable name="position" select="position()"/>
<xsl:for-each select="terminal"> <xsl:value-of select="$rule-set[$position - 1]/lhs"/>
<xsl:text> </xsl:text> </xsl:if>
<xsl:value-of select="."/> </xsl:with-param>
<xsl:text>&#10;</xsl:text> </xsl:apply-templates>
</xsl:for-each> </xsl:for-each>
<xsl:text>&#10;&#10;</xsl:text>
</p>
</xsl:if>
</xsl:template> </xsl:template>
<xsl:template match="automaton" mode="conflicts"> <xsl:template match="automaton" mode="conflicts">
@@ -260,22 +298,6 @@
</xsl:if> </xsl:if>
</xsl:template> </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"> <xsl:template match="grammar/terminals">
<h3> <h3>
<a name="terminals"/> <a name="terminals"/>
@@ -295,7 +317,9 @@
</h3> </h3>
<xsl:text>&#10;&#10;</xsl:text> <xsl:text>&#10;&#10;</xsl:text>
<p class="pre"> <p class="pre">
<xsl:apply-templates select="nonterminal"/> <xsl:apply-templates
select="nonterminal[@usefulness!='useless-in-grammar']"
/>
</p> </p>
</xsl:template> </xsl:template>
@@ -446,8 +470,7 @@
<xsl:param name="point"/> <xsl:param name="point"/>
<xsl:param name="lookaheads"/> <xsl:param name="lookaheads"/>
<xsl:if test="$itemset != 'true' <xsl:if test="$itemset != 'true' and not($prev-lhs = lhs[text()])">
and not(preceding-sibling::rule[1]/lhs[text()] = lhs[text()])">
<xsl:text>&#10;</xsl:text> <xsl:text>&#10;</xsl:text>
</xsl:if> </xsl:if>
@@ -483,8 +506,7 @@
<!-- LHS --> <!-- LHS -->
<xsl:choose> <xsl:choose>
<xsl:when test="$itemset != 'true' <xsl:when test="$itemset != 'true' and $prev-lhs = lhs[text()]">
and preceding-sibling::rule[1]/lhs[text()] = lhs[text()]">
<xsl:call-template name="lpad"> <xsl:call-template name="lpad">
<xsl:with-param name="str" select="'|'"/> <xsl:with-param name="str" select="'|'"/>
<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/> <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 The next section reports useless tokens, nonterminal and rules. Useless
nonterminals and rules are removed in order to produce a smaller parser, nonterminals and rules are removed in order to produce a smaller parser,
but useless tokens are preserved, since they might be used by the 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): below):
@example @example
Useless nonterminals: Nonterminals useless in grammar:
useless useless
Terminals which are not used: Terminals unused in grammar:
STR STR
Rules useless in grammar: Rules useless in grammar:

View File

@@ -196,36 +196,6 @@ grammar_rules_partial_print (FILE *out, const char *title,
fputs ("\n\n", out); 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 void
grammar_rules_print (FILE *out) grammar_rules_print (FILE *out)
{ {
@@ -235,7 +205,33 @@ grammar_rules_print (FILE *out)
void void
grammar_rules_print_xml (FILE *out, int level) 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 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. */ /* Print the grammar's rules that match FILTER on OUT under TITLE. */
void grammar_rules_partial_print (FILE *out, const char *title, void grammar_rules_partial_print (FILE *out, const char *title,
rule_filter filter); 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. */ /* Print the grammar's useful rules on OUT. */
void grammar_rules_print (FILE *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); void grammar_rules_print_xml (FILE *out, int level);
/* Dump the grammar. */ /* Dump the grammar. */

View File

@@ -51,35 +51,6 @@ struct escape_buf
static struct escape_buf escape_bufs[2]; 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. | | Report information on a state. |
`--------------------------------*/ `--------------------------------*/
@@ -430,8 +401,10 @@ print_grammar (FILE *out, int level)
xml_printf (out, level + 2, xml_printf (out, level + 2,
"<terminal symbol-number=\"%d\" token-number=\"%d\"" "<terminal symbol-number=\"%d\" token-number=\"%d\""
" name=\"%s\">", " name=\"%s\" usefulness=\"%s\">",
token_translations[i], i, xml_escape (tag)); 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 (r = 0; r < nrules; r++)
for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++) for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
@@ -446,7 +419,7 @@ print_grammar (FILE *out, int level)
/* Nonterminals */ /* Nonterminals */
xml_puts (out, level + 1, "<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; int left_count = 0, right_count = 0;
rule_number r; rule_number r;
@@ -466,8 +439,11 @@ print_grammar (FILE *out, int level)
} }
xml_printf (out, level + 2, xml_printf (out, level + 2,
"<nonterminal symbol-number=\"%d\" name=\"%s\">", "<nonterminal symbol-number=\"%d\" name=\"%s\""
i, xml_escape (tag)); " usefulness=\"%s\">",
i, xml_escape (tag),
reduce_nonterminal_useless_in_grammar (i)
? "useless-in-grammar" : "useful");
if (left_count > 0) if (left_count > 0)
{ {
@@ -584,12 +560,6 @@ print_xml (void)
xml_printf (out, level + 1, "<filename>%s</filename>", xml_printf (out, level + 1, "<filename>%s</filename>",
xml_escape (grammar_file)); 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 */
print_grammar (out, level + 1); print_grammar (out, level + 1);

View File

@@ -358,10 +358,10 @@ reduce_output (FILE *out)
bool b = false; bool b = false;
int i; int i;
for (i = 0; i < ntokens; 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) if (!b)
fprintf (out, "%s\n\n", _("Terminals which are not used")); fprintf (out, "%s\n\n", _("Terminals unused in grammar"));
b = true; b = true;
fprintf (out, " %s\n", symbols[i]->tag); 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. | | 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. | | Free the global sets used to compute the reduced grammar. |

View File

@@ -22,7 +22,8 @@
void reduce_grammar (void); void reduce_grammar (void);
void reduce_output (FILE *out); 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); void reduce_free (void);
extern symbol_number nuseless_nonterminals; extern symbol_number nuseless_nonterminals;

View File

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