| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591 |
- %{
- // XPath/XSLT Pattern parser
- //
- // Author: Piers Haken <[email protected]>
- // Atsushi Enomoto <[email protected]>
- //
- // IMPORTANT:
- // Do not edit "PatternParser.jay". It is autogenerated from
- // Parser.jay. It will be overwritten!
- //
- using System;
- using System.Collections;
- using System.Xml;
- using System.Xml.XPath;
- #if XSLT_PATTERN
- namespace Mono.Xml.Xsl
- #else
- namespace Mono.Xml.XPath
- #endif
- {
- #if XSLT_PATTERN
- internal class XsltPatternParser
- #else
- internal class XPathParser
- #endif
- {
-
- internal System.Xml.Xsl.IStaticXsltContext Context;
-
- #if XSLT_PATTERN
- public XsltPatternParser () : this (null) {}
- internal XsltPatternParser (System.Xml.Xsl.IStaticXsltContext context)
- #else
- public XPathParser () : this (null) {}
- internal XPathParser (System.Xml.Xsl.IStaticXsltContext context)
- #endif
- {
- Context = context;
- ErrorOutput = System.IO.TextWriter.Null;
- // debug = new yydebug.yyDebugSimple ();
- }
-
- internal Expression Compile (string xpath)
- {
- try {
- Tokenizer tokenizer = new Tokenizer (xpath);
- return (Expression) yyparse (tokenizer);
- } catch (XPathException) {
- throw;
- } catch (Exception e) {
- throw new XPathException ("Error during parse of " + xpath, e);
- }
- }
- static int yacc_verbose_flag;
- private NodeSet CreateNodeTest (Axes axis, object nodeTest, ArrayList plist)
- {
- NodeSet test = CreateNodeTest (axis, nodeTest);
- if (plist != null) {
- for (int i = 0; i < plist.Count; i++)
- test = new ExprFilter (test,
- (Expression) plist [i]);
- }
- return test;
- }
- private NodeTest CreateNodeTest (Axes axis, object test)
- {
- if (test is XPathNodeType)
- return new NodeTypeTest (axis,
- (XPathNodeType) test, null);
- else if (test is string || test == null)
- return new NodeTypeTest (axis,
- XPathNodeType.ProcessingInstruction,
- (string) test);
- XmlQualifiedName q = (XmlQualifiedName) test;
- if (q == XmlQualifiedName.Empty)
- return new NodeTypeTest (axis);
- else
- return new NodeNameTest (axis, q, Context);
- }
- %}
- %token ERROR
- %token EOF
- %token SLASH "/"
- %token SLASH2 "//"
- %token DOT "."
- %token DOT2 ".."
- %token COLON2 "::"
- %token COMMA ","
- %token AT "@"
- %token FUNCTION_NAME
- %token BRACKET_OPEN "["
- %token BRACKET_CLOSE "]"
- %token PAREN_OPEN "("
- %token PAREN_CLOSE ")"
- %token AND "and"
- %token OR "or"
- %token DIV "div"
- %token MOD "mod"
- %token PLUS "+"
- %token MINUS "-"
- %token ASTERISK "*"
- %token DOLLAR "$"
- %token BAR "|"
- %token EQ "="
- %token NE "!="
- %token LE "<="
- %token GE ">="
- %token LT "<"
- %token GT ">"
- %token ANCESTOR "ancestor"
- %token ANCESTOR_OR_SELF "ancstor-or-self"
- %token ATTRIBUTE "attribute"
- %token CHILD "child"
- %token DESCENDANT "descendant"
- %token DESCENDANT_OR_SELF "descendant-or-self"
- %token FOLLOWING "following"
- %token FOLLOWING_SIBLING "sibling"
- %token NAMESPACE "NameSpace"
- %token PARENT "parent"
- %token PRECEDING "preceding"
- %token PRECEDING_SIBLING "preceding-sibling"
- %token SELF "self"
- %token COMMENT "comment"
- %token TEXT "text"
- %token PROCESSING_INSTRUCTION "processing-instruction"
- %token NODE "node"
- %token MULTIPLY "*"
- %token NUMBER
- %token LITERAL
- %token QName
- %start Expr
- %left AND
- %left OR
- %left EQ
- %left NE
- %left LE
- %left GE
- %left LT
- %left GT
- %left DIV
- %left MOD
- %left PLUS
- %left MINUS
- %%
- /* XSLT Pattern */
- Pattern
- : LocationPathPattern
- | Pattern BAR LocationPathPattern
- {
- $$ = new ExprUNION ((NodeSet) $1, (NodeSet) $3);
- }
- ;
- LocationPathPattern
- : SLASH
- {
- $$ = new ExprRoot ();
- }
- | SLASH RelativePathPattern
- {
- $$ = new ExprSLASH (new ExprRoot (), (NodeSet) $2);
- }
- | IdKeyPattern
- | IdKeyPattern SLASH RelativePathPattern
- {
- $$ = new ExprSLASH ((Expression) $1, (NodeSet) $3);
- }
- | IdKeyPattern SLASH2 RelativePathPattern
- {
- $$ = new ExprSLASH2 ((Expression) $1, (NodeSet) $3);
- }
- | SLASH2 RelativePathPattern
- {
- $$ = new ExprSLASH2 (new ExprRoot (), (NodeSet) $2);
- }
- | RelativePathPattern
- ;
- // to avoid context-sensitive tokenizer, I just reuse FUNCTION_NAME
- IdKeyPattern
- : FUNCTION_NAME PAREN_OPEN LITERAL PAREN_CLOSE
- {
- XmlQualifiedName name = (XmlQualifiedName) $1;
- if (name.Name != "id" || name.Namespace != String.Empty)
- throw new XPathException (String.Format ("Expected 'id' but got '{0}'", name));
- $$ = ExprFunctionCall.Factory (name,
- new FunctionArguments (
- new ExprLiteral ((string) $3),
- null),
- Context);
- }
- | FUNCTION_NAME PAREN_OPEN LITERAL COMMA LITERAL PAREN_CLOSE
- {
- XmlQualifiedName name = (XmlQualifiedName) $1;
- if (name.Name != "key" || name.Namespace != String.Empty)
- throw new XPathException (String.Format ("Expected 'key' but got '{0}'", name));
- $$ = Context.TryGetFunction (name,
- new FunctionArguments (
- new ExprLiteral ((string) $3),
- new FunctionArguments (
- new ExprLiteral ((string) $5),
- null)));
- }
- ;
- RelativePathPattern
- : StepPattern
- | RelativePathPattern SLASH StepPattern
- {
- $$ = new ExprSLASH ((Expression) $1, (NodeSet) $3);
- }
- | RelativePathPattern SLASH2 StepPattern
- {
- $$ = new ExprSLASH2 ((Expression) $1, (NodeSet) $3);
- }
- ;
- StepPattern
- : ChildOrAttributeAxisSpecifier NodeTest Predicates
- {
- $$ = CreateNodeTest ((Axes) $1, $2, (ArrayList) $3);
- }
- ;
- ChildOrAttributeAxisSpecifier
- : AbbreviatedAxisSpecifier
- | CHILD COLON2
- {
- $$ = Axes.Child;
- }
- | ATTRIBUTE COLON2
- {
- $$ = Axes.Attribute;
- }
- ;
- Predicates
- : // empty
- {
- $$ = null;
- }
- | Predicates Predicate
- {
- ArrayList al = (ArrayList) $1;
- if (al == null)
- al = new ArrayList ();
- al.Add ((Expression) $2);
- $$ = al;
- }
- ;
- /* ---- end of XSLT Pattern ---- */
- Expr
- : OrExpr
- ;
-
- OrExpr
- : AndExpr
- | OrExpr OR AndExpr
- {
- $$ = new ExprOR ((Expression) $1, (Expression) $3);
- }
- ;
- AndExpr
- : EqualityExpr
- | AndExpr AND EqualityExpr
- {
- $$ = new ExprAND ((Expression) $1, (Expression) $3);
- }
- ;
- EqualityExpr
- : RelationalExpr
- | EqualityExpr EQ RelationalExpr
- {
- $$ = new ExprEQ ((Expression) $1, (Expression) $3);
- }
- | EqualityExpr NE RelationalExpr
- {
- $$ = new ExprNE ((Expression) $1, (Expression) $3);
- }
- ;
- RelationalExpr
- : AdditiveExpr
- | RelationalExpr LT AdditiveExpr
- {
- $$ = new ExprLT ((Expression) $1, (Expression) $3);
- }
- | RelationalExpr GT AdditiveExpr
- {
- $$ = new ExprGT ((Expression) $1, (Expression) $3);
- }
- | RelationalExpr LE AdditiveExpr
- {
- $$ = new ExprLE ((Expression) $1, (Expression) $3);
- }
- | RelationalExpr GE AdditiveExpr
- {
- $$ = new ExprGE ((Expression) $1, (Expression) $3);
- }
- ;
- AdditiveExpr
- : MultiplicativeExpr
- | AdditiveExpr PLUS MultiplicativeExpr
- {
- $$ = new ExprPLUS ((Expression) $1, (Expression) $3);
- }
- | AdditiveExpr MINUS MultiplicativeExpr
- {
- $$ = new ExprMINUS ((Expression) $1, (Expression) $3);
- }
- ;
- MultiplicativeExpr
- : UnaryExpr
- | MultiplicativeExpr MULTIPLY UnaryExpr
- {
- $$ = new ExprMULT ((Expression) $1, (Expression) $3);
- }
- | MultiplicativeExpr DIV UnaryExpr
- {
- $$ = new ExprDIV ((Expression) $1, (Expression) $3);
- }
- | MultiplicativeExpr MOD UnaryExpr
- {
- $$ = new ExprMOD ((Expression) $1, (Expression) $3);
- }
- ;
- UnaryExpr
- : UnionExpr
- | MINUS UnaryExpr
- {
- $$ = new ExprNEG ((Expression) $2);
- }
- ;
- UnionExpr
- : PathExpr
- | UnionExpr BAR PathExpr
- {
- $$ = new ExprUNION ((Expression) $1, (Expression) $3);
- }
- ;
- PathExpr
- : LocationPath
- | FilterExpr
- | FilterExpr SLASH RelativeLocationPath
- {
- $$ = new ExprSLASH ((Expression) $1, (NodeSet) $3);
- }
- | FilterExpr SLASH2 RelativeLocationPath
- {
- $$ = new ExprSLASH2 ((Expression) $1, (NodeSet) $3);
- }
- ;
- LocationPath
- : RelativeLocationPath
- | AbsoluteLocationPath
- ;
- AbsoluteLocationPath
- : SLASH
- {
- $$ = new ExprRoot ();
- }
- | SLASH RelativeLocationPath
- {
- $$ = new ExprSLASH (new ExprRoot (), (NodeSet) $2);
- }
- | SLASH2 RelativeLocationPath
- {
- $$ = new ExprSLASH2 (new ExprRoot (), (NodeSet) $2);
- }
- ;
- RelativeLocationPath
- : Step
- | RelativeLocationPath SLASH Step
- {
- $$ = new ExprSLASH ((NodeSet) $1, (NodeSet) $3);
- }
- | RelativeLocationPath SLASH2 Step
- {
- $$ = new ExprSLASH2 ((NodeSet) $1, (NodeSet) $3);
- }
- ;
- Step
- : AxisSpecifier NodeTest Predicates
- {
- $$ = CreateNodeTest ((Axes) $1, $2, (ArrayList) $3);
- }
- | AbbreviatedStep
- ;
- NodeTest // QName, XPathNodeType or string
- : NameTest
- | NodeType PAREN_OPEN PAREN_CLOSE
- {
- $$ = (XPathNodeType) $1;
- }
- | PROCESSING_INSTRUCTION PAREN_OPEN OptionalLiteral PAREN_CLOSE
- {
- $$ = (string) $3;
- }
- ;
- NameTest
- : ASTERISK
- {
- $$ = XmlQualifiedName.Empty;
- }
- | QName // token QName also contains "blah:*"
- ;
- AbbreviatedStep
- : DOT
- {
- $$ = new NodeTypeTest (Axes.Self, XPathNodeType.All);
- }
- | DOT2
- {
- $$ = new NodeTypeTest (Axes.Parent, XPathNodeType.All);
- }
- ;
- Predicates
- : /* empty */
- {
- $$ = null;
- }
- | Predicates Predicate
- {
- ArrayList al = (ArrayList) $1;
- if (al == null)
- al = new ArrayList ();
- al.Add ($2);
- $$ = al;
- }
- ;
- AxisSpecifier
- : AxisName COLON2
- {
- $$ = $1;
- }
- | AbbreviatedAxisSpecifier
- ;
- AbbreviatedAxisSpecifier
- : /* empty */
- {
- $$ = Axes.Child;
- }
- | AT
- {
- $$ = Axes.Attribute;
- }
- ;
- NodeType
- : COMMENT { $$ = XPathNodeType.Comment; }
- | TEXT { $$ = XPathNodeType.Text; }
- | PROCESSING_INSTRUCTION { $$ = XPathNodeType.ProcessingInstruction; }
- | NODE { $$ = XPathNodeType.All; }
- ;
- FilterExpr
- : PrimaryExpr
- | FilterExpr Predicate
- {
- $$ = new ExprFilter ((Expression) $1, (Expression) $2);
- }
- ;
- PrimaryExpr
- : DOLLAR QName
- {
- Expression ret = null;
- if (Context != null)
- ret = Context.TryGetVariable (((XmlQualifiedName) $2).ToString ());
-
- if (ret == null)
- ret = new ExprVariable ((XmlQualifiedName) $2, Context);
-
- $$ = ret;
- }
- | PAREN_OPEN Expr PAREN_CLOSE
- {
- $$ = new ExprParens ((Expression) $2);
- }
- | LITERAL
- {
- $$ = new ExprLiteral ((String) $1);
- }
- | NUMBER
- {
- $$ = new ExprNumber ((double) $1);
- }
- | FunctionCall
- ;
- FunctionCall
- : FUNCTION_NAME PAREN_OPEN OptionalArgumentList PAREN_CLOSE
- {
- Expression ret = null;
- if (Context != null)
- ret = Context.TryGetFunction ((XmlQualifiedName) $1, (FunctionArguments) $3);
- if (ret == null)
- ret = ExprFunctionCall.Factory ((XmlQualifiedName) $1, (FunctionArguments) $3, Context);
-
- $$ = ret;
- }
- ;
- OptionalArgumentList
- : /* empty */
- | Expr OptionalArgumentListTail
- {
- $$ = new FunctionArguments ((Expression) $1, (FunctionArguments) $2);
- }
- ;
- OptionalArgumentListTail
- : /* empty */
- | COMMA Expr OptionalArgumentListTail
- {
- $$ = new FunctionArguments ((Expression) $2, (FunctionArguments) $3);
- }
- ;
- Predicate
- : BRACKET_OPEN Expr BRACKET_CLOSE
- {
- $$ = $2;
- }
- ;
- AxisName
- : ANCESTOR { $$ = Axes.Ancestor; }
- | ANCESTOR_OR_SELF { $$ = Axes.AncestorOrSelf; }
- | ATTRIBUTE { $$ = Axes.Attribute; }
- | CHILD { $$ = Axes.Child; }
- | DESCENDANT { $$ = Axes.Descendant; }
- | DESCENDANT_OR_SELF { $$ = Axes.DescendantOrSelf; }
- | FOLLOWING { $$ = Axes.Following; }
- | FOLLOWING_SIBLING { $$ = Axes.FollowingSibling; }
- | NAMESPACE { $$ = Axes.Namespace; }
- | PARENT { $$ = Axes.Parent; }
- | PRECEDING { $$ = Axes.Preceding; }
- | PRECEDING_SIBLING { $$ = Axes.PrecedingSibling; }
- | SELF { $$ = Axes.Self; }
- ;
- OptionalLiteral
- : /* empty */
- | LITERAL
- ;
- %%
- }
|