]> git.saurik.com Git - bison.git/blob - data/xslt/xml2text.xsl
c21bf21755db11164e765762655593b8960a94a6
[bison.git] / data / xslt / xml2text.xsl
1 <?xml version="1.0" encoding="UTF-8"?>
2
3 <!--
4 xml2text.xsl - transform Bison XML Report into plain text.
5 $Id$
6
7 Copyright (C) 2007 Free Software Foundation, Inc.
8
9 This file is part of Bison, the GNU Compiler Compiler.
10
11 This program is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
23
24 Written by Wojciech Polak <polak@gnu.org>.
25 -->
26
27 <xsl:stylesheet version="1.0"
28 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
29 xmlns:bison="http://www.gnu.org/software/bison/">
30
31 <xsl:import href="bison.xsl"/>
32 <xsl:output method="text" encoding="UTF-8" indent="no"/>
33
34 <xsl:template match="/">
35 <xsl:apply-templates select="bison-xml-report"/>
36 </xsl:template>
37
38 <xsl:template match="bison-xml-report">
39 <xsl:apply-templates select="reductions"/>
40 <xsl:apply-templates select="rules-never-reduced"/>
41 <xsl:apply-templates select="automaton" mode="conflicts"/>
42 <xsl:apply-templates select="grammar"/>
43 <xsl:apply-templates select="automaton"/>
44 </xsl:template>
45
46 <xsl:template match="rules-never-reduced">
47 <xsl:if test="rule">
48 <xsl:text>Rules never reduced&#10;</xsl:text>
49 <xsl:apply-templates select="rule">
50 <xsl:with-param name="pad" select="'3'"/>
51 </xsl:apply-templates>
52 <xsl:text>&#10;&#10;</xsl:text>
53 </xsl:if>
54 </xsl:template>
55
56 <xsl:template match="reductions">
57 <xsl:apply-templates select="useless/nonterminals"/>
58 <xsl:apply-templates select="unused/terminals"/>
59 <xsl:apply-templates select="useless/rules"/>
60 </xsl:template>
61
62 <xsl:template match="useless/nonterminals">
63 <xsl:if test="nonterminal">
64 <xsl:text>Useless nonterminals&#10;&#10;</xsl:text>
65 <xsl:for-each select="nonterminal">
66 <xsl:text> </xsl:text>
67 <xsl:value-of select="."/>
68 <xsl:text>&#10;</xsl:text>
69 </xsl:for-each>
70 <xsl:text>&#10;&#10;</xsl:text>
71 </xsl:if>
72 </xsl:template>
73
74 <xsl:template match="useless/rules">
75 <xsl:if test="rule">
76 <xsl:text>Useless rules&#10;</xsl:text>
77 <xsl:apply-templates select="rule">
78 <xsl:with-param name="pad" select="'3'"/>
79 </xsl:apply-templates>
80 <xsl:text>&#10;&#10;</xsl:text>
81 </xsl:if>
82 </xsl:template>
83
84 <xsl:template match="unused/terminals">
85 <xsl:if test="terminal">
86 <xsl:text>Terminals which are not used&#10;&#10;</xsl:text>
87 <xsl:for-each select="terminal">
88 <xsl:text> </xsl:text>
89 <xsl:value-of select="."/>
90 <xsl:text>&#10;</xsl:text>
91 </xsl:for-each>
92 <xsl:text>&#10;&#10;</xsl:text>
93 </xsl:if>
94 </xsl:template>
95
96 <xsl:template match="grammar">
97 <xsl:text>Grammar&#10;</xsl:text>
98 <xsl:apply-templates select="rules/rule">
99 <xsl:with-param name="pad" select="'3'"/>
100 </xsl:apply-templates>
101 <xsl:text>&#10;&#10;</xsl:text>
102 <xsl:apply-templates select="terminals"/>
103 <xsl:apply-templates select="nonterminals"/>
104 </xsl:template>
105
106 <xsl:template match="grammar/terminals">
107 <xsl:text>Terminals, with rules where they appear&#10;&#10;</xsl:text>
108 <xsl:apply-templates select="terminal"/>
109 <xsl:text>&#10;&#10;</xsl:text>
110 </xsl:template>
111
112 <xsl:template match="grammar/nonterminals">
113 <xsl:text>Nonterminals, with rules where they appear&#10;&#10;</xsl:text>
114 <xsl:apply-templates select="nonterminal"/>
115 </xsl:template>
116
117 <xsl:template match="terminal">
118 <xsl:value-of select="@symbol"/>
119 <xsl:call-template name="line-wrap">
120 <xsl:with-param
121 name="first-line-length" select="66 - string-length(@symbol)"
122 />
123 <xsl:with-param name="line-length" select="66" />
124 <xsl:with-param name="text">
125 <xsl:value-of select="concat(' (', @type, ')')"/>
126 <xsl:apply-templates select="rule" />
127 </xsl:with-param>
128 </xsl:call-template>
129 </xsl:template>
130
131 <xsl:template match="terminal/rule">
132 <xsl:text> </xsl:text>
133 <xsl:value-of select="."/>
134 </xsl:template>
135
136 <xsl:template match="nonterminal">
137 <xsl:value-of select="@symbol"/>
138 <xsl:value-of select="concat(' (', @type, ')')"/>
139 <xsl:text>&#10;</xsl:text>
140 <xsl:variable name="output">
141 <xsl:call-template name="line-wrap">
142 <xsl:with-param name="line-length" select="66" />
143 <xsl:with-param name="text">
144 <xsl:text> </xsl:text>
145 <xsl:if test="left/rule">
146 <xsl:text>on@left:</xsl:text>
147 </xsl:if>
148 <xsl:apply-templates select="left/rule"/>
149 <xsl:if test="left/rule and right/rule">
150 <xsl:text>, </xsl:text>
151 </xsl:if>
152 <xsl:if test="right/rule">
153 <xsl:text>on@right:</xsl:text>
154 </xsl:if>
155 <xsl:apply-templates select="right/rule"/>
156 </xsl:with-param>
157 </xsl:call-template>
158 </xsl:variable>
159 <xsl:value-of select="translate($output, '@', ' ')" />
160 </xsl:template>
161
162 <xsl:template match="nonterminal/left/rule|nonterminal/right/rule">
163 <xsl:text> </xsl:text>
164 <xsl:value-of select="."/>
165 </xsl:template>
166
167 <xsl:template match="automaton" mode="conflicts">
168 <xsl:variable name="conflict-report">
169 <xsl:apply-templates select="state" mode="conflicts"/>
170 </xsl:variable>
171 <xsl:if test="string-length($conflict-report) != 0">
172 <xsl:value-of select="$conflict-report"/>
173 <xsl:text>&#10;&#10;</xsl:text>
174 </xsl:if>
175 </xsl:template>
176
177 <xsl:template match="state" mode="conflicts">
178 <xsl:variable name="conflict-counts">
179 <xsl:apply-templates select="." mode="bison:count-conflicts" />
180 </xsl:variable>
181 <xsl:variable
182 name="sr-count" select="substring-before($conflict-counts, ',')"
183 />
184 <xsl:variable
185 name="rr-count" select="substring-after($conflict-counts, ',')"
186 />
187 <xsl:if test="$sr-count > 0 or $rr-count > 0">
188 <xsl:value-of select="concat('State ', @number, ' conflicts:')"/>
189 <xsl:if test="$sr-count > 0">
190 <xsl:value-of select="concat(' ', $sr-count, ' shift/reduce')"/>
191 <xsl:if test="$rr-count > 0">
192 <xsl:value-of select="(',')"/>
193 </xsl:if>
194 </xsl:if>
195 <xsl:if test="$rr-count > 0">
196 <xsl:value-of select="concat(' ', $rr-count, ' reduce/reduce')"/>
197 </xsl:if>
198 <xsl:value-of select="'&#10;'"/>
199 </xsl:if>
200 </xsl:template>
201
202 <xsl:template match="automaton">
203 <xsl:apply-templates select="state">
204 <xsl:with-param name="pad" select="'3'"/>
205 </xsl:apply-templates>
206 </xsl:template>
207
208 <xsl:template match="automaton/state">
209 <xsl:param name="pad"/>
210 <xsl:text>&#10;&#10;</xsl:text>
211 <xsl:text>state </xsl:text>
212 <xsl:value-of select="@number"/>
213 <xsl:text>&#10;&#10;</xsl:text>
214 <xsl:apply-templates select="itemset/item">
215 <xsl:with-param name="pad" select="$pad"/>
216 </xsl:apply-templates>
217 <xsl:apply-templates select="actions/transitions">
218 <xsl:with-param name="type" select="'shift'"/>
219 </xsl:apply-templates>
220 <xsl:apply-templates select="actions/errors"/>
221 <xsl:apply-templates select="actions/reductions"/>
222 <xsl:apply-templates select="actions/transitions">
223 <xsl:with-param name="type" select="'goto'"/>
224 </xsl:apply-templates>
225 <xsl:apply-templates select="solved-conflicts"/>
226 </xsl:template>
227
228 <xsl:template match="actions/transitions">
229 <xsl:param name="type"/>
230 <xsl:if test="transition[@type = $type]">
231 <xsl:text>&#10;</xsl:text>
232 <xsl:apply-templates select="transition[@type = $type]">
233 <xsl:with-param name="pad">
234 <xsl:call-template name="max-width-symbol">
235 <xsl:with-param name="node" select="transition[@type = $type]"/>
236 </xsl:call-template>
237 </xsl:with-param>
238 </xsl:apply-templates>
239 </xsl:if>
240 </xsl:template>
241
242 <xsl:template match="actions/errors">
243 <xsl:if test="error">
244 <xsl:text>&#10;</xsl:text>
245 <xsl:apply-templates select="error">
246 <xsl:with-param name="pad">
247 <xsl:call-template name="max-width-symbol">
248 <xsl:with-param name="node" select="error"/>
249 </xsl:call-template>
250 </xsl:with-param>
251 </xsl:apply-templates>
252 </xsl:if>
253 </xsl:template>
254
255 <xsl:template match="actions/reductions">
256 <xsl:if test="reduction">
257 <xsl:text>&#10;</xsl:text>
258 <xsl:apply-templates select="reduction">
259 <xsl:with-param name="pad">
260 <xsl:call-template name="max-width-symbol">
261 <xsl:with-param name="node" select="reduction"/>
262 </xsl:call-template>
263 </xsl:with-param>
264 </xsl:apply-templates>
265 </xsl:if>
266 </xsl:template>
267
268 <xsl:template match="item">
269 <xsl:param name="pad"/>
270 <xsl:param name="prev-rule-number"
271 select="preceding-sibling::item[1]/@rule-number"/>
272 <xsl:apply-templates select="key('bison:ruleNumber', current()/@rule-number)">
273 <xsl:with-param name="itemset" select="'true'"/>
274 <xsl:with-param name="pad" select="$pad"/>
275 <xsl:with-param name="prev-lhs"
276 select="key('bison:ruleNumber', $prev-rule-number)/lhs[text()]"/>
277 <xsl:with-param name="point" select="@point"/>
278 <xsl:with-param name="lookaheads">
279 <xsl:apply-templates select="lookaheads"/>
280 </xsl:with-param>
281 </xsl:apply-templates>
282 </xsl:template>
283
284 <xsl:template match="rule">
285 <xsl:param name="itemset"/>
286 <xsl:param name="pad"/>
287 <xsl:param name="prev-lhs"/>
288 <xsl:param name="point"/>
289 <xsl:param name="lookaheads"/>
290
291 <xsl:if test="$itemset != 'true'
292 and not(preceding-sibling::rule[1]/lhs[text()] = lhs[text()])">
293 <xsl:text>&#10;</xsl:text>
294 </xsl:if>
295
296 <xsl:text> </xsl:text>
297 <xsl:call-template name="lpad">
298 <xsl:with-param name="str" select="string(@number)"/>
299 <xsl:with-param name="pad" select="number($pad)"/>
300 </xsl:call-template>
301 <xsl:text> </xsl:text>
302
303 <!-- LHS -->
304 <xsl:choose>
305 <xsl:when test="$itemset != 'true'
306 and preceding-sibling::rule[1]/lhs[text()] = lhs[text()]">
307 <xsl:call-template name="lpad">
308 <xsl:with-param name="str" select="'|'"/>
309 <xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 1"/>
310 </xsl:call-template>
311 </xsl:when>
312 <xsl:when test="$itemset = 'true' and $prev-lhs = lhs[text()]">
313 <xsl:call-template name="lpad">
314 <xsl:with-param name="str" select="'|'"/>
315 <xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 1"/>
316 </xsl:call-template>
317 </xsl:when>
318 <xsl:otherwise>
319 <xsl:value-of select="lhs"/>
320 <xsl:text>:</xsl:text>
321 </xsl:otherwise>
322 </xsl:choose>
323
324 <!-- RHS -->
325 <xsl:for-each select="rhs/*">
326 <xsl:if test="position() = $point + 1">
327 <xsl:text> .</xsl:text>
328 </xsl:if>
329 <xsl:if test="$itemset = 'true' and name(.) != 'empty'">
330 <xsl:apply-templates select="."/>
331 </xsl:if>
332 <xsl:if test="$itemset != 'true'">
333 <xsl:apply-templates select="."/>
334 </xsl:if>
335 <xsl:if test="position() = last() and position() = $point">
336 <xsl:text> .</xsl:text>
337 </xsl:if>
338 </xsl:for-each>
339 <xsl:if test="$lookaheads">
340 <xsl:value-of select="$lookaheads"/>
341 </xsl:if>
342
343 <xsl:text>&#10;</xsl:text>
344 </xsl:template>
345
346 <xsl:template match="symbol">
347 <xsl:text> </xsl:text>
348 <xsl:value-of select="."/>
349 </xsl:template>
350
351 <xsl:template match="empty">
352 <xsl:text> /* empty */</xsl:text>
353 </xsl:template>
354
355 <xsl:template match="lookaheads">
356 <xsl:text> [</xsl:text>
357 <xsl:apply-templates select="symbol"/>
358 <xsl:text>]</xsl:text>
359 </xsl:template>
360
361 <xsl:template match="lookaheads/symbol">
362 <xsl:value-of select="."/>
363 <xsl:if test="position() != last()">
364 <xsl:text>, </xsl:text>
365 </xsl:if>
366 </xsl:template>
367
368 <xsl:template match="transition">
369 <xsl:param name="pad"/>
370 <xsl:text> </xsl:text>
371 <xsl:call-template name="rpad">
372 <xsl:with-param name="str" select="string(@symbol)"/>
373 <xsl:with-param name="pad" select="number($pad) + 2"/>
374 </xsl:call-template>
375 <xsl:choose>
376 <xsl:when test="@type = 'shift'">
377 <xsl:text>shift, and go to state </xsl:text>
378 <xsl:value-of select="@state"/>
379 </xsl:when>
380 <xsl:when test="@type = 'goto'">
381 <xsl:text>go to state </xsl:text>
382 <xsl:value-of select="@state"/>
383 </xsl:when>
384 </xsl:choose>
385 <xsl:text>&#10;</xsl:text>
386 </xsl:template>
387
388 <xsl:template match="error">
389 <xsl:param name="pad"/>
390 <xsl:text> </xsl:text>
391 <xsl:call-template name="rpad">
392 <xsl:with-param name="str" select="string(@symbol)"/>
393 <xsl:with-param name="pad" select="number($pad) + 2"/>
394 </xsl:call-template>
395 <xsl:text>error</xsl:text>
396 <xsl:text> (</xsl:text>
397 <xsl:value-of select="text()"/>
398 <xsl:text>)</xsl:text>
399 <xsl:text>&#10;</xsl:text>
400 </xsl:template>
401
402 <xsl:template match="reduction">
403 <xsl:param name="pad"/>
404 <xsl:text> </xsl:text>
405 <xsl:call-template name="rpad">
406 <xsl:with-param name="str" select="string(@symbol)"/>
407 <xsl:with-param name="pad" select="number($pad) + 2"/>
408 </xsl:call-template>
409 <xsl:if test="@enabled = 'false'">
410 <xsl:text>[</xsl:text>
411 </xsl:if>
412 <xsl:choose>
413 <xsl:when test="@rule = 'accept'">
414 <xsl:text>accept</xsl:text>
415 </xsl:when>
416 <xsl:otherwise>
417 <xsl:text>reduce using rule </xsl:text>
418 <xsl:value-of select="@rule"/>
419 <xsl:text> (</xsl:text>
420 <xsl:value-of
421 select="key('bison:ruleNumber', current()/@rule)/lhs[text()]"/>
422 <xsl:text>)</xsl:text>
423 </xsl:otherwise>
424 </xsl:choose>
425 <xsl:if test="@enabled = 'false'">
426 <xsl:text>]</xsl:text>
427 </xsl:if>
428 <xsl:text>&#10;</xsl:text>
429 </xsl:template>
430
431 <xsl:template match="solved-conflicts">
432 <xsl:if test="resolution">
433 <xsl:text>&#10;</xsl:text>
434 <xsl:apply-templates select="resolution"/>
435 </xsl:if>
436 </xsl:template>
437
438 <xsl:template match="resolution">
439 <xsl:text> Conflict between rule </xsl:text>
440 <xsl:value-of select="@rule"/>
441 <xsl:text> and token </xsl:text>
442 <xsl:value-of select="@symbol"/>
443 <xsl:text> resolved as </xsl:text>
444 <xsl:if test="@type = 'error'">
445 <xsl:text>an </xsl:text>
446 </xsl:if>
447 <xsl:value-of select="@type"/>
448 <xsl:text> (</xsl:text>
449 <xsl:value-of select="."/>
450 <xsl:text>).&#10;</xsl:text>
451 </xsl:template>
452
453 <xsl:template name="max-width-symbol">
454 <xsl:param name="node"/>
455 <xsl:variable name="longest">
456 <xsl:for-each select="$node">
457 <xsl:sort data-type="number" select="string-length(@symbol)"
458 order="descending"/>
459 <xsl:if test="position() = 1">
460 <xsl:value-of select="string-length(@symbol)"/>
461 </xsl:if>
462 </xsl:for-each>
463 </xsl:variable>
464 <xsl:value-of select="$longest"/>
465 </xsl:template>
466
467 <xsl:template name="lpad">
468 <xsl:param name="str" select="''"/>
469 <xsl:param name="pad" select="0"/>
470 <xsl:variable name="diff" select="$pad - string-length($str)" />
471 <xsl:choose>
472 <xsl:when test="$diff &lt; 0">
473 <xsl:value-of select="$str"/>
474 </xsl:when>
475 <xsl:otherwise>
476 <xsl:call-template name="space">
477 <xsl:with-param name="repeat" select="$diff"/>
478 </xsl:call-template>
479 <xsl:value-of select="$str"/>
480 </xsl:otherwise>
481 </xsl:choose>
482 </xsl:template>
483
484 <xsl:template name="rpad">
485 <xsl:param name="str" select="''"/>
486 <xsl:param name="pad" select="0"/>
487 <xsl:variable name="diff" select="$pad - string-length($str)"/>
488 <xsl:choose>
489 <xsl:when test="$diff &lt; 0">
490 <xsl:value-of select="$str"/>
491 </xsl:when>
492 <xsl:otherwise>
493 <xsl:value-of select="$str"/>
494 <xsl:call-template name="space">
495 <xsl:with-param name="repeat" select="$diff"/>
496 </xsl:call-template>
497 </xsl:otherwise>
498 </xsl:choose>
499 </xsl:template>
500
501 <xsl:template name="space">
502 <xsl:param name="repeat">0</xsl:param>
503 <xsl:param name="fill" select="' '"/>
504 <xsl:if test="number($repeat) &gt;= 1">
505 <xsl:call-template name="space">
506 <xsl:with-param name="repeat" select="$repeat - 1"/>
507 <xsl:with-param name="fill" select="$fill"/>
508 </xsl:call-template>
509 <xsl:value-of select="$fill"/>
510 </xsl:if>
511 </xsl:template>
512
513 <xsl:template name="line-wrap">
514 <xsl:param name="line-length"/> <!-- required -->
515 <xsl:param name="first-line-length" select="$line-length"/>
516 <xsl:param name="text"/> <!-- required -->
517 <xsl:choose>
518 <xsl:when test="string-length($text) = 0 or normalize-space($text) = ''" />
519 <xsl:when test="string-length($text) &lt;= $first-line-length">
520 <xsl:value-of select="concat($text, '&#10;')" />
521 </xsl:when>
522 <xsl:otherwise>
523 <xsl:variable name="break-pos">
524 <xsl:call-template name="ws-search">
525 <xsl:with-param name="text" select="$text" />
526 <xsl:with-param name="pos" select="$first-line-length+1" />
527 </xsl:call-template>
528 </xsl:variable>
529 <xsl:value-of select="substring($text, 1, $break-pos - 1)" />
530 <xsl:text>&#10;</xsl:text>
531 <xsl:call-template name="line-wrap">
532 <xsl:with-param name="line-length" select="$line-length" />
533 <xsl:with-param
534 name="text" select="concat(' ', substring($text, $break-pos+1))"
535 />
536 </xsl:call-template>
537 </xsl:otherwise>
538 </xsl:choose>
539 </xsl:template>
540
541 <xsl:template name="ws-search">
542 <xsl:param name="text"/> <!-- required -->
543 <xsl:param name="pos"/> <!-- required -->
544 <xsl:choose>
545 <xsl:when
546 test="$pos &gt; string-length($text) or substring($text, $pos, 1) = ' '"
547 >
548 <xsl:value-of select="$pos" />
549 </xsl:when>
550 <xsl:otherwise>
551 <xsl:call-template name="ws-search">
552 <xsl:with-param name="text" select="$text" />
553 <xsl:with-param name="pos" select="$pos+1" />
554 </xsl:call-template>
555 </xsl:otherwise>
556 </xsl:choose>
557 </xsl:template>
558
559 </xsl:stylesheet>