clock: Update Korean resource.
[wine/multimedia.git] / dlls / msxml3 / xslpattern.y
blob2e20328931ef60c227cf13c9920576b16db64e64
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 "config.h"
23 #include "wine/port.h"
25 #ifdef HAVE_LIBXML2
26 #include "xslpattern.h"
27 #include <libxml/xpathInternals.h>
29 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
32 static const xmlChar NameTest_mod_pre[] = "*[name()='";
33 static const xmlChar NameTest_mod_post[] = "']";
35 #define U(str) BAD_CAST str
37 static inline BOOL is_literal(xmlChar const* tok)
39 return (tok && tok[0] && tok[1] &&
40 tok[0]== tok[xmlStrlen(tok)-1] &&
41 (tok[0] == '\'' || tok[0] == '"'));
46 %token TOK_Parent TOK_Self TOK_DblFSlash TOK_FSlash TOK_Axis TOK_Colon
47 %token TOK_OpAnd TOK_OpOr TOK_OpNot
48 %token TOK_OpEq TOK_OpIEq TOK_OpNEq TOK_OpINEq
49 %token TOK_OpLt TOK_OpILt TOK_OpGt TOK_OpIGt TOK_OpLEq TOK_OpILEq TOK_OpGEq TOK_OpIGEq
50 %token TOK_OpAll TOK_OpAny
51 %token TOK_NCName TOK_Literal TOK_Number
53 %start XSLPattern
55 %pure_parser
56 %parse-param {parser_param* p}
57 %parse-param {void* scanner}
58 %lex-param {yyscan_t* scanner}
60 %left TOK_OpAnd TOK_OpOr
61 %left TOK_OpEq TOK_OpIEq TOK_OpNEq TOK_OpINEq
62 %left TOK_OpLt TOK_OpILt TOK_OpGt TOK_OpIGt TOK_OpLEq TOK_OpILEq TOK_OpGEq TOK_OpIGEq
64 %expect 14
68 XSLPattern : Expr
70 p->out = $1;
74 /* Mostly verbatim from the w3c XML Namespaces standard.
75 * <http://www.w3.org/TR/REC-xml-names/> */
77 /* [4] Qualified Names */
78 QName : PrefixedName
79 | UnprefixedName
81 PrefixedName : TOK_NCName TOK_Colon TOK_NCName
83 TRACE("Got PrefixedName: \"%s:%s\"\n", $1, $3);
84 $$=$1;
85 $$=xmlStrcat($$,U(":"));
86 $$=xmlStrcat($$,$3);
87 xmlFree($3);
90 UnprefixedName : TOK_NCName
92 TRACE("Got UnprefixedName: \"%s\"\n", $1);
93 $$=$1;
97 /* Based on the w3c XPath standard, adapted where needed.
98 * <http://www.w3.org/TR/xpath/> */
100 /* [2] Location Paths */
101 LocationPath : RelativeLocationPath
102 | AbsoluteLocationPath
104 AbsoluteLocationPath : TOK_FSlash RelativeLocationPath
106 TRACE("Got AbsoluteLocationPath: \"/%s\"\n", $2);
107 $$=xmlStrdup(U("/"));
108 $$=xmlStrcat($$,$2);
109 xmlFree($2);
111 | TOK_FSlash
113 TRACE("Got AbsoluteLocationPath: \"/\"\n");
114 $$=xmlStrdup(U("/"));
116 | AbbreviatedAbsoluteLocationPath
118 RelativeLocationPath : Step
119 | RelativeLocationPath TOK_FSlash Step
121 TRACE("Got RelativeLocationPath: \"%s/%s\"\n", $1, $3);
122 $$=$1;
123 $$=xmlStrcat($$,U("/"));
124 $$=xmlStrcat($$,$3);
125 xmlFree($3);
127 | AbbreviatedRelativeLocationPath
129 /* [2.1] Location Steps */
130 Step : AxisSpecifier NodeTest Predicates
132 TRACE("Got Step: \"%s%s%s\"\n", $1, $2, $3);
133 $$=$1;
134 $$=xmlStrcat($$,$2);
135 xmlFree($2);
136 $$=xmlStrcat($$,$3);
137 xmlFree($3);
139 | NodeTest Predicates
141 TRACE("Got Step: \"%s%s\"\n", $1, $2);
142 $$=$1;
143 $$=xmlStrcat($$,$2);
144 xmlFree($2);
146 | AxisSpecifier NodeTest
148 TRACE("Got Step: \"%s%s\"\n", $1, $2);
149 $$=$1;
150 $$=xmlStrcat($$,$2);
151 xmlFree($2);
153 | NodeTest
154 | Attribute
155 | AbbreviatedStep
157 AxisSpecifier : TOK_NCName TOK_Axis
159 TRACE("Got AxisSpecifier: \"%s::\"\n", $1);
160 $$=$1;
161 $$=xmlStrcat($$,U("::"));
164 Attribute : '@' TOK_NCName
166 TRACE("Got Attribute: \"@%s\"\n", $2);
167 $$=xmlStrdup(U("@"));
168 $$=xmlStrcat($$,$2);
169 xmlFree($2);
173 /* [2.3] Node Tests */
174 NodeTest : NameTest
175 | FunctionCall
177 NameTest : '*'
179 TRACE("Got NameTest: \"*\"\n");
180 $$=xmlStrdup(U("*"));
182 | TOK_NCName TOK_Colon '*'
184 TRACE("Got NameTest: \"%s:*\"\n", $1);
185 $$=$1;
186 $$=xmlStrcat($$,U(":*"));
188 | TOK_NCName TOK_Colon TOK_NCName
189 { /* PrefixedName */
190 xmlChar const* registeredNsURI = xmlXPathNsLookup(p->ctx, $1);
191 TRACE("Got PrefixedName: \"%s:%s\"\n", $1, $3);
193 if (registeredNsURI)
194 $$=xmlStrdup(U(""));
195 else
196 $$=xmlStrdup(NameTest_mod_pre);
198 $$=xmlStrcat($$,$1);
199 xmlFree($1);
200 $$=xmlStrcat($$,U(":"));
201 $$=xmlStrcat($$,$3);
202 xmlFree($3);
204 if (!registeredNsURI)
205 $$=xmlStrcat($$,NameTest_mod_post);
207 | UnprefixedName
209 $$=xmlStrdup(NameTest_mod_pre);
210 $$=xmlStrcat($$,$1);
211 xmlFree($1);
212 $$=xmlStrcat($$,NameTest_mod_post);
214 /* [2.4] Predicates */
215 Predicates : Predicates Predicate
217 $$=$1;
218 $$=xmlStrcat($$,$2);
219 xmlFree($2);
221 | Predicate
223 Predicate : '[' PredicateExpr ']'
225 TRACE("Got Predicate: \"[%s]\"\n", $2);
226 $$=xmlStrdup(U("["));
227 $$=xmlStrcat($$,$2);
228 xmlFree($2);
229 $$=xmlStrcat($$,U("]"));
232 PredicateExpr : TOK_Number
234 $$=xmlStrdup(U("index()="));
235 $$=xmlStrcat($$,$1);
236 xmlFree($1);
238 | BoolExpr
239 | Attribute
241 /* [2.5] Abbreviated Syntax */
242 AbbreviatedAbsoluteLocationPath : TOK_DblFSlash RelativeLocationPath
244 TRACE("Got AbbreviatedAbsoluteLocationPath: \"//%s\"\n", $2);
245 $$=xmlStrdup(U("//"));
246 $$=xmlStrcat($$,$2);
247 xmlFree($2);
250 AbbreviatedRelativeLocationPath : RelativeLocationPath TOK_DblFSlash Step
252 TRACE("Got AbbreviatedRelativeLocationPath: \"%s//%s\"\n", $1, $3);
253 $$=$1;
254 $$=xmlStrcat($$,U("//"));
255 $$=xmlStrcat($$,$3);
256 xmlFree($3);
259 AbbreviatedStep : TOK_Parent
261 TRACE("Got AbbreviatedStep: \"..\"\n");
262 $$=xmlStrdup(U(".."));
264 | TOK_Self
266 TRACE("Got AbbreviatedStep: \".\"\n");
267 $$=xmlStrdup(U("."));
271 /* [3] Expressions */
272 /* [3.1] Basics */
273 Expr : OrExpr
275 BoolExpr : FunctionCall
276 | BoolUnaryExpr
277 | BoolRelationalExpr
278 | BoolEqualityExpr
279 | BoolAndExpr
280 | BoolOrExpr
282 PrimaryExpr : '(' Expr ')'
284 TRACE("Got PrimaryExpr: \"(%s)\"\n", $1);
285 $$=xmlStrdup(U("("));
286 $$=xmlStrcat($$,$2);
287 xmlFree($2);
288 $$=xmlStrcat($$,U(")"));
290 | PathExpr '!' FunctionCall
292 TRACE("Got PrimaryExpr: \"%s!%s\"\n", $1, $3);
293 $$=$1;
294 $$=xmlStrcat($$,U("/"));
295 $$=xmlStrcat($$,$3);
296 xmlFree($3);
298 | TOK_Literal
299 | TOK_Number
301 /* [3.2] Function Calls */
302 FunctionCall : QName '(' Arguments ')'
304 TRACE("Got FunctionCall: \"%s(%s)\"\n", $1, $3);
305 if (xmlStrEqual($1,U("ancestor")))
307 $$=$1;
308 $$=xmlStrcat($$,U("::"));
309 $$=xmlStrcat($$,$3);
310 xmlFree($3);
312 else if (xmlStrEqual($1,U("attribute")))
314 if (is_literal($3))
316 $$=xmlStrdup(U("@*[name()="));
317 xmlFree($1);
318 $$=xmlStrcat($$,$3);
319 xmlFree($3);
320 $$=xmlStrcat($$,U("]"));
322 else
324 /* XML_XPATH_INVALID_TYPE */
325 $$=xmlStrdup(U("error(1211, 'Error: attribute("));
326 xmlFree($1);
327 $$=xmlStrcat($$,$3);
328 xmlFree($3);
329 $$=xmlStrcat($$,U("): invalid argument')"));
332 else if (xmlStrEqual($1,U("element")))
334 if (is_literal($3))
336 $$=xmlStrdup(U("node()[nodeType()=1][name()="));
337 xmlFree($1);
338 $$=xmlStrcat($$,$3);
339 xmlFree($3);
340 $$=xmlStrcat($$,U("]"));
342 else
344 /* XML_XPATH_INVALID_TYPE */
345 $$=xmlStrdup(U("error(1211, 'Error: element("));
346 xmlFree($1);
347 $$=xmlStrcat($$,$3);
348 xmlFree($3);
349 $$=xmlStrcat($$,U("): invalid argument')"));
352 else
354 $$=$1;
355 $$=xmlStrcat($$,U("("));
356 $$=xmlStrcat($$,$3);
357 xmlFree($3);
358 $$=xmlStrcat($$,U(")"));
361 | QName '(' ')'
363 TRACE("Got FunctionCall: \"%s()\"\n", $1);
364 /* comment() & node() work the same in XPath */
365 if (xmlStrEqual($1,U("attribute")))
367 $$=xmlStrdup(U("@*"));
368 xmlFree($1);
370 else if (xmlStrEqual($1,U("element")))
372 $$=xmlStrdup(U("node()[nodeType()=1]"));
373 xmlFree($1);
375 else if (xmlStrEqual($1,U("pi")))
377 $$=xmlStrdup(U("processing-instruction()"));
378 xmlFree($1);
380 else if (xmlStrEqual($1,U("textnode")))
382 $$=xmlStrdup(U("text()"));
383 xmlFree($1);
385 else
387 $$=$1;
388 $$=xmlStrcat($$,U("()"));
392 Arguments : Argument ',' Arguments
394 $$=$1;
395 $$=xmlStrcat($$,U(","));
396 $$=xmlStrcat($$,$3);
397 xmlFree($3);
399 | Argument
401 Argument : Expr
403 /* [3.3] Node-sets */
404 UnionExpr : PathExpr
405 | UnionExpr '|' PathExpr
407 TRACE("Got UnionExpr: \"%s|%s\"\n", $1, $3);
408 $$=$1;
409 $$=xmlStrcat($$,U("|"));
410 $$=xmlStrcat($$,$3);
411 xmlFree($3);
414 PathExpr : LocationPath
415 | FilterExpr TOK_FSlash RelativeLocationPath
417 TRACE("Got PathExpr: \"%s/%s\"\n", $1, $3);
418 $$=$1;
419 $$=xmlStrcat($$,U("/"));
420 $$=xmlStrcat($$,$3);
421 xmlFree($3);
423 | FilterExpr TOK_DblFSlash RelativeLocationPath
425 TRACE("Got PathExpr: \"%s//%s\"\n", $1, $3);
426 $$=$1;
427 $$=xmlStrcat($$,U("//"));
428 $$=xmlStrcat($$,$3);
429 xmlFree($3);
431 | FilterExpr
433 FilterExpr : PrimaryExpr
434 | FilterExpr Predicate
436 TRACE("Got FilterExpr: \"%s%s\"\n", $1, $2);
437 $$=$1;
438 $$=xmlStrcat($$,$2);
439 xmlFree($2);
442 /* [3.4] Booleans */
443 OrExpr : AndExpr
444 | BoolOrExpr
446 BoolOrExpr : OrExpr TOK_OpOr AndExpr
448 TRACE("Got OrExpr: \"%s $or$ %s\"\n", $1, $3);
449 $$=$1;
450 $$=xmlStrcat($$,U(" or "));
451 $$=xmlStrcat($$,$3);
452 xmlFree($3);
455 AndExpr : EqualityExpr
456 | BoolAndExpr
458 BoolAndExpr : AndExpr TOK_OpAnd EqualityExpr
460 TRACE("Got AndExpr: \"%s $and$ %s\"\n", $1, $3);
461 $$=$1;
462 $$=xmlStrcat($$,U(" and "));
463 $$=xmlStrcat($$,$3);
464 xmlFree($3);
467 EqualityExpr : RelationalExpr
468 | BoolEqualityExpr
470 BoolEqualityExpr : EqualityExpr TOK_OpEq RelationalExpr
472 TRACE("Got EqualityExpr: \"%s $eq$ %s\"\n", $1, $3);
473 $$=$1;
474 $$=xmlStrcat($$,U("="));
475 $$=xmlStrcat($$,$3);
476 xmlFree($3);
478 | EqualityExpr TOK_OpIEq RelationalExpr
480 TRACE("Got EqualityExpr: \"%s $ieq$ %s\"\n", $1, $3);
481 $$=xmlStrdup(U("OP_IEq("));
482 $$=xmlStrcat($$,$1);
483 xmlFree($1);
484 $$=xmlStrcat($$,U(","));
485 $$=xmlStrcat($$,$3);
486 xmlFree($3);
487 $$=xmlStrcat($$,U(")"));
489 | EqualityExpr TOK_OpNEq RelationalExpr
491 TRACE("Got EqualityExpr: \"%s $ne$ %s\"\n", $1, $3);
492 $$=$1;
493 $$=xmlStrcat($$,U("!="));
494 $$=xmlStrcat($$,$3);
495 xmlFree($3);
497 | EqualityExpr TOK_OpINEq RelationalExpr
499 TRACE("Got EqualityExpr: \"%s $ine$ %s\"\n", $1, $3);
500 $$=xmlStrdup(U("OP_INEq("));
501 $$=xmlStrcat($$,$1);
502 xmlFree($1);
503 $$=xmlStrcat($$,U(","));
504 $$=xmlStrcat($$,$3);
505 xmlFree($3);
506 $$=xmlStrcat($$,U(")"));
509 RelationalExpr : UnaryExpr
510 | BoolRelationalExpr
512 BoolRelationalExpr : RelationalExpr TOK_OpLt UnaryExpr
514 TRACE("Got RelationalExpr: \"%s $lt$ %s\"\n", $1, $3);
515 $$=$1;
516 $$=xmlStrcat($$,U("<"));
517 $$=xmlStrcat($$,$3);
518 xmlFree($3);
520 | RelationalExpr TOK_OpILt UnaryExpr
522 TRACE("Got RelationalExpr: \"%s $ilt$ %s\"\n", $1, $3);
523 $$=xmlStrdup(U("OP_ILt("));
524 $$=xmlStrcat($$,$1);
525 xmlFree($1);
526 $$=xmlStrcat($$,U(","));
527 $$=xmlStrcat($$,$3);
528 xmlFree($3);
529 $$=xmlStrcat($$,U(")"));
531 | RelationalExpr TOK_OpGt UnaryExpr
533 TRACE("Got RelationalExpr: \"%s $gt$ %s\"\n", $1, $3);
534 $$=$1;
535 $$=xmlStrcat($$,U(">"));
536 $$=xmlStrcat($$,$3);
537 xmlFree($3);
539 | RelationalExpr TOK_OpIGt UnaryExpr
541 TRACE("Got RelationalExpr: \"%s $igt$ %s\"\n", $1, $3);
542 $$=xmlStrdup(U("OP_IGt("));
543 $$=xmlStrcat($$,$1);
544 xmlFree($1);
545 $$=xmlStrcat($$,U(","));
546 $$=xmlStrcat($$,$3);
547 xmlFree($3);
548 $$=xmlStrcat($$,U(")"));
550 | RelationalExpr TOK_OpLEq UnaryExpr
552 TRACE("Got RelationalExpr: \"%s $le$ %s\"\n", $1, $3);
553 $$=$1;
554 $$=xmlStrcat($$,U("<="));
555 $$=xmlStrcat($$,$3);
556 xmlFree($3);
558 | RelationalExpr TOK_OpILEq UnaryExpr
560 TRACE("Got RelationalExpr: \"%s $ile$ %s\"\n", $1, $3);
561 $$=xmlStrdup(U("OP_ILEq("));
562 $$=xmlStrcat($$,$1);
563 xmlFree($1);
564 $$=xmlStrcat($$,U(","));
565 $$=xmlStrcat($$,$3);
566 xmlFree($3);
567 $$=xmlStrcat($$,U(")"));
569 | RelationalExpr TOK_OpGEq UnaryExpr
571 TRACE("Got RelationalExpr: \"%s $ge$ %s\"\n", $1, $3);
572 $$=$1;
573 $$=xmlStrcat($$,U(">="));
574 $$=xmlStrcat($$,$3);
575 xmlFree($3);
577 | RelationalExpr TOK_OpIGEq UnaryExpr
579 TRACE("Got RelationalExpr: \"%s $ige$ %s\"\n", $1, $3);
580 $$=xmlStrdup(U("OP_IGEq("));
581 $$=xmlStrcat($$,$1);
582 xmlFree($1);
583 $$=xmlStrcat($$,U(","));
584 $$=xmlStrcat($$,$3);
585 xmlFree($3);
586 $$=xmlStrcat($$,U(")"));
590 /* [3.5] Numbers */
591 UnaryExpr : UnionExpr
592 | BoolUnaryExpr
594 BoolUnaryExpr : TOK_OpNot UnaryExpr
596 TRACE("Got UnaryExpr: \"$not$ %s\"\n", $2);
597 $$=xmlStrdup(U(" not("));
598 $$=xmlStrcat($$,$2);
599 xmlFree($2);
600 $$=xmlStrcat($$,U(")"));
602 | TOK_OpAny Expr
604 TRACE("Got UnaryExpr: \"$any$ %s\"\n", $2);
605 $$=xmlStrdup(U("boolean("));
606 $$=xmlStrcat($$,$2);
607 xmlFree($2);
608 $$=xmlStrcat($$,U(")"));
610 | TOK_OpAll AllExpr
612 TRACE("Got UnaryExpr: \"$all$ %s\"\n", $2);
613 $$=xmlStrdup(U("not("));
614 $$=xmlStrcat($$,$2);
615 xmlFree($2);
616 $$=xmlStrcat($$,U(")"));
618 | TOK_OpAll
620 FIXME("Unrecognized $all$ expression - ignoring\n");
621 $$=xmlStrdup(U(""));
624 AllExpr : PathExpr TOK_OpEq PathExpr
626 $$=$1;
627 $$=xmlStrcat($$,U("!="));
628 $$=xmlStrcat($$,$3);
629 xmlFree($3);
631 | PathExpr TOK_OpNEq PathExpr
633 $$=$1;
634 $$=xmlStrcat($$,U("="));
635 $$=xmlStrcat($$,$3);
636 xmlFree($3);
638 | PathExpr TOK_OpLt PathExpr
640 $$=$1;
641 $$=xmlStrcat($$,U(">="));
642 $$=xmlStrcat($$,$3);
643 xmlFree($3);
645 | PathExpr TOK_OpLEq PathExpr
647 $$=$1;
648 $$=xmlStrcat($$,U(">"));
649 $$=xmlStrcat($$,$3);
650 xmlFree($3);
652 | PathExpr TOK_OpGt PathExpr
654 $$=$1;
655 $$=xmlStrcat($$,U("<="));
656 $$=xmlStrcat($$,$3);
657 xmlFree($3);
659 | PathExpr TOK_OpGEq PathExpr
661 $$=$1;
662 $$=xmlStrcat($$,U("<"));
663 $$=xmlStrcat($$,$3);
664 xmlFree($3);
666 | PathExpr TOK_OpIEq PathExpr
668 $$=xmlStrdup(U("OP_INEq("));
669 $$=xmlStrcat($$,$1);
670 xmlFree($1);
671 $$=xmlStrcat($$,U(","));
672 $$=xmlStrcat($$,$3);
673 xmlFree($3);
674 $$=xmlStrcat($$,U(")"));
676 | PathExpr TOK_OpINEq PathExpr
678 $$=xmlStrdup(U("OP_IEq("));
679 $$=xmlStrcat($$,$1);
680 xmlFree($1);
681 $$=xmlStrcat($$,U(","));
682 $$=xmlStrcat($$,$3);
683 xmlFree($3);
684 $$=xmlStrcat($$,U(")"));
686 | PathExpr TOK_OpILt PathExpr
688 $$=xmlStrdup(U("OP_IGEq("));
689 $$=xmlStrcat($$,$1);
690 xmlFree($1);
691 $$=xmlStrcat($$,U(","));
692 $$=xmlStrcat($$,$3);
693 xmlFree($3);
694 $$=xmlStrcat($$,U(")"));
696 | PathExpr TOK_OpILEq PathExpr
698 $$=xmlStrdup(U("OP_IGt("));
699 $$=xmlStrcat($$,$1);
700 xmlFree($1);
701 $$=xmlStrcat($$,U(","));
702 $$=xmlStrcat($$,$3);
703 xmlFree($3);
704 $$=xmlStrcat($$,U(")"));
706 | PathExpr TOK_OpIGt PathExpr
708 $$=xmlStrdup(U("OP_ILEq("));
709 $$=xmlStrcat($$,$1);
710 xmlFree($1);
711 $$=xmlStrcat($$,U(","));
712 $$=xmlStrcat($$,$3);
713 xmlFree($3);
714 $$=xmlStrcat($$,U(")"));
716 | PathExpr TOK_OpIGEq PathExpr
718 $$=xmlStrdup(U("OP_ILt("));
719 $$=xmlStrcat($$,$1);
720 xmlFree($1);
721 $$=xmlStrcat($$,U(","));
722 $$=xmlStrcat($$,$3);
723 xmlFree($3);
724 $$=xmlStrcat($$,U(")"));
730 void xslpattern_error(parser_param* param, void const* scanner, char const* msg)
732 FIXME("%s:\n"
733 " param {\n"
734 " yyscanner=%p\n"
735 " ctx=%p\n"
736 " in=\"%s\"\n"
737 " pos=%i\n"
738 " len=%i\n"
739 " out=\"%s\"\n"
740 " err=%i\n"
741 " }\n"
742 " scanner=%p\n",
743 msg, param->yyscanner, param->ctx, param->in, param->pos,
744 param->len, param->out, ++param->err, scanner);
748 #endif /* HAVE_LIBXML2 */