|
@@ -1,7 +1,12 @@
|
|
|
%{
|
|
%{
|
|
|
-// XPath parser
|
|
|
|
|
|
|
+// XPath/XSLT Pattern parser
|
|
|
//
|
|
//
|
|
|
-// Author - Piers Haken <[email protected]>
|
|
|
|
|
|
|
+// 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;
|
|
@@ -9,15 +14,28 @@ using System.Collections;
|
|
|
using System.Xml;
|
|
using System.Xml;
|
|
|
using System.Xml.XPath;
|
|
using System.Xml.XPath;
|
|
|
|
|
|
|
|
|
|
+#if XSLT_PATTERN
|
|
|
|
|
+namespace Mono.Xml.Xsl
|
|
|
|
|
+#else
|
|
|
namespace Mono.Xml.XPath
|
|
namespace Mono.Xml.XPath
|
|
|
|
|
+#endif
|
|
|
{
|
|
{
|
|
|
|
|
+#if XSLT_PATTERN
|
|
|
|
|
+ internal class XsltPatternParser
|
|
|
|
|
+#else
|
|
|
internal class XPathParser
|
|
internal class XPathParser
|
|
|
|
|
+#endif
|
|
|
{
|
|
{
|
|
|
|
|
|
|
|
internal System.Xml.Xsl.IStaticXsltContext Context;
|
|
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) {}
|
|
public XPathParser () : this (null) {}
|
|
|
internal XPathParser (System.Xml.Xsl.IStaticXsltContext context)
|
|
internal XPathParser (System.Xml.Xsl.IStaticXsltContext context)
|
|
|
|
|
+#endif
|
|
|
{
|
|
{
|
|
|
Context = context;
|
|
Context = context;
|
|
|
ErrorOutput = System.IO.TextWriter.Null;
|
|
ErrorOutput = System.IO.TextWriter.Null;
|
|
@@ -29,7 +47,7 @@ namespace Mono.Xml.XPath
|
|
|
try {
|
|
try {
|
|
|
Tokenizer tokenizer = new Tokenizer (xpath);
|
|
Tokenizer tokenizer = new Tokenizer (xpath);
|
|
|
return (Expression) yyparse (tokenizer);
|
|
return (Expression) yyparse (tokenizer);
|
|
|
- } catch (XPathException e) {
|
|
|
|
|
|
|
+ } catch (XPathException) {
|
|
|
throw;
|
|
throw;
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
throw new XPathException ("Error during parse of " + xpath, e);
|
|
throw new XPathException ("Error during parse of " + xpath, e);
|
|
@@ -144,6 +162,115 @@ namespace Mono.Xml.XPath
|
|
|
|
|
|
|
|
%%
|
|
%%
|
|
|
|
|
|
|
|
|
|
+/* 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
|
|
Expr
|