Home | History | Annotate | Download | only in xslt
      1 <?xml version="1.0" encoding="UTF-8"?>
      2 
      3 <!--
      4     xml2html.xsl - transform Bison XML Report into XHTML.
      5 
      6     Copyright (C) 2007-2012 Free Software Foundation, Inc.
      7 
      8     This file is part of Bison, the GNU Compiler Compiler.
      9 
     10     This program is free software: you can redistribute it and/or modify
     11     it under the terms of the GNU General Public License as published by
     12     the Free Software Foundation, either version 3 of the License, or
     13     (at your option) any later version.
     14 
     15     This program is distributed in the hope that it will be useful,
     16     but WITHOUT ANY WARRANTY; without even the implied warranty of
     17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18     GNU General Public License for more details.
     19 
     20     You should have received a copy of the GNU General Public License
     21     along with this program.  If not, see <http://www.gnu.org/licenses/>.
     22 
     23     Written by Wojciech Polak <polak (a] gnu.org>.
     24   -->
     25 
     26 <xsl:stylesheet version="1.0"
     27   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     28   xmlns="http://www.w3.org/1999/xhtml"
     29   xmlns:bison="http://www.gnu.org/software/bison/">
     30 
     31 <xsl:import href="bison.xsl"/>
     32 
     33 <xsl:output method="xml" encoding="UTF-8"
     34 	    doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
     35 	    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
     36 	    indent="yes"/>
     37 
     38 <xsl:template match="/">
     39   <html>
     40     <head>
     41       <title>
     42 	<xsl:value-of select="bison-xml-report/filename"/>
     43 	<xsl:text> - GNU Bison XML Automaton Report</xsl:text>
     44       </title>
     45       <style type="text/css"><![CDATA[
     46       body {
     47         font-family: "Nimbus Sans L", Arial, sans-serif;
     48 	font-size: 9pt;
     49       }
     50       a:link {
     51 	color: #1f00ff;
     52 	text-decoration: none;
     53       }
     54       a:visited {
     55 	color: #1f00ff;
     56 	text-decoration: none;
     57       }
     58       a:hover {
     59 	color: red;
     60       }
     61       #menu a {
     62         text-decoration: underline;
     63       }
     64       .i {
     65         font-style: italic;
     66       }
     67       .pre {
     68         font-family: monospace;
     69         white-space: pre;
     70       }
     71       ol.decimal {
     72         list-style-type: decimal;
     73       }
     74       ol.lower-alpha {
     75         list-style-type: lower-alpha;
     76       }
     77       .point {
     78         color: #cc0000;
     79       }
     80       #footer {
     81         margin-top: 3.5em;
     82         font-size: 7pt;
     83       }
     84       ]]></style>
     85     </head>
     86     <body>
     87       <xsl:apply-templates select="bison-xml-report"/>
     88       <xsl:text>&#10;&#10;</xsl:text>
     89       <div id="footer"><hr />This document was generated using
     90       <a href="http://www.gnu.org/software/bison/" title="GNU Bison">
     91       GNU Bison <xsl:value-of select="/bison-xml-report/@version"/></a>
     92       XML Automaton Report.<br />
     93       <!-- default copying notice -->
     94       Verbatim copying and distribution of this entire page is
     95       permitted in any medium, provided this notice is preserved.</div>
     96     </body>
     97   </html>
     98 </xsl:template>
     99 
    100 <xsl:template match="bison-xml-report">
    101   <h1>GNU Bison XML Automaton Report</h1>
    102   <p>
    103     input grammar: <span class="i"><xsl:value-of select="filename"/></span>
    104   </p>
    105 
    106   <xsl:text>&#10;&#10;</xsl:text>
    107   <h3>Table of Contents</h3>
    108   <ul id="menu">
    109     <li>
    110       <a href="#reductions">Reductions</a>
    111       <ul class="lower-alpha">
    112 	<li><a href="#nonterminals_useless_in_grammar">Nonterminals useless in grammar</a></li>
    113 	<li><a href="#terminals_unused_in_grammar">Terminals unused in grammar</a></li>
    114 	<li><a href="#rules_useless_in_grammar">Rules useless in grammar</a></li>
    115 	<xsl:if test="grammar/rules/rule[@usefulness='useless-in-parser']">
    116 	  <li><a href="#rules_useless_in_parser">Rules useless in parser due to conflicts</a></li>
    117 	</xsl:if>
    118       </ul>
    119     </li>
    120     <li><a href="#conflicts">Conflicts</a></li>
    121     <li>
    122       <a href="#grammar">Grammar</a>
    123       <ul class="lower-alpha">
    124 	<li><a href="#grammar">Itemset</a></li>
    125 	<li><a href="#terminals">Terminal symbols</a></li>
    126 	<li><a href="#nonterminals">Nonterminal symbols</a></li>
    127       </ul>
    128     </li>
    129     <li><a href="#automaton">Automaton</a></li>
    130   </ul>
    131   <xsl:apply-templates select="grammar" mode="reductions"/>
    132   <xsl:apply-templates select="grammar" mode="useless-in-parser"/>
    133   <xsl:apply-templates select="automaton" mode="conflicts"/>
    134   <xsl:apply-templates select="grammar"/>
    135   <xsl:apply-templates select="automaton"/>
    136 </xsl:template>
    137 
    138 <xsl:template match="grammar" mode="reductions">
    139   <h2>
    140     <a name="reductions"/>
    141     <xsl:text> Reductions</xsl:text>
    142   </h2>
    143   <xsl:apply-templates select="nonterminals" mode="useless-in-grammar"/>
    144   <xsl:apply-templates select="terminals" mode="unused-in-grammar"/>
    145   <xsl:apply-templates select="rules" mode="useless-in-grammar"/>
    146 </xsl:template>
    147 
    148 <xsl:template match="nonterminals" mode="useless-in-grammar">
    149   <h3>
    150     <a name="nonterminals_useless_in_grammar"/>
    151     <xsl:text> Nonterminals useless in grammar</xsl:text>
    152   </h3>
    153   <xsl:text>&#10;&#10;</xsl:text>
    154   <xsl:if test="nonterminal[@usefulness='useless-in-grammar']">
    155     <p class="pre">
    156       <xsl:for-each select="nonterminal[@usefulness='useless-in-grammar']">
    157 	<xsl:text>   </xsl:text>
    158 	<xsl:value-of select="@name"/>
    159 	<xsl:text>&#10;</xsl:text>
    160       </xsl:for-each>
    161       <xsl:text>&#10;&#10;</xsl:text>
    162     </p>
    163   </xsl:if>
    164 </xsl:template>
    165 
    166 <xsl:template match="terminals" mode="unused-in-grammar">
    167   <h3>
    168     <a name="terminals_unused_in_grammar"/>
    169     <xsl:text> Terminals unused in grammar</xsl:text>
    170   </h3>
    171   <xsl:text>&#10;&#10;</xsl:text>
    172   <xsl:if test="terminal[@usefulness='unused-in-grammar']">
    173     <p class="pre">
    174       <xsl:for-each select="terminal[@usefulness='unused-in-grammar']">
    175         <xsl:sort select="@symbol-number" data-type="number"/>
    176 	<xsl:text>   </xsl:text>
    177 	<xsl:value-of select="@name"/>
    178 	<xsl:text>&#10;</xsl:text>
    179       </xsl:for-each>
    180       <xsl:text>&#10;&#10;</xsl:text>
    181     </p>
    182   </xsl:if>
    183 </xsl:template>
    184 
    185 <xsl:template match="rules" mode="useless-in-grammar">
    186   <h3>
    187     <a name="rules_useless_in_grammar"/>
    188     <xsl:text> Rules useless in grammar</xsl:text>
    189   </h3>
    190   <xsl:text>&#10;</xsl:text>
    191   <xsl:variable name="set" select="rule[@usefulness='useless-in-grammar']"/>
    192   <xsl:if test="$set">
    193     <p class="pre">
    194       <xsl:call-template name="style-rule-set">
    195         <xsl:with-param name="rule-set" select="$set"/>
    196       </xsl:call-template>
    197       <xsl:text>&#10;&#10;</xsl:text>
    198     </p>
    199   </xsl:if>
    200 </xsl:template>
    201 
    202 <xsl:template match="grammar" mode="useless-in-parser">
    203   <xsl:variable
    204     name="set" select="rules/rule[@usefulness='useless-in-parser']"
    205   />
    206   <xsl:if test="$set">
    207     <h2>
    208       <a name="rules_useless_in_parser"/>
    209       <xsl:text> Rules useless in parser due to conflicts</xsl:text>
    210     </h2>
    211     <xsl:text>&#10;</xsl:text>
    212     <p class="pre">
    213       <xsl:call-template name="style-rule-set">
    214         <xsl:with-param name="rule-set" select="$set"/>
    215       </xsl:call-template>
    216     </p>
    217     <xsl:text>&#10;&#10;</xsl:text>
    218   </xsl:if>
    219 </xsl:template>
    220 
    221 <xsl:template match="grammar">
    222   <h2>
    223     <a name="grammar"/>
    224     <xsl:text> Grammar</xsl:text>
    225   </h2>
    226   <xsl:text>&#10;</xsl:text>
    227   <p class="pre">
    228     <xsl:call-template name="style-rule-set">
    229       <xsl:with-param
    230         name="rule-set" select="rules/rule[@usefulness!='useless-in-grammar']"
    231       />
    232     </xsl:call-template>
    233   </p>
    234   <xsl:text>&#10;&#10;</xsl:text>
    235   <xsl:apply-templates select="terminals"/>
    236   <xsl:apply-templates select="nonterminals"/>
    237 </xsl:template>
    238 
    239 <xsl:template name="style-rule-set">
    240   <xsl:param name="rule-set"/>
    241   <xsl:for-each select="$rule-set">
    242     <xsl:apply-templates select=".">
    243       <xsl:with-param name="pad" select="'3'"/>
    244       <xsl:with-param name="prev-lhs">
    245         <xsl:if test="position()>1">
    246           <xsl:variable name="position" select="position()"/>
    247           <xsl:value-of select="$rule-set[$position - 1]/lhs"/>
    248         </xsl:if>
    249       </xsl:with-param>
    250     </xsl:apply-templates>
    251   </xsl:for-each>
    252 </xsl:template>
    253 
    254 <xsl:template match="automaton" mode="conflicts">
    255   <h2>
    256     <a name="conflicts"/>
    257     <xsl:text> Conflicts</xsl:text>
    258   </h2>
    259   <xsl:text>&#10;&#10;</xsl:text>
    260   <xsl:variable name="conflict-report">
    261     <xsl:apply-templates select="state" mode="conflicts"/>
    262   </xsl:variable>
    263   <xsl:if test="string-length($conflict-report) != 0">
    264     <p class="pre">
    265       <xsl:copy-of select="$conflict-report"/>
    266       <xsl:text>&#10;&#10;</xsl:text>
    267     </p>
    268   </xsl:if>
    269 </xsl:template>
    270 
    271 <xsl:template match="state" mode="conflicts">
    272   <xsl:variable name="conflict-counts">
    273     <xsl:apply-templates select="." mode="bison:count-conflicts" />
    274   </xsl:variable>
    275   <xsl:variable
    276     name="sr-count" select="substring-before($conflict-counts, ',')"
    277   />
    278   <xsl:variable
    279     name="rr-count" select="substring-after($conflict-counts, ',')"
    280   />
    281   <xsl:if test="$sr-count > 0 or $rr-count > 0">
    282     <a>
    283       <xsl:attribute name="href">
    284         <xsl:value-of select="concat('#state_', @number)"/>
    285       </xsl:attribute>
    286       <xsl:value-of select="concat('State ', @number)"/>
    287     </a>
    288     <xsl:text> conflicts:</xsl:text>
    289     <xsl:if test="$sr-count > 0">
    290       <xsl:value-of select="concat(' ', $sr-count, ' shift/reduce')"/>
    291       <xsl:if test="$rr-count > 0">
    292         <xsl:value-of select="(',')"/>
    293       </xsl:if>
    294     </xsl:if>
    295     <xsl:if test="$rr-count > 0">
    296       <xsl:value-of select="concat(' ', $rr-count, ' reduce/reduce')"/>
    297     </xsl:if>
    298     <xsl:value-of select="'&#10;'"/>
    299   </xsl:if>
    300 </xsl:template>
    301 
    302 <xsl:template match="grammar/terminals">
    303   <h3>
    304     <a name="terminals"/>
    305     <xsl:text> Terminals, with rules where they appear</xsl:text>
    306   </h3>
    307   <xsl:text>&#10;&#10;</xsl:text>
    308   <p class="pre">
    309     <xsl:apply-templates select="terminal"/>
    310   </p>
    311   <xsl:text>&#10;&#10;</xsl:text>
    312 </xsl:template>
    313 
    314 <xsl:template match="grammar/nonterminals">
    315   <h3>
    316     <a name="nonterminals"/>
    317     <xsl:text> Nonterminals, with rules where they appear</xsl:text>
    318   </h3>
    319   <xsl:text>&#10;&#10;</xsl:text>
    320   <p class="pre">
    321     <xsl:apply-templates
    322       select="nonterminal[@usefulness!='useless-in-grammar']"
    323     />
    324   </p>
    325 </xsl:template>
    326 
    327 <xsl:template match="terminal">
    328   <b><xsl:value-of select="@name"/></b>
    329   <xsl:value-of select="concat(' (', @token-number, ')')"/>
    330   <xsl:for-each select="key('bison:ruleByRhs', @name)">
    331     <xsl:apply-templates select="." mode="number-link"/>
    332   </xsl:for-each>
    333   <xsl:text>&#10;</xsl:text>
    334 </xsl:template>
    335 
    336 <xsl:template match="nonterminal">
    337   <b><xsl:value-of select="@name"/></b>
    338   <xsl:value-of select="concat(' (', @symbol-number, ')')"/>
    339   <xsl:text>&#10;    </xsl:text>
    340   <xsl:if test="key('bison:ruleByLhs', @name)">
    341     <xsl:text>on left:</xsl:text>
    342     <xsl:for-each select="key('bison:ruleByLhs', @name)">
    343       <xsl:apply-templates select="." mode="number-link"/>
    344     </xsl:for-each>
    345   </xsl:if>
    346   <xsl:if test="key('bison:ruleByRhs', @name)">
    347     <xsl:if test="key('bison:ruleByLhs', @name)">
    348       <xsl:text>&#10;    </xsl:text>
    349     </xsl:if>
    350     <xsl:text>on right:</xsl:text>
    351     <xsl:for-each select="key('bison:ruleByRhs', @name)">
    352       <xsl:apply-templates select="." mode="number-link"/>
    353     </xsl:for-each>
    354   </xsl:if>
    355   <xsl:text>&#10;</xsl:text>
    356 </xsl:template>
    357 
    358 <xsl:template match="rule" mode="number-link">
    359   <xsl:text> </xsl:text>
    360   <a>
    361     <xsl:attribute name="href">
    362       <xsl:value-of select="concat('#rule_', @number)"/>
    363     </xsl:attribute>
    364     <xsl:value-of select="@number"/>
    365   </a>
    366 </xsl:template>
    367 
    368 <xsl:template match="automaton">
    369   <h2>
    370     <a name="automaton"/>
    371     <xsl:text> Automaton</xsl:text>
    372   </h2>
    373   <xsl:apply-templates select="state">
    374     <xsl:with-param name="pad" select="'3'"/>
    375   </xsl:apply-templates>
    376 </xsl:template>
    377 
    378 <xsl:template match="automaton/state">
    379   <xsl:param name="pad"/>
    380   <xsl:text>&#10;&#10;</xsl:text>
    381   <h3>
    382     <a>
    383       <xsl:attribute name="name">
    384 	<xsl:value-of select="concat('state_', @number)"/>
    385       </xsl:attribute>
    386     </a>
    387     <xsl:text>state </xsl:text>
    388     <xsl:value-of select="@number"/>
    389   </h3>
    390   <xsl:text>&#10;&#10;</xsl:text>
    391   <p class="pre">
    392     <xsl:apply-templates select="itemset/item">
    393       <xsl:with-param name="pad" select="$pad"/>
    394     </xsl:apply-templates>
    395     <xsl:apply-templates select="actions/transitions">
    396       <xsl:with-param name="type" select="'shift'"/>
    397     </xsl:apply-templates>
    398     <xsl:apply-templates select="actions/errors"/>
    399     <xsl:apply-templates select="actions/reductions"/>
    400     <xsl:apply-templates select="actions/transitions">
    401       <xsl:with-param name="type" select="'goto'"/>
    402     </xsl:apply-templates>
    403     <xsl:apply-templates select="solved-conflicts"/>
    404   </p>
    405 </xsl:template>
    406 
    407 <xsl:template match="actions/transitions">
    408   <xsl:param name="type"/>
    409   <xsl:if test="transition[@type = $type]">
    410     <xsl:text>&#10;</xsl:text>
    411     <xsl:apply-templates select="transition[@type = $type]">
    412       <xsl:with-param name="pad">
    413 	<xsl:call-template name="max-width-symbol">
    414 	  <xsl:with-param name="node" select="transition[@type = $type]"/>
    415 	</xsl:call-template>
    416       </xsl:with-param>
    417     </xsl:apply-templates>
    418   </xsl:if>
    419 </xsl:template>
    420 
    421 <xsl:template match="actions/errors">
    422   <xsl:if test="error">
    423     <xsl:text>&#10;</xsl:text>
    424     <xsl:apply-templates select="error">
    425       <xsl:with-param name="pad">
    426 	<xsl:call-template name="max-width-symbol">
    427 	  <xsl:with-param name="node" select="error"/>
    428 	</xsl:call-template>
    429       </xsl:with-param>
    430     </xsl:apply-templates>
    431   </xsl:if>
    432 </xsl:template>
    433 
    434 <xsl:template match="actions/reductions">
    435   <xsl:if test="reduction">
    436     <xsl:text>&#10;</xsl:text>
    437     <xsl:apply-templates select="reduction">
    438       <xsl:with-param name="pad">
    439 	<xsl:call-template name="max-width-symbol">
    440 	  <xsl:with-param name="node" select="reduction"/>
    441 	</xsl:call-template>
    442       </xsl:with-param>
    443     </xsl:apply-templates>
    444   </xsl:if>
    445 </xsl:template>
    446 
    447 <xsl:template match="item">
    448   <xsl:param name="pad"/>
    449   <xsl:param name="prev-rule-number"
    450 	     select="preceding-sibling::item[1]/@rule-number"/>
    451   <xsl:apply-templates
    452     select="key('bison:ruleByNumber', current()/@rule-number)"
    453   >
    454     <xsl:with-param name="itemset" select="'true'"/>
    455     <xsl:with-param name="pad" select="$pad"/>
    456     <xsl:with-param name="prev-lhs"
    457       select="key('bison:ruleByNumber', $prev-rule-number)/lhs[text()]"
    458    />
    459     <xsl:with-param name="point" select="@point"/>
    460     <xsl:with-param name="lookaheads">
    461       <xsl:apply-templates select="lookaheads"/>
    462     </xsl:with-param>
    463   </xsl:apply-templates>
    464 </xsl:template>
    465 
    466 <xsl:template match="rule">
    467   <xsl:param name="itemset"/>
    468   <xsl:param name="pad"/>
    469   <xsl:param name="prev-lhs"/>
    470   <xsl:param name="point"/>
    471   <xsl:param name="lookaheads"/>
    472 
    473   <xsl:if test="$itemset != 'true' and not($prev-lhs = lhs[text()])">
    474     <xsl:text>&#10;</xsl:text>
    475   </xsl:if>
    476 
    477   <xsl:if test="$itemset != 'true'">
    478     <a>
    479       <xsl:attribute name="name">
    480 	<xsl:value-of select="concat('rule_', @number)"/>
    481       </xsl:attribute>
    482     </a>
    483   </xsl:if>
    484   <xsl:text>  </xsl:text>
    485 
    486   <xsl:choose>
    487     <xsl:when test="$itemset = 'true'">
    488       <a>
    489 	<xsl:attribute name="href">
    490 	  <xsl:value-of select="concat('#rule_', @number)"/>
    491 	</xsl:attribute>
    492 	<xsl:call-template name="lpad">
    493 	  <xsl:with-param name="str" select="string(@number)"/>
    494 	  <xsl:with-param name="pad" select="number($pad)"/>
    495 	</xsl:call-template>
    496       </a>
    497     </xsl:when>
    498     <xsl:otherwise>
    499       <xsl:call-template name="lpad">
    500 	<xsl:with-param name="str" select="string(@number)"/>
    501 	<xsl:with-param name="pad" select="number($pad)"/>
    502       </xsl:call-template>
    503     </xsl:otherwise>
    504   </xsl:choose>
    505   <xsl:text> </xsl:text>
    506 
    507   <!-- LHS -->
    508   <xsl:choose>
    509     <xsl:when test="$itemset != 'true' and $prev-lhs = lhs[text()]">
    510       <xsl:call-template name="lpad">
    511 	<xsl:with-param name="str" select="'|'"/>
    512 	<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
    513       </xsl:call-template>
    514     </xsl:when>
    515     <xsl:when test="$itemset = 'true' and $prev-lhs = lhs[text()]">
    516       <xsl:call-template name="lpad">
    517 	<xsl:with-param name="str" select="'|'"/>
    518 	<xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 2"/>
    519       </xsl:call-template>
    520     </xsl:when>
    521     <xsl:otherwise>
    522       <span class="i">
    523 	<xsl:value-of select="lhs"/>
    524       </span>
    525       <xsl:text> &#8594;</xsl:text>
    526     </xsl:otherwise>
    527   </xsl:choose>
    528 
    529   <!-- RHS -->
    530   <xsl:for-each select="rhs/*">
    531     <xsl:if test="position() = $point + 1">
    532       <xsl:text> </xsl:text>
    533       <span class="point">.</span>
    534     </xsl:if>
    535     <xsl:if test="$itemset = 'true' and name(.) != 'empty'">
    536       <xsl:apply-templates select="."/>
    537     </xsl:if>
    538     <xsl:if test="$itemset != 'true'">
    539       <xsl:apply-templates select="."/>
    540     </xsl:if>
    541     <xsl:if test="position() = last() and position() = $point">
    542       <xsl:text> </xsl:text>
    543       <span class="point">.</span>
    544     </xsl:if>
    545   </xsl:for-each>
    546   <xsl:if test="$lookaheads">
    547     <xsl:value-of select="$lookaheads"/>
    548   </xsl:if>
    549 
    550   <xsl:text>&#10;</xsl:text>
    551 </xsl:template>
    552 
    553 <xsl:template match="symbol">
    554   <xsl:text> </xsl:text>
    555   <xsl:choose>
    556     <xsl:when test="name(key('bison:symbolByName', .)) = 'nonterminal'">
    557       <span class="i"><xsl:value-of select="."/></span>
    558     </xsl:when>
    559     <xsl:otherwise>
    560       <b><xsl:value-of select="."/></b>
    561     </xsl:otherwise>
    562   </xsl:choose>
    563 </xsl:template>
    564 
    565 <xsl:template match="empty">
    566   <xsl:text> &#949;</xsl:text>
    567 </xsl:template>
    568 
    569 <xsl:template match="lookaheads">
    570   <xsl:text>  [</xsl:text>
    571   <xsl:apply-templates select="symbol"/>
    572   <xsl:text>]</xsl:text>
    573 </xsl:template>
    574 
    575 <xsl:template match="lookaheads/symbol">
    576   <xsl:value-of select="."/>
    577   <xsl:if test="position() != last()">
    578     <xsl:text>, </xsl:text>
    579   </xsl:if>
    580 </xsl:template>
    581 
    582 <xsl:template match="transition">
    583   <xsl:param name="pad"/>
    584   <xsl:text>    </xsl:text>
    585   <xsl:call-template name="rpad">
    586     <xsl:with-param name="str" select="string(@symbol)"/>
    587     <xsl:with-param name="pad" select="number($pad) + 2"/>
    588   </xsl:call-template>
    589   <xsl:choose>
    590     <xsl:when test="@type = 'shift'">
    591       <a>
    592 	<xsl:attribute name="href">
    593 	  <xsl:value-of select="concat('#state_', @state)"/>
    594 	</xsl:attribute>
    595 	<xsl:value-of select="concat('shift, and go to state ', @state)"/>
    596       </a>
    597     </xsl:when>
    598     <xsl:when test="@type = 'goto'">
    599       <a>
    600 	<xsl:attribute name="href">
    601 	  <xsl:value-of select="concat('#state_', @state)"/>
    602 	</xsl:attribute>
    603 	<xsl:value-of select="concat('go to state ', @state)"/>
    604       </a>
    605     </xsl:when>
    606   </xsl:choose>
    607   <xsl:text>&#10;</xsl:text>
    608 </xsl:template>
    609 
    610 <xsl:template match="error">
    611   <xsl:param name="pad"/>
    612   <xsl:text>    </xsl:text>
    613   <xsl:call-template name="rpad">
    614     <xsl:with-param name="str" select="string(@symbol)"/>
    615     <xsl:with-param name="pad" select="number($pad) + 2"/>
    616   </xsl:call-template>
    617   <xsl:text>error</xsl:text>
    618   <xsl:text> (</xsl:text>
    619   <xsl:value-of select="text()"/>
    620   <xsl:text>)</xsl:text>
    621   <xsl:text>&#10;</xsl:text>
    622 </xsl:template>
    623 
    624 <xsl:template match="reduction">
    625   <xsl:param name="pad"/>
    626   <xsl:text>    </xsl:text>
    627   <xsl:call-template name="rpad">
    628     <xsl:with-param name="str" select="string(@symbol)"/>
    629     <xsl:with-param name="pad" select="number($pad) + 2"/>
    630   </xsl:call-template>
    631   <xsl:if test="@enabled = 'false'">
    632     <xsl:text>[</xsl:text>
    633   </xsl:if>
    634   <xsl:choose>
    635     <xsl:when test="@rule = 'accept'">
    636       <xsl:text>accept</xsl:text>
    637     </xsl:when>
    638     <xsl:otherwise>
    639       <a>
    640 	<xsl:attribute name="href">
    641 	  <xsl:value-of select="concat('#rule_', @rule)"/>
    642 	</xsl:attribute>
    643 	<xsl:value-of select="concat('reduce using rule ', @rule)"/>
    644       </a>
    645       <xsl:text> (</xsl:text>
    646       <xsl:value-of
    647         select="key('bison:ruleByNumber', current()/@rule)/lhs[text()]"
    648       />
    649       <xsl:text>)</xsl:text>
    650     </xsl:otherwise>
    651   </xsl:choose>
    652   <xsl:if test="@enabled = 'false'">
    653     <xsl:text>]</xsl:text>
    654   </xsl:if>
    655   <xsl:text>&#10;</xsl:text>
    656 </xsl:template>
    657 
    658 <xsl:template match="solved-conflicts">
    659   <xsl:if test="resolution">
    660     <xsl:text>&#10;</xsl:text>
    661     <xsl:apply-templates select="resolution"/>
    662   </xsl:if>
    663 </xsl:template>
    664 
    665 <xsl:template match="resolution">
    666   <xsl:text>    Conflict between </xsl:text>
    667   <a>
    668     <xsl:attribute name="href">
    669       <xsl:value-of select="concat('#rule_', @rule)"/>
    670     </xsl:attribute>
    671     <xsl:value-of select="concat('rule ',@rule)"/>
    672   </a>
    673   <xsl:text> and token </xsl:text>
    674   <xsl:value-of select="@symbol"/>
    675   <xsl:text> resolved as </xsl:text>
    676   <xsl:if test="@type = 'error'">
    677     <xsl:text>an </xsl:text>
    678   </xsl:if>
    679   <xsl:value-of select="@type"/>
    680   <xsl:text> (</xsl:text>
    681   <xsl:value-of select="."/>
    682   <xsl:text>).&#10;</xsl:text>
    683 </xsl:template>
    684 
    685 <xsl:template name="max-width-symbol">
    686   <xsl:param name="node"/>
    687   <xsl:variable name="longest">
    688     <xsl:for-each select="$node">
    689       <xsl:sort data-type="number" select="string-length(@symbol)"
    690 		order="descending"/>
    691       <xsl:if test="position() = 1">
    692 	<xsl:value-of select="string-length(@symbol)"/>
    693       </xsl:if>
    694     </xsl:for-each>
    695   </xsl:variable>
    696   <xsl:value-of select="$longest"/>
    697 </xsl:template>
    698 
    699 <xsl:template name="lpad">
    700   <xsl:param name="str" select="''"/>
    701   <xsl:param name="pad" select="0"/>
    702   <xsl:variable name="diff" select="$pad - string-length($str)" />
    703   <xsl:choose>
    704     <xsl:when test="$diff &lt; 0">
    705       <xsl:value-of select="$str"/>
    706     </xsl:when>
    707     <xsl:otherwise>
    708       <xsl:call-template name="space">
    709 	<xsl:with-param name="repeat" select="$diff"/>
    710       </xsl:call-template>
    711       <xsl:value-of select="$str"/>
    712     </xsl:otherwise>
    713   </xsl:choose>
    714 </xsl:template>
    715 
    716 <xsl:template name="rpad">
    717   <xsl:param name="str" select="''"/>
    718   <xsl:param name="pad" select="0"/>
    719   <xsl:variable name="diff" select="$pad - string-length($str)"/>
    720   <xsl:choose>
    721     <xsl:when test="$diff &lt; 0">
    722       <xsl:value-of select="$str"/>
    723     </xsl:when>
    724     <xsl:otherwise>
    725       <xsl:value-of select="$str"/>
    726       <xsl:call-template name="space">
    727 	<xsl:with-param name="repeat" select="$diff"/>
    728       </xsl:call-template>
    729     </xsl:otherwise>
    730   </xsl:choose>
    731 </xsl:template>
    732 
    733 <xsl:template name="space">
    734   <xsl:param name="repeat">0</xsl:param>
    735   <xsl:param name="fill" select="' '"/>
    736   <xsl:if test="number($repeat) &gt;= 1">
    737     <xsl:call-template name="space">
    738       <xsl:with-param name="repeat" select="$repeat - 1"/>
    739       <xsl:with-param name="fill" select="$fill"/>
    740     </xsl:call-template>
    741     <xsl:value-of select="$fill"/>
    742   </xsl:if>
    743 </xsl:template>
    744 
    745 </xsl:stylesheet>
    746