diff options
author | Atsushi Eno <atsushieno@gmail.com> | 2005-03-18 10:09:50 +0300 |
---|---|---|
committer | Atsushi Eno <atsushieno@gmail.com> | 2005-03-18 10:09:50 +0300 |
commit | 15b3e50931ac60648eefd9e285e9f8cfb986ead1 (patch) | |
tree | b25edb7f4016fac354e314fa38bd5a6522e6880a /mcs/class/Mono.Xml.Ext | |
parent | 8dfb831cb011d991ddd284309adcc82385df693d (diff) |
2005-03-18 Atsushi Enomoto <atsushi@ximian.com>
* Makefile:
build XPath2/XQuery parsers/tokenizers from common codebase.
* Mono.Xml.Ext.dll:
removed built sources.
* skeleton-2.0.cs,
XQueryParser.jay,
XQueryTokenizer.cs : removed.
* ParserBase.jay,
TokenizerBase.cs : added, used to create both XQuery parser and
XPath2 parser.
* XQueryASTCompiler.cs,
XQueryCommandImpl.cs : updated in reflection to XQuery parser change.
* SequenceType.cs : added namespace axis.
svn path=/trunk/mcs/; revision=41976
Diffstat (limited to 'mcs/class/Mono.Xml.Ext')
-rw-r--r-- | mcs/class/Mono.Xml.Ext/ChangeLog | 7 | ||||
-rwxr-xr-x | mcs/class/Mono.Xml.Ext/Makefile | 40 | ||||
-rwxr-xr-x | mcs/class/Mono.Xml.Ext/Mono.Xml.Ext.dll.sources | 2 | ||||
-rwxr-xr-x | mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/ChangeLog | 12 | ||||
-rw-r--r-- | mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/ParserBase.jay | 2680 | ||||
-rwxr-xr-x | mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/SequenceType.cs | 7 | ||||
-rw-r--r-- | mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/TokenizerBase.cs | 1288 | ||||
-rwxr-xr-x | mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryASTCompiler.cs | 2 | ||||
-rwxr-xr-x | mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryCommandImpl.cs | 2 | ||||
-rwxr-xr-x | mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryParser.jay | 142 | ||||
-rwxr-xr-x | mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryTokenizer.cs | 8 | ||||
-rwxr-xr-x | mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/skeleton-2.0.cs | 364 |
12 files changed, 4175 insertions, 379 deletions
diff --git a/mcs/class/Mono.Xml.Ext/ChangeLog b/mcs/class/Mono.Xml.Ext/ChangeLog index ccfe0e7586d..9b6c5b32064 100644 --- a/mcs/class/Mono.Xml.Ext/ChangeLog +++ b/mcs/class/Mono.Xml.Ext/ChangeLog @@ -1,3 +1,10 @@ +2005-03-18 Atsushi Enomoto <atsushi@ximian.com> + + * Makefile: + build XPath2/XQuery parsers/tokenizers from common codebase. + * Mono.Xml.Ext.dll: + removed built sources. + 2004-11-19 Atsushi Enomoto <atsushi@ximian.com> * Mono.Xml.Ext.dll.sources : added XPathNavigatorReader.cs. diff --git a/mcs/class/Mono.Xml.Ext/Makefile b/mcs/class/Mono.Xml.Ext/Makefile index 4ee0064d802..20b70c83ecd 100755 --- a/mcs/class/Mono.Xml.Ext/Makefile +++ b/mcs/class/Mono.Xml.Ext/Makefile @@ -17,9 +17,43 @@ TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) EXTRA_DISTFILES = \ Mono.Xml.XPath2/XQueryParser.jay -Mono.Xml.XPath2/XQueryParser.cs: Mono.Xml.XPath2/XQueryParser.jay Mono.Xml.XPath2/skeleton-2.0.cs - $(topdir)/jay/jay -ct < Mono.Xml.XPath2/skeleton-2.0.cs $< >$@ +SKELETON = $(topdir)/jay/skeleton.cs -CLEAN_FILES = Mono.Xml.Ext.pdb Mono.Xml.XPath2/XQueryParser.cs y.output +Mono.Xml.XPath2/XPath2Parser.jay: Mono.Xml.XPath2/ParserBase.jay $(SKELETON) + sed "s/%start Module/%start Expr/" $< | sed "/\#XQueryStart/,/\#XQueryEnd/d" | sed "/\#XPath2Start/d" | sed "/\#XPath2End/d" >$@ + +Mono.Xml.XPath2/XQueryParser.jay: Mono.Xml.XPath2/ParserBase.jay $(SKELETON) + sed "/\#XPath2Start/,/\#XPath2End/d" $< | sed "/\#XQueryStart/d" | sed "/\#XQueryEnd/d" >$@ + +Mono.Xml.XPath2/XPath2Parser.cs: Mono.Xml.XPath2/XPath2Parser.jay + echo "#define XPATH2_PARSER" > $@ + echo "#if NET_2_0" >> $@ + $(topdir)/jay/jay -ct < $(SKELETON) $< >>$@ + echo "#endif" >> $@ + +Mono.Xml.XPath2/XQueryParser.cs: Mono.Xml.XPath2/XQueryParser.jay $(SKELETON) + echo "#define XQUERY_PARSER" > $@ + echo "#if NET_2_0" >> $@ + $(topdir)/jay/jay -ct < $(SKELETON) $< >>$@ + echo "#endif" >> $@ + +Mono.Xml.XPath2/XPath2Tokenizer.cs: Mono.Xml.XPath2/TokenizerBase.cs + echo "#define XPATH2_PARSER" > $@ + cat $< >>$@ + +Mono.Xml.XPath2/XQueryTokenizer.cs: Mono.Xml.XPath2/TokenizerBase.cs + echo "#define XQUERY_PARSER" > $@ + cat $< >>$@ + +BUILT_SOURCES = Mono.Xml.XPath2/XPath2Parser.cs \ + Mono.Xml.XPath2/XPath2Tokenizer.cs \ + Mono.Xml.XPath2/XQueryParser.cs \ + Mono.Xml.XPath2/XQueryTokenizer.cs + +CLEAN_FILES = Mono.Xml.Ext.pdb \ + Mono.Xml.XPath2/XPath2Parser.jay \ + Mono.Xml.XPath2/XPath2Parser.cs \ + Mono.Xml.XPath2/XQueryParser.cs \ + y.output include ../../build/library.make diff --git a/mcs/class/Mono.Xml.Ext/Mono.Xml.Ext.dll.sources b/mcs/class/Mono.Xml.Ext/Mono.Xml.Ext.dll.sources index 281478bb598..1d82e38cbc7 100755 --- a/mcs/class/Mono.Xml.Ext/Mono.Xml.Ext.dll.sources +++ b/mcs/class/Mono.Xml.Ext/Mono.Xml.Ext.dll.sources @@ -23,9 +23,7 @@ Mono.Xml.XPath2/XQueryFunctionCliImpl.cs Mono.Xml.XPath2/XQueryFunctionContextAttribute.cs Mono.Xml.XPath2/XQueryFunctionTable.cs Mono.Xml.XPath2/XQueryModuleProlog.cs -Mono.Xml.XPath2/XQueryParser.cs Mono.Xml.XPath2/XQueryStaticContext.cs -Mono.Xml.XPath2/XQueryTokenizer.cs Mono.Xml.XPath2/XmlArgumentList.cs Mono.Xml.XPath2/XmlQueryCompileException.cs Mono.Xml.XPath2/XmlQueryException.cs diff --git a/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/ChangeLog b/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/ChangeLog index eb36cb0df72..900591c0ac5 100755 --- a/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/ChangeLog +++ b/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/ChangeLog @@ -1,3 +1,15 @@ +2005-03-18 Atsushi Enomoto <atsushi@ximian.com> + + * skeleton-2.0.cs, + XQueryParser.jay, + XQueryTokenizer.cs : removed. + * ParserBase.jay, + TokenizerBase.cs : added, used to create both XQuery parser and + XPath2 parser. + * XQueryASTCompiler.cs, + XQueryCommandImpl.cs : updated in reflection to XQuery parser change. + * SequenceType.cs : added namespace axis. + 2004-11-20 Atsushi Enomoto <atsushi@ximian.com> * XQueryParser.jay : don't output parser error by default. 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 diff --git a/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/SequenceType.cs b/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/SequenceType.cs index dadaeb8b8f0..55cb7113ace 100755 --- a/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/SequenceType.cs +++ b/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/SequenceType.cs @@ -370,7 +370,7 @@ namespace Mono.Xml.XPath2 static XPathAxis child, descendant, attribute, self, descendantOrSelf, followingSibling, following, parent, ancestor, precedingSibling, preceding, - ancestorOrSelf; + ancestorOrSelf, namespaceAxis; static XPathAxis () { @@ -386,6 +386,7 @@ namespace Mono.Xml.XPath2 precedingSibling = new XPathAxis (XPathAxisType.PrecedingSibling); preceding = new XPathAxis (XPathAxisType.Preceding); ancestorOrSelf = new XPathAxis (XPathAxisType.AncestorOrSelf); + namespaceAxis = new XPathAxis (XPathAxisType.Namespace); } public static XPathAxis Child { @@ -416,6 +417,10 @@ namespace Mono.Xml.XPath2 get { return following; } } + public static XPathAxis NamespaceAxis { + get { return namespaceAxis; } + } + public static XPathAxis Parent { get { return parent; } } diff --git a/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/TokenizerBase.cs b/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/TokenizerBase.cs new file mode 100644 index 00000000000..9fa0286b1ce --- /dev/null +++ b/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/TokenizerBase.cs @@ -0,0 +1,1288 @@ +// +// XQueryTokenizer.cs +// +// 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. +// +#if NET_2_0 + +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Security.Policy; +using System.Xml; +using System.Xml.Query; +using System.Xml.Schema; +using System.Xml.XPath; +using Mono.Xml.XQuery; +using Mono.Xml.XPath2; +using Mono.Xml; + +#if XPATH2_PARSER +namespace Mono.Xml.XPath2.Parser +#elif XQUERY_PARSER +namespace Mono.Xml.XQuery.Parser +#endif +{ + // FIXME: make internal in the future + public class XQueryTokenizer : yyParser.yyInput, IXmlLineInfo + { + int line = 1; + int column = 0; + bool nextIncrementLine; + + // namespace resolver + XmlNamespaceManager nsResolver; + string defaultFunctionNamespace = XQueryFunction.Namespace; + + // input source + TextReader source; + int peekChar = -1; + + // token info + int currentToken; + string prefixName; + object tokenValue; + + int lookAheadToken = -1; + object lookAheadTokenValue; + + // state info + WhitespaceHandling ws = WhitespaceHandling.Arbitrary; + ParseState state = ParseState.Default; + Stack stateStack; + + char [] buffer = new char [30]; + int bufferIndex; + + public XQueryTokenizer (TextReader reader) + { + this.source = reader; + + stateStack = new Stack (); + + nsResolver = new XmlNamespaceManager (new NameTable ()); + nsResolver.AddNamespace ("xs", XmlSchema.Namespace); + nsResolver.AddNamespace ("xdt", InternalPool.XdtNamespace); + // FIXME: Are they really predefined? + nsResolver.AddNamespace ("xsi", XmlSchema.InstanceNamespace); + nsResolver.AddNamespace ("fn", "http://www.w3.org/2003/11/xpath-functions"); + nsResolver.AddNamespace ("local", "http://www.w3.org/2003/11/xquery-local-functions"); + } + + internal IXmlNamespaceResolver NSResolver { + get { return nsResolver; } + } + + internal string DefaultFunctionNamespace { + get { return defaultFunctionNamespace; } + set { defaultFunctionNamespace = value; } + } + + public void AddNamespace (string prefix, string ns) + { + nsResolver.AddNamespace (prefix, ns); + } + + public bool advance () + { + if (currentToken < 0) + return false; + if (lookAheadToken >= 0) { + tokenValue = lookAheadTokenValue; + currentToken = lookAheadToken; + lookAheadToken = -1; + } + else + currentToken = ParseToken (); + return currentToken >= 0; + } + + public int token () + { + return currentToken; + } + + public object value () + { + return tokenValue; + } + + public bool HasLineInfo () + { + return true; + } + + public int LineNumber { + get { return line; } + } + + public int LinePosition { + get { return column; } + } + + internal WhitespaceHandling Space { + get { return ws; } + set { ws = value; } + } + + internal ParseState State { + get { return state; } + set { +// Console.Error.WriteLine ("**** eno **** state transition from {0} to {1}, stack count = {2}", state, value, stateStack.Count); +//foreach (ParseState ps in stateStack.ToArray ()) Console.Error.WriteLine ("***** eno ***** " + ps); + state = value; + } + } + + internal void PushState (ParseState newState) + { + stateStack.Push (newState); +// Console.Error.WriteLine ("**** eno **** state pushed {0}, added stack count = {1}", newState, stateStack.Count); +//foreach (ParseState ps in stateStack.ToArray ()) Console.Error.WriteLine ("***** eno ***** " + ps); + } + + internal void PopState () + { + if (stateStack.Count == 0) + throw Error ("Internal state transition error. State stack is empty."); + state = (ParseState) stateStack.Pop (); +// Console.Error.WriteLine ("**** eno **** state pop, now as {0}, stack count = {1}", state, stateStack.Count); +//foreach (ParseState ps in stateStack.ToArray ()) Console.Error.WriteLine ("***** eno ***** " + ps); + } + + private XmlQueryCompileException Error (string message) + { + return new XmlQueryCompileException (message, this, null, null); + } + + private int ParseToken () + { + bufferIndex = 0; + + switch (state) { + case ParseState.StartTag: + break; + default: + SkipWhitespaces (); + break; + } + /* + switch (ws) { + case WhitespaceHandling.Arbitrary: + SkipWhitespaces (); + break; + case WhitespaceHandling.Explicit: + if (!XmlChar.IsWhitespace (PeekChar ())) + throw Error ("Whitespace is required."); + goto case WhitespaceHandling.Arbitrary; + } + */ + + int c = PeekChar (); + if (c < 0) + return -1; + + // FIXME: consider DOUBLE_LITERAL + if (Char.IsNumber ((char) c)) { + tokenValue = ReadDecimal (false); + return Token.DECIMAL_LITERAL; + } + + switch (state) { + case ParseState.OccurenceIndicator: + return ParseOccurenceIndicator (); + case ParseState.XmlPIContent: + return ParseXmlPIContent (); + case ParseState.XmlComment: + return ParseXmlCommentContent (); + case ParseState.ElementContent: + return ParseElementContent (); + case ParseState.StartTag: + return ParseStartTag (); + case ParseState.QuotAttributeContent: + return ParseAttributeContent ('"'); + case ParseState.AposAttributeContent: + return ParseAttributeContent ('\''); + default: + return ParseDefault (); + } + } + + private int ParseXQueryComment () + { + while (true) { + int c = ReadChar (); + if (c < 0) + throw Error ("Unexpected end of query text inside XML processing instruction content"); + if (c == ':') { + if (PeekChar () == ')') { + ReadChar (); + tokenValue = CreateValueString (); + return Token.XML_PI_TO_END; + } + else + AddValueChar (':'); + } + else + AddValueChar ((char) c); + } + } + + private int ParseXmlPIContent () + { + while (true) { + int c = ReadChar (); + if (c < 0) + throw Error ("Unexpected end of query text inside XML processing instruction content"); + if (c == '?') { + if (PeekChar () == '>') { + ReadChar (); + tokenValue = CreateValueString (); + return Token.XML_PI_TO_END; + } + else + AddValueChar ('?'); + } + else + AddValueChar ((char) c); + } + } + + private int ParseXmlCommentContent () + { + // FIXME: handle ---> correctly + while (true) { + int c = ReadChar (); + if (c < 0) + throw Error ("Unexpected end of query text inside XML comment content"); + if (c == '-') { + if (PeekChar () == '-') { + ReadChar (); + if (PeekChar () == '>') { + tokenValue = CreateValueString (); + return Token.XML_COMMENT_TO_END; + } else { + AddValueChar ('-'); + AddValueChar ('-'); + } + } + else + AddValueChar ('-'); + } + else + AddValueChar ((char) c); + } + } + + private int ParseXmlCDataContent () + { + // FIXME: handle ]]]> correctly + while (true) { + int c = ReadChar (); + if (c < 0) + throw Error ("Unexpected end of query text inside XML CDATA section content"); + if (c == ']') { + ReadChar (); + if (PeekChar () == ']') { + ReadChar (); + if (PeekChar () == '>') { + tokenValue = CreateValueString (); + return Token.XML_CDATA_TO_END; + } else { + AddValueChar (']'); + AddValueChar (']'); + } + } + else + AddValueChar (']'); + } + else + AddValueChar ((char) c); + } + } + + private int ParseElementContent () + { + tokenValue = null; + int c = PeekChar (); + if (c < 0) + throw Error ("Unexpected end of query text inside XML processing instruction content"); + switch ((char) c) { + case '<': + case '{': + return ParseDefault (); + } + + while (true) { + c = PeekChar (); + if (c < 0) + throw Error ("Unexpected end of query text inside XML processing instruction content"); + switch ((char) c) { + case '&': + ReadChar (); + ReadPredefinedEntity (); + continue; + case '<': + tokenValue += CreateValueString (); + return Token.ELEM_CONTENT_LITERAL; + default: + AddValueChar ((char) c); + ReadChar (); + continue; + } + } + } + + private void ReadPredefinedEntity () + { + string token = ReadOneToken (); + Expect (";"); + switch (token) { + case "lt": + AddValueChar ('<'); + return; + case "gt": + AddValueChar ('>'); + return; + case "amp": + AddValueChar ('&'); + return; + case "quot": + AddValueChar ('"'); + return; + case "apos": + AddValueChar ('\''); + return; + default: + throw Error (String.Format ("Unexpected general entity name: {0} .", token)); + } + } + + // FIXME: not used as yet + private int ParseExtContent () + { + // FIXME: handle :::) correctly + while (true) { + int c = PeekChar (); + if (c < 0) + throw Error ("Unexpected end of query text inside external content"); + if (c == ':') { + ReadChar (); + if (PeekChar () == ':') { + ReadChar (); + if (PeekChar () == ')') { + tokenValue = CreateValueString (); + return Token.EXT_CONTENT; + } else { + AddValueChar (':'); + AddValueChar (':'); + } + } + else + AddValueChar (':'); + } + else + AddValueChar ((char) c); + } + } + + private int ParseOccurenceIndicator () + { + state = ParseState.Operator; + switch (PeekChar ()) { + case '?': + ReadChar (); + return Token.QUESTION; + case '*': + ReadChar (); + return Token.ASTERISK; + case '+': + ReadChar (); + return Token.PLUS; + default: + return ParseOperator (); + } + } + + private int ParseStartTag () + { + int c = PeekChar (); + switch (c) { + case '\'': + ReadChar (); + return Token.APOS; + case '"': + ReadChar (); + return Token.QUOT; + case '>': + ReadChar (); + return Token.GREATER; + case '/': + ReadChar (); + Expect (">"); + return Token.EMPTY_TAG_CLOSE; + } + // FIXME: there seems a bug in the spec that StartTag + // state must accept QName without heading space for + // start tag name. +// if (!XmlChar.IsWhitespace (PeekChar ())) +// throw Error ("Whitespace is required."); + SkipWhitespaces (); + return ParseDefault (); // only QName is allowed here. + } + + private int ParseAttributeContent (char closeChar) + { + int t = Token.ATT_VALUE_LITERAL; + while (true) { + int c = PeekChar (); + if (c < 0) + throw Error ("Unexpected end of attribute value content."); + if (c == closeChar) { + ReadChar (); + c = PeekChar (); + if (c == closeChar) { + ReadChar (); + AddValueChar (closeChar); + } + else + t = closeChar == '"' ? Token.QUOT : Token.APOS; + } + else if (c == '{') { + ReadChar (); + c = PeekChar (); + if (c == '{') { + ReadChar (); + AddValueChar ('{'); + } + else + t = Token.OPEN_CURLY; + } + else + AddValueChar ((char) ReadChar ()); + + if (t != Token.ATT_VALUE_LITERAL) { + if (bufferIndex > 0) { + lookAheadToken = t; + tokenValue = CreateValueString (); + return Token.ATT_VALUE_LITERAL; + } + else + return t; + } + } + } + + private int ParseOperator () + { + // TODO: implement + return ParseDefault (); + } + + private int ParseDefault () + { + int c = ReadChar (); + switch (c) { + case '.': + if (PeekChar () == '.') { + ReadChar (); + return Token.DOT2; + } + else if (Char.IsNumber ((char) PeekChar ())) { + tokenValue = ReadDecimal (true); + } + return Token.DOT; + case ',': + return Token.COMMA; + case ';': + return Token.SEMICOLON; + case '(': + if (PeekChar () == ':') { + ReadChar (); + if (PeekChar () == ':') { + ReadChar (); + return Token.PRAGMA_OPEN; + } + ParseXQueryComment (); + return ParseToken (); // start again + } + return Token.OPEN_PAREN; + case ')': + return Token.CLOSE_PAREN; + case ':': + switch (PeekChar ()) { + case ':': + ReadChar (); + if (PeekChar () == ')') { + ReadChar (); + return Token.PRAGMA_CLOSE; + } + return Token.COLON2; + case ')': + ReadChar (); + return Token.CLOSE_PAREN_COLON; + case '=': + ReadChar (); + return Token.COLON_EQUAL; + } + return Token.COLON; + case '[': + return Token.OPEN_BRACKET; + case ']': + return Token.CLOSE_BRACKET; + case '{': + return Token.OPEN_CURLY; + case '}': + return Token.CLOSE_CURLY; + case '$': + return Token.DOLLAR; + case '\'': + tokenValue = ReadQuoted ('\''); + return Token.STRING_LITERAL; + case '"': + tokenValue = ReadQuoted ('"'); + return Token.STRING_LITERAL; + case '=': + return Token.EQUAL; + case '<': + // only happens when state is ElementContent + // (otherwise it might be "/foo</bar") + if (state == ParseState.ElementContent) { + switch ((char) PeekChar ()) { + case '/': + ReadChar (); + return Token.END_TAG_START; + case '!': + ReadChar (); + switch (PeekChar ()) { + case '-': + ReadChar (); + if (ReadChar () != '-') + throw Error ("Invalid sequence of characters '<!-'."); + + return Token.XML_COMMENT_START; + case '[': + ReadChar (); + Expect ("CDATA["); + return Token.XML_CDATA_START; + } + throw Error ("Invalid sequence of characters '<!'."); + case '?': + ReadChar (); + return Token.XML_PI_START; + default: + return Token.LESSER; + } + } + + switch (PeekChar ()) { + case '<': + ReadChar (); + return Token.LESSER2; + case '=': + ReadChar (); + return Token.LESSER_EQUAL; + } + return Token.LESSER; + case '>': + switch (PeekChar ()) { + case '>': + ReadChar (); + return Token.GREATER2; + case '=': + ReadChar (); + return Token.GREATER_EQUAL; + } + return Token.GREATER; + case '|': + return Token.BAR; + case '*': + if (PeekChar () == ':') { + ReadChar (); + // FIXME: more check + tokenValue = new XmlQualifiedName (ReadOneToken (), "*"); + return Token.WILD_PREFIX; + } + return Token.ASTERISK; + case '+': + return Token.PLUS; + case '-': + return Token.MINUS; + case '/': + // only happens when state is StartTag + // (otherwise it might be "/>$extvar") + if (state == ParseState.StartTag && PeekChar () == '>') { + ReadChar (); + return Token.EMPTY_TAG_CLOSE; + } + if (PeekChar () == '/') { + ReadChar (); + return Token.SLASH2; + } + return Token.SLASH; + case '?': + return Token.QUESTION; + case '@': + return Token.AT; + } + + peekChar = c; + prefixName = null; + string name = ReadOneToken (); + + tokenValue = name; + bool validKeyword = false; + + switch (state) { + case ParseState.XmlSpaceDecl: + switch (name) { + case "preserve": + return Token.PRESERVE; + case "strip": + return Token.STRIP; + } + break; + case ParseState.CloseKindTest: + if (name == "nillable") + return Token.NILLABLE; + break; + case ParseState.ExtKey: + switch (name) { + case "pragma": + return Token.PRAGMA; + case "extension": + return Token.EXTENSION; + } + break; + case ParseState.KindTest: + switch (name) { + case "context": + return Token.CONTEXT; + case "element": + return Token.ELEMENT; + case "global": + return Token.GLOBAL; + case "type": + return Token.TYPE; + } + break; + case ParseState.ItemType: + switch (name) { + case "attribute": + return Token.ATTRIBUTE; + case "comment": + return Token.COMMENT; + case "document-node": + return Token.DOCUMENT_NODE; + case "element": + return Token.ELEMENT; + case "empty": + return Token.EMPTY; + case "item": + return Token.ITEM; + case "node": + return Token.NODE; + case "processing-instruction": + return Token.PROCESSING_INSTRUCTION; + case "text": + return Token.TEXT; + } + break; + case ParseState.NamespaceKeyword: + switch (name) { + case "declare": + return Token.DECLARE; + case "default": + return Token.DEFAULT; + case "element": + return Token.ELEMENT; + case "function": + return Token.FUNCTION; + case "namespace": + return Token.NAMESPACE; + } + break; + case ParseState.OccurenceIndicator: + case ParseState.Operator: + switch (name) { + case "and": + case "as": + case "ascending": + case "at": + case "base-uri": + case "by": + case "case": + case "cast": + case "castable": + case "collation": + case "declare": + case "default": + case "descending": + case "div": + case "element": + case "else": + case "empty": + case "eq": + case "every": + case "except": + case "external": + case "for": + case "function": + case "ge": + case "global": + case "greatest": + case "gt": + case "idiv": + case "import": + case "in": + case "instance": + case "intersect": + case "is": + case "lax": + case "le": + case "least": + case "let": + case "lt": + case "mod": + case "module": + case "namespace": + case "ne": + case "of": + case "or": + case "order": + case "ordered": + case "ordering": + case "return": + case "satisfies": + case "schema": + case "skip": + case "some": + case "stable": + case "strict": + case "then": + case "to": + case "treat": + case "typwswitch": + case "union": + case "unordered": + case "variable": + case "where": + case "xmlspace": + validKeyword = true; + break; + } + break; + case ParseState.Default: + switch (name) { + case "ancestor": + case "ancestor-or-self": + case "as": + case "attribute": + case "base-uri": + case "child": + case "collation": + case "comment": + case "construction": + case "declare": + case "default": + case "descendant": + case "descendant-or-self": + case "document": + case "document-node": + case "element": + case "every": + case "following": + case "following-sibling": + case "for": + case "function": + case "global": + case "if": + case "import": + case "lax": + case "let": + case "module": + case "namespace": + case "node": + case "ordered": + case "parent": + case "preceding": + case "preceding-sibling": + case "processing-instruction": + case "schema": + case "self": + case "some": + case "strict": + case "strip": + case "text": + case "typeswitch": + case "unordered": + case "validate": + case "validation": + case "version": + case "xmlspace": + case "xquery": + validKeyword = true; + break; + } + break; + } + + if (validKeyword) { + switch (name) { + case "xquery": + return Token.XQUERY; + case "version": + return Token.VERSION; + case "pragma": + return Token.PRAGMA; + case "extension": + return Token.EXTENSION; + case "module": + return Token.MODULE; + case "namespace": + return Token.NAMESPACE; + case "declare": + return Token.DECLARE; + case "xmlspace": + return Token.XMLSPACE; + case "preserve": + return Token.PRESERVE; + case "strip": + return Token.STRIP; + case "default": + return Token.DEFAULT; + case "construction": + return Token.CONSTRUCTION; + case "ordering": + return Token.ORDERING; + case "ordered": + return Token.ORDERED; + case "unordered": + return Token.UNORDERED; + case "document-node": + return Token.DOCUMENT_NODE; + case "document": + return Token.DOCUMENT; + case "element": + return Token.ELEMENT; + case "attribute": + return Token.ATTRIBUTE; + case "processing-instruction": + return Token.PROCESSING_INSTRUCTION; + case "comment": + return Token.COMMENT; + case "text": + return Token.TEXT; + case "node": + return Token.NODE; + case "function": + return Token.FUNCTION; + case "collation": + return Token.COLLATION; + case "base-uri": + return Token.BASEURI; + case "import": + return Token.IMPORT; + case "schema": + return Token.SCHEMA; + case "at": + return Token.AT; + case "variable": + return Token.VARIABLE; + case "as": + return Token.AS; + case "external": + return Token.EXTERNAL; + case "validation": + return Token.VALIDATION; + case "lax": + return Token.LAX; + case "strict": + return Token.STRICT; + case "skip": + return Token.SKIP; + case "return": + return Token.RETURN; + case "for": + return Token.FOR; + case "let": + return Token.LET; + case "in": + return Token.IN; + case "where": + return Token.WHERE; + case "order": + return Token.ORDER; + case "by": + return Token.BY; + case "stable": + return Token.STABLE; + case "ascending": + return Token.ASCENDING; + case "descending": + return Token.DESCENDING; + case "empty": + return Token.EMPTY; + case "greatest": + return Token.GREATEST; + case "least": + return Token.LEAST; + case "some": + return Token.SOME; + case "every": + return Token.EVERY; + case "satisfies": + return Token.SATISFIES; + case "is": + return Token.IS; + case "to": + return Token.TO; + case "eq": + return Token.EQ; + case "ne": + return Token.NE; + case "lt": + return Token.LT; + case "le": + return Token.LE; + case "gt": + return Token.GT; + case "ge": + return Token.GE; + case "and": + return Token.AND; + case "or": + return Token.OR; + case "instance": + return Token.INSTANCE; + case "of": + return Token.OF; + case "if": + return Token.IF; + case "then": + return Token.THEN; + case "else": + return Token.ELSE; + case "typeswitch": + return Token.TYPESWITCH; + case "case": + return Token.CASE; + case "treat": + return Token.TREAT; + case "castable": + return Token.CASTABLE; + case "cast": + return Token.CAST; + case "div": + return Token.DIV; + case "idiv": + return Token.IDIV; + case "mod": + return Token.MOD; + case "union": + return Token.UNION; + case "intersect": + return Token.INTERSECT; + case "except": + return Token.EXCEPT; + case "validate": + return Token.VALIDATE; + case "context": + return Token.CONTEXT; + case "nillable": + return Token.NILLABLE; + case "item": + return Token.ITEM; + case "global": + return Token.GLOBAL; + case "type": + return Token.TYPE; + case "child": + return Token.CHILD; + case "descendant": + return Token.DESCENDANT; + case "self": + return Token.SELF; + case "descendant-or-self": + return Token.DESCENDANT_OR_SELF; + case "following-sibling": + return Token.FOLLOWING_SIBLING; + case "following": + return Token.FOLLOWING; + case "parent": + return Token.PARENT; + case "ancestor": + return Token.ANCESTOR; + case "preceding": + return Token.PRECEDING; + case "preceding-sibling": + return Token.PRECEDING_SIBLING; + case "ancestor-or-self": + return Token.ANCESTOR_OR_SELF; + } + } + + switch (state) { + case ParseState.NamespaceDecl: + case ParseState.NamespaceKeyword: + case ParseState.XmlSpaceDecl: + case ParseState.KindTestForPI: + case ParseState.XmlPI: + return Token.NCNAME; + } + + if (PeekChar () == ':') { + ReadChar (); + prefixName = name; + switch (PeekChar ()) { + case '*': + ReadChar (); + name = "*"; + break; + case '=': // ex. let foo:= ... + ReadChar (); + tokenValue = new XmlQualifiedName (name, nsResolver.DefaultNamespace); + lookAheadToken = Token.COLON_EQUAL; + return Token.QNAME; + default: + name = ReadOneToken (); + break; + } + + string ns = nsResolver.LookupNamespace (prefixName); + if (ns == null) + throw Error (String.Format ("Prefix '{0}' is not mapped to any namespace URI.", prefixName)); + tokenValue = new XmlQualifiedName (name, ns); + prefixName = null; + return name == "*" ? Token.WILD_LOCALNAME : Token.QNAME; + } + tokenValue = new XmlQualifiedName (name); + return Token.QNAME; + } + + private int PeekChar () + { + if (peekChar == -1) + peekChar = source.Read (); + return peekChar; + } + + private int ReadChar () + { + int ret; + if (peekChar != -1) { + ret = peekChar; + peekChar = -1; + } + else + ret = source.Read (); + + if (nextIncrementLine) { + line++; + column = 0; + nextIncrementLine = false; + } + column++; + switch (ret) { + case '\r': + break; + case '\n': + nextIncrementLine = true; + goto default; + default: + break; + } + + return ret; + } + + private void SkipWhitespaces () + { + while (true) { + switch (PeekChar ()) { + case ' ': + case '\t': + case '\r': + case '\n': + ReadChar (); + continue; + default: + return; + } + } + } + + private void AddValueChar (char c) + { + if (bufferIndex == buffer.Length) { + char [] newBuf = new char [bufferIndex * 2]; + Array.Copy (buffer, newBuf, bufferIndex); + buffer = newBuf; + } + buffer [bufferIndex++] = c; + } + + private string CreateValueString () + { + return new string (buffer, 0, bufferIndex); + } + + private void Expect (string expected) + { + for (int i = 0; i < expected.Length; i++) + if (ReadChar () != expected [i]) + throw Error (String.Format ("Expected token '{0}' did not appear.", expected)); + } + + // TODO: parse three quoted + private string ReadQuoted (char quoteChar) + { + bufferIndex = 0; + bool loop = true; + do { + int c = ReadChar (); + switch (c) { + case -1: + case '"': + if (quoteChar == '"') + loop = false; + break; + case '\'': + if (quoteChar == '\'') + loop = false; + break; + default: + AddValueChar ((char) c); + break; + } + } while (loop); + + return CreateValueString (); + } + + private decimal ReadDecimal (bool floatingPoint) + { + bufferIndex = 0; + bool cond = true; + do { + int c = PeekChar (); + if (c < 0) { + cond = false; + } + // FIXME: more complex + else if (Char.IsNumber ((char) c) || c == '.') { + ReadChar (); + AddValueChar ((char) c); + continue; + } + else + cond = false; + } while (cond); + string s = (floatingPoint ? "." : "") + CreateValueString (); + return decimal.Parse (s); + } + + private string ReadOneToken () + { + bufferIndex = 0; + bool loop = true; + do { + int c = PeekChar (); + switch (c) { + case -1: + case ' ': + case '\t': + case '\r': + case '\n': + loop = false; + break; + default: + if (!IsTokenContinuable (c)) { + if (c == ':') { + if (prefixName != null) + throw new XmlQueryCompileException ("Invalid colon was found."); + prefixName = CreateValueString (); + } + loop = false; + break; + } + + ReadChar (); + AddValueChar ((char) c); + break; + } + } while (loop); + + return CreateValueString (); + } + + private bool IsTokenContinuable (int c) + { + switch (c) { + case '-': + case '_': + case '.': + return true; + } + return XmlChar.IsNCNameChar (c); + } + + } + + public enum WhitespaceHandling { + Arbitrary, + Explicit, + Significant + } + + public enum ParseState { + Default, + Operator, + NamespaceDecl, + NamespaceKeyword, + XmlSpaceDecl, + ItemType, + KindTest, + KindTestForPI, + CloseKindTest, + OccurenceIndicator, + SchemaContextStep, + VarName, + StartTag, + ElementContent, + EndTag, + XmlComment, + ExprComment, + ExtKey, + XmlPI, + XmlPIContent, + CDataSection, + QuotAttributeContent, + AposAttributeContent, + } + +} +#endif diff --git a/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryASTCompiler.cs b/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryASTCompiler.cs index 2d18e9e676c..7a92fc936dd 100755 --- a/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryASTCompiler.cs +++ b/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryASTCompiler.cs @@ -127,7 +127,7 @@ namespace Mono.Xml.XPath2 foreach (ModuleImport modimp in p.ModuleImports) { foreach (string uri in modimp.Locations) { Stream s = res.GetEntity (res.ResolveUri (null, uri), null, typeof (Stream)) as Stream; - XQueryLibraryModule ext = XQueryParser.Parse (new StreamReader (s)) as XQueryLibraryModule; + XQueryLibraryModule ext = Mono.Xml.XQuery.Parser.Parser.Parse (new StreamReader (s)) as XQueryLibraryModule; if (ext == null) throw new XmlQueryCompileException (String.Format ("External module {0} is resolved as a main module, while it should be a library module.")); XQueryStaticContext sctx = new XQueryASTCompiler (ext, options, compileContext, evidence, commandImpl).Compile (); diff --git a/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryCommandImpl.cs b/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryCommandImpl.cs index e77ec257e23..e3cfdd5ecd4 100755 --- a/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryCommandImpl.cs +++ b/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryCommandImpl.cs @@ -63,7 +63,7 @@ namespace Mono.Xml.XPath2 public void Compile (TextReader input, Evidence evidence, object xqueryCommand) { - staticContext = XQueryASTCompiler.Compile (XQueryParser.Parse (input), null, evidence, this); + staticContext = XQueryASTCompiler.Compile (Mono.Xml.XQuery.Parser.Parser.Parse (input), null, evidence, this); this.xqueryCommand = xqueryCommand; // FIXME: generate executable assembly, and load it with evidence. } diff --git a/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryParser.jay b/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryParser.jay index 0f5f2416132..7b90e34213a 100755 --- a/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryParser.jay +++ b/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryParser.jay @@ -31,6 +31,7 @@ // FIXME: // attribute value template // handle double literal +// string literal in XQuery and XPath2 are different // #if NET_2_0 @@ -47,15 +48,19 @@ 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 XQueryParser + internal class Parser { // See also FunctionCall production rule. static Hashtable reservedFunctionNames; static int yacc_verbose_flag; - static XQueryParser () + static Parser () { reservedFunctionNames = new Hashtable (); reservedFunctionNames.Add ("attribute", "attribute"); @@ -74,13 +79,20 @@ namespace Mono.Xml.XQuery.Parser public static XQueryModule Parse (TextReader reader) { - return new XQueryParser ().RunParse (reader); + return new Parser ().RunParse (reader); } private XQueryTokenizer tokenizer; + private bool isXQueryMode; - private XQueryParser () + private Parser () + : this (true) { + } + + private Parser (bool isXQueryMode) + { + this.isXQueryMode = isXQueryMode; ErrorOutput = TextWriter.Null; } @@ -90,7 +102,8 @@ namespace Mono.Xml.XQuery.Parser { tokenizer = null; try { -// debug = new yydebug.yyDebugSimple (); + if (Environment.GetEnvironmentVariable ("MONO_DEBUG_XPATH2") == "yes") + debug = new yydebug.yyDebugSimple (); tokenizer = new XQueryTokenizer (source); XQueryModule mod = (XQueryModule) yyparse (tokenizer); mod.NSResolver = tokenizer.NSResolver; @@ -345,6 +358,9 @@ namespace Mono.Xml.XQuery.Parser %token PRECEDING //"preceding" %token ANCESTOR_OR_SELF //"ancestor-or-self" +%token PRAGMA_START "(#" +%token PRAGMA_END "#)" +%token PragmaContents %token QNAME @@ -934,6 +950,57 @@ ExprSingle // returns ExprSingle | OrExpr ; + +/* ------------------------------------- + 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 ------------------------------------- */ @@ -943,6 +1010,8 @@ FLWORExpr // returns FLWORExpr 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); } @@ -1233,6 +1302,8 @@ TypeswitchExpr // returns TypeswitchExpr 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); } ; @@ -1578,8 +1649,46 @@ IntersectExceptExpr 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 ----------------- */ @@ -1592,6 +1701,8 @@ ValidateExpr // returns ValidateExpr tokenizer.PushState (ParseState.Operator); } Expr CloseCurly { + if (!isXQueryMode) + throw new XmlQueryCompileException ("XPath2 does not support validate expression."); $$ = new ValidateExpr ((XmlSchemaContentProcessing) $2, (ExprSequence) $6); } ; @@ -1723,6 +1834,12 @@ ForwardAxis // returns XPathAxis { $$ = XPathAxis.Following; } + | NAMESPACE COLON2 + { + if (isXQueryMode) + throw new XmlQueryCompileException ("XQuery does not support namespace axis."); + $$ = XPathAxis.NamespaceAxis; + } ; ReverseAxis // returns XPathAxis @@ -2037,8 +2154,23 @@ PrimaryExpr // returns ExprSingle | 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 diff --git a/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryTokenizer.cs b/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryTokenizer.cs index 67a10da8ce9..2a4cd93204b 100755 --- a/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryTokenizer.cs +++ b/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/XQueryTokenizer.cs @@ -1,3 +1,4 @@ +#define XQUERY_PARSER // // XQueryTokenizer.cs // @@ -40,11 +41,14 @@ using Mono.Xml.XQuery; using Mono.Xml.XPath2; using Mono.Xml; +#if XPATH2_PARSER +namespace Mono.Xml.XPath2.Parser +#elif XQUERY_PARSER namespace Mono.Xml.XQuery.Parser +#endif { // FIXME: make internal in the future - public class XQueryTokenizer - : Mono.Xml.XQuery.Parser.yyParser.yyInput, IXmlLineInfo + public class XQueryTokenizer : yyParser.yyInput, IXmlLineInfo { int line = 1; int column = 0; diff --git a/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/skeleton-2.0.cs b/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/skeleton-2.0.cs deleted file mode 100755 index e6bc3b1b856..00000000000 --- a/mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/skeleton-2.0.cs +++ /dev/null @@ -1,364 +0,0 @@ -# jay skeleton - -# character in column 1 determines outcome... -# # is a comment -# . is copied -# t is copied as //t if -t is set -# other lines are interpreted to call jay procedures - -.// created by jay 0.7 (c) 1998 Axel.Schreiner@informatik.uni-osnabrueck.de -. -.#if NET_2_0 -. - prolog ## %{ ... %} prior to the first %% - -. -. /** error output stream. -. It should be changeable. -. */ -. internal System.IO.TextWriter ErrorOutput = System.Console.Out; -. -. /** simplified error message. -. @see <a href="#yyerror(java.lang.String, java.lang.String[])">yyerror</a> -. */ -. internal void yyerror (string message) { -. yyerror(message, null); -. } -. -. /** (syntax) error message. -. Can be overwritten to control message format. -. @param message text to be displayed. -. @param expected vector of acceptable tokens, if available. -. */ -. internal void yyerror (string message, string[] expected) { -. if ((expected != null) && (expected.Length > 0)) { -. ErrorOutput.Write (message+", expecting"); -. for (int n = 0; n < expected.Length; ++ n) -. ErrorOutput.Write (" "+expected[n]); -. ErrorOutput.WriteLine (); -. } else -. ErrorOutput.WriteLine (message); -. } -. -. /** debugging support, requires the package jay.yydebug. -. Set to null to suppress debugging messages. -. */ -t internal yydebug.yyDebug debug; -. - debug ## tables for debugging support -. -. /** index-checked interface to yyNames[]. -. @param token single character or %token value. -. @return token name or [illegal] or [unknown]. -. */ -t internal static string yyname (int token) { -t if ((token < 0) || (token > yyNames.Length)) return "[illegal]"; -t string name; -t if ((name = yyNames[token]) != null) return name; -t return "[unknown]"; -t } -. -. /** computes list of expected tokens on error by tracing the tables. -. @param state for which to compute the list. -. @return list of token names. -. */ -. internal string[] yyExpecting (int state) { -. int token, n, len = 0; -. bool[] ok = new bool[yyNames.Length]; -. -. if ((n = yySindex[state]) != 0) -. for (token = n < 0 ? -n : 0; -. (token < yyNames.Length) && (n+token < yyTable.Length); ++ token) -. if (yyCheck[n+token] == token && !ok[token] && yyNames[token] != null) { -. ++ len; -. ok[token] = true; -. } -. if ((n = yyRindex[state]) != 0) -. for (token = n < 0 ? -n : 0; -. (token < yyNames.Length) && (n+token < yyTable.Length); ++ token) -. if (yyCheck[n+token] == token && !ok[token] && yyNames[token] != null) { -. ++ len; -. ok[token] = true; -. } -. -. string [] result = new string[len]; -. for (n = token = 0; n < len; ++ token) -. if (ok[token]) result[n++] = yyNames[token]; -. return result; -. } -. -. /** the generated parser, with debugging messages. -. Maintains a state and a value stack, currently with fixed maximum size. -. @param yyLex scanner. -. @param yydebug debug message writer implementing yyDebug, or null. -. @return result of the last reduction, if any. -. @throws yyException on irrecoverable parse error. -. */ -. internal Object yyparse (yyParser.yyInput yyLex, Object yyd) -. { -t this.debug = (yydebug.yyDebug)yyd; -. return yyparse(yyLex); -. } -. -. /** initial size and increment of the state/value stack [default 256]. -. This is not final so that it can be overwritten outside of invocations -. of yyparse(). -. */ -. internal int yyMax; -. -. /** executed at the beginning of a reduce action. -. Used as $$ = yyDefault($1), prior to the user-specified action, if any. -. Can be overwritten to provide deep copy, etc. -. @param first value for $1, or null. -. @return first. -. */ -. internal Object yyDefault (Object first) { -. return first; -. } -. -. /** the generated parser. -. Maintains a state and a value stack, currently with fixed maximum size. -. @param yyLex scanner. -. @return result of the last reduction, if any. -. @throws yyException on irrecoverable parse error. -. */ -. internal Object yyparse (yyParser.yyInput yyLex) -. { -. if (yyMax <= 0) yyMax = 256; // initial size -. int yyState = 0; // state stack ptr -. int [] yyStates = new int[yyMax]; // state stack -. Object yyVal = null; // value stack ptr -. Object [] yyVals = new Object[yyMax]; // value stack -. int yyToken = -1; // current input -. int yyErrorFlag = 0; // #tks to shift -. - local ## %{ ... %} after the first %% - -. int yyTop = 0; -. goto skip; -. yyLoop: -. yyTop++; -. skip: -. for (;; ++ yyTop) { -. if (yyTop >= yyStates.Length) { // dynamically increase -. int[] i = new int[yyStates.Length+yyMax]; -. yyStates.CopyTo (i, 0); -. yyStates = i; -. Object[] o = new Object[yyVals.Length+yyMax]; -. yyVals.CopyTo (o, 0); -. yyVals = o; -. } -. yyStates[yyTop] = yyState; -. yyVals[yyTop] = yyVal; -t if (debug != null) debug.push(yyState, yyVal); -. -. yyDiscarded: for (;;) { // discarding a token does not change stack -. int yyN; -. if ((yyN = yyDefRed[yyState]) == 0) { // else [default] reduce (yyN) -. if (yyToken < 0) { -. yyToken = yyLex.advance() ? yyLex.token() : 0; - -t if (debug != null) -t debug.lex(yyState, yyToken, yyname(yyToken), yyLex.value()); -. } -. if ((yyN = yySindex[yyState]) != 0 && ((yyN += yyToken) >= 0) -. && (yyN < yyTable.Length) && (yyCheck[yyN] == yyToken)) { -t if (debug != null) -t debug.shift(yyState, yyTable[yyN], yyErrorFlag-1); -. yyState = yyTable[yyN]; // shift to yyN -. yyVal = yyLex.value(); -. yyToken = -1; -. if (yyErrorFlag > 0) -- yyErrorFlag; -. goto yyLoop; -. } -. if ((yyN = yyRindex[yyState]) != 0 && (yyN += yyToken) >= 0 -. && yyN < yyTable.Length && yyCheck[yyN] == yyToken) -. yyN = yyTable[yyN]; // reduce (yyN) -. else -. switch (yyErrorFlag) { -. -. case 0: -. yyerror(String.Format ("syntax error, got token `{0}'", yyname (yyToken)), yyExpecting(yyState)); -t if (debug != null) debug.error("syntax error"); -. goto case 1; -. case 1: case 2: -. yyErrorFlag = 3; -. do { -. if ((yyN = yySindex[yyStates[yyTop]]) != 0 -. && (yyN += Token.yyErrorCode) >= 0 && yyN < yyTable.Length -. && yyCheck[yyN] == Token.yyErrorCode) { -t if (debug != null) -t debug.shift(yyStates[yyTop], yyTable[yyN], 3); -. yyState = yyTable[yyN]; -. yyVal = yyLex.value(); -. goto yyLoop; -. } -t if (debug != null) debug.pop(yyStates[yyTop]); -. } while (-- yyTop >= 0); -t if (debug != null) debug.reject(); -. throw new yyParser.yyException("irrecoverable syntax error"); -. -. case 3: -. if (yyToken == 0) { -t if (debug != null) debug.reject(); -. throw new yyParser.yyException("irrecoverable syntax error at end-of-file"); -. } -t if (debug != null) -t debug.discard(yyState, yyToken, yyname(yyToken), -t yyLex.value()); -. yyToken = -1; -. goto yyDiscarded; // leave stack alone -. } -. } -. int yyV = yyTop + 1-yyLen[yyN]; -t if (debug != null) -t debug.reduce(yyState, yyStates[yyV-1], yyN, yyRule[yyN], yyLen[yyN]); -. yyVal = yyDefault(yyV > yyTop ? null : yyVals[yyV]); -. switch (yyN) { - - actions ## code from the actions within the grammar - -. } -. yyTop -= yyLen[yyN]; -. yyState = yyStates[yyTop]; -. int yyM = yyLhs[yyN]; -. if (yyState == 0 && yyM == 0) { -t if (debug != null) debug.shift(0, yyFinal); -. yyState = yyFinal; -. if (yyToken < 0) { -. yyToken = yyLex.advance() ? yyLex.token() : 0; - -t if (debug != null) -t debug.lex(yyState, yyToken,yyname(yyToken), yyLex.value()); -. } -. if (yyToken == 0) { -t if (debug != null) debug.accept(yyVal); -. return yyVal; -. } -. goto yyLoop; -. } -. if (((yyN = yyGindex[yyM]) != 0) && ((yyN += yyState) >= 0) -. && (yyN < yyTable.Length) && (yyCheck[yyN] == yyState)) -. yyState = yyTable[yyN]; -. else -. yyState = yyDgoto[yyM]; -t if (debug != null) debug.shift(yyStates[yyTop], yyState); -. goto yyLoop; -. } -. } -. } -. - tables ## tables for rules, default reduction, and action calls -. - epilog ## text following second %% -.namespace yydebug { -. using System; -. internal interface yyDebug { -. void push (int state, Object value); -. void lex (int state, int token, string name, Object value); -. void shift (int from, int to, int errorFlag); -. void pop (int state); -. void discard (int state, int token, string name, Object value); -. void reduce (int from, int to, int rule, string text, int len); -. void shift (int from, int to); -. void accept (Object value); -. void error (string message); -. void reject (); -. } -. -. class yyDebugSimple : yyDebug { -. void println (string s){ -. Console.Error.WriteLine (s); -. } -. -. public void push (int state, Object value) { -. println ("push\tstate "+state+"\tvalue "+value); -. } -. -. public void lex (int state, int token, string name, Object value) { -. println("lex\tstate "+state+"\treading "+name+"\tvalue "+value); -. } -. -. public void shift (int from, int to, int errorFlag) { -. switch (errorFlag) { -. default: // normally -. println("shift\tfrom state "+from+" to "+to); -. break; -. case 0: case 1: case 2: // in error recovery -. println("shift\tfrom state "+from+" to "+to -. +"\t"+errorFlag+" left to recover"); -. break; -. case 3: // normally -. println("shift\tfrom state "+from+" to "+to+"\ton error"); -. break; -. } -. } -. -. public void pop (int state) { -. println("pop\tstate "+state+"\ton error"); -. } -. -. public void discard (int state, int token, string name, Object value) { -. println("discard\tstate "+state+"\ttoken "+name+"\tvalue "+value); -. } -. -. public void reduce (int from, int to, int rule, string text, int len) { -. println("reduce\tstate "+from+"\tuncover "+to -. +"\trule ("+rule+") "+text); -. } -. -. public void shift (int from, int to) { -. println("goto\tfrom state "+from+" to "+to); -. } -. -. public void accept (Object value) { -. println("accept\tvalue "+value); -. } -. -. public void error (string message) { -. println("error\t"+message); -. } -. -. public void reject () { -. println("reject"); -. } -. -. } -.} -.// %token constants -. class Token { - tokens public const int -. } -. namespace yyParser { -. using System; -. /** thrown for irrecoverable syntax errors and stack overflow. -. */ -. internal class yyException : System.Exception { -. public yyException (string message) : base (message) { -. } -. } -. -. /** must be implemented by a scanner object to supply input to the parser. -. */ -. internal interface yyInput { -. /** move on to next token. -. @return false if positioned beyond tokens. -. @throws IOException on input error. -. */ -. bool advance (); // throws java.io.IOException; -. /** classifies current token. -. Should not be called if advance() returned false. -. @return current %token or single character. -. */ -. int token (); -. /** associated with current token. -. Should not be called if advance() returned false. -. @return value for token(). -. */ -. Object value (); -. } -. } -.} // close outermost namespace, that MUST HAVE BEEN opened in the prolog -. -.#endif - |