]> git.saurik.com Git - bison.git/commitdiff
In the XML output, list useless and unused symbols and rules with the
authorJoel E. Denny <jdenny@ces.clemson.edu>
Sat, 24 Nov 2007 19:41:25 +0000 (19:41 +0000)
committerJoel E. Denny <jdenny@ces.clemson.edu>
Sat, 24 Nov 2007 19:41:25 +0000 (19:41 +0000)
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.

ChangeLog
NEWS
data/xslt/xml2text.xsl
data/xslt/xml2xhtml.xsl
doc/bison.texinfo
src/gram.c
src/gram.h
src/print-xml.c
src/reduce.c
src/reduce.h
tests/reduce.at

index 741f68ed98dccf661ebd5c63f18210eda492c482..0b81e8c1e6c32c2cc09c44fa7efc65606bf7d920 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/NEWS b/NEWS
index afc354211e027d4a1518a9a8fc11ae3e071fa14a..2a3e57c22ba34b777e6ede3ae67b3fdb99e07daa 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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
 
index b2c73eacb112cc53182599f3ba199c737ab4c6a6..c2568a44c879a98369ca5839ae22564347c4c525 100644 (file)
 </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 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[@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>
+  </xsl:if>
 </xsl:template>
 
-<xsl:template match="useless-in-grammar/nonterminals">
-  <xsl:if test="nonterminal">
-    <xsl:text>Nonterminals useless in grammar&#10;&#10;</xsl:text>
-    <xsl:for-each select="nonterminal">
+<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="."/>
+      <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="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"/>
 
 <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">
   <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>
 
 
   <!-- 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"/>
index 6277663704b5a46ed994ab0c18f559f6ab78539b..15155e9d0409a55766b59a32c5d45b948b0dde5f 100644 (file)
       <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>
     </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">
-    <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>
-    </p>
-    <xsl:text>&#10;&#10;</xsl:text>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template match="reductions">
+<xsl:template match="grammar" mode="reductions">
   <h2>
     <a name="reductions"/>
     <xsl:text> Reductions</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: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="useless-in-grammar/nonterminals">
+<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">
+  <xsl:if test="nonterminal[@usefulness='useless-in-grammar']">
     <p class="pre">
-      <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:template match="terminals" mode="unused-in-grammar">
   <h3>
-    <a name="rules_useless_in_grammar"/>
-    <xsl:text> Rules useless in grammar</xsl:text>
+    <a name="terminals_unused_in_grammar"/>
+    <xsl:text> Terminals unused in grammar</xsl:text>
   </h3>
-  <xsl:text>&#10;</xsl:text>
-  <xsl:if test="rule">
+  <xsl:text>&#10;&#10;</xsl:text>
+  <xsl:if test="terminal[@usefulness='unused-in-grammar']">
     <p class="pre">
-      <xsl:apply-templates select="rule">
-       <xsl:with-param name="pad" select="'3'"/>
-      </xsl:apply-templates>
+      <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="unused/terminals">
+<xsl:template match="rules" mode="useless-in-grammar">
   <h3>
-    <a name="unused_terminals"/>
-    <xsl:text> Terminals which are not used</xsl:text>
+    <a name="rules_useless_in_grammar"/>
+    <xsl:text> Rules useless in grammar</xsl:text>
   </h3>
-  <xsl:text>&#10;&#10;</xsl:text>
-  <xsl:if test="terminal">
+  <xsl:text>&#10;</xsl:text>
+  <xsl:variable name="set" select="rule[@usefulness='useless-in-grammar']"/>
+  <xsl:if test="$set">
     <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: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: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="grammar">
+  <h2>
+    <a name="grammar"/>
+    <xsl:text> Grammar</xsl:text>
+  </h2>
+  <xsl:text>&#10;</xsl:text>
+  <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 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">
   <h2>
     <a name="conflicts"/>
   </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"/>
   </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>
 
   <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>
 
 
   <!-- 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"/>
index 9d0da773eb75ebef0bc91b66f03ade79f5beddf0..210bbad493a2481ca0ccfd2eee25d16dcad56d65 100644 (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:
index fa3fdbf552ff89769bb4f108aeee9062aec5e385..1f2885f07d37929b7019f5dc252e85bdc79fb818 100644 (file)
@@ -197,45 +197,41 @@ grammar_rules_partial_print (FILE *out, const char *title,
 }
 
 void
-grammar_rules_partial_print_xml (FILE *out, int level, bool rtag,
-                                rule_filter filter)
+grammar_rules_print (FILE *out)
+{
+  grammar_rules_partial_print (out, _("Grammar"), rule_useful_in_grammar_p);
+}
+
+void
+grammar_rules_print_xml (FILE *out, int level)
 {
   rule_number r;
   bool first = true;
 
   for (r = 0; r < nrules + nuseless_productions; r++)
     {
-      if (filter && !filter (&rules[r]))
-       continue;
-      if (rtag && first)
+      if (first)
        xml_puts (out, level + 1, "<rules>");
       first = false;
-
-      xml_printf (out, level + 2, "<rule number=\"%d\">",
-                 rules[r].number);
+      {
+        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 (rtag)
-    {
-      if (!first)
-       xml_puts (out, level + 1, "</rules>");
-      else
-       xml_puts (out, level + 1, "<rules/>");
-    }
-}
-
-void
-grammar_rules_print (FILE *out)
-{
-  grammar_rules_partial_print (out, _("Grammar"), rule_useful_in_grammar_p);
-}
-
-void
-grammar_rules_print_xml (FILE *out, int level)
-{
-  grammar_rules_partial_print_xml (out, level, true, rule_useful_in_grammar_p);
+  if (!first)
+    xml_puts (out, level + 1, "</rules>");
+  else
+   xml_puts (out, level + 1, "<rules/>");
 }
 
 void
index 57097379ef4748afc57224c464f90b9bd6639fe3..8e997ec52d84458868091b2c4e61c1591663e70e 100644 (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. */
index f7cae3f0c4c006ee82e5783f579e3708c3b3f25c..ff2bacd9b25951a2833d84d1a7c656744fe71854 100644 (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);
 
index 2d01255c375ec7647e99c850a046596afff76444..1306374acbfd0065f89ee190ba345019a7b737d2 100644 (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)
 }
 \f
 
-/*--------------------------------------------------------------.
-| 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);
-}
-\f
-
 /*-------------------------------.
 | 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.  |
index aaa2bab137b7307d264f82ee5e629cbdc422557b..3d039ef59b7b336becc9084991ed5ff67f2d587a 100644 (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;
index 9f331b0bf6f4743656b9bde0436fa99cae16e82c..9e5246af7c879d0e2715405bbadc59a328e4611d 100644 (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