From 15b3e50931ac60648eefd9e285e9f8cfb986ead1 Mon Sep 17 00:00:00 2001 From: Atsushi Eno Date: Fri, 18 Mar 2005 07:09:50 +0000 Subject: 2005-03-18 Atsushi Enomoto * 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 --- mcs/class/Mono.Xml.Ext/ChangeLog | 7 + mcs/class/Mono.Xml.Ext/Makefile | 40 +- mcs/class/Mono.Xml.Ext/Mono.Xml.Ext.dll.sources | 2 - mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/ChangeLog | 12 + .../Mono.Xml.Ext/Mono.Xml.XPath2/ParserBase.jay | 2680 ++++++++++++++++++++ .../Mono.Xml.Ext/Mono.Xml.XPath2/SequenceType.cs | 7 +- .../Mono.Xml.Ext/Mono.Xml.XPath2/TokenizerBase.cs | 1288 ++++++++++ .../Mono.Xml.XPath2/XQueryASTCompiler.cs | 2 +- .../Mono.Xml.XPath2/XQueryCommandImpl.cs | 2 +- .../Mono.Xml.Ext/Mono.Xml.XPath2/XQueryParser.jay | 142 +- .../Mono.Xml.XPath2/XQueryTokenizer.cs | 8 +- .../Mono.Xml.Ext/Mono.Xml.XPath2/skeleton-2.0.cs | 364 --- 12 files changed, 4175 insertions(+), 379 deletions(-) create mode 100644 mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/ParserBase.jay create mode 100644 mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/TokenizerBase.cs delete mode 100755 mcs/class/Mono.Xml.Ext/Mono.Xml.XPath2/skeleton-2.0.cs (limited to 'mcs/class/Mono.Xml.Ext') 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 + + * Makefile: + build XPath2/XQuery parsers/tokenizers from common codebase. + * Mono.Xml.Ext.dll: + removed built sources. + 2004-11-19 Atsushi Enomoto * 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 + + * 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 * 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 +// +// 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_PI_START // "" +%token XML_CDATA_START // " +%token EMPTY_TAG_CLOSE // "/>" +%token END_TAG_START // " there after 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 +// +// 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': + 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 yyerror -. */ -. 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 - -- cgit v1.2.3