]> 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.
 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"
 
 
     %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
 
 
 * Unreachable State Removal
 
index b2c73eacb112cc53182599f3ba199c737ab4c6a6..c2568a44c879a98369ca5839ae22564347c4c525 100644 (file)
 </xsl:template>
 
 <xsl:template match="bison-xml-report">
 </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: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>
 
-<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>
 
-<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: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: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: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: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: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: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/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: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:template>
 
 <xsl:template match="terminal">
   <xsl:param name="point"/>
   <xsl:param name="lookaheads"/>
 
   <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>
 
     <xsl:text>&#10;</xsl:text>
   </xsl:if>
 
 
   <!-- LHS -->
   <xsl:choose>
 
   <!-- 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"/>
       <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>
       <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>
        <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><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>
     </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: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>
   <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>
 
-<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>
   <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">
     <p class="pre">
-      <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:for-each>
       <xsl:text>&#10;&#10;</xsl:text>
        <xsl:text>&#10;</xsl:text>
       </xsl:for-each>
       <xsl:text>&#10;&#10;</xsl:text>
   </xsl:if>
 </xsl:template>
 
   </xsl:if>
 </xsl:template>
 
-<xsl:template match="useless-in-grammar/rules">
+<xsl:template match="terminals" mode="unused-in-grammar">
   <h3>
   <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>
   </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">
     <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:text>&#10;&#10;</xsl:text>
     </p>
   </xsl:if>
 </xsl:template>
 
-<xsl:template match="unused/terminals">
+<xsl:template match="rules" mode="useless-in-grammar">
   <h3>
   <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>
   </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">
     <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: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:template match="automaton" mode="conflicts">
   <h2>
     <a name="conflicts"/>
   </xsl:if>
 </xsl:template>
 
   </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"/>
 <xsl:template match="grammar/terminals">
   <h3>
     <a name="terminals"/>
   </h3>
   <xsl:text>&#10;&#10;</xsl:text>
   <p class="pre">
   </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>
 
   </p>
 </xsl:template>
 
   <xsl:param name="point"/>
   <xsl:param name="lookaheads"/>
 
   <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>
 
     <xsl:text>&#10;</xsl:text>
   </xsl:if>
 
 
   <!-- LHS -->
   <xsl:choose>
 
   <!-- 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"/>
       <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
 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
 below):
 
 @example
-Useless nonterminals:
+Nonterminals useless in grammar:
    useless
 
    useless
 
-Terminals which are not used:
+Terminals unused in grammar:
    STR
 
 Rules useless 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
 }
 
 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++)
     {
 {
   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_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>");
     }
       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
 }
 
 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);
 /* 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 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. */
 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];
 
 
 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,
                    "<terminal symbol-number=\"%d\" token-number=\"%d\""
 
        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++)
 
        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>");
 
   /* 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;
     {
       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,
        }
 
       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)
        {
 
       if (left_count > 0)
        {
@@ -584,12 +560,6 @@ print_xml (void)
   xml_printf (out, level + 1, "<filename>%s</filename>",
              xml_escape (grammar_file));
 
   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);
 
   /* 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++)
     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)
        {
          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);
        }
          b = true;
          fprintf (out, "   %s\n", symbols[i]->tag);
        }
@@ -375,64 +375,6 @@ reduce_output (FILE *out)
 }
 \f
 
 }
 \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.  |
 `-------------------------------*/
 /*-------------------------------.
 | 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.  |
index aaa2bab137b7307d264f82ee5e629cbdc422557b..3d039ef59b7b336becc9084991ed5ff67f2d587a 100644 (file)
@@ -22,7 +22,8 @@
 
 void reduce_grammar (void);
 void reduce_output (FILE *out);
 
 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;
 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,
 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
    useless1
    useless2
    useless3
@@ -174,7 +174,7 @@ AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
    useless7
    useless8
    useless9
    useless7
    useless8
    useless9
-Terminals which are not used
+Terminals unused in grammar
    '1'
    '2'
    '3'
    '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
 [[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
    useless_token
 Rules useless in grammar
     2 exp: non_productive