]> git.saurik.com Git - bison.git/blame_incremental - data/xslt/xml2text.xsl
Make xml2dot.xsl and --graph produce the same output.
[bison.git] / data / xslt / xml2text.xsl
... / ...
CommitLineData
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/rule">
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="rule">
269 <xsl:param name="pad"/>
270 <xsl:if test="not(name(..) = 'itemset') and not(preceding-sibling::rule[1]/lhs[text()] = lhs[text()])">
271 <xsl:text>&#10;</xsl:text>
272 </xsl:if>
273 <xsl:text> </xsl:text>
274 <xsl:call-template name="lpad">
275 <xsl:with-param name="str" select="string(@number)"/>
276 <xsl:with-param name="pad" select="number($pad)"/>
277 </xsl:call-template>
278 <xsl:text> </xsl:text>
279 <xsl:choose>
280 <xsl:when test="preceding-sibling::rule[1]/lhs[text()] = lhs[text()]">
281 <xsl:call-template name="lpad">
282 <xsl:with-param name="str" select="'|'"/>
283 <xsl:with-param name="pad" select="number(string-length(lhs[text()])) + 1"/>
284 </xsl:call-template>
285 </xsl:when>
286 <xsl:otherwise>
287 <xsl:value-of select="lhs"/>
288 <xsl:text>:</xsl:text>
289 </xsl:otherwise>
290 </xsl:choose>
291 <xsl:apply-templates select="rhs/symbol|rhs/point|rhs/empty"/>
292 <xsl:apply-templates select="lookaheads"/>
293 <xsl:text>&#10;</xsl:text>
294</xsl:template>
295
296<xsl:template match="symbol">
297 <xsl:text> </xsl:text>
298 <xsl:value-of select="."/>
299</xsl:template>
300
301<xsl:template match="point">
302 <xsl:text> .</xsl:text>
303</xsl:template>
304
305<xsl:template match="empty">
306 <xsl:text> /* empty */</xsl:text>
307</xsl:template>
308
309<xsl:template match="lookaheads">
310 <xsl:text> [</xsl:text>
311 <xsl:apply-templates select="symbol"/>
312 <xsl:text>]</xsl:text>
313</xsl:template>
314
315<xsl:template match="lookaheads/symbol">
316 <xsl:value-of select="."/>
317 <xsl:if test="position() != last()">
318 <xsl:text>, </xsl:text>
319 </xsl:if>
320</xsl:template>
321
322<xsl:template match="transition">
323 <xsl:param name="pad"/>
324 <xsl:text> </xsl:text>
325 <xsl:call-template name="rpad">
326 <xsl:with-param name="str" select="string(@symbol)"/>
327 <xsl:with-param name="pad" select="number($pad) + 2"/>
328 </xsl:call-template>
329 <xsl:choose>
330 <xsl:when test="@type = 'shift'">
331 <xsl:text>shift, and go to state </xsl:text>
332 <xsl:value-of select="@state"/>
333 </xsl:when>
334 <xsl:when test="@type = 'goto'">
335 <xsl:text>go to state </xsl:text>
336 <xsl:value-of select="@state"/>
337 </xsl:when>
338 </xsl:choose>
339 <xsl:text>&#10;</xsl:text>
340</xsl:template>
341
342<xsl:template match="error">
343 <xsl:param name="pad"/>
344 <xsl:text> </xsl:text>
345 <xsl:call-template name="rpad">
346 <xsl:with-param name="str" select="string(@symbol)"/>
347 <xsl:with-param name="pad" select="number($pad) + 2"/>
348 </xsl:call-template>
349 <xsl:text>error</xsl:text>
350 <xsl:text> (</xsl:text>
351 <xsl:value-of select="text()"/>
352 <xsl:text>)</xsl:text>
353 <xsl:text>&#10;</xsl:text>
354</xsl:template>
355
356<xsl:template match="reduction">
357 <xsl:param name="pad"/>
358 <xsl:text> </xsl:text>
359 <xsl:call-template name="rpad">
360 <xsl:with-param name="str" select="string(@symbol)"/>
361 <xsl:with-param name="pad" select="number($pad) + 2"/>
362 </xsl:call-template>
363 <xsl:if test="@enabled = 'false'">
364 <xsl:text>[</xsl:text>
365 </xsl:if>
366 <xsl:choose>
367 <xsl:when test="@rule = 'accept'">
368 <xsl:text>accept</xsl:text>
369 </xsl:when>
370 <xsl:otherwise>
371 <xsl:text>reduce using rule </xsl:text>
372 <xsl:value-of select="@rule"/>
373 <xsl:text> (</xsl:text>
374 <xsl:value-of
375 select="/bison-xml-report/grammar/rules/rule[@number = current()/@rule]/lhs[text()]"/>
376 <xsl:text>)</xsl:text>
377 </xsl:otherwise>
378 </xsl:choose>
379 <xsl:if test="@enabled = 'false'">
380 <xsl:text>]</xsl:text>
381 </xsl:if>
382 <xsl:text>&#10;</xsl:text>
383</xsl:template>
384
385<xsl:template match="solved-conflicts">
386 <xsl:if test="resolution">
387 <xsl:text>&#10;</xsl:text>
388 <xsl:apply-templates select="resolution"/>
389 </xsl:if>
390</xsl:template>
391
392<xsl:template match="resolution">
393 <xsl:text> Conflict between rule </xsl:text>
394 <xsl:value-of select="@rule"/>
395 <xsl:text> and token </xsl:text>
396 <xsl:value-of select="@symbol"/>
397 <xsl:text> resolved as </xsl:text>
398 <xsl:if test="@type = 'error'">
399 <xsl:text>an </xsl:text>
400 </xsl:if>
401 <xsl:value-of select="@type"/>
402 <xsl:text> (</xsl:text>
403 <xsl:value-of select="."/>
404 <xsl:text>).&#10;</xsl:text>
405</xsl:template>
406
407<xsl:template name="max-width-symbol">
408 <xsl:param name="node"/>
409 <xsl:variable name="longest">
410 <xsl:for-each select="$node">
411 <xsl:sort data-type="number" select="string-length(@symbol)"
412 order="descending"/>
413 <xsl:if test="position() = 1">
414 <xsl:value-of select="string-length(@symbol)"/>
415 </xsl:if>
416 </xsl:for-each>
417 </xsl:variable>
418 <xsl:value-of select="$longest"/>
419</xsl:template>
420
421<xsl:template name="lpad">
422 <xsl:param name="str" select="''"/>
423 <xsl:param name="pad" select="0"/>
424 <xsl:variable name="diff" select="$pad - string-length($str)" />
425 <xsl:choose>
426 <xsl:when test="$diff &lt; 0">
427 <xsl:value-of select="$str"/>
428 </xsl:when>
429 <xsl:otherwise>
430 <xsl:call-template name="space">
431 <xsl:with-param name="repeat" select="$diff"/>
432 </xsl:call-template>
433 <xsl:value-of select="$str"/>
434 </xsl:otherwise>
435 </xsl:choose>
436</xsl:template>
437
438<xsl:template name="rpad">
439 <xsl:param name="str" select="''"/>
440 <xsl:param name="pad" select="0"/>
441 <xsl:variable name="diff" select="$pad - string-length($str)"/>
442 <xsl:choose>
443 <xsl:when test="$diff &lt; 0">
444 <xsl:value-of select="$str"/>
445 </xsl:when>
446 <xsl:otherwise>
447 <xsl:value-of select="$str"/>
448 <xsl:call-template name="space">
449 <xsl:with-param name="repeat" select="$diff"/>
450 </xsl:call-template>
451 </xsl:otherwise>
452 </xsl:choose>
453</xsl:template>
454
455<xsl:template name="space">
456 <xsl:param name="repeat">0</xsl:param>
457 <xsl:param name="fill" select="' '"/>
458 <xsl:if test="number($repeat) &gt;= 1">
459 <xsl:call-template name="space">
460 <xsl:with-param name="repeat" select="$repeat - 1"/>
461 <xsl:with-param name="fill" select="$fill"/>
462 </xsl:call-template>
463 <xsl:value-of select="$fill"/>
464 </xsl:if>
465</xsl:template>
466
467<xsl:template name="line-wrap">
468 <xsl:param name="line-length" required="yes" />
469 <xsl:param name="first-line-length" select="$line-length" />
470 <xsl:param name="text" required="yes" />
471 <xsl:choose>
472 <xsl:when test="string-length($text) = 0 or normalize-space($text) = ''" />
473 <xsl:when test="string-length($text) &lt;= $first-line-length">
474 <xsl:value-of select="concat($text, '&#10;')" />
475 </xsl:when>
476 <xsl:otherwise>
477 <xsl:variable name="break-pos">
478 <xsl:call-template name="ws-search">
479 <xsl:with-param name="text" select="$text" />
480 <xsl:with-param name="pos" select="$first-line-length+1" />
481 </xsl:call-template>
482 </xsl:variable>
483 <xsl:value-of select="substring($text, 1, $break-pos - 1)" />
484 <xsl:text>&#10;</xsl:text>
485 <xsl:call-template name="line-wrap">
486 <xsl:with-param name="line-length" select="$line-length" />
487 <xsl:with-param
488 name="text" select="concat(' ', substring($text, $break-pos+1))"
489 />
490 </xsl:call-template>
491 </xsl:otherwise>
492 </xsl:choose>
493</xsl:template>
494
495<xsl:template name="ws-search">
496 <xsl:param name="text" required="yes" />
497 <xsl:param name="pos" required="yes" />
498 <xsl:choose>
499 <xsl:when
500 test="$pos &gt; string-length($text) or substring($text, $pos, 1) = ' '"
501 >
502 <xsl:value-of select="$pos" />
503 </xsl:when>
504 <xsl:otherwise>
505 <xsl:call-template name="ws-search">
506 <xsl:with-param name="text" select="$text" />
507 <xsl:with-param name="pos" select="$pos+1" />
508 </xsl:call-template>
509 </xsl:otherwise>
510 </xsl:choose>
511</xsl:template>
512
513</xsl:stylesheet>