Synchronize with trunk revision 59636 (just before Alex's CreateProcess revamp).
[reactos.git] / dll / win32 / 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 #include "wine/debug.h"
29
30 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
31
32
33 static const xmlChar NameTest_mod_pre[] = "*[name()='";
34 static const xmlChar NameTest_mod_post[] = "']";
35
36 #define U(str) BAD_CAST str
37
38 static inline BOOL is_literal(xmlChar const* tok)
39 {
40 return (tok && tok[0] && tok[1] &&
41 tok[0]== tok[xmlStrlen(tok)-1] &&
42 (tok[0] == '\'' || tok[0] == '"'));
43 }
44
45 static void xslpattern_error(parser_param* param, void const* scanner, char const* msg)
46 {
47 FIXME("%s:\n"
48 " param {\n"
49 " yyscanner=%p\n"
50 " ctx=%p\n"
51 " in=\"%s\"\n"
52 " pos=%i\n"
53 " len=%i\n"
54 " out=\"%s\"\n"
55 " err=%i\n"
56 " }\n"
57 " scanner=%p\n",
58 msg, param->yyscanner, param->ctx, param->in, param->pos,
59 param->len, param->out, ++param->err, scanner);
60 }
61
62 %}
63
64 %token TOK_Parent TOK_Self TOK_DblFSlash TOK_FSlash TOK_Axis TOK_Colon
65 %token TOK_OpAnd TOK_OpOr TOK_OpNot
66 %token TOK_OpEq TOK_OpIEq TOK_OpNEq TOK_OpINEq
67 %token TOK_OpLt TOK_OpILt TOK_OpGt TOK_OpIGt TOK_OpLEq TOK_OpILEq TOK_OpGEq TOK_OpIGEq
68 %token TOK_OpAll TOK_OpAny
69 %token TOK_NCName TOK_Literal TOK_Number
70
71 %start XSLPattern
72
73 %pure_parser
74 %parse-param {parser_param* p}
75 %parse-param {void* scanner}
76 %lex-param {yyscan_t* scanner}
77
78 %left TOK_OpAnd TOK_OpOr
79 %left TOK_OpEq TOK_OpIEq TOK_OpNEq TOK_OpINEq
80 %left TOK_OpLt TOK_OpILt TOK_OpGt TOK_OpIGt TOK_OpLEq TOK_OpILEq TOK_OpGEq TOK_OpIGEq
81
82 %expect 14
83
84 %%
85
86 XSLPattern : Expr
87 {
88 p->out = $1;
89 }
90 ;
91
92 /* Mostly verbatim from the w3c XML Namespaces standard.
93 * <http://www.w3.org/TR/REC-xml-names/> */
94
95 /* [4] Qualified Names */
96 QName : PrefixedName
97 | UnprefixedName
98 ;
99 PrefixedName : TOK_NCName TOK_Colon TOK_NCName
100 {
101 TRACE("Got PrefixedName: \"%s:%s\"\n", $1, $3);
102 $$=$1;
103 $$=xmlStrcat($$,U(":"));
104 $$=xmlStrcat($$,$3);
105 xmlFree($3);
106 }
107 ;
108 UnprefixedName : TOK_NCName
109 {
110 TRACE("Got UnprefixedName: \"%s\"\n", $1);
111 $$=$1;
112 }
113 ;
114
115 /* Based on the w3c XPath standard, adapted where needed.
116 * <http://www.w3.org/TR/xpath/> */
117
118 /* [2] Location Paths */
119 LocationPath : RelativeLocationPath
120 | AbsoluteLocationPath
121 ;
122 AbsoluteLocationPath : TOK_FSlash RelativeLocationPath
123 {
124 TRACE("Got AbsoluteLocationPath: \"/%s\"\n", $2);
125 $$=xmlStrdup(U("/"));
126 $$=xmlStrcat($$,$2);
127 xmlFree($2);
128 }
129 | TOK_FSlash
130 {
131 TRACE("Got AbsoluteLocationPath: \"/\"\n");
132 $$=xmlStrdup(U("/"));
133 }
134 | AbbreviatedAbsoluteLocationPath
135 ;
136 RelativeLocationPath : Step
137 | RelativeLocationPath TOK_FSlash Step
138 {
139 TRACE("Got RelativeLocationPath: \"%s/%s\"\n", $1, $3);
140 $$=$1;
141 $$=xmlStrcat($$,U("/"));
142 $$=xmlStrcat($$,$3);
143 xmlFree($3);
144 }
145 | AbbreviatedRelativeLocationPath
146 ;
147 /* [2.1] Location Steps */
148 Step : AxisSpecifier NodeTest Predicates
149 {
150 TRACE("Got Step: \"%s%s%s\"\n", $1, $2, $3);
151 $$=$1;
152 $$=xmlStrcat($$,$2);
153 xmlFree($2);
154 $$=xmlStrcat($$,$3);
155 xmlFree($3);
156 }
157 | NodeTest Predicates
158 {
159 TRACE("Got Step: \"%s%s\"\n", $1, $2);
160 $$=$1;
161 $$=xmlStrcat($$,$2);
162 xmlFree($2);
163 }
164 | AxisSpecifier NodeTest
165 {
166 TRACE("Got Step: \"%s%s\"\n", $1, $2);
167 $$=$1;
168 $$=xmlStrcat($$,$2);
169 xmlFree($2);
170 }
171 | NodeTest
172 | Attribute
173 | AbbreviatedStep
174 ;
175 AxisSpecifier : TOK_NCName TOK_Axis
176 {
177 TRACE("Got AxisSpecifier: \"%s::\"\n", $1);
178 $$=$1;
179 $$=xmlStrcat($$,U("::"));
180 }
181 ;
182 Attribute : '@' QName
183 {
184 TRACE("Got Attribute: \"@%s\"\n", $2);
185 $$=xmlStrdup(U("@"));
186 $$=xmlStrcat($$,$2);
187 xmlFree($2);
188 }
189 ;
190
191 /* [2.3] Node Tests */
192 NodeTest : NameTest
193 | FunctionCall
194 ;
195 NameTest : '*'
196 {
197 TRACE("Got NameTest: \"*\"\n");
198 $$=xmlStrdup(U("*"));
199 }
200 | TOK_NCName TOK_Colon '*'
201 {
202 TRACE("Got NameTest: \"%s:*\"\n", $1);
203 $$=$1;
204 $$=xmlStrcat($$,U(":*"));
205 }
206 | TOK_NCName TOK_Colon TOK_NCName
207 { /* PrefixedName */
208 xmlChar const* registeredNsURI = xmlXPathNsLookup(p->ctx, $1);
209 TRACE("Got PrefixedName: \"%s:%s\"\n", $1, $3);
210
211 if (registeredNsURI)
212 $$=xmlStrdup(U(""));
213 else
214 $$=xmlStrdup(NameTest_mod_pre);
215
216 $$=xmlStrcat($$,$1);
217 xmlFree($1);
218 $$=xmlStrcat($$,U(":"));
219 $$=xmlStrcat($$,$3);
220 xmlFree($3);
221
222 if (!registeredNsURI)
223 $$=xmlStrcat($$,NameTest_mod_post);
224 }
225 | UnprefixedName
226 {
227 $$=xmlStrdup(NameTest_mod_pre);
228 $$=xmlStrcat($$,$1);
229 xmlFree($1);
230 $$=xmlStrcat($$,NameTest_mod_post);
231 }
232 /* [2.4] Predicates */
233 Predicates : Predicates Predicate
234 {
235 $$=$1;
236 $$=xmlStrcat($$,$2);
237 xmlFree($2);
238 }
239 | Predicate
240 ;
241 Predicate : '[' PredicateExpr ']'
242 {
243 TRACE("Got Predicate: \"[%s]\"\n", $2);
244 $$=xmlStrdup(U("["));
245 $$=xmlStrcat($$,$2);
246 xmlFree($2);
247 $$=xmlStrcat($$,U("]"));
248 }
249 ;
250 PredicateExpr : TOK_Number
251 {
252 $$=xmlStrdup(U("index()="));
253 $$=xmlStrcat($$,$1);
254 xmlFree($1);
255 }
256 | BoolExpr
257 | Attribute
258 | TOK_NCName
259 ;
260 /* [2.5] Abbreviated Syntax */
261 AbbreviatedAbsoluteLocationPath : TOK_DblFSlash RelativeLocationPath
262 {
263 TRACE("Got AbbreviatedAbsoluteLocationPath: \"//%s\"\n", $2);
264 $$=xmlStrdup(U("//"));
265 $$=xmlStrcat($$,$2);
266 xmlFree($2);
267 }
268 ;
269 AbbreviatedRelativeLocationPath : RelativeLocationPath TOK_DblFSlash Step
270 {
271 TRACE("Got AbbreviatedRelativeLocationPath: \"%s//%s\"\n", $1, $3);
272 $$=$1;
273 $$=xmlStrcat($$,U("//"));
274 $$=xmlStrcat($$,$3);
275 xmlFree($3);
276 }
277 ;
278 AbbreviatedStep : TOK_Parent
279 {
280 TRACE("Got AbbreviatedStep: \"..\"\n");
281 $$=xmlStrdup(U(".."));
282 }
283 | TOK_Self
284 {
285 TRACE("Got AbbreviatedStep: \".\"\n");
286 $$=xmlStrdup(U("."));
287 }
288 ;
289
290 /* [3] Expressions */
291 /* [3.1] Basics */
292 Expr : OrExpr
293 ;
294 BoolExpr : FunctionCall
295 | BoolUnaryExpr
296 | BoolRelationalExpr
297 | BoolEqualityExpr
298 | BoolAndExpr
299 | BoolOrExpr
300 ;
301 PrimaryExpr : '(' Expr ')'
302 {
303 TRACE("Got PrimaryExpr: \"(%s)\"\n", $1);
304 $$=xmlStrdup(U("("));
305 $$=xmlStrcat($$,$2);
306 xmlFree($2);
307 $$=xmlStrcat($$,U(")"));
308 }
309 | PathExpr '!' FunctionCall
310 {
311 TRACE("Got PrimaryExpr: \"%s!%s\"\n", $1, $3);
312 $$=$1;
313 $$=xmlStrcat($$,U("/"));
314 $$=xmlStrcat($$,$3);
315 xmlFree($3);
316 }
317 | TOK_Literal
318 | TOK_Number
319 ;
320 /* [3.2] Function Calls */
321 FunctionCall : QName '(' Arguments ')'
322 {
323 TRACE("Got FunctionCall: \"%s(%s)\"\n", $1, $3);
324 if (xmlStrEqual($1,U("ancestor")))
325 {
326 $$=$1;
327 $$=xmlStrcat($$,U("::"));
328 $$=xmlStrcat($$,$3);
329 xmlFree($3);
330 }
331 else if (xmlStrEqual($1,U("attribute")))
332 {
333 if (is_literal($3))
334 {
335 $$=xmlStrdup(U("@*[name()="));
336 xmlFree($1);
337 $$=xmlStrcat($$,$3);
338 xmlFree($3);
339 $$=xmlStrcat($$,U("]"));
340 }
341 else
342 {
343 /* XML_XPATH_INVALID_TYPE */
344 $$=xmlStrdup(U("error(1211, 'Error: attribute("));
345 xmlFree($1);
346 $$=xmlStrcat($$,$3);
347 xmlFree($3);
348 $$=xmlStrcat($$,U("): invalid argument')"));
349 }
350 }
351 else if (xmlStrEqual($1,U("element")))
352 {
353 if (is_literal($3))
354 {
355 $$=xmlStrdup(U("node()[nodeType()=1][name()="));
356 xmlFree($1);
357 $$=xmlStrcat($$,$3);
358 xmlFree($3);
359 $$=xmlStrcat($$,U("]"));
360 }
361 else
362 {
363 /* XML_XPATH_INVALID_TYPE */
364 $$=xmlStrdup(U("error(1211, 'Error: element("));
365 xmlFree($1);
366 $$=xmlStrcat($$,$3);
367 xmlFree($3);
368 $$=xmlStrcat($$,U("): invalid argument')"));
369 }
370 }
371 else
372 {
373 $$=$1;
374 $$=xmlStrcat($$,U("("));
375 $$=xmlStrcat($$,$3);
376 xmlFree($3);
377 $$=xmlStrcat($$,U(")"));
378 }
379 }
380 | QName '(' ')'
381 {
382 TRACE("Got FunctionCall: \"%s()\"\n", $1);
383 /* comment() & node() work the same in XPath */
384 if (xmlStrEqual($1,U("attribute")))
385 {
386 $$=xmlStrdup(U("@*"));
387 xmlFree($1);
388 }
389 else if (xmlStrEqual($1,U("element")))
390 {
391 $$=xmlStrdup(U("node()[nodeType()=1]"));
392 xmlFree($1);
393 }
394 else if (xmlStrEqual($1,U("pi")))
395 {
396 $$=xmlStrdup(U("processing-instruction()"));
397 xmlFree($1);
398 }
399 else if (xmlStrEqual($1,U("textnode")))
400 {
401 $$=xmlStrdup(U("text()"));
402 xmlFree($1);
403 }
404 else
405 {
406 $$=$1;
407 $$=xmlStrcat($$,U("()"));
408 }
409 }
410 ;
411 Arguments : Argument ',' Arguments
412 {
413 $$=$1;
414 $$=xmlStrcat($$,U(","));
415 $$=xmlStrcat($$,$3);
416 xmlFree($3);
417 }
418 | Argument
419 ;
420 Argument : Expr
421 ;
422 /* [3.3] Node-sets */
423 UnionExpr : PathExpr
424 | UnionExpr '|' PathExpr
425 {
426 TRACE("Got UnionExpr: \"%s|%s\"\n", $1, $3);
427 $$=$1;
428 $$=xmlStrcat($$,U("|"));
429 $$=xmlStrcat($$,$3);
430 xmlFree($3);
431 }
432 ;
433 PathExpr : LocationPath
434 | FilterExpr TOK_FSlash RelativeLocationPath
435 {
436 TRACE("Got PathExpr: \"%s/%s\"\n", $1, $3);
437 $$=$1;
438 $$=xmlStrcat($$,U("/"));
439 $$=xmlStrcat($$,$3);
440 xmlFree($3);
441 }
442 | FilterExpr TOK_DblFSlash RelativeLocationPath
443 {
444 TRACE("Got PathExpr: \"%s//%s\"\n", $1, $3);
445 $$=$1;
446 $$=xmlStrcat($$,U("//"));
447 $$=xmlStrcat($$,$3);
448 xmlFree($3);
449 }
450 | FilterExpr
451 ;
452 FilterExpr : PrimaryExpr
453 | FilterExpr Predicate
454 {
455 TRACE("Got FilterExpr: \"%s%s\"\n", $1, $2);
456 $$=$1;
457 $$=xmlStrcat($$,$2);
458 xmlFree($2);
459 }
460 ;
461 /* [3.4] Booleans */
462 OrExpr : AndExpr
463 | BoolOrExpr
464 ;
465 BoolOrExpr : OrExpr TOK_OpOr AndExpr
466 {
467 TRACE("Got OrExpr: \"%s $or$ %s\"\n", $1, $3);
468 $$=$1;
469 $$=xmlStrcat($$,U(" or "));
470 $$=xmlStrcat($$,$3);
471 xmlFree($3);
472 }
473 ;
474 AndExpr : EqualityExpr
475 | BoolAndExpr
476 ;
477 BoolAndExpr : AndExpr TOK_OpAnd EqualityExpr
478 {
479 TRACE("Got AndExpr: \"%s $and$ %s\"\n", $1, $3);
480 $$=$1;
481 $$=xmlStrcat($$,U(" and "));
482 $$=xmlStrcat($$,$3);
483 xmlFree($3);
484 }
485 ;
486 EqualityExpr : RelationalExpr
487 | BoolEqualityExpr
488 ;
489 BoolEqualityExpr : EqualityExpr TOK_OpEq RelationalExpr
490 {
491 TRACE("Got EqualityExpr: \"%s $eq$ %s\"\n", $1, $3);
492 $$=$1;
493 $$=xmlStrcat($$,U("="));
494 $$=xmlStrcat($$,$3);
495 xmlFree($3);
496 }
497 | EqualityExpr TOK_OpIEq RelationalExpr
498 {
499 TRACE("Got EqualityExpr: \"%s $ieq$ %s\"\n", $1, $3);
500 $$=xmlStrdup(U("OP_IEq("));
501 $$=xmlStrcat($$,$1);
502 xmlFree($1);
503 $$=xmlStrcat($$,U(","));
504 $$=xmlStrcat($$,$3);
505 xmlFree($3);
506 $$=xmlStrcat($$,U(")"));
507 }
508 | EqualityExpr TOK_OpNEq RelationalExpr
509 {
510 TRACE("Got EqualityExpr: \"%s $ne$ %s\"\n", $1, $3);
511 $$=$1;
512 $$=xmlStrcat($$,U("!="));
513 $$=xmlStrcat($$,$3);
514 xmlFree($3);
515 }
516 | EqualityExpr TOK_OpINEq RelationalExpr
517 {
518 TRACE("Got EqualityExpr: \"%s $ine$ %s\"\n", $1, $3);
519 $$=xmlStrdup(U("OP_INEq("));
520 $$=xmlStrcat($$,$1);
521 xmlFree($1);
522 $$=xmlStrcat($$,U(","));
523 $$=xmlStrcat($$,$3);
524 xmlFree($3);
525 $$=xmlStrcat($$,U(")"));
526 }
527 ;
528 RelationalExpr : UnaryExpr
529 | BoolRelationalExpr
530 ;
531 BoolRelationalExpr : RelationalExpr TOK_OpLt UnaryExpr
532 {
533 TRACE("Got RelationalExpr: \"%s $lt$ %s\"\n", $1, $3);
534 $$=$1;
535 $$=xmlStrcat($$,U("<"));
536 $$=xmlStrcat($$,$3);
537 xmlFree($3);
538 }
539 | RelationalExpr TOK_OpILt UnaryExpr
540 {
541 TRACE("Got RelationalExpr: \"%s $ilt$ %s\"\n", $1, $3);
542 $$=xmlStrdup(U("OP_ILt("));
543 $$=xmlStrcat($$,$1);
544 xmlFree($1);
545 $$=xmlStrcat($$,U(","));
546 $$=xmlStrcat($$,$3);
547 xmlFree($3);
548 $$=xmlStrcat($$,U(")"));
549 }
550 | RelationalExpr TOK_OpGt UnaryExpr
551 {
552 TRACE("Got RelationalExpr: \"%s $gt$ %s\"\n", $1, $3);
553 $$=$1;
554 $$=xmlStrcat($$,U(">"));
555 $$=xmlStrcat($$,$3);
556 xmlFree($3);
557 }
558 | RelationalExpr TOK_OpIGt UnaryExpr
559 {
560 TRACE("Got RelationalExpr: \"%s $igt$ %s\"\n", $1, $3);
561 $$=xmlStrdup(U("OP_IGt("));
562 $$=xmlStrcat($$,$1);
563 xmlFree($1);
564 $$=xmlStrcat($$,U(","));
565 $$=xmlStrcat($$,$3);
566 xmlFree($3);
567 $$=xmlStrcat($$,U(")"));
568 }
569 | RelationalExpr TOK_OpLEq UnaryExpr
570 {
571 TRACE("Got RelationalExpr: \"%s $le$ %s\"\n", $1, $3);
572 $$=$1;
573 $$=xmlStrcat($$,U("<="));
574 $$=xmlStrcat($$,$3);
575 xmlFree($3);
576 }
577 | RelationalExpr TOK_OpILEq UnaryExpr
578 {
579 TRACE("Got RelationalExpr: \"%s $ile$ %s\"\n", $1, $3);
580 $$=xmlStrdup(U("OP_ILEq("));
581 $$=xmlStrcat($$,$1);
582 xmlFree($1);
583 $$=xmlStrcat($$,U(","));
584 $$=xmlStrcat($$,$3);
585 xmlFree($3);
586 $$=xmlStrcat($$,U(")"));
587 }
588 | RelationalExpr TOK_OpGEq UnaryExpr
589 {
590 TRACE("Got RelationalExpr: \"%s $ge$ %s\"\n", $1, $3);
591 $$=$1;
592 $$=xmlStrcat($$,U(">="));
593 $$=xmlStrcat($$,$3);
594 xmlFree($3);
595 }
596 | RelationalExpr TOK_OpIGEq UnaryExpr
597 {
598 TRACE("Got RelationalExpr: \"%s $ige$ %s\"\n", $1, $3);
599 $$=xmlStrdup(U("OP_IGEq("));
600 $$=xmlStrcat($$,$1);
601 xmlFree($1);
602 $$=xmlStrcat($$,U(","));
603 $$=xmlStrcat($$,$3);
604 xmlFree($3);
605 $$=xmlStrcat($$,U(")"));
606 }
607 ;
608
609 /* [3.5] Numbers */
610 UnaryExpr : UnionExpr
611 | BoolUnaryExpr
612 ;
613 BoolUnaryExpr : TOK_OpNot UnaryExpr
614 {
615 TRACE("Got UnaryExpr: \"$not$ %s\"\n", $2);
616 $$=xmlStrdup(U(" not("));
617 $$=xmlStrcat($$,$2);
618 xmlFree($2);
619 $$=xmlStrcat($$,U(")"));
620 }
621 | TOK_OpAny Expr
622 {
623 TRACE("Got UnaryExpr: \"$any$ %s\"\n", $2);
624 $$=xmlStrdup(U("boolean("));
625 $$=xmlStrcat($$,$2);
626 xmlFree($2);
627 $$=xmlStrcat($$,U(")"));
628 }
629 | TOK_OpAll AllExpr
630 {
631 TRACE("Got UnaryExpr: \"$all$ %s\"\n", $2);
632 $$=xmlStrdup(U("not("));
633 $$=xmlStrcat($$,$2);
634 xmlFree($2);
635 $$=xmlStrcat($$,U(")"));
636 }
637 | TOK_OpAll
638 {
639 FIXME("Unrecognized $all$ expression - ignoring\n");
640 $$=xmlStrdup(U(""));
641 }
642 ;
643 AllExpr : PathExpr TOK_OpEq PathExpr
644 {
645 $$=$1;
646 $$=xmlStrcat($$,U("!="));
647 $$=xmlStrcat($$,$3);
648 xmlFree($3);
649 }
650 | PathExpr TOK_OpNEq PathExpr
651 {
652 $$=$1;
653 $$=xmlStrcat($$,U("="));
654 $$=xmlStrcat($$,$3);
655 xmlFree($3);
656 }
657 | PathExpr TOK_OpLt PathExpr
658 {
659 $$=$1;
660 $$=xmlStrcat($$,U(">="));
661 $$=xmlStrcat($$,$3);
662 xmlFree($3);
663 }
664 | PathExpr TOK_OpLEq PathExpr
665 {
666 $$=$1;
667 $$=xmlStrcat($$,U(">"));
668 $$=xmlStrcat($$,$3);
669 xmlFree($3);
670 }
671 | PathExpr TOK_OpGt PathExpr
672 {
673 $$=$1;
674 $$=xmlStrcat($$,U("<="));
675 $$=xmlStrcat($$,$3);
676 xmlFree($3);
677 }
678 | PathExpr TOK_OpGEq PathExpr
679 {
680 $$=$1;
681 $$=xmlStrcat($$,U("<"));
682 $$=xmlStrcat($$,$3);
683 xmlFree($3);
684 }
685 | PathExpr TOK_OpIEq PathExpr
686 {
687 $$=xmlStrdup(U("OP_INEq("));
688 $$=xmlStrcat($$,$1);
689 xmlFree($1);
690 $$=xmlStrcat($$,U(","));
691 $$=xmlStrcat($$,$3);
692 xmlFree($3);
693 $$=xmlStrcat($$,U(")"));
694 }
695 | PathExpr TOK_OpINEq PathExpr
696 {
697 $$=xmlStrdup(U("OP_IEq("));
698 $$=xmlStrcat($$,$1);
699 xmlFree($1);
700 $$=xmlStrcat($$,U(","));
701 $$=xmlStrcat($$,$3);
702 xmlFree($3);
703 $$=xmlStrcat($$,U(")"));
704 }
705 | PathExpr TOK_OpILt PathExpr
706 {
707 $$=xmlStrdup(U("OP_IGEq("));
708 $$=xmlStrcat($$,$1);
709 xmlFree($1);
710 $$=xmlStrcat($$,U(","));
711 $$=xmlStrcat($$,$3);
712 xmlFree($3);
713 $$=xmlStrcat($$,U(")"));
714 }
715 | PathExpr TOK_OpILEq PathExpr
716 {
717 $$=xmlStrdup(U("OP_IGt("));
718 $$=xmlStrcat($$,$1);
719 xmlFree($1);
720 $$=xmlStrcat($$,U(","));
721 $$=xmlStrcat($$,$3);
722 xmlFree($3);
723 $$=xmlStrcat($$,U(")"));
724 }
725 | PathExpr TOK_OpIGt PathExpr
726 {
727 $$=xmlStrdup(U("OP_ILEq("));
728 $$=xmlStrcat($$,$1);
729 xmlFree($1);
730 $$=xmlStrcat($$,U(","));
731 $$=xmlStrcat($$,$3);
732 xmlFree($3);
733 $$=xmlStrcat($$,U(")"));
734 }
735 | PathExpr TOK_OpIGEq PathExpr
736 {
737 $$=xmlStrdup(U("OP_ILt("));
738 $$=xmlStrcat($$,$1);
739 xmlFree($1);
740 $$=xmlStrcat($$,U(","));
741 $$=xmlStrcat($$,$3);
742 xmlFree($3);
743 $$=xmlStrcat($$,U(")"));
744 }
745 ;
746
747 %%
748
749 #endif /* HAVE_LIBXML2 */