include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / dlls / msxml3 / xslpattern.y
blobb308c3150b0936f3ee4ad769c5713ee64e37ada1
1 /*
2 * XSLPattern parser (XSLPattern => XPath)
4 * Copyright 2010 Adam Martinson for CodeWeavers
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.
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.
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
22 #include "xslpattern.h"
23 #include <libxml/xpathInternals.h>
24 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
29 static const xmlChar NameTest_mod_pre[] = "*[name()='";
30 static const xmlChar NameTest_mod_post[] = "']";
32 #define U(str) BAD_CAST str
34 static inline BOOL is_literal(xmlChar const* tok)
36 return (tok && tok[0] && tok[1] &&
37 tok[0]== tok[xmlStrlen(tok)-1] &&
38 (tok[0] == '\'' || tok[0] == '"'));
41 static void xslpattern_error(parser_param* param, void const* scanner, char const* msg)
43 param->err++;
44 FIXME("%s:\n"
45 " param {\n"
46 " yyscanner=%p\n"
47 " ctx=%p\n"
48 " in=\"%s\"\n"
49 " pos=%i\n"
50 " len=%i\n"
51 " out=\"%s\"\n"
52 " err=%i\n"
53 " }\n"
54 " scanner=%p\n",
55 msg, param->yyscanner, param->ctx, param->in, param->pos,
56 param->len, param->out, param->err, scanner);
61 %token TOK_Parent TOK_Self TOK_DblFSlash TOK_FSlash TOK_Axis TOK_Colon
62 %token TOK_OpAnd TOK_OpOr TOK_OpNot
63 %token TOK_OpEq TOK_OpIEq TOK_OpNEq TOK_OpINEq
64 %token TOK_OpLt TOK_OpILt TOK_OpGt TOK_OpIGt TOK_OpLEq TOK_OpILEq TOK_OpGEq TOK_OpIGEq
65 %token TOK_OpAll TOK_OpAny
66 %token TOK_NCName TOK_Literal TOK_Number
68 %start XSLPattern
70 %define api.prefix {xslpattern_}
71 %define api.pure
72 %parse-param {parser_param* p}
73 %parse-param {void* scanner}
74 %lex-param {yyscan_t* scanner}
76 %left TOK_OpAnd TOK_OpOr
77 %left TOK_OpEq TOK_OpIEq TOK_OpNEq TOK_OpINEq
78 %left TOK_OpLt TOK_OpILt TOK_OpGt TOK_OpIGt TOK_OpLEq TOK_OpILEq TOK_OpGEq TOK_OpIGEq
80 %expect 14
84 XSLPattern : Expr
86 p->out = $1;
90 /* Mostly verbatim from the w3c XML Namespaces standard.
91 * <http://www.w3.org/TR/REC-xml-names/> */
93 /* [4] Qualified Names */
94 QName : PrefixedName
95 | UnprefixedName
97 PrefixedName : TOK_NCName TOK_Colon TOK_NCName
99 TRACE("Got PrefixedName: \"%s:%s\"\n", $1, $3);
100 $$=$1;
101 $$=xmlStrcat($$,U(":"));
102 $$=xmlStrcat($$,$3);
103 xmlFree($3);
106 UnprefixedName : TOK_NCName
108 TRACE("Got UnprefixedName: \"%s\"\n", $1);
109 $$=$1;
113 /* Based on the w3c XPath standard, adapted where needed.
114 * <http://www.w3.org/TR/xpath/> */
116 /* [2] Location Paths */
117 LocationPath : RelativeLocationPath
118 | AbsoluteLocationPath
120 AbsoluteLocationPath : TOK_FSlash RelativeLocationPath
122 TRACE("Got AbsoluteLocationPath: \"/%s\"\n", $2);
123 $$=xmlStrdup(U("/"));
124 $$=xmlStrcat($$,$2);
125 xmlFree($2);
127 | TOK_FSlash
129 TRACE("Got AbsoluteLocationPath: \"/\"\n");
130 $$=xmlStrdup(U("/"));
132 | AbbreviatedAbsoluteLocationPath
134 RelativeLocationPath : Step
135 | RelativeLocationPath TOK_FSlash Step
137 TRACE("Got RelativeLocationPath: \"%s/%s\"\n", $1, $3);
138 $$=$1;
139 $$=xmlStrcat($$,U("/"));
140 $$=xmlStrcat($$,$3);
141 xmlFree($3);
143 | AbbreviatedRelativeLocationPath
145 /* [2.1] Location Steps */
146 Step : AxisSpecifier NodeTest Predicates
148 TRACE("Got Step: \"%s%s%s\"\n", $1, $2, $3);
149 $$=$1;
150 $$=xmlStrcat($$,$2);
151 xmlFree($2);
152 $$=xmlStrcat($$,$3);
153 xmlFree($3);
155 | NodeTest Predicates
157 TRACE("Got Step: \"%s%s\"\n", $1, $2);
158 $$=$1;
159 $$=xmlStrcat($$,$2);
160 xmlFree($2);
162 | AxisSpecifier NodeTest
164 TRACE("Got Step: \"%s%s\"\n", $1, $2);
165 $$=$1;
166 $$=xmlStrcat($$,$2);
167 xmlFree($2);
169 | NodeTest
170 | Attribute
171 | AbbreviatedStep
173 AxisSpecifier : TOK_NCName TOK_Axis
175 TRACE("Got AxisSpecifier: \"%s::\"\n", $1);
176 $$=$1;
177 $$=xmlStrcat($$,U("::"));
180 Attribute : '@' QName
182 TRACE("Got Attribute: \"@%s\"\n", $2);
183 $$=xmlStrdup(U("@"));
184 $$=xmlStrcat($$,$2);
185 xmlFree($2);
187 | '@' '*'
189 TRACE("Got All attributes pattern: \"@*\"\n");
190 $$=xmlStrdup(U("@*"));
194 /* [2.3] Node Tests */
195 NodeTest : NameTest
196 | FunctionCall
198 NameTest : '*'
200 TRACE("Got NameTest: \"*\"\n");
201 $$=xmlStrdup(U("*"));
203 | TOK_NCName TOK_Colon '*'
205 TRACE("Got NameTest: \"%s:*\"\n", $1);
206 $$=$1;
207 $$=xmlStrcat($$,U(":*"));
209 | TOK_NCName TOK_Colon TOK_NCName
210 { /* PrefixedName */
211 xmlChar const* registeredNsURI = xmlXPathNsLookup(p->ctx, $1);
212 TRACE("Got PrefixedName: \"%s:%s\"\n", $1, $3);
214 if (registeredNsURI)
215 $$=xmlStrdup(U(""));
216 else
217 $$=xmlStrdup(NameTest_mod_pre);
219 $$=xmlStrcat($$,$1);
220 xmlFree($1);
221 $$=xmlStrcat($$,U(":"));
222 $$=xmlStrcat($$,$3);
223 xmlFree($3);
225 if (!registeredNsURI)
226 $$=xmlStrcat($$,NameTest_mod_post);
228 | UnprefixedName
230 $$=xmlStrdup(NameTest_mod_pre);
231 $$=xmlStrcat($$,$1);
232 xmlFree($1);
233 $$=xmlStrcat($$,NameTest_mod_post);
235 /* [2.4] Predicates */
236 Predicates : Predicates Predicate
238 $$=$1;
239 $$=xmlStrcat($$,$2);
240 xmlFree($2);
242 | Predicate
244 Predicate : '[' PredicateExpr ']'
246 TRACE("Got Predicate: \"[%s]\"\n", $2);
247 $$=xmlStrdup(U("["));
248 $$=xmlStrcat($$,$2);
249 xmlFree($2);
250 $$=xmlStrcat($$,U("]"));
253 PredicateExpr : TOK_Number
255 $$=xmlStrdup(U("index()="));
256 $$=xmlStrcat($$,$1);
257 xmlFree($1);
259 | BoolExpr
260 | Attribute
261 | TOK_NCName
263 /* [2.5] Abbreviated Syntax */
264 AbbreviatedAbsoluteLocationPath : TOK_DblFSlash RelativeLocationPath
266 TRACE("Got AbbreviatedAbsoluteLocationPath: \"//%s\"\n", $2);
267 $$=xmlStrdup(U("//"));
268 $$=xmlStrcat($$,$2);
269 xmlFree($2);
272 AbbreviatedRelativeLocationPath : RelativeLocationPath TOK_DblFSlash Step
274 TRACE("Got AbbreviatedRelativeLocationPath: \"%s//%s\"\n", $1, $3);
275 $$=$1;
276 $$=xmlStrcat($$,U("//"));
277 $$=xmlStrcat($$,$3);
278 xmlFree($3);
281 AbbreviatedStep : TOK_Parent
283 TRACE("Got AbbreviatedStep: \"..\"\n");
284 $$=xmlStrdup(U(".."));
286 | TOK_Self
288 TRACE("Got AbbreviatedStep: \".\"\n");
289 $$=xmlStrdup(U("."));
293 /* [3] Expressions */
294 /* [3.1] Basics */
295 Expr : OrExpr
297 BoolExpr : FunctionCall
298 | BoolUnaryExpr
299 | BoolRelationalExpr
300 | BoolEqualityExpr
301 | BoolAndExpr
302 | BoolOrExpr
304 PrimaryExpr : '(' Expr ')'
306 TRACE("Got PrimaryExpr: \"(%s)\"\n", $1);
307 $$=xmlStrdup(U("("));
308 $$=xmlStrcat($$,$2);
309 xmlFree($2);
310 $$=xmlStrcat($$,U(")"));
312 | PathExpr '!' FunctionCall
314 TRACE("Got PrimaryExpr: \"%s!%s\"\n", $1, $3);
315 $$=$1;
316 $$=xmlStrcat($$,U("/"));
317 $$=xmlStrcat($$,$3);
318 xmlFree($3);
320 | TOK_Literal
321 | TOK_Number
323 /* [3.2] Function Calls */
324 FunctionCall : QName '(' Arguments ')'
326 TRACE("Got FunctionCall: \"%s(%s)\"\n", $1, $3);
327 if (xmlStrEqual($1,U("ancestor")))
329 $$=$1;
330 $$=xmlStrcat($$,U("::"));
331 $$=xmlStrcat($$,$3);
332 xmlFree($3);
334 else if (xmlStrEqual($1,U("attribute")))
336 if (is_literal($3))
338 $$=xmlStrdup(U("@*[name()="));
339 xmlFree($1);
340 $$=xmlStrcat($$,$3);
341 xmlFree($3);
342 $$=xmlStrcat($$,U("]"));
344 else
346 /* XML_XPATH_INVALID_TYPE */
347 $$=xmlStrdup(U("error(1211, 'Error: attribute("));
348 xmlFree($1);
349 $$=xmlStrcat($$,$3);
350 xmlFree($3);
351 $$=xmlStrcat($$,U("): invalid argument')"));
354 else if (xmlStrEqual($1,U("element")))
356 if (is_literal($3))
358 $$=xmlStrdup(U("node()[nodeType()=1][name()="));
359 xmlFree($1);
360 $$=xmlStrcat($$,$3);
361 xmlFree($3);
362 $$=xmlStrcat($$,U("]"));
364 else
366 /* XML_XPATH_INVALID_TYPE */
367 $$=xmlStrdup(U("error(1211, 'Error: element("));
368 xmlFree($1);
369 $$=xmlStrcat($$,$3);
370 xmlFree($3);
371 $$=xmlStrcat($$,U("): invalid argument')"));
374 else
376 $$=$1;
377 $$=xmlStrcat($$,U("("));
378 $$=xmlStrcat($$,$3);
379 xmlFree($3);
380 $$=xmlStrcat($$,U(")"));
383 | QName '(' ')'
385 TRACE("Got FunctionCall: \"%s()\"\n", $1);
386 /* comment() & node() work the same in XPath */
387 if (xmlStrEqual($1,U("attribute")))
389 $$=xmlStrdup(U("@*"));
390 xmlFree($1);
392 else if (xmlStrEqual($1,U("element")))
394 $$=xmlStrdup(U("node()[nodeType()=1]"));
395 xmlFree($1);
397 else if (xmlStrEqual($1,U("pi")))
399 $$=xmlStrdup(U("processing-instruction()"));
400 xmlFree($1);
402 else if (xmlStrEqual($1,U("textnode")))
404 $$=xmlStrdup(U("text()"));
405 xmlFree($1);
407 else
409 $$=$1;
410 $$=xmlStrcat($$,U("()"));
414 Arguments : Argument ',' Arguments
416 $$=$1;
417 $$=xmlStrcat($$,U(","));
418 $$=xmlStrcat($$,$3);
419 xmlFree($3);
421 | Argument
423 Argument : Expr
425 /* [3.3] Node-sets */
426 UnionExpr : PathExpr
427 | UnionExpr '|' PathExpr
429 TRACE("Got UnionExpr: \"%s|%s\"\n", $1, $3);
430 $$=$1;
431 $$=xmlStrcat($$,U("|"));
432 $$=xmlStrcat($$,$3);
433 xmlFree($3);
436 PathExpr : LocationPath
437 | FilterExpr TOK_FSlash RelativeLocationPath
439 TRACE("Got PathExpr: \"%s/%s\"\n", $1, $3);
440 $$=$1;
441 $$=xmlStrcat($$,U("/"));
442 $$=xmlStrcat($$,$3);
443 xmlFree($3);
445 | FilterExpr TOK_DblFSlash RelativeLocationPath
447 TRACE("Got PathExpr: \"%s//%s\"\n", $1, $3);
448 $$=$1;
449 $$=xmlStrcat($$,U("//"));
450 $$=xmlStrcat($$,$3);
451 xmlFree($3);
453 | FilterExpr
455 FilterExpr : PrimaryExpr
456 | FilterExpr Predicate
458 TRACE("Got FilterExpr: \"%s%s\"\n", $1, $2);
459 $$=$1;
460 $$=xmlStrcat($$,$2);
461 xmlFree($2);
464 /* [3.4] Booleans */
465 OrExpr : AndExpr
466 | BoolOrExpr
468 BoolOrExpr : OrExpr TOK_OpOr AndExpr
470 TRACE("Got OrExpr: \"%s $or$ %s\"\n", $1, $3);
471 $$=$1;
472 $$=xmlStrcat($$,U(" or "));
473 $$=xmlStrcat($$,$3);
474 xmlFree($3);
477 AndExpr : EqualityExpr
478 | BoolAndExpr
480 BoolAndExpr : AndExpr TOK_OpAnd EqualityExpr
482 TRACE("Got AndExpr: \"%s $and$ %s\"\n", $1, $3);
483 $$=$1;
484 $$=xmlStrcat($$,U(" and "));
485 $$=xmlStrcat($$,$3);
486 xmlFree($3);
489 EqualityExpr : RelationalExpr
490 | BoolEqualityExpr
492 BoolEqualityExpr : EqualityExpr TOK_OpEq RelationalExpr
494 TRACE("Got EqualityExpr: \"%s $eq$ %s\"\n", $1, $3);
495 $$=$1;
496 $$=xmlStrcat($$,U("="));
497 $$=xmlStrcat($$,$3);
498 xmlFree($3);
500 | EqualityExpr TOK_OpIEq RelationalExpr
502 TRACE("Got EqualityExpr: \"%s $ieq$ %s\"\n", $1, $3);
503 $$=xmlStrdup(U("OP_IEq("));
504 $$=xmlStrcat($$,$1);
505 xmlFree($1);
506 $$=xmlStrcat($$,U(","));
507 $$=xmlStrcat($$,$3);
508 xmlFree($3);
509 $$=xmlStrcat($$,U(")"));
511 | EqualityExpr TOK_OpNEq RelationalExpr
513 TRACE("Got EqualityExpr: \"%s $ne$ %s\"\n", $1, $3);
514 $$=$1;
515 $$=xmlStrcat($$,U("!="));
516 $$=xmlStrcat($$,$3);
517 xmlFree($3);
519 | EqualityExpr TOK_OpINEq RelationalExpr
521 TRACE("Got EqualityExpr: \"%s $ine$ %s\"\n", $1, $3);
522 $$=xmlStrdup(U("OP_INEq("));
523 $$=xmlStrcat($$,$1);
524 xmlFree($1);
525 $$=xmlStrcat($$,U(","));
526 $$=xmlStrcat($$,$3);
527 xmlFree($3);
528 $$=xmlStrcat($$,U(")"));
531 RelationalExpr : UnaryExpr
532 | BoolRelationalExpr
534 BoolRelationalExpr : RelationalExpr TOK_OpLt UnaryExpr
536 TRACE("Got RelationalExpr: \"%s $lt$ %s\"\n", $1, $3);
537 $$=$1;
538 $$=xmlStrcat($$,U("<"));
539 $$=xmlStrcat($$,$3);
540 xmlFree($3);
542 | RelationalExpr TOK_OpILt UnaryExpr
544 TRACE("Got RelationalExpr: \"%s $ilt$ %s\"\n", $1, $3);
545 $$=xmlStrdup(U("OP_ILt("));
546 $$=xmlStrcat($$,$1);
547 xmlFree($1);
548 $$=xmlStrcat($$,U(","));
549 $$=xmlStrcat($$,$3);
550 xmlFree($3);
551 $$=xmlStrcat($$,U(")"));
553 | RelationalExpr TOK_OpGt UnaryExpr
555 TRACE("Got RelationalExpr: \"%s $gt$ %s\"\n", $1, $3);
556 $$=$1;
557 $$=xmlStrcat($$,U(">"));
558 $$=xmlStrcat($$,$3);
559 xmlFree($3);
561 | RelationalExpr TOK_OpIGt UnaryExpr
563 TRACE("Got RelationalExpr: \"%s $igt$ %s\"\n", $1, $3);
564 $$=xmlStrdup(U("OP_IGt("));
565 $$=xmlStrcat($$,$1);
566 xmlFree($1);
567 $$=xmlStrcat($$,U(","));
568 $$=xmlStrcat($$,$3);
569 xmlFree($3);
570 $$=xmlStrcat($$,U(")"));
572 | RelationalExpr TOK_OpLEq UnaryExpr
574 TRACE("Got RelationalExpr: \"%s $le$ %s\"\n", $1, $3);
575 $$=$1;
576 $$=xmlStrcat($$,U("<="));
577 $$=xmlStrcat($$,$3);
578 xmlFree($3);
580 | RelationalExpr TOK_OpILEq UnaryExpr
582 TRACE("Got RelationalExpr: \"%s $ile$ %s\"\n", $1, $3);
583 $$=xmlStrdup(U("OP_ILEq("));
584 $$=xmlStrcat($$,$1);
585 xmlFree($1);
586 $$=xmlStrcat($$,U(","));
587 $$=xmlStrcat($$,$3);
588 xmlFree($3);
589 $$=xmlStrcat($$,U(")"));
591 | RelationalExpr TOK_OpGEq UnaryExpr
593 TRACE("Got RelationalExpr: \"%s $ge$ %s\"\n", $1, $3);
594 $$=$1;
595 $$=xmlStrcat($$,U(">="));
596 $$=xmlStrcat($$,$3);
597 xmlFree($3);
599 | RelationalExpr TOK_OpIGEq UnaryExpr
601 TRACE("Got RelationalExpr: \"%s $ige$ %s\"\n", $1, $3);
602 $$=xmlStrdup(U("OP_IGEq("));
603 $$=xmlStrcat($$,$1);
604 xmlFree($1);
605 $$=xmlStrcat($$,U(","));
606 $$=xmlStrcat($$,$3);
607 xmlFree($3);
608 $$=xmlStrcat($$,U(")"));
612 /* [3.5] Numbers */
613 UnaryExpr : UnionExpr
614 | BoolUnaryExpr
616 BoolUnaryExpr : TOK_OpNot UnaryExpr
618 TRACE("Got UnaryExpr: \"$not$ %s\"\n", $2);
619 $$=xmlStrdup(U(" not("));
620 $$=xmlStrcat($$,$2);
621 xmlFree($2);
622 $$=xmlStrcat($$,U(")"));
624 | TOK_OpAny Expr
626 TRACE("Got UnaryExpr: \"$any$ %s\"\n", $2);
627 $$=xmlStrdup(U("boolean("));
628 $$=xmlStrcat($$,$2);
629 xmlFree($2);
630 $$=xmlStrcat($$,U(")"));
632 | TOK_OpAll AllExpr
634 TRACE("Got UnaryExpr: \"$all$ %s\"\n", $2);
635 $$=xmlStrdup(U("not("));
636 $$=xmlStrcat($$,$2);
637 xmlFree($2);
638 $$=xmlStrcat($$,U(")"));
640 | TOK_OpAll
642 FIXME("Unrecognized $all$ expression - ignoring\n");
643 $$=xmlStrdup(U(""));
646 AllExpr : PathExpr TOK_OpEq PathExpr
648 $$=$1;
649 $$=xmlStrcat($$,U("!="));
650 $$=xmlStrcat($$,$3);
651 xmlFree($3);
653 | PathExpr TOK_OpNEq PathExpr
655 $$=$1;
656 $$=xmlStrcat($$,U("="));
657 $$=xmlStrcat($$,$3);
658 xmlFree($3);
660 | PathExpr TOK_OpLt PathExpr
662 $$=$1;
663 $$=xmlStrcat($$,U(">="));
664 $$=xmlStrcat($$,$3);
665 xmlFree($3);
667 | PathExpr TOK_OpLEq PathExpr
669 $$=$1;
670 $$=xmlStrcat($$,U(">"));
671 $$=xmlStrcat($$,$3);
672 xmlFree($3);
674 | PathExpr TOK_OpGt PathExpr
676 $$=$1;
677 $$=xmlStrcat($$,U("<="));
678 $$=xmlStrcat($$,$3);
679 xmlFree($3);
681 | PathExpr TOK_OpGEq PathExpr
683 $$=$1;
684 $$=xmlStrcat($$,U("<"));
685 $$=xmlStrcat($$,$3);
686 xmlFree($3);
688 | PathExpr TOK_OpIEq PathExpr
690 $$=xmlStrdup(U("OP_INEq("));
691 $$=xmlStrcat($$,$1);
692 xmlFree($1);
693 $$=xmlStrcat($$,U(","));
694 $$=xmlStrcat($$,$3);
695 xmlFree($3);
696 $$=xmlStrcat($$,U(")"));
698 | PathExpr TOK_OpINEq PathExpr
700 $$=xmlStrdup(U("OP_IEq("));
701 $$=xmlStrcat($$,$1);
702 xmlFree($1);
703 $$=xmlStrcat($$,U(","));
704 $$=xmlStrcat($$,$3);
705 xmlFree($3);
706 $$=xmlStrcat($$,U(")"));
708 | PathExpr TOK_OpILt PathExpr
710 $$=xmlStrdup(U("OP_IGEq("));
711 $$=xmlStrcat($$,$1);
712 xmlFree($1);
713 $$=xmlStrcat($$,U(","));
714 $$=xmlStrcat($$,$3);
715 xmlFree($3);
716 $$=xmlStrcat($$,U(")"));
718 | PathExpr TOK_OpILEq PathExpr
720 $$=xmlStrdup(U("OP_IGt("));
721 $$=xmlStrcat($$,$1);
722 xmlFree($1);
723 $$=xmlStrcat($$,U(","));
724 $$=xmlStrcat($$,$3);
725 xmlFree($3);
726 $$=xmlStrcat($$,U(")"));
728 | PathExpr TOK_OpIGt PathExpr
730 $$=xmlStrdup(U("OP_ILEq("));
731 $$=xmlStrcat($$,$1);
732 xmlFree($1);
733 $$=xmlStrcat($$,U(","));
734 $$=xmlStrcat($$,$3);
735 xmlFree($3);
736 $$=xmlStrcat($$,U(")"));
738 | PathExpr TOK_OpIGEq PathExpr
740 $$=xmlStrdup(U("OP_ILt("));
741 $$=xmlStrcat($$,$1);
742 xmlFree($1);
743 $$=xmlStrcat($$,U(","));
744 $$=xmlStrcat($$,$3);
745 xmlFree($3);
746 $$=xmlStrcat($$,U(")"));