2 // XPath/XSLT Pattern parser
4 // Author: Piers Haken <piersh@friskit.com>
5 // Atsushi Enomoto <atsushi@ximian.com>
8 // Do not edit "PatternParser.jay". It is autogenerated from
9 // Parser.jay. It will be overwritten!
13 using System.Collections;
15 using System.Xml.XPath;
18 namespace Mono.Xml.Xsl
20 namespace Mono.Xml.XPath
24 internal class XsltPatternParser
26 internal class XPathParser
30 internal System.Xml.Xsl.IStaticXsltContext Context;
33 public XsltPatternParser () : this (null) {}
34 internal XsltPatternParser (System.Xml.Xsl.IStaticXsltContext context)
36 public XPathParser () : this (null) {}
37 internal XPathParser (System.Xml.Xsl.IStaticXsltContext context)
41 ErrorOutput = System.IO.TextWriter.Null;
42 // debug = new yydebug.yyDebugSimple ();
45 internal Expression Compile (string xpath)
48 Tokenizer tokenizer = new Tokenizer (xpath);
49 return (Expression) yyparse (tokenizer);
50 } catch (XPathException) {
52 } catch (Exception e) {
53 throw new XPathException ("Error during parse of " + xpath, e);
56 static int yacc_verbose_flag;
58 private NodeSet CreateNodeTest (Axes axis, object nodeTest, ArrayList plist)
60 NodeSet test = CreateNodeTest (axis, nodeTest);
62 for (int i = 0; i < plist.Count; i++)
63 test = new ExprFilter (test,
64 (Expression) plist [i]);
69 private NodeTest CreateNodeTest (Axes axis, object test)
71 if (test is XPathNodeType)
72 return new NodeTypeTest (axis,
73 (XPathNodeType) test, null);
74 else if (test is string || test == null)
75 return new NodeTypeTest (axis,
76 XPathNodeType.ProcessingInstruction,
78 XmlQualifiedName q = (XmlQualifiedName) test;
79 if (q == XmlQualifiedName.Empty)
80 return new NodeTypeTest (axis);
82 return new NodeNameTest (axis, q, Context);
99 %token BRACKET_OPEN "["
100 %token BRACKET_CLOSE "]"
101 %token PAREN_OPEN "("
102 %token PAREN_CLOSE ")"
120 %token ANCESTOR "ancestor"
121 %token ANCESTOR_OR_SELF "ancstor-or-self"
122 %token ATTRIBUTE "attribute"
124 %token DESCENDANT "descendant"
125 %token DESCENDANT_OR_SELF "descendant-or-self"
126 %token FOLLOWING "following"
127 %token FOLLOWING_SIBLING "sibling"
128 %token NAMESPACE "NameSpace"
129 %token PARENT "parent"
130 %token PRECEDING "preceding"
131 %token PRECEDING_SIBLING "preceding-sibling"
134 %token COMMENT "comment"
136 %token PROCESSING_INSTRUCTION "processing-instruction"
168 : LocationPathPattern
169 | Pattern BAR LocationPathPattern
171 $$ = new ExprUNION ((NodeSet) $1, (NodeSet) $3);
178 $$ = new ExprRoot ();
180 | SLASH RelativePathPattern
182 $$ = new ExprSLASH (new ExprRoot (), (NodeSet) $2);
185 | IdKeyPattern SLASH RelativePathPattern
187 $$ = new ExprSLASH ((Expression) $1, (NodeSet) $3);
189 | IdKeyPattern SLASH2 RelativePathPattern
191 $$ = new ExprSLASH2 ((Expression) $1, (NodeSet) $3);
193 | SLASH2 RelativePathPattern
195 $$ = new ExprSLASH2 (new ExprRoot (), (NodeSet) $2);
197 | RelativePathPattern
200 // to avoid context-sensitive tokenizer, I just reuse FUNCTION_NAME
202 : FUNCTION_NAME PAREN_OPEN LITERAL PAREN_CLOSE
204 XmlQualifiedName name = (XmlQualifiedName) $1;
205 if (name.Name != "id" || name.Namespace != String.Empty)
206 throw new XPathException (String.Format ("Expected 'id' but got '{0}'", name));
207 $$ = ExprFunctionCall.Factory (name,
208 new FunctionArguments (
209 new ExprLiteral ((string) $3),
213 | FUNCTION_NAME PAREN_OPEN LITERAL COMMA LITERAL PAREN_CLOSE
215 XmlQualifiedName name = (XmlQualifiedName) $1;
216 if (name.Name != "key" || name.Namespace != String.Empty)
217 throw new XPathException (String.Format ("Expected 'key' but got '{0}'", name));
218 $$ = Context.TryGetFunction (name,
219 new FunctionArguments (
220 new ExprLiteral ((string) $3),
221 new FunctionArguments (
222 new ExprLiteral ((string) $5),
229 | RelativePathPattern SLASH StepPattern
231 $$ = new ExprSLASH ((Expression) $1, (NodeSet) $3);
233 | RelativePathPattern SLASH2 StepPattern
235 $$ = new ExprSLASH2 ((Expression) $1, (NodeSet) $3);
240 : ChildOrAttributeAxisSpecifier NodeTest Predicates
242 $$ = CreateNodeTest ((Axes) $1, $2, (ArrayList) $3);
246 ChildOrAttributeAxisSpecifier
247 : AbbreviatedAxisSpecifier
263 | Predicates Predicate
265 ArrayList al = (ArrayList) $1;
267 al = new ArrayList ();
268 al.Add ((Expression) $2);
273 /* ---- end of XSLT Pattern ---- */
284 $$ = new ExprOR ((Expression) $1, (Expression) $3);
290 | AndExpr AND EqualityExpr
292 $$ = new ExprAND ((Expression) $1, (Expression) $3);
298 | EqualityExpr EQ RelationalExpr
300 $$ = new ExprEQ ((Expression) $1, (Expression) $3);
302 | EqualityExpr NE RelationalExpr
304 $$ = new ExprNE ((Expression) $1, (Expression) $3);
310 | RelationalExpr LT AdditiveExpr
312 $$ = new ExprLT ((Expression) $1, (Expression) $3);
314 | RelationalExpr GT AdditiveExpr
316 $$ = new ExprGT ((Expression) $1, (Expression) $3);
318 | RelationalExpr LE AdditiveExpr
320 $$ = new ExprLE ((Expression) $1, (Expression) $3);
322 | RelationalExpr GE AdditiveExpr
324 $$ = new ExprGE ((Expression) $1, (Expression) $3);
330 | AdditiveExpr PLUS MultiplicativeExpr
332 $$ = new ExprPLUS ((Expression) $1, (Expression) $3);
334 | AdditiveExpr MINUS MultiplicativeExpr
336 $$ = new ExprMINUS ((Expression) $1, (Expression) $3);
342 | MultiplicativeExpr MULTIPLY UnaryExpr
344 $$ = new ExprMULT ((Expression) $1, (Expression) $3);
346 | MultiplicativeExpr DIV UnaryExpr
348 $$ = new ExprDIV ((Expression) $1, (Expression) $3);
350 | MultiplicativeExpr MOD UnaryExpr
352 $$ = new ExprMOD ((Expression) $1, (Expression) $3);
360 $$ = new ExprNEG ((Expression) $2);
366 | UnionExpr BAR PathExpr
368 $$ = new ExprUNION ((Expression) $1, (Expression) $3);
375 | FilterExpr SLASH RelativeLocationPath
377 $$ = new ExprSLASH ((Expression) $1, (NodeSet) $3);
379 | FilterExpr SLASH2 RelativeLocationPath
381 $$ = new ExprSLASH2 ((Expression) $1, (NodeSet) $3);
386 : RelativeLocationPath
387 | AbsoluteLocationPath
393 $$ = new ExprRoot ();
395 | SLASH RelativeLocationPath
397 $$ = new ExprSLASH (new ExprRoot (), (NodeSet) $2);
399 | SLASH2 RelativeLocationPath
401 $$ = new ExprSLASH2 (new ExprRoot (), (NodeSet) $2);
407 | RelativeLocationPath SLASH Step
409 $$ = new ExprSLASH ((NodeSet) $1, (NodeSet) $3);
411 | RelativeLocationPath SLASH2 Step
413 $$ = new ExprSLASH2 ((NodeSet) $1, (NodeSet) $3);
418 : AxisSpecifier NodeTest Predicates
420 $$ = CreateNodeTest ((Axes) $1, $2, (ArrayList) $3);
425 NodeTest // QName, XPathNodeType or string
427 | NodeType PAREN_OPEN PAREN_CLOSE
429 $$ = (XPathNodeType) $1;
431 | PROCESSING_INSTRUCTION PAREN_OPEN OptionalLiteral PAREN_CLOSE
440 $$ = XmlQualifiedName.Empty;
442 | QName // token QName also contains "blah:*"
448 $$ = new NodeTypeTest (Axes.Self, XPathNodeType.All);
452 $$ = new NodeTypeTest (Axes.Parent, XPathNodeType.All);
461 | Predicates Predicate
463 ArrayList al = (ArrayList) $1;
465 al = new ArrayList ();
476 | AbbreviatedAxisSpecifier
479 AbbreviatedAxisSpecifier
491 : COMMENT { $$ = XPathNodeType.Comment; }
492 | TEXT { $$ = XPathNodeType.Text; }
493 | PROCESSING_INSTRUCTION { $$ = XPathNodeType.ProcessingInstruction; }
494 | NODE { $$ = XPathNodeType.All; }
500 | FilterExpr Predicate
502 $$ = new ExprFilter ((Expression) $1, (Expression) $2);
509 Expression ret = null;
511 ret = Context.TryGetVariable (((XmlQualifiedName) $2).ToString ());
514 ret = new ExprVariable ((XmlQualifiedName) $2, Context);
518 | PAREN_OPEN Expr PAREN_CLOSE
520 $$ = new ExprParens ((Expression) $2);
524 $$ = new ExprLiteral ((String) $1);
528 $$ = new ExprNumber ((double) $1);
534 : FUNCTION_NAME PAREN_OPEN OptionalArgumentList PAREN_CLOSE
536 Expression ret = null;
538 ret = Context.TryGetFunction ((XmlQualifiedName) $1, (FunctionArguments) $3);
540 ret = ExprFunctionCall.Factory ((XmlQualifiedName) $1, (FunctionArguments) $3, Context);
548 | Expr OptionalArgumentListTail
550 $$ = new FunctionArguments ((Expression) $1, (FunctionArguments) $2);
554 OptionalArgumentListTail
556 | COMMA Expr OptionalArgumentListTail
558 $$ = new FunctionArguments ((Expression) $2, (FunctionArguments) $3);
563 : BRACKET_OPEN Expr BRACKET_CLOSE
570 : ANCESTOR { $$ = Axes.Ancestor; }
571 | ANCESTOR_OR_SELF { $$ = Axes.AncestorOrSelf; }
572 | ATTRIBUTE { $$ = Axes.Attribute; }
573 | CHILD { $$ = Axes.Child; }
574 | DESCENDANT { $$ = Axes.Descendant; }
575 | DESCENDANT_OR_SELF { $$ = Axes.DescendantOrSelf; }
576 | FOLLOWING { $$ = Axes.Following; }
577 | FOLLOWING_SIBLING { $$ = Axes.FollowingSibling; }
578 | NAMESPACE { $$ = Axes.Namespace; }
579 | PARENT { $$ = Axes.Parent; }
580 | PRECEDING { $$ = Axes.Preceding; }
581 | PRECEDING_SIBLING { $$ = Axes.PrecedingSibling; }
582 | SELF { $$ = Axes.Self; }