msxml3: Fix XSLPattern namespace handling.
[wine] / dlls / msxml3 / xslpattern.y
1 /*
2  *    XSLPattern parser (XSLPattern => XPath)
3  *
4  * Copyright 2010 Adam Martinson for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 %{
22 #include "config.h"
23 #include "wine/port.h"
24
25 #ifdef HAVE_LIBXML2
26 #include "xslpattern.h"
27 #include <libxml/xpathInternals.h>
28
29 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
30
31
32 static const xmlChar NameTest_mod_pre[] = "*[name()='";
33 static const xmlChar NameTest_mod_post[] = "']";
34
35 #define U(str) BAD_CAST str
36
37 %}
38
39 %token TOK_Parent TOK_Self TOK_DblFSlash TOK_FSlash TOK_Axis TOK_Colon
40 %token TOK_OpAnd TOK_OpOr TOK_OpNot
41 %token TOK_OpEq TOK_OpIEq TOK_OpNEq TOK_OpINEq
42 %token TOK_OpLt TOK_OpILt TOK_OpGt TOK_OpIGt TOK_OpLEq TOK_OpILEq TOK_OpGEq TOK_OpIGEq
43 %token TOK_OpAll TOK_OpAny
44 %token TOK_NCName TOK_Literal TOK_Number
45
46 %start XSLPattern
47
48 %pure_parser
49 %parse-param {parser_param* p}
50 %parse-param {void* scanner}
51 %lex-param {yyscan_t* scanner}
52
53 %left TOK_OpAnd TOK_OpOr
54 %left TOK_OpEq TOK_OpIEq TOK_OpNEq TOK_OpINEq
55 %left TOK_OpLt TOK_OpILt TOK_OpGt TOK_OpIGt TOK_OpLEq TOK_OpILEq TOK_OpGEq TOK_OpIGEq
56
57 %%
58
59     XSLPattern              : Expr
60                             {
61                                 p->out = $1;
62                             }
63     ;
64
65 /* Mostly verbatim from the w3c XML Namespaces standard.
66  * <http://www.w3.org/TR/REC-xml-names/> */
67
68     /* [4] Qualified Names */
69     QName                   : PrefixedName
70                             | UnprefixedName
71     ;
72     PrefixedName            : TOK_NCName TOK_Colon TOK_NCName
73                             {
74                                 TRACE("Got PrefixedName: \"%s:%s\"\n", $1, $3);
75                                 $$=$1;
76                                 $$=xmlStrcat($$,U(":"));
77                                 $$=xmlStrcat($$,$3);
78                                 xmlFree($3);
79                             }
80     ;
81     UnprefixedName          : TOK_NCName
82                             {
83                                 TRACE("Got UnprefixedName: \"%s\"\n", $1);
84                                 $$=$1;
85                             }
86     ;
87
88 /* Based on the w3c XPath standard, adapted where needed.
89  * <http://www.w3.org/TR/xpath/> */
90
91     /* [2] Location Paths */
92     LocationPath            : RelativeLocationPath
93                             | AbsoluteLocationPath
94     ;
95     AbsoluteLocationPath    : TOK_FSlash RelativeLocationPath
96                             {
97                                 TRACE("Got AbsoluteLocationPath: \"/%s\"\n", $2);
98                                 $$=xmlStrdup(U("/"));
99                                 $$=xmlStrcat($$,$2);
100                                 xmlFree($2);
101                             }
102                             | TOK_FSlash
103                             {
104                                 TRACE("Got AbsoluteLocationPath: \"/\"\n");
105                                 $$=xmlStrdup(U("/"));
106                             }
107                             | AbbreviatedAbsoluteLocationPath
108     ;
109     RelativeLocationPath    : Step
110                             | RelativeLocationPath TOK_FSlash Step
111                             {
112                                 TRACE("Got RelativeLocationPath: \"%s/%s\"\n", $1, $3);
113                                 $$=$1;
114                                 $$=xmlStrcat($$,U("/"));
115                                 $$=xmlStrcat($$,$3);
116                                 xmlFree($3);
117                             }
118                             | AbbreviatedRelativeLocationPath
119     ;
120     /* [2.1] Location Steps */
121     Step                    : AxisSpecifier NameTest Predicates
122                             {
123                                 TRACE("Got Step: \"%s%s%s\"\n", $1, $2, $3);
124                                 $$=$1;
125                                 $$=xmlStrcat($$,$2);
126                                 xmlFree($2);
127                                 $$=xmlStrcat($$,$3);
128                                 xmlFree($3);
129                             }
130                             | NameTest Predicates
131                             {
132                                 TRACE("Got Step: \"%s%s\"\n", $1, $2);
133                                 $$=$1;
134                                 $$=xmlStrcat($$,$2);
135                                 xmlFree($2);
136                             }
137                             | AxisSpecifier NameTest
138                             {
139                                 TRACE("Got Step: \"%s%s\"\n", $1, $2);
140                                 $$=$1;
141                                 $$=xmlStrcat($$,$2);
142                                 xmlFree($2);
143                             }
144                             | NameTest
145                             | Attribute
146                             | AbbreviatedStep
147     ;
148     AxisSpecifier           : TOK_NCName TOK_Axis
149                             {
150                                 TRACE("Got AxisSpecifier: \"%s::\"\n", $1);
151                                 $$=$1;
152                                 $$=xmlStrcat($$,U("::"));
153                             }
154     ;
155     Attribute               : '@' TOK_NCName
156                             {
157                                 TRACE("Got Attribute: \"@%s\"\n", $2);
158                                 $$=xmlStrdup(U("@"));
159                                 $$=xmlStrcat($$,$2);
160                                 xmlFree($2);
161                             }
162     ;
163
164     /* [2.3] Node Tests */
165     NameTest                : '*'
166                             {
167                                 TRACE("Got NameTest: \"*\"\n");
168                                 $$=xmlStrdup(U("*"));
169                             }
170                             | TOK_NCName TOK_Colon '*'
171                             {
172                                 TRACE("Got NameTest: \"%s:*\"\n", $1);
173                                 $$=$1;
174                                 $$=xmlStrcat($$,U(":*"));
175                             }
176                             | TOK_NCName TOK_Colon TOK_NCName
177                             { /* PrefixedName */
178                                 xmlChar const* registeredNsURI = xmlXPathNsLookup(p->ctx, $1);
179                                 TRACE("Got PrefixedName: \"%s:%s\"\n", $1, $3);
180
181                                 if (registeredNsURI)
182                                     $$=xmlStrdup(U(""));
183                                 else
184                                     $$=xmlStrdup(NameTest_mod_pre);
185
186                                 $$=xmlStrcat($$,$1);
187                                 xmlFree($1);
188                                 $$=xmlStrcat($$,U(":"));
189                                 $$=xmlStrcat($$,$3);
190                                 xmlFree($3);
191
192                                 if (!registeredNsURI)
193                                     $$=xmlStrcat($$,NameTest_mod_post);
194                             }
195                             | UnprefixedName
196                             {
197                                 $$=xmlStrdup(NameTest_mod_pre);
198                                 $$=xmlStrcat($$,$1);
199                                 xmlFree($1);
200                                 $$=xmlStrcat($$,NameTest_mod_post);
201                             }
202     /* [2.4] Predicates */
203     Predicates              : Predicates Predicate
204                             {
205                                 $$=$1;
206                                 $$=xmlStrcat($$,$2);
207                                 xmlFree($2);
208                             }
209                             | Predicate
210     ;
211     Predicate               : '[' PredicateExpr ']'
212                             {
213                                 TRACE("Got Predicate: \"[%s]\"\n", $2);
214                                 $$=xmlStrdup(U("["));
215                                 $$=xmlStrcat($$,$2);
216                                 xmlFree($2);
217                                 $$=xmlStrcat($$,U("]"));
218                             }
219     ;
220     PredicateExpr           : TOK_Number
221                             {
222                                 $$=xmlStrdup(U("index()="));
223                                 $$=xmlStrcat($$,$1);
224                                 xmlFree($1);
225                             }
226                             | BoolExpr
227                             | Attribute
228     ;
229     /* [2.5] Abbreviated Syntax */
230     AbbreviatedAbsoluteLocationPath : TOK_DblFSlash RelativeLocationPath
231                             {
232                                 TRACE("Got AbbreviatedAbsoluteLocationPath: \"//%s\"\n", $2);
233                                 $$=xmlStrdup(U("//"));
234                                 $$=xmlStrcat($$,$2);
235                                 xmlFree($2);
236                             }
237     ;
238     AbbreviatedRelativeLocationPath : RelativeLocationPath TOK_DblFSlash Step
239                             {
240                                 TRACE("Got AbbreviatedRelativeLocationPath: \"%s//%s\"\n", $1, $3);
241                                 $$=$1;
242                                 $$=xmlStrcat($$,U("//"));
243                                 $$=xmlStrcat($$,$3);
244                                 xmlFree($3);
245                             }
246     ;
247     AbbreviatedStep         : TOK_Parent
248                             {
249                                 TRACE("Got AbbreviatedStep: \"..\"\n");
250                                 $$=xmlStrdup(U(".."));
251                             }
252                             | TOK_Self
253                             {
254                                 TRACE("Got AbbreviatedStep: \".\"\n");
255                                 $$=xmlStrdup(U("."));
256                             }
257     ;
258
259     /* [3] Expressions */
260     /* [3.1] Basics */
261     Expr                    : OrExpr
262     ;
263     BoolExpr                : FunctionCall
264                             | BoolUnaryExpr
265                             | BoolRelationalExpr
266                             | BoolEqualityExpr
267                             | BoolAndExpr
268                             | BoolOrExpr
269     ;
270     PrimaryExpr             : '(' Expr ')'
271                             {
272                                 TRACE("Got PrimaryExpr: \"(%s)\"\n", $1);
273                                 $$=xmlStrdup(U("("));
274                                 $$=xmlStrcat($$,$2);
275                                 xmlFree($2);
276                                 $$=xmlStrcat($$,U(")"));
277                             }
278                             | PathExpr '!' FunctionCall
279                             {
280                                 TRACE("Got PrimaryExpr: \"%s!%s\"\n", $1, $3);
281                                 $$=$1;
282                                 $$=xmlStrcat($$,U("/"));
283                                 $$=xmlStrcat($$,$3);
284                                 xmlFree($3);
285                             }
286                             | TOK_Literal
287                             | TOK_Number
288                             | FunctionCall
289     ;
290     /* [3.2] Function Calls */
291     FunctionCall            : QName '(' Arguments ')'
292                             {
293                                 TRACE("Got FunctionCall: \"%s(%s)\"\n", $1, $3);
294                                 $$=$1;
295                                 $$=xmlStrcat($$,U("("));
296                                 $$=xmlStrcat($$,$3);
297                                 xmlFree($3);
298                                 $$=xmlStrcat($$,U(")"));
299                             }
300                             | QName '(' ')'
301                             {
302                                 TRACE("Got FunctionCall: \"%s()\"\n", $1);
303                                 $$=$1;
304                                 $$=xmlStrcat($$,U("()"));
305                             }
306     ;
307     Arguments               : Argument ',' Arguments
308                             {
309                                 $$=$1;
310                                 $$=xmlStrcat($$,U(","));
311                                 $$=xmlStrcat($$,$3);
312                                 xmlFree($3);
313                             }
314                             | Argument
315     ;
316     Argument                : Expr
317     ;
318     /* [3.3] Node-sets */
319     UnionExpr               : PathExpr
320                             | UnionExpr '|' PathExpr
321                             {
322                                 TRACE("Got UnionExpr: \"%s|%s\"\n", $1, $3);
323                                 $$=$1;
324                                 $$=xmlStrcat($$,U("|"));
325                                 $$=xmlStrcat($$,$3);
326                                 xmlFree($3);
327                             }
328     ;
329     PathExpr                : LocationPath
330                             | FilterExpr TOK_FSlash RelativeLocationPath
331                             {
332                                 TRACE("Got PathExpr: \"%s/%s\"\n", $1, $3);
333                                 $$=$1;
334                                 $$=xmlStrcat($$,U("/"));
335                                 $$=xmlStrcat($$,$3);
336                                 xmlFree($3);
337                             }
338                             | FilterExpr TOK_DblFSlash RelativeLocationPath
339                             {
340                                 TRACE("Got PathExpr: \"%s//%s\"\n", $1, $3);
341                                 $$=$1;
342                                 $$=xmlStrcat($$,U("//"));
343                                 $$=xmlStrcat($$,$3);
344                                 xmlFree($3);
345                             }
346                             | FilterExpr
347     ;
348     FilterExpr              : PrimaryExpr
349                             | FilterExpr Predicate
350                             {
351                                 TRACE("Got FilterExpr: \"%s%s\"\n", $1, $2);
352                                 $$=$1;
353                                 $$=xmlStrcat($$,$2);
354                                 xmlFree($2);
355                             }
356     ;
357     /* [3.4] Booleans */
358     OrExpr                  : AndExpr
359                             | BoolOrExpr
360     ;
361     BoolOrExpr              : OrExpr TOK_OpOr AndExpr
362                             {
363                                 TRACE("Got OrExpr: \"%s $or$ %s\"\n", $1, $3);
364                                 $$=$1;
365                                 $$=xmlStrcat($$,U(" or "));
366                                 $$=xmlStrcat($$,$3);
367                                 xmlFree($3);
368                             }
369     ;
370     AndExpr                 : EqualityExpr
371                             | BoolAndExpr
372     ;
373     BoolAndExpr             : AndExpr TOK_OpAnd EqualityExpr
374                             {
375                                 TRACE("Got AndExpr: \"%s $and$ %s\"\n", $1, $3);
376                                 $$=$1;
377                                 $$=xmlStrcat($$,U(" and "));
378                                 $$=xmlStrcat($$,$3);
379                                 xmlFree($3);
380                             }
381     ;
382     EqualityExpr            : RelationalExpr
383                             | BoolEqualityExpr
384     ;
385     BoolEqualityExpr        : EqualityExpr TOK_OpEq RelationalExpr
386                             {
387                                 TRACE("Got EqualityExpr: \"%s $eq$ %s\"\n", $1, $3);
388                                 $$=$1;
389                                 $$=xmlStrcat($$,U("="));
390                                 $$=xmlStrcat($$,$3);
391                                 xmlFree($3);
392                             }
393                             | EqualityExpr TOK_OpIEq RelationalExpr
394                             {
395                                 TRACE("Got EqualityExpr: \"%s $ieq$ %s\"\n", $1, $3);
396                                 $$=xmlStrdup(U("OP_IEq("));
397                                 $$=xmlStrcat($$,$1);
398                                 xmlFree($1);
399                                 $$=xmlStrcat($$,U(","));
400                                 $$=xmlStrcat($$,$3);
401                                 xmlFree($3);
402                                 $$=xmlStrcat($$,U(")"));
403                             }
404                             | EqualityExpr TOK_OpNEq RelationalExpr
405                             {
406                                 TRACE("Got EqualityExpr: \"%s $ne$ %s\"\n", $1, $3);
407                                 $$=$1;
408                                 $$=xmlStrcat($$,U("!="));
409                                 $$=xmlStrcat($$,$3);
410                                 xmlFree($3);
411                             }
412                             | EqualityExpr TOK_OpINEq RelationalExpr
413                             {
414                                 TRACE("Got EqualityExpr: \"%s $ine$ %s\"\n", $1, $3);
415                                 $$=xmlStrdup(U("OP_INEq("));
416                                 $$=xmlStrcat($$,$1);
417                                 xmlFree($1);
418                                 $$=xmlStrcat($$,U(","));
419                                 $$=xmlStrcat($$,$3);
420                                 xmlFree($3);
421                                 $$=xmlStrcat($$,U(")"));
422                             }
423     ;
424     RelationalExpr          : UnaryExpr
425                             | BoolRelationalExpr
426     ;
427     BoolRelationalExpr      : RelationalExpr TOK_OpLt UnaryExpr
428                             {
429                                 TRACE("Got RelationalExpr: \"%s $lt$ %s\"\n", $1, $3);
430                                 $$=$1;
431                                 $$=xmlStrcat($$,U("<"));
432                                 $$=xmlStrcat($$,$3);
433                                 xmlFree($3);
434                             }
435                             | RelationalExpr TOK_OpILt UnaryExpr
436                             {
437                                 TRACE("Got RelationalExpr: \"%s $ilt$ %s\"\n", $1, $3);
438                                 $$=xmlStrdup(U("OP_ILt("));
439                                 $$=xmlStrcat($$,$1);
440                                 xmlFree($1);
441                                 $$=xmlStrcat($$,U(","));
442                                 $$=xmlStrcat($$,$3);
443                                 xmlFree($3);
444                                 $$=xmlStrcat($$,U(")"));
445                             }
446                             | RelationalExpr TOK_OpGt UnaryExpr
447                             {
448                                 TRACE("Got RelationalExpr: \"%s $gt$ %s\"\n", $1, $3);
449                                 $$=$1;
450                                 $$=xmlStrcat($$,U(">"));
451                                 $$=xmlStrcat($$,$3);
452                                 xmlFree($3);
453                             }
454                             | RelationalExpr TOK_OpIGt UnaryExpr
455                             {
456                                 TRACE("Got RelationalExpr: \"%s $igt$ %s\"\n", $1, $3);
457                                 $$=xmlStrdup(U("OP_IGt("));
458                                 $$=xmlStrcat($$,$1);
459                                 xmlFree($1);
460                                 $$=xmlStrcat($$,U(","));
461                                 $$=xmlStrcat($$,$3);
462                                 xmlFree($3);
463                                 $$=xmlStrcat($$,U(")"));
464                             }
465                             | RelationalExpr TOK_OpLEq UnaryExpr
466                             {
467                                 TRACE("Got RelationalExpr: \"%s $le$ %s\"\n", $1, $3);
468                                 $$=$1;
469                                 $$=xmlStrcat($$,U("<="));
470                                 $$=xmlStrcat($$,$3);
471                                 xmlFree($3);
472                             }
473                             | RelationalExpr TOK_OpILEq UnaryExpr
474                             {
475                                 TRACE("Got RelationalExpr: \"%s $ile$ %s\"\n", $1, $3);
476                                 $$=xmlStrdup(U("OP_ILEq("));
477                                 $$=xmlStrcat($$,$1);
478                                 xmlFree($1);
479                                 $$=xmlStrcat($$,U(","));
480                                 $$=xmlStrcat($$,$3);
481                                 xmlFree($3);
482                                 $$=xmlStrcat($$,U(")"));
483                             }
484                             | RelationalExpr TOK_OpGEq UnaryExpr
485                             {
486                                 TRACE("Got RelationalExpr: \"%s $ge$ %s\"\n", $1, $3);
487                                 $$=$1;
488                                 $$=xmlStrcat($$,U(">="));
489                                 $$=xmlStrcat($$,$3);
490                                 xmlFree($3);
491                             }
492                             | RelationalExpr TOK_OpIGEq UnaryExpr
493                             {
494                                 TRACE("Got RelationalExpr: \"%s $ige$ %s\"\n", $1, $3);
495                                 $$=xmlStrdup(U("OP_IGEq("));
496                                 $$=xmlStrcat($$,$1);
497                                 xmlFree($1);
498                                 $$=xmlStrcat($$,U(","));
499                                 $$=xmlStrcat($$,$3);
500                                 xmlFree($3);
501                                 $$=xmlStrcat($$,U(")"));
502                             }
503     ;
504
505     /* [3.5] Numbers */
506     UnaryExpr               : UnionExpr
507                             | BoolUnaryExpr
508     ;
509     BoolUnaryExpr           : TOK_OpNot UnaryExpr
510                             {
511                                 TRACE("Got UnaryExpr: \"$not$ %s\"\n", $2);
512                                 $$=xmlStrdup(U(" not("));
513                                 $$=xmlStrcat($$,$2);
514                                 xmlFree($2);
515                                 $$=xmlStrcat($$,U(")"));
516                             }
517                             | TOK_OpAny Expr
518                             {
519                                 TRACE("Got UnaryExpr: \"$any$ %s\"\n", $2);
520                                 $$=xmlStrdup(U("boolean("));
521                                 $$=xmlStrcat($$,$2);
522                                 xmlFree($2);
523                                 $$=xmlStrcat($$,U(")"));
524                             }
525                             | TOK_OpAll AllExpr
526                             {
527                                 TRACE("Got UnaryExpr: \"$all$ %s\"\n", $2);
528                                 $$=xmlStrdup(U("not("));
529                                 $$=xmlStrcat($$,$2);
530                                 xmlFree($2);
531                                 $$=xmlStrcat($$,U(")"));
532                             }
533                             | TOK_OpAll
534                             {
535                                 FIXME("Unrecognized $all$ expression - ignoring\n");
536                                 $$=xmlStrdup(U(""));
537                             }
538     ;
539     AllExpr                 : PathExpr TOK_OpEq PathExpr
540                             {
541                                 $$=$1;
542                                 $$=xmlStrcat($$,U("!="));
543                                 $$=xmlStrcat($$,$3);
544                                 xmlFree($3);
545                             }
546                             | PathExpr TOK_OpNEq PathExpr
547                             {
548                                 $$=$1;
549                                 $$=xmlStrcat($$,U("="));
550                                 $$=xmlStrcat($$,$3);
551                                 xmlFree($3);
552                             }
553                             | PathExpr TOK_OpLt PathExpr
554                             {
555                                 $$=$1;
556                                 $$=xmlStrcat($$,U(">="));
557                                 $$=xmlStrcat($$,$3);
558                                 xmlFree($3);
559                             }
560                             | PathExpr TOK_OpLEq PathExpr
561                             {
562                                 $$=$1;
563                                 $$=xmlStrcat($$,U(">"));
564                                 $$=xmlStrcat($$,$3);
565                                 xmlFree($3);
566                             }
567                             | PathExpr TOK_OpGt PathExpr
568                             {
569                                 $$=$1;
570                                 $$=xmlStrcat($$,U("<="));
571                                 $$=xmlStrcat($$,$3);
572                                 xmlFree($3);
573                             }
574                             | PathExpr TOK_OpGEq PathExpr
575                             {
576                                 $$=$1;
577                                 $$=xmlStrcat($$,U("<"));
578                                 $$=xmlStrcat($$,$3);
579                                 xmlFree($3);
580                             }
581                             | PathExpr TOK_OpIEq PathExpr
582                             {
583                                 $$=xmlStrdup(U("OP_INEq("));
584                                 $$=xmlStrcat($$,$1);
585                                 xmlFree($1);
586                                 $$=xmlStrcat($$,U(","));
587                                 $$=xmlStrcat($$,$3);
588                                 xmlFree($3);
589                                 $$=xmlStrcat($$,U(")"));
590                             }
591                             | PathExpr TOK_OpINEq PathExpr
592                             {
593                                 $$=xmlStrdup(U("OP_IEq("));
594                                 $$=xmlStrcat($$,$1);
595                                 xmlFree($1);
596                                 $$=xmlStrcat($$,U(","));
597                                 $$=xmlStrcat($$,$3);
598                                 xmlFree($3);
599                                 $$=xmlStrcat($$,U(")"));
600                             }
601                             | PathExpr TOK_OpILt PathExpr
602                             {
603                                 $$=xmlStrdup(U("OP_IGEq("));
604                                 $$=xmlStrcat($$,$1);
605                                 xmlFree($1);
606                                 $$=xmlStrcat($$,U(","));
607                                 $$=xmlStrcat($$,$3);
608                                 xmlFree($3);
609                                 $$=xmlStrcat($$,U(")"));
610                             }
611                             | PathExpr TOK_OpILEq PathExpr
612                             {
613                                 $$=xmlStrdup(U("OP_IGt("));
614                                 $$=xmlStrcat($$,$1);
615                                 xmlFree($1);
616                                 $$=xmlStrcat($$,U(","));
617                                 $$=xmlStrcat($$,$3);
618                                 xmlFree($3);
619                                 $$=xmlStrcat($$,U(")"));
620                             }
621                             | PathExpr TOK_OpIGt PathExpr
622                             {
623                                 $$=xmlStrdup(U("OP_ILEq("));
624                                 $$=xmlStrcat($$,$1);
625                                 xmlFree($1);
626                                 $$=xmlStrcat($$,U(","));
627                                 $$=xmlStrcat($$,$3);
628                                 xmlFree($3);
629                                 $$=xmlStrcat($$,U(")"));
630                             }
631                             | PathExpr TOK_OpIGEq PathExpr
632                             {
633                                 $$=xmlStrdup(U("OP_ILt("));
634                                 $$=xmlStrcat($$,$1);
635                                 xmlFree($1);
636                                 $$=xmlStrcat($$,U(","));
637                                 $$=xmlStrcat($$,$3);
638                                 xmlFree($3);
639                                 $$=xmlStrcat($$,U(")"));
640                             }
641     ;
642
643 %%
644
645 void xslpattern_error(parser_param* param, void const* scanner, char const* msg)
646 {
647     FIXME("%s:\n"
648           "  param {\n"
649           "    yyscanner=%p\n"
650           "    ctx=%p\n"
651           "    in=\"%s\"\n"
652           "    pos=%i\n"
653           "    len=%i\n"
654           "    out=\"%s\"\n"
655           "    err=%i\n"
656           "  }\n"
657           "  scanner=%p\n",
658           msg, param->yyscanner, param->ctx, param->in, param->pos,
659           param->len, param->out, ++param->err, scanner);
660 }
661
662
663 #endif  /* HAVE_LIBXML2 */