diff options
Diffstat (limited to 'mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/ParserBase.jay')
-rw-r--r-- | mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/ParserBase.jay | 2680 |
1 files changed, 2680 insertions, 0 deletions
diff --git a/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/ParserBase.jay b/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/ParserBase.jay new file mode 100644 index 00000000000..5a288a3c802 --- /dev/null +++ b/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/ParserBase.jay @@ -0,0 +1,2680 @@ +%{ +// +// XQueryParser.jay +// +// Author: +// Atsushi Enomoto <atsushi@ximian.com> +// +// Copyright (C) 2004 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +// +// FIXME: +// attribute value template +// handle double literal +// string literal in XQuery and XPath2 are different +// + +#if NET_2_0 + +using System; +using System.Collections; +using System.IO; +using System.Xml; +using System.Xml.Query; +using System.Xml.Schema; +using System.Xml.XPath; +using System.Security.Policy; +using Mono.Xml.XPath2; +using Mono.Xml.XQuery; +using Mono.Xml; + +#if XQUERY_PARSER +namespace Mono.Xml.XQuery.Parser +#elif XPATH2_PARSER +namespace Mono.Xml.XPath2.Parser +#endif +{ + internal class Parser + { + // See also FunctionCall production rule. + static Hashtable reservedFunctionNames; + static int yacc_verbose_flag; + + static Parser () + { + reservedFunctionNames = new Hashtable (); + reservedFunctionNames.Add ("attribute", "attribute"); + reservedFunctionNames.Add ("comment", "comment"); + reservedFunctionNames.Add ("document", "document"); + reservedFunctionNames.Add ("element", "element"); + reservedFunctionNames.Add ("empty", "empty"); + reservedFunctionNames.Add ("if", "if"); + reservedFunctionNames.Add ("item", "item"); + reservedFunctionNames.Add ("node", "node"); + reservedFunctionNames.Add ("processing-instruction", "processing-instruction"); + reservedFunctionNames.Add ("text", "text"); + reservedFunctionNames.Add ("type", "type"); + reservedFunctionNames.Add ("typeswitch", "typeswitch"); + } + + public static XQueryModule Parse (TextReader reader) + { + return new Parser ().RunParse (reader); + } + + private XQueryTokenizer tokenizer; + private bool isXQueryMode; + + private Parser () + : this (true) + { + } + + private Parser (bool isXQueryMode) + { + this.isXQueryMode = isXQueryMode; + ErrorOutput = TextWriter.Null; + } + + // FIXME: we don't need Evidence here at all. It is used only + // to generate runnable IL (on loading resulting Assembly). + public XQueryModule RunParse (TextReader source) + { + tokenizer = null; + try { + if (Environment.GetEnvironmentVariable ("MONO_DEBUG_XPATH2") == "yes") + debug = new yydebug.yyDebugSimple (); + tokenizer = new XQueryTokenizer (source); + XQueryModule mod = (XQueryModule) yyparse (tokenizer); + mod.NSResolver = tokenizer.NSResolver; + return mod; + } catch (yyParser.yyException ex) { + throw new XmlQueryCompileException (String.Format ("Tokenizer error at line {0}, column {1}: {2}", tokenizer.LineNumber, tokenizer.LinePosition, ex.Message), ex); + } + } + + public XmlTypeCode GetAtomicTypeCode (XmlQualifiedName name) + { + if (name.Namespace == InternalPool.XdtNamespace) { + switch (name.Name) { + case "anyAtomicType": + return XmlTypeCode.AnyAtomicType; + case "dayTimeDuration": + return XmlTypeCode.DayTimeDuration; + case "item": + return XmlTypeCode.Item; + case "untypedAtomic": + return XmlTypeCode.UntypedAtomic; + case "yearMonthDuration": + return XmlTypeCode.YearMonthDuration; + } + } else if (name.Namespace == XmlSchema.Namespace) { + switch (name.Name) { + case "boolean": + return XmlTypeCode.Boolean; + case "byte": + return XmlTypeCode.Byte; + case "date": + return XmlTypeCode.Date; + case "dateTime": + return XmlTypeCode.DateTime; + case "decimal": + return XmlTypeCode.Decimal; + case "double": + return XmlTypeCode.Double; + case "duration": + return XmlTypeCode.Duration; + case "entity": + return XmlTypeCode.Entity; + case "float": + return XmlTypeCode.Float; + case "gDay": + return XmlTypeCode.GDay; + case "gMonth": + return XmlTypeCode.GMonth; + case "gMonthDay": + return XmlTypeCode.GMonthDay; + case "gYear": + return XmlTypeCode.GYear; + case "gYearMonth": + return XmlTypeCode.GYearMonth; + case "hexBinary": + return XmlTypeCode.HexBinary; + case "id": + return XmlTypeCode.Id; + case "idref": + return XmlTypeCode.Idref; + case "int": + return XmlTypeCode.Int; + case "integer": + return XmlTypeCode.Integer; + case "language": + return XmlTypeCode.Language; + case "long": + return XmlTypeCode.Long; + case "Name": + return XmlTypeCode.Name; + case "NCName": + return XmlTypeCode.NCName; + case "negativeInteger": + return XmlTypeCode.NegativeInteger; + case "NMTOKEN": + return XmlTypeCode.NmToken; + case "nonNegativeInteger": + return XmlTypeCode.NonNegativeInteger; + case "nonPositiveInteger": + return XmlTypeCode.NonPositiveInteger; + case "normalizedString": + return XmlTypeCode.NormalizedString; + case "NOTATION": + return XmlTypeCode.Notation; + case "positiveInteger": + return XmlTypeCode.PositiveInteger; + case "QName": + return XmlTypeCode.QName; + case "short": + return XmlTypeCode.Short; + case "string": + return XmlTypeCode.String; + case "time": + return XmlTypeCode.Time; + case "token": + return XmlTypeCode.Token; + case "unsignedByte": + return XmlTypeCode.UnsignedByte; + case "unsignedInt": + return XmlTypeCode.UnsignedInt; + case "unsignedLong": + return XmlTypeCode.UnsignedLong; + case "unsignedShort": + return XmlTypeCode.UnsignedShort; + } + } + throw new XmlQueryCompileException (String.Format ("Unexpected type name was specified as atomic type: {0}", name)); + } + +%} + +/* -------------------------------------------------------- + Tokens +-------------------------------------------------------- */ + +/* These are for numbers */ +//%token SMALL_E //"e" +//%token LARGE_E //"E" + +%token DOT "." +%token DOT2 ".." +%token SEMICOLON ";" +%token OPEN_PAREN "(" +%token OPEN_PAREN_COLON "(:" +%token PRAGMA_OPEN "(::" +%token CLOSE_PAREN ")" +%token COLON ":" +%token COLON2 "::" +%token PRAGMA_CLOSE "::)" +%token CLOSE_PAREN_COLON ":)" +%token COLON_EQUAL ":=" +%token OPEN_BRACKET "[" +%token CLOSE_BRACKET "]" +%token OPEN_CURLY "{" +%token CLOSE_CURLY "}" +%token COMMA "," +%token DOLLAR "$" +%token EQUAL "=" +%token NOT_EQUAL "!=" +%token LESSER "<" +%token LESSER2 "<<" +%token LESSER_EQUAL "<=" +%token GREATER ">" +%token GREATER2 ">>" +%token GREATER_EQUAL ">=" +%token BAR "|" +%token ASTERISK "*" +%token PLUS "+" +%token MINUS "-" +%token SLASH "/" +%token SLASH2 "//" +%token QUESTION "?" + + +%token XQUERY //"xquery" +%token VERSION //"version" +%token PRAGMA //"pragma" +%token EXTENSION //"extension" +%token MODULE //"module" +%token NAMESPACE //"namespace" +%token DECLARE //"declare" +%token XMLSPACE //"xmlspace" +%token PRESERVE //"preserve" +%token STRIP //"strip" +%token DEFAULT //"default" +%token DOCUMENT_NODE //"document-node" +%token DOCUMENT //"document" +%token ELEMENT //"element" +%token ATTRIBUTE //"attribute" +%token PROCESSING_INSTRUCTION //"processing-instruction" +%token COMMENT //"comment" +%token TEXT //"text" +%token NODE //"node" +%token FUNCTION //"function" +%token COLLATION //"collation" +%token CONSTRUCTION //"construction" +%token ORDERING //"ordering" +%token ORDERED //"ordered" +%token UNORDERED //"unordered" +%token BASEURI //"base-uri" +%token IMPORT //"import" +%token SCHEMA //"schema" +%token AT //"at" +%token VARIABLE //"variable" +%token AS //"as" +%token EXTERNAL //"external" +%token VALIDATION //"validation" +%token LAX //"lax" +%token STRICT //"strict" +%token SKIP //"skip" +%token RETURN //"return" +%token FOR //"for" +%token LET //"let" +%token IN //"in" +%token WHERE //"where" +%token ORDER //"order" +%token BY //"by" +%token STABLE //"stable" +%token ASCENDING //"ascending" +%token DESCENDING //"descending" +%token EMPTY //"empty" +%token GREATEST //"greatest" +%token LEAST //"least" +%token SOME //"some" +%token EVERY //"every" +%token SATISFIES //"satisfies" +%token IS //"is" +%token TO //"to" +%token EQ //"eq" +%token NE //"ne" +%token LT //"lt" +%token LE //"le" +%token GT //"gt" +%token GE //"ge" +%token AND //"and" +%token OR //"or" +%token INSTANCE //"instance" +%token OF //"of" +%token IF //"if" +%token THEN //"then" +%token ELSE //"else" +%token TYPESWITCH //"typeswitch" +%token CASE //"case" +%token TREAT //"treat" +%token CASTABLE //"castable" +%token CAST //"as" +%token DIV //"div" +%token IDIV //"idiv" +%token MOD //"mod" +%token UNION //"union" +%token INTERSECT //"intersect" +%token EXCEPT //"except" +%token VALIDATE //"validate" +%token CONTEXT //"context" +%token NILLABLE //"nillable" +%token ITEM //"item" + + +%token GLOBAL //"global" +%token TYPE //"type" + +%token CHILD //"child" +%token DESCENDANT //"descendant" +%token ATTRIBUTE //"attribute" +%token SELF //"self" +%token DESCENDANT_OR_SELF //"descendant-or-self" +%token FOLLOWING_SIBLING //"following-sibling" +%token FOLLOWING //"following" +%token PARENT //"parent" +%token ANCESTOR //"ancestor" +%token PRECEDING_SIBLING //"preceding-sibling" +%token PRECEDING //"preceding" +%token ANCESTOR_OR_SELF //"ancestor-or-self" + +%token PRAGMA_START "(#" +%token PRAGMA_END "#)" +%token PragmaContents + + +%token QNAME +%token NCNAME +%token WILD_LOCALNAME +%token WILD_PREFIX + +%token STRING_LITERAL +%token DECIMAL_LITERAL +%token DOUBLE_LITERAL + +%token PRAGMA_CONTENTS // characters until "::)" + + +%token PREDEFINED_ENTITY_REF +%token CHAR_REF + +// Used only inside Constructor +%token XML_COMMENT_START // "<!--" +%token XML_COMMENT_TO_END // XML comment content immediate before "-->" +%token XML_PI_START // "<?" +%token XML_PI_TO_END // PI content immediate before "?>" +%token XML_CDATA_START // <![CDATA[ +%token XML_CDATA_TO_END // CDATA section content immediate before "]]>" +%token EMPTY_TAG_CLOSE // "/>" +%token END_TAG_START // "</". Its appearance depends on the context +%token ATT_VALUE_LITERAL +%token ELEM_CONTENT_LITERAL +%token EXT_CONTENT +%token APOS "'" +//%token APOS2 "''" +%token QUOT //"""" +//%token QUOT2 //"""""" + +%start Module + +%% + +/* -------------------------------------------------------- + Modules and Prologs +-------------------------------------------------------- */ + +Module // returns Module + : VersionDecl MainModule + { + string version = (string) $1; + XQueryMainModule module = (XQueryMainModule) $2; + module.Version = version; + $$ = module; + } + | VersionDecl LibraryModule + { + string version = (string) $1; + XQueryLibraryModule module = (XQueryLibraryModule) $2; + $$ = module; + } + ; + +VersionDecl // returns string + : // empty + { + $$ = null; + } + | XQUERY VERSION STRING_LITERAL { + tokenizer.State = ParseState.Operator; + } SEMICOLON { + tokenizer.State = ParseState.Default; + } + { + $$ = (string) $3; + } + ; + +MainModule // returns MainModule + : Prolog QueryBody + { + Prolog prolog = (Prolog) $1; + ExprSequence body = (ExprSequence) $2; + + XQueryMainModule mod = new XQueryMainModule (); + mod.Prolog = prolog; + mod.QueryBody = body; + $$ = mod; + } + ; + +LibraryModule // returns LibraryModule + : ModuleDecl Prolog + { + XQueryLibraryModule mod = new XQueryLibraryModule (); + mod.ModuleDecl = (ModuleDecl) $1; + mod.Prolog = (Prolog) $2; + $$ = mod; + } + ; + +ModuleDecl // returns ModuleDecl + : MODULE NAMESPACE { + tokenizer.State = ParseState.NamespaceDecl; + } NCName EQUAL STRING_LITERAL { + tokenizer.State = ParseState.Default; + } SEMICOLON + { + ModuleDecl decl = new ModuleDecl (); + decl.Prefix = (string) $4; + decl.Namespace = (string) $6; + tokenizer.AddNamespace (decl.Prefix, decl.Namespace); + $$ = decl; + } + ; + +Prolog + : // empty + { + $$ = new Prolog (); + } + | PrologContent SEMICOLON Prolog + { + Prolog p = (Prolog) $3; + p.Add ($1); + $$ = p; + } + ; + +PrologContent + : Setter + | DeclarationOrImport + ; + +// FIXME: this production rule is the right one, but it brings +// major shift/reduce conflicts. +/* +Prolog // returns Prolog + : Setters DeclarationsAndImports + { + Prolog p = (Prolog) $1; + ArrayList al = (ArrayList) $2; + if (al != null) { + foreach (object o in al) + p.Add (o); + } + $$ = p; + } + ; + +Setters // returns Prolog + : // empty + { + $$ = new Prolog (); + } + | Setter SEMICOLON Setters + { + Prolog p = (Prolog) $3; + p.Add ($1); + $$ = p; + } + ; + +DeclarationsAndImports // returns ArrayList + : // empty + { + $$ = null; + } + | DeclarationOrImport SEMICOLON DeclarationsAndImports + { + ArrayList al = (ArrayList) $3; + if (al == null) + al = new ArrayList (); + al.Add ($1); + $$ = al; + } + ; + +*/ + +Setter // returns object + : XmlSpaceDecl // XmlSpaceDecl + | DefaultCollationDecl // SimplePrologContent + | BaseURIDecl // SimplePrologContent + | ConstructionDecl // ConstuctionDecl + | DefaultNamespaceDecl // SimplePrologContent + | DefaultOrderingDecl // bool + ; + +DeclarationOrImport // returns object + : SchemaImport + | ModuleImport + | NamespaceDecl + | VarDecl + | FunctionDecl + ; + +NamespaceDecl // returns XmlQualifiedName + : DECLARE NAMESPACE { + tokenizer.State = ParseState.NamespaceDecl; + } NCName EQUAL STRING_LITERAL { + tokenizer.State = ParseState.Default; + } + { + XmlQualifiedName name = new XmlQualifiedName ((string) $4, (string) $6); + tokenizer.AddNamespace (name.Name, name.Namespace); + $$ = name; + } + ; + +XmlSpaceDecl // returns XmlSpaceDecl + : DECLARE XMLSPACE { + tokenizer.State = ParseState.XmlSpaceDecl; + } PRESERVE { + tokenizer.State = ParseState.Default; + } + { + $$ = new XmlSpaceDecl (XmlSpace.Preserve); + } + | DECLARE XMLSPACE { + tokenizer.State = ParseState.XmlSpaceDecl; + } STRIP { + tokenizer.State = ParseState.Default; + } + { + $$ = new XmlSpaceDecl (XmlSpace.Default); + } + ; + +ConstructionDecl // returns ConstructionDecl + : DECLARE CONSTRUCTION { + tokenizer.State = ParseState.Operator; + } PRESERVE { + tokenizer.State = ParseState.Default; + } + { + $$ = new ConstructionDecl (XmlSpace.Preserve); + } + | DECLARE CONSTRUCTION { + tokenizer.State = ParseState.Operator; + } STRIP { + tokenizer.State = ParseState.Default; + } + { + $$ = new ConstructionDecl (XmlSpace.Default); + } + ; + +DefaultNamespaceDecl // returns SimplePrologContent + : DECLARE DEFAULT ELEMENT { + tokenizer.State = ParseState.NamespaceKeyword; + } NAMESPACE { + tokenizer.State = ParseState.NamespaceDecl; + } STRING_LITERAL { + tokenizer.State = ParseState.Default; + } + { + tokenizer.AddNamespace (String.Empty, (string) $7); + $$ = new SimplePrologContent (PrologContentType.DefaultElementNamespace, (string) $7); + } + | DECLARE DEFAULT FUNCTION { + tokenizer.State = ParseState.NamespaceKeyword; + } NAMESPACE { + tokenizer.State = ParseState.NamespaceDecl; + } STRING_LITERAL { + tokenizer.State = ParseState.Default; + } + { + tokenizer.DefaultFunctionNamespace = (string) $5; + $$ = new SimplePrologContent (PrologContentType.DefaultFunctionNamespace, (string) $5); + } + ; + +DefaultCollationDecl // returns SimplePrologContent + : DECLARE DEFAULT COLLATION { + tokenizer.State = ParseState.NamespaceDecl; + } STRING_LITERAL { + tokenizer.State = ParseState.Default; + } + { + $$ = new SimplePrologContent (PrologContentType.DefaultCollation, (string) $4); + } + ; + +DefaultOrderingDecl // returns bool + : DECLARE DEFAULT ORDERING { + tokenizer.State = ParseState.Operator; + } ORDERED { + tokenizer.State = ParseState.Default; + } + { + $$ = true; + } + | DECLARE DEFAULT ORDERING { + tokenizer.State = ParseState.Operator; + } UNORDERED { + tokenizer.State = ParseState.Default; + } + { + $$ = false; + } + ; + +BaseURIDecl // returns SimplePrologContent + : DECLARE BASEURI { + tokenizer.State = ParseState.NamespaceDecl; + } STRING_LITERAL { + tokenizer.State = ParseState.Default; + } + { + $$ = new SimplePrologContent (PrologContentType.BaseUri, (string) $3); + } + ; + +SchemaImport // returns SchemaImport + : IMPORT SCHEMA { + tokenizer.State = ParseState.NamespaceKeyword; + } OptionalSchemaPrefix STRING_LITERAL { + tokenizer.State = ParseState.Default; + } OptionalLocations + { + if ($4 != null) + tokenizer.AddNamespace ((string) $4, (string) $5); + $$ = new SchemaImport ((string) $4, (string) $5, (ICollection) $7); + } + ; + +OptionalSchemaPrefix // returns string or null + : // empty + { + $$ = null; + } + | SchemaPrefix + ; + +SchemaPrefix // returns string + : NAMESPACE { + tokenizer.State = ParseState.NamespaceDecl; + } NCName EQUAL { + } + { + $$ = (string) $3; + } + | DEFAULT ELEMENT NAMESPACE { + tokenizer.State = ParseState.NamespaceDecl; + } + { + $$ = ""; + } + ; + +ModuleImport // returns ModuleImport + : IMPORT MODULE { + tokenizer.State = ParseState.NamespaceKeyword; + } OptionalModuleNamespace STRING_LITERAL { + tokenizer.State = ParseState.Default; + } OptionalLocations + { + $$ = new ModuleImport ((string) $4, (string) $5, (ICollection) $7); + tokenizer.AddNamespace ((string) $4, (string) $5); + } + ; + +OptionalModuleNamespace // returns string + : // empty + { + $$ = String.Empty; + } + | NAMESPACE { + tokenizer.State = ParseState.NamespaceDecl; + } NCName EQUAL + { + $$ = (string) $3; + } + ; + +OptionalLocations // returns ArrayList or null + : // empty + { + $$ = null; + } + | AT STRING_LITERAL AdditionalLocations + { + ArrayList al = (ArrayList) $3; + if (al != null) + al = new ArrayList (); + al.Add ((string) $2); + $$ = al; + } + ; + +AdditionalLocations // returns ArrayList or null + : // empty + { + $$ = null; + } + | COMMA STRING_LITERAL AdditionalLocations + { + ArrayList al = (ArrayList) $3; + if (al == null) + al = new ArrayList (); + al.Add ((string) $2); + $$ = al; + } + ; + +VarDecl // returns VariableDeclaration + : DECLARE VARIABLE DOLLAR { + tokenizer.PushState (ParseState.Default); + tokenizer.State = ParseState.VarName; + } VarName { + tokenizer.State = ParseState.Operator; + } OptionalTypeDeclaration VarDeclBody + { + $$ = new XQueryVariable ((XmlQualifiedName) $4, (SequenceType) $5, (ExprSequence) $6); + } + ; + +VarDeclBody // returns ExprSequence or null + : OPEN_CURLY { + tokenizer.State = ParseState.Default; + } Expr CloseCurly + { + $$ = $2; + } + | EXTERNAL { + // LAMESPEC: This state transition is not described in XQuery 1.0 spec + tokenizer.PopState (); + } + { + $$ = null; + } + ; + +VarName // returns XmlQualifiedName + : QName { + tokenizer.State = ParseState.Operator; + } + { + $$ = $1; + } + ; + +OptionalTypeDeclaration // returns SequenceType or null + : // empty + { + $$ = null; + } + | TypeDeclaration + ; + +TypeDeclaration // returns SequenceType + : AS { // Note that this transition applies only at Operator state. + tokenizer.State = ParseState.ItemType; + } SequenceType + { + $$ = $2; + } + ; + +FunctionDecl // returns FunctionDeclaration + : DECLARE FUNCTION { + tokenizer.PushState (ParseState.Default); + tokenizer.State = ParseState.Default; + } QName OPEN_PAREN OptionalParamList CLOSE_PAREN { + tokenizer.State = ParseState.Operator; + } OptionalTypeDeclaration FunctionBody + { + $$ = new FunctionDeclaration ( + (XmlQualifiedName) $4, + (XQueryFunctionArgumentList) $6, + (SequenceType) $9, + (EnclosedExpr) $10); + } + ; + +FunctionBody // returns EnclosedExpr or null + : EnclosedExpr + | EXTERNAL + { + $$ = null; + } + ; + +SequenceType // returns SequenceType + : ItemType OptionalOccurenceIndicator + { + $$ = new SequenceType ((ItemType) $1, (Occurence) $2); + } + | EMPTY OPEN_PAREN CLOSE_PAREN { + tokenizer.State = ParseState.Operator; + } + { + $$ = SequenceType.Create (XmlTypeCode.None, Occurence.One); + } + ; + +OptionalOccurenceIndicator // returns Occurence + : // empty + { + $$ = Occurence.One; + } + | OccurenceIndicator + ; + +OccurenceIndicator // returns Occurence + : QUESTION + { + $$ = Occurence.Optional; + } + | ASTERISK + { + $$ = Occurence.ZeroOrMore; + } + | PLUS + { + $$ = Occurence.OneOrMore; + } + ; + +OptionalParamList // returns XQueryFunctionArgumentList + : // empty + { + $$ = new XQueryFunctionArgumentList (); + } + | ParamList + ; + +ParamList // returns XQueryFunctionArgumentList + : Param + { + XQueryFunctionArgumentList pl = new XQueryFunctionArgumentList (); + pl.Add ((XQueryFunctionArgument) $1); + $$ = pl; + } + | Param COMMA ParamList + { + XQueryFunctionArgumentList pl = (XQueryFunctionArgumentList) $3; + pl.Insert (0, (XQueryFunctionArgument) $1); + $$ = pl; + } + ; + +Param // returns XQueryFunctionArgument + : DOLLAR { + tokenizer.State = ParseState.VarName; + } VarName { + tokenizer.State = ParseState.Operator; + } OptionalTypeDeclaration + { + $$ = new XQueryFunctionArgument ((XmlQualifiedName) $3, (SequenceType) $5); + } + ; + +QueryBody + : Expr + ; + + +/* -------------------------------------------------------- + Expressions +-------------------------------------------------------- */ + +Expr // returns ExprSequence + : ExprSequence + { + ExprSequence seq = (ExprSequence) $1; + $$ = seq; + } + ; + +ExprSequence // returns ExprSequence + : ExprSingle + { + ExprSequence seq = new ExprSequence (); + seq.Add ((ExprSingle) $1); + $$ = seq; + } + | ExprSingle COMMA ExprSequence + { + ExprSequence seq = (ExprSequence) $3; + seq.Insert (0, (ExprSingle) $1); + $$ = seq; + } + ; + +#XPath2Start +ExprSingle // returns ExprSingle + : ForExpr + | QuantifiedExpr + | TypeswitchExpr + | IfExpr + | OrExpr + ; +#XPath2End +#XQueryStart +ExprSingle // returns ExprSingle + : FLWORExpr + | QuantifiedExpr + | TypeswitchExpr + | IfExpr + | OrExpr + ; +#XQueryEnd + + +/* ------------------------------------- + ForExpr +------------------------------------- */ + +ForExpr + : SimpleForClause RETURN ExprSingle { + if (isXQueryMode) + throw new XmlQueryCompileException ("XQuery does not support for expression."); + ForLetClauseCollection col = new ForLetClauseCollection (); + col.Add ((ForClause) $1); + $$ = new FLWORExpr (col, null, null, (ExprSingle) $3); + } + ; + +SimpleForClause // returns ForClause + : FOR SimpleForBody + { + $$ = (ForClause) $2; + } + ; + +SimpleForBody // returns ForClause + : SimpleForSingleBody + { + ForClause fc = new ForClause (); + fc.Add ((ForSingleBody) $1); + $$ = fc; + } + | SimpleForSingleBody COMMA SimpleForBody + { + ForClause fc = (ForClause) $3; + fc.Insert (0, (ForSingleBody) $1); + $$ = fc; + } + ; + +SimpleForSingleBody // returns ForSingleBody + : DOLLAR { + tokenizer.State = ParseState.VarName; + } VarName { + tokenizer.State = ParseState.Operator; + } IN { + tokenizer.State = ParseState.Default; + } ExprSingle + { + $$ = new ForSingleBody ((XmlQualifiedName) $3, (SequenceType) $5, null, (ExprSingle) $7); + } + ; + + +/* ------------------------------------- + FLWORExpr +------------------------------------- */ + +FLWORExpr // returns FLWORExpr + : RepeatedForLetClause OptionalWhereClause OptionalOrderByClause RETURN { + tokenizer.State = ParseState.Default; + } ExprSingle + { + if (!isXQueryMode) + throw new XmlQueryCompileException ("XPath2 does not support FLWOR expression."); + ForLetClauseCollection col = (ForLetClauseCollection) $1; + $$ = new FLWORExpr (col, (ExprSequence) $2, (OrderSpecList) $3, (ExprSingle) $6); + } + ; + +RepeatedForLetClause // returns ForLetClauseCollection + : ForLetClause + { + ForLetClauseCollection col = new ForLetClauseCollection (); + col.Add ((ForLetClause) $1); + $$ = col; + } + | ForLetClause RepeatedForLetClause + { + ForLetClauseCollection col = (ForLetClauseCollection) $2; + col.Insert (0, (ForLetClause) $1); + $$ = col; + } + ; + +ForLetClause // returns ForLetClause + : ForClause + | LetClause + ; + +OptionalWhereClause // returns ExprSequence or null + : // empty + { + $$ = null; + } + | WhereClause + ; + +OptionalOrderByClause + : // empty + { + $$ = null; + } + | OrderByClause + ; + +ForClause // returns ForClause + : FOR ForBody + { + ForClause fc = (ForClause) $2; + $$ = fc; + } + ; + +ForBody + : ForSingleBody + { + ForClause fc = new ForClause (); + fc.Add ((ForSingleBody) $1); + $$ = fc; + } + | ForSingleBody COMMA ForBody + { + ForClause fc = (ForClause) $3; + fc.Insert (0, (ForSingleBody) $1); + $$ = fc; + } + ; + +ForSingleBody // returns ForSingleBody + : DOLLAR { + tokenizer.State = ParseState.VarName; + } VarName { + tokenizer.State = ParseState.Operator; + } OptionalTypeDeclaration OptionalPositionalVar IN { + tokenizer.State = ParseState.Default; + } ExprSingle + { + $$ = new ForSingleBody ((XmlQualifiedName) $3, (SequenceType) $5, (XmlQualifiedName) $6, (ExprSingle) $9); + } + ; + +LetClause + : LET LetBody + { + LetClause let = (LetClause) $2; + $$ = let; + } + ; + +LetBody + : LetSingleBody + { + LetClause lc = new LetClause (); + lc.Add ((LetSingleBody) $1); + $$ = lc; + } + | LetSingleBody COMMA LetBody + { + LetClause let = (LetClause) $3; + let.Insert (0, (LetSingleBody) $1); + $$ = let; + } + +LetSingleBody + : DOLLAR { + tokenizer.State = ParseState.VarName; + } VarName { + tokenizer.State = ParseState.Operator; + } OptionalTypeDeclaration COLON_EQUAL { + tokenizer.State = ParseState.Default; + } ExprSingle + { + $$ = new LetSingleBody ((XmlQualifiedName) $3, (SequenceType) $5, (ExprSingle) $8); + } + ; + +OptionalPositionalVar // returns XmlQualifiedName + : // empty + { + $$ = XmlQualifiedName.Empty; + } + | PositionalVar + ; + +PositionalVar + : AT { + tokenizer.State = ParseState.Default; + } DOLLAR { + tokenizer.State = ParseState.VarName; + } VarName { + tokenizer.State = ParseState.Operator; + } + { + $$ = $5; + } + ; + +WhereClause // returns ExprSequence + : WHERE { + tokenizer.State = ParseState.Default; + } Expr + { + $$ = $3; + } + ; + +OrderByClause // returns OrderSpecList + : ORDER BY { + tokenizer.State = ParseState.Default; + } OrderSpecList + { + OrderSpecList l = (OrderSpecList) $4; + $$ = l; + } + | STABLE ORDER BY { + tokenizer.State = ParseState.Default; + } OrderSpecList + { + OrderSpecList l = (OrderSpecList) $5; + l.IsStable = true; + $$ = l; + } + ; + +OrderSpecList // returns OrderSpecList + : OrderSpec + { + OrderSpecList osl = new OrderSpecList (); + osl.Add ((OrderSpec) $1); + $$ = osl; + } + | OrderSpec COMMA OrderSpecList + { + OrderSpecList l = (OrderSpecList) $3; + l.Insert (0, (OrderSpec) $1); + $$ = l; + } + ; + +OrderSpec // returns OrderSpec + : ExprSingle OrderModifier + { + $$ = new OrderSpec ((ExprSingle) $1, (OrderModifier) $2); + } + ; + +OrderModifier + : OrderSpecBase OrderEmptyHandling OptionalCollation + { + $$ = new OrderModifier ((XmlSortOrder) $1, (XmlSortOrder) $2, (string) $3); + } + ; + +OrderSpecBase // returns XmlSortOrder + : // empty + { + $$ = XmlSortOrder.Ascending; + } + | ASCENDING + { + $$ = XmlSortOrder.Ascending; + } + | DESCENDING + { + $$ = XmlSortOrder.Descending; + } + ; + +/* FIXME: check if it is correct (especially empty case) */ +OrderEmptyHandling // returns XmlSortOrder + : // empty + { + $$ = XmlSortOrder.Ascending; + } + | EMPTY GREATEST + { + $$ = XmlSortOrder.Ascending; + } + | EMPTY LEAST + { + $$ = XmlSortOrder.Descending; + } + ; + +OptionalCollation // returns string + : // empty + { + $$ = null; + } + | COLLATION STRING_LITERAL + { + $$ = $2; + } + ; + +/* ------------------------------------- + QuantifiedExpr +------------------------------------- */ + +QuantifiedExpr + : SOME QuantifiedExprBody SATISFIES ExprSingle + { + QuantifiedExprBodyList l = (QuantifiedExprBodyList) $2; + $$ = new QuantifiedExpr (false, l, (ExprSingle) $4); + } + | EVERY QuantifiedExprBody SATISFIES ExprSingle + { + QuantifiedExprBodyList l = (QuantifiedExprBodyList) $2; + $$ = new QuantifiedExpr (true, l, (ExprSingle) $4); + } + ; + +QuantifiedExprBody + : SingleQuantifiedExprBody + { + QuantifiedExprBodyList l = new QuantifiedExprBodyList (); + l.Add ((QuantifiedExprBody) $1); + $$ = l; + } + | SingleQuantifiedExprBody COMMA QuantifiedExprBody + { + QuantifiedExprBodyList l = (QuantifiedExprBodyList) $3; + l.Insert (0, (QuantifiedExprBody) $1); + $$ = l; + } + ; + +SingleQuantifiedExprBody // returns QuantifiedExprBody + : DOLLAR { + tokenizer.State = ParseState.VarName; + } VarName { + tokenizer.State = ParseState.Operator; + } OptionalTypeDeclaration IN { + tokenizer.State = ParseState.Default; + } ExprSingle + { + $$ = new QuantifiedExprBody ((XmlQualifiedName) $3, (SequenceType) $5, (ExprSingle) $8); + } + ; + +/* ------------------------------------- + TypeswitchExpr +------------------------------------- */ + +TypeswitchExpr // returns TypeswitchExpr + : TYPESWITCH OPEN_PAREN { + tokenizer.PushState (ParseState.Operator); + tokenizer.State = ParseState.Default; + } Expr CLOSE_PAREN { + tokenizer.State = ParseState.Operator; + } RepeatedCaseClause DEFAULT OptionalVarSpec RETURN { + tokenizer.State = ParseState.Default; + } ExprSingle + { + if (!isXQueryMode) + throw new XmlQueryCompileException ("XPath2 does not support typeswitch."); + $$ = new TypeswitchExpr ((ExprSequence) $4, (CaseClauseList) $7, (XmlQualifiedName) $9, (ExprSingle) $12); + } + ; + +RepeatedCaseClause // returns CaseClauseList + : CaseClause + { + CaseClauseList ccl = new CaseClauseList (); + ccl.Add ((CaseClause) $1); + $$ = ccl; + } + | CaseClause RepeatedCaseClause + { + CaseClauseList l = (CaseClauseList) $2; + l.Add ((CaseClause) $1); + $$ = l; + } + ; + +CaseClause // returns CaseClause + : CASE { + tokenizer.State = ParseState.ItemType; + } SequenceType RETURN { + tokenizer.State = ParseState.Default; + } ExprSingle + { + $$ = new CaseClause ((SequenceType) $3, (ExprSingle) $6, XmlQualifiedName.Empty); + } + | CASE { + tokenizer.State = ParseState.ItemType; + } DOLLAR { + tokenizer.State = ParseState.VarName; + } VarName { + tokenizer.State = ParseState.Operator; + } AS { + tokenizer.State = ParseState.ItemType; + } SequenceType RETURN { + tokenizer.State = ParseState.Default; + } ExprSingle + { + $$ = new CaseClause ((SequenceType) $9, (ExprSingle) $12, (XmlQualifiedName) $5); + } + ; + +OptionalVarSpec // returns XmlQualifiedName + : // empty + { + $$ = XmlQualifiedName.Empty; + } + | DOLLAR VarName + { + $$ = (XmlQualifiedName) $2; + } + ; + +/* ------------------------------------- + IfExpr +------------------------------------- */ + +IfExpr + : IF OPEN_PAREN Expr CLOSE_PAREN { + tokenizer.State = ParseState.Operator; + } THEN { + tokenizer.State = ParseState.Default; + } ExprSingle ELSE { + tokenizer.State = ParseState.Default; + } ExprSingle + { + $$ = new IfExpr ((ExprSequence) $3, (ExprSingle) $8, (ExprSingle) $11); + } + ; + +/* ------------------------------------- + Logical Expressions +------------------------------------- */ + +OrExpr + : AndExpr + | AndExpr OR { + tokenizer.State = ParseState.Default; + } OrExpr + { + $$ = new OrExpr ((ExprSingle) $1, (ExprSingle) $4); + } + ; + +AndExpr + : InstanceOfExpr + | InstanceOfExpr AND { + tokenizer.State = ParseState.Default; + } AndExpr + { + $$ = new AndExpr ((ExprSingle) $1, (ExprSingle) $4); + } + ; + +/* ------------------------------------- + Typed Expressions +------------------------------------- */ + +InstanceOfExpr + : TreatExpr + | TreatExpr INSTANCE OF { + tokenizer.State = ParseState.ItemType; + } SequenceType + { + $$ = new InstanceOfExpr ((ExprSingle) $1, (SequenceType) $5); + } + ; + +TreatExpr + : CastableExpr + | CastableExpr TREAT AS { + tokenizer.State = ParseState.ItemType; + } SequenceType + { + $$ = new TreatExpr ((ExprSingle) $1, (SequenceType) $5); + } + ; + +CastableExpr + : CastExpr + | CastExpr CASTABLE AS { + tokenizer.State = ParseState.ItemType; + } AtomicType OptionalQuestion + { + $$ = new CastableExpr ((ExprSingle) $1, (XmlTypeCode) $5, (bool)$6); + } + ; + +OptionalQuestion + : // empty + { + $$ = false; + } + | QUESTION + { + $$ = true; + } + ; + +CastExpr + : ComparisonExpr + | ComparisonExpr CAST AS { + tokenizer.State = ParseState.ItemType; + } AtomicType OptionalQuestion + { + $$ = new CastExpr ((ExprSingle) $1, (XmlTypeCode) $5, (bool) $6); + } + ; + +/* ------------------------------------- + Comparison Expressions +------------------------------------- */ + +ComparisonExpr + : RangeExpr + | RangeExpr Comp { + tokenizer.State = ParseState.Default; + } RangeExpr + { + $$ = new ComparisonExpr ((ExprSingle) $1, (ExprSingle) $4, (ComparisonOperator) $2); + } + ; + +Comp // returns ComparisonOperator + : ValueComp + | GeneralComp + | NodeComp + ; + +ValueComp + : EQ + { + $$ = ComparisonOperator.ValueEQ; + } + | NE + { + $$ = ComparisonOperator.ValueNE; + } + | LT + { + $$ = ComparisonOperator.ValueLT; + } + | LE + { + $$ = ComparisonOperator.ValueLE; + } + | GT + { + $$ = ComparisonOperator.ValueGT; + } + | GE + { + $$ = ComparisonOperator.ValueGE; + } + ; + +GeneralComp + : EQUAL + { + $$ = ComparisonOperator.GeneralEQ; + } + | NOT_EQUAL + { + $$ = ComparisonOperator.GeneralNE; + } + | LESSER + { + $$ = ComparisonOperator.GeneralLT; + } + | LESSER_EQUAL + { + $$ = ComparisonOperator.GeneralLE; + } + | GREATER + { + $$ = ComparisonOperator.GeneralGT; + } + | GREATER_EQUAL + { + $$ = ComparisonOperator.GeneralGE; + } + ; + +NodeComp + : IS + { + $$ = ComparisonOperator.NodeIs; + } + | LESSER2 + { + $$ = ComparisonOperator.NodeFWD; + } + | GREATER2 + { + $$ = ComparisonOperator.NodeBWD; + } + ; + +RangeExpr + : AdditiveExpr + | AdditiveExpr TO { + tokenizer.State = ParseState.Default; + } AdditiveExpr + { + $$ = new RangeExpr ((ExprSingle) $1, (ExprSingle)$4); + } + ; + +/* ------------------------------------- + Arithmetic Expressions +------------------------------------- */ + +AdditiveExpr + : MultiplicativeExpr + | MultiplicativeExpr PLUS { + tokenizer.State = ParseState.Default; + } AdditiveExpr + { + $$ = new ArithmeticOperationExpr ((ExprSingle) $1, (ExprSingle) $4, ArithmeticOperator.Add); + } + | MultiplicativeExpr MINUS { + tokenizer.State = ParseState.Default; + } AdditiveExpr + { + $$ = new ArithmeticOperationExpr ((ExprSingle) $1, (ExprSingle) $4, ArithmeticOperator.Sub); + } + ; + +MultiplicativeExpr + : UnaryExpr + | UnaryExpr ASTERISK { + tokenizer.State = ParseState.Default; + } MultiplicativeExpr + { + $$ = new ArithmeticOperationExpr ((ExprSingle) $1, (ExprSingle) $4, ArithmeticOperator.Mul); + } + | UnaryExpr DIV { + tokenizer.State = ParseState.Default; + } MultiplicativeExpr + { + $$ = new ArithmeticOperationExpr ((ExprSingle) $1, (ExprSingle) $4, ArithmeticOperator.Div); + } + | UnaryExpr IDIV { + tokenizer.State = ParseState.Default; + } MultiplicativeExpr + { + $$ = new ArithmeticOperationExpr ((ExprSingle) $1, (ExprSingle) $4, ArithmeticOperator.IDiv); + } + | UnaryExpr MOD { + tokenizer.State = ParseState.Default; + } MultiplicativeExpr + { + $$ = new ArithmeticOperationExpr ((ExprSingle) $1, (ExprSingle) $4, ArithmeticOperator.IMod); + } + ; + +UnaryExpr + : UnionExpr + | MINUS UnionExpr + { + $$ = new MinusExpr ((ExprSingle) $2); + } + | PLUS UnionExpr + { + $$ = $2; + } + ; + +UnionExpr + : IntersectExceptExpr + | IntersectExceptExpr UNION { + tokenizer.State = ParseState.Default; + } UnionExpr + { + $$ = new GroupExpr ((ExprSingle) $1, (ExprSingle) $4, AggregationType.Union); + } + | IntersectExceptExpr BAR { + tokenizer.State = ParseState.Default; + } UnionExpr + { + $$ = new GroupExpr ((ExprSingle) $1, (ExprSingle) $4, AggregationType.Union); + } + ; + +IntersectExceptExpr + : ValueExpr + | ValueExpr INTERSECT { + tokenizer.State = ParseState.Default; + } IntersectExceptExpr + { + $$ = new GroupExpr ((ExprSingle) $1, (ExprSingle) $4, AggregationType.Intersect); + } + | ValueExpr EXCEPT { + tokenizer.State = ParseState.Default; + } IntersectExceptExpr + { + $$ = new GroupExpr ((ExprSingle) $1, (ExprSingle) $4, AggregationType.Except); + } + ; + +ValueExpr + : ValidateExpr + | PathExpr + | ExtensionExpr + ; + +/* ----------------- + Extension Expressions +----------------- */ + +ExtensionExpr + : PragmaList OPEN_CURLY OptionalExpr CLOSE_CURLY + { + if (!isXQueryMode) + throw new XmlQueryCompileException ("XPath2 does not suport extension expression."); + throw new NotImplementedException (); + } + ; + +OptionalExpr + : + | Expr + ; + +PragmaList + : Pragma + { + throw new NotImplementedException (); + } + | Pragma PragmaList + { + throw new NotImplementedException (); + } + ; + +Pragma + : PRAGMA_START QName PragmaContents PRAGMA_END + { + throw new NotImplementedException (); + } + ; + + +/* ----------------- + Validation Expressions +----------------- */ + +// FIXME: Here state transition is not well-tracked. + +ValidateExpr // returns ValidateExpr + : VALIDATE OptionalValidationMode OPEN_CURLY { + tokenizer.State = ParseState.Default; + tokenizer.PushState (ParseState.Operator); + } Expr CloseCurly + { + if (!isXQueryMode) + throw new XmlQueryCompileException ("XPath2 does not support validate expression."); + $$ = new ValidateExpr ((XmlSchemaContentProcessing) $2, (ExprSequence) $6); + } + ; + +OptionalValidationMode // returns XmlSchemaContentProcessing + : // empty + { + $$ = XmlSchemaContentProcessing.Strict; // FIXME: confirm + } + | LAX + { + $$ = XmlSchemaContentProcessing.Lax; + } + | STRICT + { + $$ = XmlSchemaContentProcessing.Strict; + } + ; + +/* ----------------- + Path Expressions +----------------- */ + +PathExpr // returns PathExpr + : Slash + { + $$ = new PathRootExpr (); + } + | Slash RelativePathExpr + { + $$ = new PathSlashExpr (new PathRootExpr (), (ExprSingle) $2); + } + | Slash2 RelativePathExpr + { + $$ = new PathSlash2Expr (new PathRootExpr (), (ExprSingle) $2); + } + | RelativePathExpr + ; + +RelativePathExpr // returns PathExpr + : StepExpr + | StepExpr Slash RelativePathExpr + { + $$ = new PathSlashExpr ((ExprSingle) $1, (ExprSingle) $3); + } + | StepExpr Slash2 RelativePathExpr + { + $$ = new PathSlash2Expr ((ExprSingle) $1, (ExprSingle) $3); + } + ; + +StepExpr // returns ExprSingle + : AxisStep + | FilterStep + ; + +AxisStep // returns PathExpr + : ForwardOrReverseStep + | AxisStep Predicate + { + $$ = new FilterStepExpr ((ExprSingle) $1, (ExprSequence) $2); + } + ; + +ForwardOrReverseStep // returns ExprSingle + : ForwardStep + | ReverseStep + ; + +Predicate + : OPEN_BRACKET Expr CLOSE_BRACKET { + tokenizer.State = ParseState.Operator; + } + { + $$ = $2; + } + ; + +FilterStep // returns ExprSingle + : PrimaryExpr + | FilterStep Predicate + { + $$ = new FilterStepExpr ((ExprSingle) $1, (ExprSequence) $2); + } + ; + +ForwardStep // returns AxisStepExpr + : ForwardAxis NodeTest + { + $$ = new AxisStepExpr ((XPathAxis) $1, (XPath2NodeTest) $2); + } + | AbbrevForwardStep + ; + +ReverseStep // returns AxisStepExpr + : ReverseAxis NodeTest + { + $$ = new AxisStepExpr ((XPathAxis) $1, (XPath2NodeTest) $2); + } + | AbbrevReverseStep + ; + +ForwardAxis // returns XPathAxis + : CHILD COLON2 + { + $$ = XPathAxis.Child; + } + | DESCENDANT COLON2 + { + $$ = XPathAxis.Descendant; + } + | ATTRIBUTE COLON2 + { + $$ = XPathAxis.Attribute; + } + | SELF COLON2 + { + $$ = XPathAxis.Self; + } + | DESCENDANT_OR_SELF COLON2 + { + $$ = XPathAxis.DescendantOrSelf; + } + | FOLLOWING_SIBLING COLON2 + { + $$ = XPathAxis.FollowingSibling; + } + | FOLLOWING COLON2 + { + $$ = XPathAxis.Following; + } + | NAMESPACE COLON2 + { + if (isXQueryMode) + throw new XmlQueryCompileException ("XQuery does not support namespace axis."); + $$ = XPathAxis.NamespaceAxis; + } + ; + +ReverseAxis // returns XPathAxis + : PARENT COLON2 + { + $$ = XPathAxis.Parent; + } + | ANCESTOR COLON2 + { + $$ = XPathAxis.Ancestor; + } + | PRECEDING_SIBLING COLON2 + { + $$ = XPathAxis.PrecedingSibling; + } + | PRECEDING COLON2 + { + $$ = XPathAxis.Preceding; + } + | ANCESTOR_OR_SELF COLON2 + { + $$ = XPathAxis.AncestorOrSelf; + } + ; + +// LAMESPEC: in the XQuery spec, it is "@? NodeTest", but NodeKindTest +// should not appear after AT. (imagine @processing-instruction::(name)). +AbbrevForwardStep // returns NodeTestExpr + : NodeTest + { + $$ = new AxisStepExpr (XPathAxis.Child, (XPath2NodeTest) $1); + } + | AT NameTest + { + $$ = new AxisStepExpr (XPathAxis.Attribute, new XPath2NodeTest ((XmlQualifiedName) $2)); + } + ; + +AbbrevReverseStep // returns AxisStepExpr + : DOT2 + { + $$ = new AxisStepExpr (XPathAxis.Parent, null); + } + ; + +NodeTest // returns NodeTest + : KindTest + { + $$ = new XPath2NodeTest ((KindTest) $1); + } + | NameTest + { + $$ = new XPath2NodeTest ((XmlQualifiedName) $1); + } + ; + +NameTest // returns XmlQualifiedName + : QName + | Wildcard { + tokenizer.State = ParseState.Operator; + } + ; + +Wildcard // returns XmlQualifiedName /*ws:explicit*/ + : ASTERISK + { + $$ = new XmlQualifiedName ("*", "*"); + } + | WILD_LOCALNAME + { + $$ = (XmlQualifiedName) $1; + } + | WILD_PREFIX + { + $$ = (XmlQualifiedName) $1; + } + ; + +AtomicType // returns XmlTypeCode + : QName + { + $$ = GetAtomicTypeCode ((XmlQualifiedName) $1); + } + ; + +ItemType // returns ItemType + : AtomicType { + tokenizer.State = ParseState.OccurenceIndicator; + } + { + $$ = new ItemType ((XmlTypeCode) $1); + } + | KindTest + | ITEM OPEN_PAREN CLOSE_PAREN { + tokenizer.State = ParseState.OccurenceIndicator; + } + { + $$ = new ItemType (XmlTypeCode.Item); + } + ; + +KindTest // returns KindTest + : DocumentTest + | ElementTest + | AttributeTest + | PITest + | CommentTest + | TextTest + | AnyKindTest + ; + +PITest + : PROCESSING_INSTRUCTION OPEN_PAREN { + // LAMESPEC: push state is described as Operator, but should + // be OccurenceIndicator (as any KindTest could be followed by + // '?' '+' or '*') + tokenizer.PushState (ParseState.OccurenceIndicator); + tokenizer.State = ParseState.KindTestForPI; + } PITestContent CLOSE_PAREN { + tokenizer.PopState (); + } + { + $$ = $4; + } + ; + +PITestContent // returns KindTest + : // empty + { + $$ = new KindTest (XmlTypeCode.ProcessingInstruction); + } + | NCName + { + $$ = new XmlPITest ((string) $1); + } + | STRING_LITERAL + { + $$ = new XmlPITest ((string) $1); + } + ; + +CommentTest + : COMMENT OPEN_PAREN { + tokenizer.PushState (ParseState.OccurenceIndicator); + tokenizer.State = ParseState.KindTest; + } CLOSE_PAREN { + tokenizer.PopState (); + } + { + $$ = new KindTest (XmlTypeCode.Comment); + } + ; + +TextTest + : TEXT OPEN_PAREN { + tokenizer.PushState (ParseState.OccurenceIndicator); + tokenizer.State = ParseState.KindTest; + } CLOSE_PAREN { + tokenizer.PopState (); + } + { + $$ = new KindTest (XmlTypeCode.Text); + } + ; + +AnyKindTest + : NODE OPEN_PAREN { + tokenizer.PushState (ParseState.OccurenceIndicator); + tokenizer.State = ParseState.KindTest; + } CLOSE_PAREN { + tokenizer.PopState (); + } + { + $$ = new KindTest (XmlTypeCode.Node); + } + ; + +DocumentTest // returns DocumentTest + : DOCUMENT_NODE OPEN_PAREN { + tokenizer.PushState (ParseState.OccurenceIndicator); + tokenizer.State = ParseState.KindTest; + } DocumentTestContent CLOSE_PAREN { + tokenizer.PopState (); + } + { + $$ = $4; + } + ; + +DocumentTestContent // returns DocumentTest + : // empty + { + $$ = new KindTest (XmlTypeCode.Document); + } + | ElementTest + { + $$ = new DocumentTest ((ElementTest) $1); + } + ; + +ElementTest // returns ElementTest + : ELEMENT OPEN_PAREN { + tokenizer.PushState (ParseState.OccurenceIndicator); + tokenizer.State = ParseState.KindTest; + } ElementTestContent CLOSE_PAREN { + tokenizer.PopState (); + } + { + $$ = $4; + } + ; + +ElementTestContent // returns ElementTest + : // empty + { + $$ = new KindTest (XmlTypeCode.Element); + } + | ElementNameOrWildcard + { + $$ = new ElementTest ((XmlQualifiedName) $1); + } + | ElementNameOrWildcard COMMA TypeName OptionalQuestion + { + $$ = new ElementTest ((XmlQualifiedName) $1, (XmlQualifiedName) $3, (bool) $4); + } + ; + +OptionalQuestion // returns bool + : // empty + { + $$ = false; + } + | QUESTION + { + $$ = true; + } + ; + +AttributeTest // returns AttributeTest + : ATTRIBUTE OPEN_PAREN { + tokenizer.PushState (ParseState.OccurenceIndicator); + tokenizer.State = ParseState.KindTest; + } AttributeTestContent CLOSE_PAREN { + tokenizer.PopState (); + } + { + $$ = $4; + } + ; + +AttributeTestContent // returns AttributeTest + : // empty + { + $$ = AttributeTest.AnyAttribute; + } + | AttributeNameOrWildcard + { + $$ = new AttributeTest ((XmlQualifiedName) $1); + } + | AttributeNameOrWildcard COMMA TypeNameOrWildcard + { + $$ = new AttributeTest ((XmlQualifiedName) $1, (XmlQualifiedName) $3); + } + ; + +ElementName + : QName + ; + +AttributeName + : QName + ; + +TypeName + : QName + ; + +ElementNameOrWildcard // returns XmlQualifiedName + : ElementName + | ASTERISK + { + $$ = new XmlQualifiedName ("*", "*"); + } + ; + +AttributeNameOrWildcard // returns XmlQualifiedName + : AttributeName + | ASTERISK + { + $$ = new XmlQualifiedName ("*", "*"); + } + ; + +TypeNameOrWildcard // returns XmlQualifiedName + : TypeName + | ASTERISK + { + $$ = new XmlQualifiedName ("*", "*"); + } + ; + +/* ---------------- + Primary Expressions +---------------- */ + +PrimaryExpr // returns ExprSingle + : Literal { + tokenizer.State = ParseState.Operator; + } + | VarRef + | ParenthesizedExpr + | ContextItemExpr + | FunctionCall + | Constructor + { + if (!isXQueryMode) + throw new XmlQueryCompileException ("XPath2 does not support constructor expression."); + $$ = $1; + } + | OrderedExpr + { + if (!isXQueryMode) + throw new XmlQueryCompileException ("XPath2 does not support ordered expression."); + $$ = $1; + } + | UnorderedExpr + { + if (!isXQueryMode) + throw new XmlQueryCompileException ("XPath2 does not support unordered expression."); + $$ = $1; + } + ; + +Literal + : DECIMAL_LITERAL + { + $$ = new DecimalLiteralExpr ((decimal) $1); + } + | DOUBLE_LITERAL + { + $$ = new DoubleLiteralExpr ((double) $1); + } + | STRING_LITERAL + { + $$ = new StringLiteralExpr ((string) $1); + } + ; + +/* +NUMERIC_LITERAL + : IntegerLiteral + | DecimalLiteral + | DoubleLiteral + ; + +IntegerLiteral + : Digits + ; + +DecimalLiteral + : DOT Digits + | Digits DOT OptDigits + ; + +DoubleLiteral + : DoubleDecimalPartSpec ExponentSpec + ; + +DoubleDecimalPartSpec + : DOT Digits + | Digits + | Digits DOT OptDigits + +ExponentSpec + : // empty/* + | ExponentAlpha Digits + | ExponentAlpha PLUS Digits + | ExponentAlpha MINUS Digits + ; + +ExponentAlpha + : LARGE_E + | SMALL_E + ; + +OptDigits + : // empty/* + | Digits + ; + +Digits + : ZERO_TO_NINE_SEQ + ; + +STRING_LITERAL + : QUOT STRING_LITERALContentQuot + | APOS STRING_LITERALContentApos + ; + +STRING_LITERALContentQuot + : PREDEFINED_ENTITY_REF + | CHAR_REF + | QUOT2 + | REMAINING_LITERAL + ; + +STRING_LITERALContentApos + : PREDEFINED_ENTITY_REF + | CHAR_REF + | APOS2 + | REMAINING_LITERAL + ; +*/ + +VarRef // returns VariableReferenceExpr + : DOLLAR { + tokenizer.State = ParseState.VarName; + } VarName + { + $$ = new VariableReferenceExpr ((XmlQualifiedName) $3); + } + ; + +VarName // returns XmlQualifiedName + : QName { + tokenizer.State = ParseState.Operator; + } + { + $$ = $1; + } + ; + +ParenthesizedExpr // returns ParenthesizedExpr + : OPEN_PAREN OptionalExpr CLOSE_PAREN { + tokenizer.State = ParseState.Operator; + } + { + $$ = new ParenthesizedExpr ((ExprSequence) $2); + } + ; + +OptionalExpr + : // empty + { + $$ = new ExprSequence (); + } + | Expr + ; + +ContextItemExpr // returns ContextItemExpr + : DOT { + tokenizer.State = ParseState.Operator; + } + { + $$ = new ContextItemExpr (); + } + ; + +FunctionCall + : QName OPEN_PAREN { + tokenizer.State = ParseState.Default; + } OptionalExpr CLOSE_PAREN { + tokenizer.State = ParseState.Operator; + } + { + XmlQualifiedName name = (XmlQualifiedName) $1; + if (name.Namespace == "") + name = new XmlQualifiedName (name.Name, tokenizer.DefaultFunctionNamespace); + if (name.Namespace != "" + && name.Namespace != InternalPool.XdtNamespace + && reservedFunctionNames [name.Name] != null) + throw new XmlQueryCompileException (String.Format ("'{0}' is reserved and cannot be used as a function name.", name.Name)); + + $$ = new FunctionCallExpr (name, (ExprSequence) $4); + } + ; + +OrderedExpr + : ORDERED OPEN_BRACKET Expr CLOSE_BRACKET + { + $$ = new OrderSpecifiedExpr ((ExprSequence) $3, true); + } + ; + +UnorderedExpr + : UNORDERED OPEN_BRACKET { + tokenizer.PushState (ParseState.Operator); + tokenizer.State = ParseState.Default; + } Expr CLOSE_BRACKET { + tokenizer.PopState (); + } + { + $$ = new OrderSpecifiedExpr ((ExprSequence) $4, false); + } + ; + + +/* ----------------- + Constructors +----------------- */ + + +Constructor // returns ExprSingle + : DirElemConstructor + | ComputedConstructor + | XmlComment + | XmlPI + | XmlCData + ; + +DirElemConstructor // returns XmlElemConstructor + : LESSER { + if (tokenizer.State == ParseState.ElementContent) + tokenizer.PushState (tokenizer.State); +// if (tokenizer.State == ParseState.Default) + else // considering <foo></foo><bar></bar> there after </foo> state is Operator. + tokenizer.PushState (ParseState.Operator); + tokenizer.State = ParseState.StartTag; + // FIXME: tokenizer.Space = WhitespaceHandling.Significant; + } QName AttributeList FollowDirElemConstructor { + tokenizer.PopState (); + } + { + ExprSequence expr = new ExprSequence (); + expr.AddRange ((ICollection) $4); + expr.AddRange ((ICollection) $5); + $$ = new XmlElemConstructor ((XmlQualifiedName) $3, expr); + } + ; + +FollowDirElemConstructor // returns ExprSequence + : EMPTY_TAG_CLOSE + { + $$ = new ExprSequence (); + } + | GREATER { + tokenizer.State = ParseState.ElementContent; + } ElementContentList END_TAG_START { + tokenizer.State = ParseState.EndTag; + } QName { +// tokenizer.Space = WhitespaceHandling.Arbitrary; + } GREATER + { + $$ = $3; + } + ; + +ElementContentList // returns ExprSequence + : // empty + { + $$ = new ExprSequence (); + } + | ElementContent ElementContentList + { + ExprSequence el = (ExprSequence) $2; + el.Insert (0, (ExprSingle) $1); + $$ = el; + } + ; + +AttributeList // returns XmlAttrConstructorList + : // empty + { + $$ = new XmlAttrConstructorList (); + } + | /* space */ Attribute AttributeList + { + XmlAttrConstructorList al = (XmlAttrConstructorList) $2; + al.Insert (0, (XmlAttrConstructor) $1); + $$ = al; + } + ; + +Attribute // returns XmlAttrConstructor + : QName /* opt-space */ EQUAL /* opt-space */ AttributeValue + { + $$ = new XmlAttrConstructor ((XmlQualifiedName) $1, (ExprSequence) $3); + } + ; + +/* +// FIXME: it should be more complex +AttributeValue // returns ExprSequence + : STRING_LITERAL + { + ExprSequence es = new ExprSequence (); + es.Insert (0, new StringLiteralExpr ((string) $1)); + $$ = es; + } + ; +*/ + +AttributeValue // returns ExprSequence + : QUOT { + tokenizer.State = ParseState.QuotAttributeContent; + } AttributeValueContentSequence QUOT { + tokenizer.State = ParseState.StartTag; + } + { + $$ = $3; + } + | APOS { + tokenizer.State = ParseState.AposAttributeContent; + } AttributeValueContentSequence APOS { + tokenizer.State = ParseState.StartTag; + } + { + $$ = $3; + } + ; + + +AttributeValueContentSequence // returns ExprSequence + : // empty + { + $$ = new ExprSequence (); + } + | AttributeValueContent AttributeValueContentSequence + { + ExprSequence es = (ExprSequence) $2; + es.Insert (0, (ExprSingle) $1); + $$ = es; + } + ; + +AttributeValueContent // returns ExprSingle + : ATT_VALUE_LITERAL // including "{{", "}}" and char/predefined entities + { + $$ = new StringLiteralExpr ((string) $1); + } + | EnclosedExpr + ; + +EnclosedExpr // returns EnclosedExpr + // FIXME: check if this state transition is valid for ElementContent and AttributeValueContent + : OPEN_CURLY { + switch (tokenizer.State) { + case ParseState.ElementContent: + case ParseState.QuotAttributeContent: + case ParseState.AposAttributeContent: + tokenizer.PushState (tokenizer.State); + break; + } + tokenizer.State = ParseState.Default; + } Expr CloseCurly + { + $$ = new EnclosedExpr ((ExprSequence) $3); + } + ; + +ElementContent // returns ExprSingle + : ELEM_CONTENT_LITERAL // including "{{", "}}" and char/predefined entities + { + $$ = new XmlTextConstructor ((string) $1); + } + | DirElemConstructor + | EnclosedExpr + | XmlCData + | XmlComment + | XmlPI + ; + +XmlCData + : XML_CDATA_START XML_CDATA_TO_END + { + $$ = new XmlTextConstructor ((string) $2); + } + ; + +XmlComment // returns XmlCommentConstructor + : XML_COMMENT_START XML_COMMENT_TO_END + { + $$ = new XmlCommentConstructor ((string) $2); + } + ; + +XmlPI // returns XmlPIConstructor + : XML_PI_START { + tokenizer.PushState (tokenizer.State); + tokenizer.State = ParseState.XmlPI; + } PITarget { + tokenizer.State = ParseState.XmlPIContent; + } XML_PI_TO_END { + tokenizer.PopState (); + } + { + string name = (string) $3; + $$ = new XmlPIConstructor (name, (string) $5); + } + ; + +PITarget + : NCName + ; + +ComputedConstructor // returns ExprSingle + : CompElemConstructor + | CompAttrConstructor + | CompDocConstructor + | CompTextConstructor + | CompXmlPI + | CompXmlComment + | CompNSConstructor + ; + +CompElemConstructor + : ELEMENT QName OPEN_CURLY Expr CloseCurly + { + $$ = new XmlElemConstructor ((XmlQualifiedName) $2, (ExprSequence) $4); + } + | ELEMENT OPEN_CURLY Expr CloseCurly OPEN_CURLY Expr CloseCurly + { + $$ = new XmlElemConstructor ((ExprSequence) $3, (ExprSequence) $6); + } + ; + +CompAttrConstructor + : ATTRIBUTE QName OPEN_CURLY Expr CloseCurly + { + $$ = new XmlAttrConstructor ((XmlQualifiedName) $2, (ExprSequence) $4); + } + | ATTRIBUTE OPEN_CURLY Expr CloseCurly OPEN_CURLY Expr CloseCurly + { + $$ = new XmlAttrConstructor ((ExprSequence) $3, (ExprSequence) $6); + } + ; + +CompNSConstructor + : NAMESPACE NCName OPEN_CURLY Expr CloseCurly + { + $$ = new XmlNSConstructor ((string) $2, (ExprSequence) $4); + } + ; + +CompDocConstructor + : DOCUMENT OPEN_CURLY Expr CloseCurly + { + $$ = new XmlDocConstructor ((ExprSequence) $3); + } + ; + +CompTextConstructor + : TEXT OPEN_CURLY Expr CloseCurly + { + $$ = new XmlTextConstructor ((ExprSequence) $3); + } + ; + +CompXmlComment + : COMMENT OPEN_CURLY Expr CloseCurly + { + $$ = new XmlCommentConstructor ((ExprSequence) $3); + } + ; + +CompXmlPI + : PROCESSING_INSTRUCTION NCName OPEN_CURLY Expr CloseCurly + { + $$ = new XmlPIConstructor ((string) $2, (ExprSequence) $4); + } + | PROCESSING_INSTRUCTION OPEN_CURLY Expr CloseCurly OPEN_CURLY Expr CloseCurly + { + $$ = new XmlPIConstructor ((ExprSequence) $3, (ExprSequence) $6); + } + ; + +/* ----------------- + Terminal Wrappers +----------------- */ + + +NCName // returns string + : NCNAME + ; + +QName // returns XmlQualifiedName. Note that this state is just a wrapper for state transition. + : QNAME { + switch (tokenizer.State) { + case ParseState.Default: + tokenizer.State = ParseState.Operator; + break; + case ParseState.ItemType: + tokenizer.State = ParseState.OccurenceIndicator; + break; + case ParseState.KindTest: + case ParseState.SchemaContextStep: + tokenizer.State = ParseState.CloseKindTest; + break; + case ParseState.ExtKey: + tokenizer.State = ParseState.ExprComment; + break; + } + } + ; + +Slash + : SLASH { + switch (tokenizer.State) { + case ParseState.Operator: + tokenizer.State = ParseState.Default; + break; + case ParseState.KindTest: + tokenizer.State = ParseState.SchemaContextStep; + break; + } + } + ; + +Slash2 + : SLASH2 { + if (tokenizer.State == ParseState.Operator) + tokenizer.State = ParseState.Default; + } + ; + +CloseCurly + : CLOSE_CURLY { + if (tokenizer.State == ParseState.Operator) + tokenizer.PopState (); + } + ; + +%% + +} + +#endif |