root/trunk/projects/bos/statistics/loop-compiler.xslt

Revision 1988, 17.7 kB (checked in by hhubner, 2 years ago)

remove x bits

Line 
1 <?xml version="1.0"?>
2
3 <!--
4      XSLT Loop Compiler,
5      translates iteration (for and while) into recursion
6      Version 1.0
7      GPL (c) Oliver Becker, 2000-07-06
8      obecker@informatik.hu-berlin.de
9 -->
10
11 <xslt:transform version="1.0"
12                 xmlns:xslt="http://www.w3.org/1999/XSL/Transform"
13                 xmlns:axslt="http://www.w3.org/1999/XSL/Transform/Alias"
14                 xmlns:loop="http://informatik.hu-berlin.de/loop"
15                 exclude-result-prefixes="loop">
16
17 <xslt:namespace-alias stylesheet-prefix="axslt" result-prefix="xslt" />
18
19 <xslt:output method="xml" indent="no" encoding="iso-8859-1" />
20
21
22 <xslt:template match="/">
23    <!-- first validate ... -->
24    <xslt:variable name="errors">
25       <xslt:apply-templates mode="validate-loops" />
26    </xslt:variable>
27    <xslt:if test="string-length($errors)!=0">
28       <xslt:message terminate="yes">
29          <xslt:value-of select="string-length($errors)"/>
30          <xslt:text> error(s) detected</xslt:text>
31       </xslt:message>
32    </xslt:if>
33
34    <!-- ... then generate code -->
35    <xslt:comment>
36
37    File generated by translating loops into recursive template calls.
38    XSLT Loop Compiler, Version 1.0
39    GPL (c) O. Becker
40
41    </xslt:comment>
42    <xslt:apply-templates />
43 </xslt:template>
44
45
46 <!-- ====================== Validation code ======================= -->
47
48 <xslt:template match="loop:for" mode="validate-loops">
49    <xslt:if test="not(@name!='')">
50       <xslt:message>
51          <xslt:text>Missing required attribute 'name' of '</xslt:text>
52          <xslt:value-of select="name()" />' <xslt:text />
53       </xslt:message>
54       <xslt:text>.</xslt:text>
55    </xslt:if>
56    <xslt:if test="not(@from!='')">
57       <xslt:message>
58          <xslt:text>Missing required attribute 'from' of '</xslt:text>
59          <xslt:value-of select="name()" />' <xslt:text />
60       </xslt:message>
61       <xslt:text>.</xslt:text>
62    </xslt:if>
63    <xslt:if test="not(@to!='')">
64       <xslt:message>
65          <xslt:text>Missing required attribute 'to' of '</xslt:text>
66          <xslt:value-of select="name()" />' <xslt:text />
67       </xslt:message>
68       <xslt:text>.</xslt:text>
69    </xslt:if>
70    <xslt:for-each select="@*">
71       <xslt:if test="name()!='name' and name()!='from' and
72                      name()!='to' and name()!='step'">
73          <xslt:message>
74             <xslt:text>Unknown attribute '</xslt:text>
75             <xslt:value-of select="name()" />
76             <xslt:text>' of '</xslt:text>
77             <xslt:value-of select="name(..)" />' <xslt:text />
78          </xslt:message>
79          <xslt:text>.</xslt:text>
80       </xslt:if>
81    </xslt:for-each>
82    <xslt:apply-templates mode="validate-loops" />
83 </xslt:template>
84
85 <xslt:template match="loop:while" mode="validate-loops">
86    <xslt:if test="not(@test!='')">
87       <xslt:message>
88          <xslt:text>Missing required attribute 'test' of '</xslt:text>
89          <xslt:value-of select="name()" />' <xslt:text />
90       </xslt:message>
91       <xslt:text>.</xslt:text>
92    </xslt:if>
93    <xslt:for-each select="@*">
94       <xslt:if test="name()!='test'">
95          <xslt:message>
96             <xslt:text>Unknown attribute '</xslt:text>
97             <xslt:value-of select="name()" />
98             <xslt:text>' of '</xslt:text>
99             <xslt:value-of select="name(..)" />' <xslt:text />
100          </xslt:message>
101          <xslt:text>.</xslt:text>
102       </xslt:if>
103    </xslt:for-each>
104    <xslt:for-each select="*|text()">
105       <xslt:if test="not(self::xslt:variable or self::loop:do or
106                          self::loop:last or self::loop:update or
107                          (self::text() and normalize-space(.)=''))" >
108          <xslt:message>
109             <xslt:text>Forbidden </xslt:text>
110             <xslt:choose>
111                <xslt:when test="self::text()">
112                   <xslt:text>text '</xslt:text>
113                   <xslt:value-of select="normalize-space(.)" />
114                </xslt:when>
115                <xslt:otherwise>
116                   <xslt:text>element '</xslt:text>
117                   <xslt:value-of select="name()" />
118                </xslt:otherwise>
119             </xslt:choose>
120             <xslt:text>' - expected '</xslt:text>
121             <xslt:value-of
122                   select="substring-before(name(//xslt:*),':')" />
123             <xslt:text>:variable', '</xslt:text>
124             <xslt:value-of select="substring-before(name(..),':')" />
125             <xslt:text>:do', '</xslt:text>
126             <xslt:value-of select="substring-before(name(..),':')" />
127             <xslt:text>:last' or '</xslt:text>
128             <xslt:value-of select="substring-before(name(..),':')" />
129             <xslt:text>:update'</xslt:text>
130          </xslt:message>
131          <xslt:text>.</xslt:text>
132       </xslt:if>
133    </xslt:for-each>
134    <xslt:if test="not(loop:update)">
135       <xslt:message>
136          <xslt:text />Warning: '<xslt:value-of select="name()" />
137          <xslt:text>' contains no '</xslt:text>
138          <xslt:value-of select="substring-before(name(..),':')" />
139          <xslt:text>:update' - infinite loop!</xslt:text>
140       </xslt:message>
141    </xslt:if>
142    <xslt:apply-templates mode="validate-loops" />
143 </xslt:template>
144
145 <xslt:template match="loop:while/xslt:variable" mode="validate-loops">
146    <xslt:choose>
147       <xslt:when test="preceding-sibling::loop:do">
148          <xslt:message>
149             <xslt:text />'<xslt:value-of select="name()" />
150             <xslt:text>' must not follow a preceding '</xslt:text>
151             <xslt:value-of select="substring-before(name(..),':')" />
152             <xslt:text>:do'</xslt:text>
153          </xslt:message>
154          <xslt:text>.</xslt:text>
155       </xslt:when>
156       <xslt:when test="preceding-sibling::loop:last">
157          <xslt:message>
158             <xslt:text />'<xslt:value-of select="name()" />
159             <xslt:text>' must not follow a preceding '</xslt:text>
160             <xslt:value-of select="substring-before(name(..),':')" />
161             <xslt:text>:last'</xslt:text>
162          </xslt:message>
163          <xslt:text>.</xslt:text>
164       </xslt:when>
165       <xslt:when test="preceding-sibling::loop:update">
166          <xslt:message>
167             <xslt:text />'<xslt:value-of select="name()" />
168             <xslt:text>' must not follow a preceding '</xslt:text>
169             <xslt:value-of select="substring-before(name(..),':')" />
170             <xslt:text>:update'</xslt:text>
171          </xslt:message>
172          <xslt:text>.</xslt:text>
173       </xslt:when>
174    </xslt:choose>
175 </xslt:template>
176
177 <xslt:template match="loop:do | loop:last" mode="validate-loops">
178    <xslt:if test="not(parent::loop:while)">
179       <xslt:message>
180          <xslt:text />'<xslt:value-of select="name()" />
181          <xslt:text>' must be an immediate child of '</xslt:text>
182          <xslt:value-of select="substring-before(name(),':')" />
183          <xslt:text>:while'</xslt:text>
184       </xslt:message>
185       <xslt:text>.</xslt:text>
186    </xslt:if>
187    <xslt:for-each select="@*">
188       <xslt:message>
189          <xslt:text>Unknown attribute '</xslt:text>
190          <xslt:value-of select="name()" />
191          <xslt:text>' of '</xslt:text>
192          <xslt:value-of select="name(..)" />' <xslt:text />
193       </xslt:message>
194       <xslt:text>.</xslt:text>
195    </xslt:for-each>
196    <xslt:choose>
197       <xslt:when test="self::loop:do and preceding-sibling::loop:do">
198          <xslt:message>
199             <xslt:text />'<xslt:value-of select="name()" />
200             <xslt:text>' must not follow a preceding '</xslt:text>
201             <xslt:value-of select="substring-before(name(),':')" />
202             <xslt:text>:do'</xslt:text>
203          </xslt:message>
204          <xslt:text>.</xslt:text>
205       </xslt:when>
206       <xslt:when test="preceding-sibling::loop:last">
207          <xslt:message>
208             <xslt:text />'<xslt:value-of select="name()" />
209             <xslt:text>' must not follow a preceding '</xslt:text>
210             <xslt:value-of select="substring-before(name(),':')" />
211             <xslt:text>:last'</xslt:text>
212          </xslt:message>
213          <xslt:text>.</xslt:text>
214       </xslt:when>
215       <xslt:when test="preceding-sibling::loop:update">
216          <xslt:message>
217             <xslt:text />'<xslt:value-of select="name()" />
218             <xslt:text>' must not follow a preceding '</xslt:text>
219             <xslt:value-of select="substring-before(name(),':')" />
220             <xslt:text>:update'</xslt:text>
221          </xslt:message>
222          <xslt:text>.</xslt:text>
223       </xslt:when>
224    </xslt:choose>
225    <xslt:apply-templates mode="validate-loops" />
226 </xslt:template>
227
228 <xslt:template match="loop:update" mode="validate-loops">
229    <xslt:if test="not(parent::loop:for) and not(parent::loop:while)">
230       <xslt:message>
231          <xslt:text />'<xslt:value-of select="name()" />
232          <xslt:text>' must be an immediate child of '</xslt:text>
233          <xslt:value-of select="substring-before(name(),':')" />
234          <xslt:text>:for' or '</xslt:text>
235          <xslt:value-of select="substring-before(name(),':')" />
236          <xslt:text>:while'</xslt:text>
237       </xslt:message>
238       <xslt:text>.</xslt:text>
239    </xslt:if>
240    <xslt:if test="not(@name!='')">
241       <xslt:message>
242          <xslt:text>Missing required attribute 'name' of '</xslt:text>
243          <xslt:value-of select="name()" />'<xslt:text/>
244       </xslt:message>
245       <xslt:text>.</xslt:text>
246    </xslt:if>
247    <xslt:for-each select="@*">
248       <xslt:if test="name()!='name' and name()!='select'">
249          <xslt:message>
250             <xslt:text>Unknown attribute '</xslt:text>
251             <xslt:value-of select="name()" />
252             <xslt:text>' of '</xslt:text>
253             <xslt:value-of select="name(..)" />' <xslt:text />
254          </xslt:message>
255          <xslt:text>.</xslt:text>
256       </xslt:if>
257    </xslt:for-each>
258    <xslt:if test="preceding-sibling::loop:update
259                                      [@name=current()/@name]">
260       <xslt:message>
261          <xslt:text />'<xslt:value-of select="name()" />
262          <xslt:text>' for variable '</xslt:text>
263          <xslt:value-of select="@name" />
264          <xslt:text>' already defined</xslt:text>
265       </xslt:message>
266       <xslt:text>.</xslt:text>
267    </xslt:if>
268    <xslt:call-template name="var-wrapper">
269       <xslt:with-param name="action" select="'validate-update'" />
270       <xslt:with-param name="loop-node" select=".." />
271    </xslt:call-template>
272    <xslt:apply-templates mode="validate-loops" />
273 </xslt:template>
274
275 <xslt:template match="loop:*" mode="validate-loops">
276    <xslt:message>
277       <xslt:text />Unknown element '<xslt:value-of select="name()" />
278       <xslt:text>'</xslt:text>
279    </xslt:message>
280    <xslt:text>.</xslt:text>
281    <xslt:apply-templates mode="validate-loops" />
282 </xslt:template>
283
284 <xslt:template match="text()" mode="validate-loops" />
285
286 <!-- =================== End of validation ======================== -->
287
288
289
290 <!-- ================= General template rules ===================== -->
291
292 <xslt:template match="xslt:stylesheet | xslt:transform">
293    <xslt:copy>
294       <xslt:copy-of select="@*" />
295       <xslt:apply-templates />
296       <xslt:apply-templates mode="create-templates" />
297    </xslt:copy>
298 </xslt:template>
299
300 <xslt:template match="text()" mode="create-templates" />
301
302 <xslt:template match="*">
303    <xslt:copy>
304       <xslt:copy-of select="@*" />
305       <xslt:apply-templates />
306    </xslt:copy>
307 </xslt:template>
308
309 <xslt:template match="comment()|processing-instruction()">
310    <xslt:copy />
311 </xslt:template>
312
313
314
315 <!-- ========================= for-loop =========================== -->
316
317 <xslt:template match="loop:for">
318    <xslt:variable name="step">
319       <xslt:choose>
320          <xslt:when test="not(@step)">1</xslt:when>
321          <xslt:otherwise>
322             <xslt:value-of select="@step" />
323          </xslt:otherwise>
324       </xslt:choose>
325    </xslt:variable>
326    <xslt:variable name="id" select="generate-id()" />
327    <axslt:call-template name="for-loop-{$id}">
328       <axslt:with-param name="{@name}" select="{@from}" />
329       <axslt:with-param name="to{$id}" select="{@to}" />
330       <axslt:with-param name="step{$id}" select="{$step}" />
331       <xslt:call-template name="var-wrapper">
332          <xslt:with-param name="action"
333                           select="'create-call-with-params'" />
334       </xslt:call-template>
335    </axslt:call-template>
336 </xslt:template>
337
338
339 <xslt:template match="loop:for" mode="create-templates">
340    <xslt:variable name="id" select="generate-id()" />
341
342    <axslt:template name="for-loop-{$id}">
343       <axslt:param name="{@name}" />
344       <axslt:param name="to{$id}" />
345       <axslt:param name="step{$id}" />
346       <xslt:call-template name="var-wrapper">
347          <xslt:with-param name="action" select="'create-loop-params'" />
348       </xslt:call-template>
349
350       <xslt:apply-templates />
351
352       <xslt:variable name="comp-op">
353          <xslt:choose>
354             <xslt:when test="@step &lt; 0">&gt;=</xslt:when>
355             <xslt:otherwise>&lt;=</xslt:otherwise>
356          </xslt:choose>
357       </xslt:variable>
358
359       <axslt:if test="${@name}+$step{$id} {$comp-op} $to{$id}">
360          <axslt:call-template name="for-loop-{$id}">
361             <axslt:with-param name="{@name}"
362                               select="${@name} + $step{$id}" />
363             <axslt:with-param name="to{$id}" select="$to{$id}" />
364             <axslt:with-param name="step{$id}" select="$step{$id}" />
365             <xslt:call-template name="var-wrapper">
366                <xslt:with-param name="action"
367                                 select="'create-loop-with-params'" />
368             </xslt:call-template>
369          </axslt:call-template>
370       </axslt:if>
371    </axslt:template>
372
373    <xslt:apply-templates mode="create-templates" />
374 </xslt:template>
375
376 <!-- ============================================================== -->
377
378
379
380 <!-- ====================== while-loop ============================ -->
381
382 <xslt:template match="loop:while">
383    <axslt:call-template name="while-loop-{generate-id()}">
384       <xslt:call-template name="var-wrapper">
385          <xslt:with-param name="action"
386                           select="'create-call-with-params'" />
387       </xslt:call-template>
388    </axslt:call-template>
389 </xslt:template>
390
391
392 <xslt:template match="loop:while" mode="create-templates">
393    <xslt:variable name="id" select="generate-id()" />
394
395    <axslt:template name="while-loop-{$id}">
396       <xslt:call-template name="var-wrapper">
397          <xslt:with-param name="action" select="'create-loop-params'" />
398       </xslt:call-template>
399
400       <xslt:copy-of select="xslt:variable" />
401       <axslt:choose>
402          <axslt:when test="{@test}">
403             <xslt:apply-templates select="loop:do" />
404             <axslt:call-template name="while-loop-{$id}">
405                <xslt:call-template name="var-wrapper">
406                   <xslt:with-param name="action"
407                                    select="'create-loop-with-params'" />
408                </xslt:call-template>
409             </axslt:call-template>
410          </axslt:when>
411          <xslt:if test="loop:last">
412             <axslt:otherwise>
413                <xslt:apply-templates select="loop:last" />
414             </axslt:otherwise>
415          </xslt:if>
416       </axslt:choose>
417    </axslt:template>
418    
419    <xslt:apply-templates mode="create-templates" />
420 </xslt:template>
421
422
423 <xslt:template match="loop:do | loop:last">
424    <xslt:apply-templates />
425 </xslt:template>
426
427
428 <xslt:template match="loop:update" />
429
430 <!-- ============================================================== -->
431
432
433
434 <!-- =================== variable wrapper ========================= -->
435 <!-- separated because the expression for $vars was a little bit
436      difficult to determine -->
437
438 <xslt:template name="var-wrapper">
439    <xslt:param name="action" />
440    <xslt:param name="loop-node" select="." />
441    <xslt:variable name="vars" select=
442                   "$loop-node/ancestor-or-self::*/preceding-sibling::xslt:variable
443                       [ancestor::xslt:template] |
444                    $loop-node/ancestor-or-self::*/preceding-sibling::xslt:param
445                       [ancestor::xslt:template] |
446                    $loop-node/ancestor::loop:for" />
447    <xslt:choose>
448       <xslt:when test="$action='create-call-with-params'">
449          <xslt:for-each select="$vars">
450             <axslt:with-param name="{@name}" select="${@name}" />
451          </xslt:for-each>
452       </xslt:when>
453       <xslt:when test="$action='create-loop-params'">
454          <xslt:for-each select="$vars">
455             <axslt:param name="{@name}" />
456          </xslt:for-each>
457       </xslt:when>
458       <xslt:when test="$action='create-loop-with-params'">
459          <xslt:for-each select="$vars">
460             <xslt:variable name="update"
461                            select="$loop-node/loop:update
462                                    [@name=current()/@name]" />
463             <xslt:choose>
464                <xslt:when test="$update">
465                   <axslt:with-param name="{@name}">
466                      <xslt:if test="$update/@select">
467                        <xslt:attribute name="select">
468                           <xslt:value-of select="$update/@select" />
469                        </xslt:attribute>
470                      </xslt:if>
471                      <xslt:apply-templates select="$update"
472                                            mode="process-update" />
473                   </axslt:with-param>
474                </xslt:when>
475                <xslt:otherwise>
476                   <axslt:with-param name="{@name}" select="${@name}" />
477                </xslt:otherwise>
478             </xslt:choose>
479          </xslt:for-each>
480       </xslt:when>
481
482       <!-- the following is validation code -->
483       <xslt:when test="$action='validate-update'">
484          <xslt:if test="@name and not($vars[@name=current()/@name])">
485             <xslt:message>
486                <xslt:text>Cannot update variable '</xslt:text>
487                <xslt:value-of select="@name" />
488                <xslt:text>' - not locally visible at parent node '</xslt:text>
489                <xslt:value-of select="name(..)" />' <xslt:text />
490             </xslt:message>
491             <xslt:text>.</xslt:text>
492          </xslt:if>
493       </xslt:when>
494
495    </xslt:choose>
496 </xslt:template>
497
498
499 <xslt:template match="loop:update" mode="process-update">
500    <xslt:apply-templates />
501 </xslt:template>
502
503
504 </xslt:transform>
Note: See TracBrowser for help on using the browser.