diff options
author | Piers Haken <piers@mono-cvs.ximian.com> | 2002-06-23 20:52:58 +0400 |
---|---|---|
committer | Piers Haken <piers@mono-cvs.ximian.com> | 2002-06-23 20:52:58 +0400 |
commit | 8d73a2306c27e346de99e78f9159c90f6a2335b3 (patch) | |
tree | 83083f5c228ffef9ead2ea138a0c1e22415c3d9b /mcs/class | |
parent | 7ec8739ed077e1243410f6914b70f1bb87757667 (diff) |
2002-06-23 Piers Haken <piersh@friskit.com>
System.Xml:
* XmlDocumentNavigator.cs: implement Clone()
* XmlElement.cs: remove bogus unimplemented override of InnerText
* XmlNode.cs: implment SelectNodes/SelectSingleNode
* XmlNodeArrayList.cs: new support class for SelectNodes
System.Xml.Xsl:
* XsltContext.cs: added 'PreserveWhitespace' abstract method
System.Xml.XPath:
* XPathNavigator.cs: implement:
- Compile
- Evaluate
- Clone
- Select
- ToString
- some forwarding methods
* XPathNodeIterator: implement caching Count
* Tokenizer.cs: new XPath tokenizer
* Parser.jay: new XPath grammar
* Parser.cs: new precompiled XPath grammar
* Expression.cs: new XPath expression objects
* Iterator.cs: new XPath result/context objects
* DefaultContext.cs: new XPath function binding context
svn path=/trunk/mcs/; revision=5421
Diffstat (limited to 'mcs/class')
17 files changed, 4152 insertions, 37 deletions
diff --git a/mcs/class/System.XML/Mono.System.XML.csproj b/mcs/class/System.XML/Mono.System.XML.csproj index 21d3819c1ef..18ecafccdae 100644 --- a/mcs/class/System.XML/Mono.System.XML.csproj +++ b/mcs/class/System.XML/Mono.System.XML.csproj @@ -91,6 +91,11 @@ BuildAction = "Compile"
/>
<File
+ RelPath = "System.Xml\IHasXmlNode.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
RelPath = "System.Xml\IXmlLineInfo.cs"
SubType = "Code"
BuildAction = "Compile"
@@ -161,6 +166,16 @@ BuildAction = "Compile"
/>
<File
+ RelPath = "System.Xml\XmlConstructs.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "System.Xml\XmlConvert.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
RelPath = "System.Xml\XmlDeclaration.cs"
SubType = "Code"
BuildAction = "Compile"
@@ -191,6 +206,11 @@ BuildAction = "Compile"
/>
<File
+ RelPath = "System.Xml\XmlEntity.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
RelPath = "System.Xml\XmlEntityReference.cs"
SubType = "Code"
BuildAction = "Compile"
@@ -261,11 +281,21 @@ BuildAction = "Compile"
/>
<File
+ RelPath = "System.Xml\XmlNodeReader.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
RelPath = "System.Xml\XmlNodeType.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
+ RelPath = "System.Xml\XmlNotation.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
RelPath = "System.Xml\XmlParserContext.cs"
SubType = "Code"
BuildAction = "Compile"
@@ -345,11 +375,40 @@ BuildAction = "None"
/>
<File
+ RelPath = "System.Xml.XPath\DefaultContext.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "System.Xml.XPath\Expression.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "System.Xml.XPath\Iterator.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
RelPath = "System.Xml.XPath\IXPathNavigable.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
+ RelPath = "System.Xml.XPath\Parser.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "System.Xml.XPath\Parser.jay"
+ BuildAction = "None"
+ />
+ <File
+ RelPath = "System.Xml.XPath\Tokenizer.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
RelPath = "System.Xml.XPath\XmlCaseOrder.cs"
SubType = "Code"
BuildAction = "Compile"
@@ -365,6 +424,16 @@ BuildAction = "Compile"
/>
<File
+ RelPath = "System.Xml.XPath\XPathDocument.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "System.Xml.XPath\XPathException.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
RelPath = "System.Xml.XPath\XPathExpression.cs"
SubType = "Code"
BuildAction = "Compile"
diff --git a/mcs/class/System.XML/System.Xml.XPath/ChangeLog b/mcs/class/System.XML/System.Xml.XPath/ChangeLog index e6597f62d20..03cc6a385c8 100644 --- a/mcs/class/System.XML/System.Xml.XPath/ChangeLog +++ b/mcs/class/System.XML/System.Xml.XPath/ChangeLog @@ -1,3 +1,22 @@ +2002-06-23 Piers Haken <piersh@friskit.com> + + * XPathNavigator.cs: implement: + - Compile + - Evaluate + - Clone + - Select + - ToString + - some forwarding methods + + * XPathNodeIterator: implement caching Count + + * Tokenizer.cs: new XPath tokenizer + * Parser.jay: new XPath grammar + * Parser.cs: new precompiled XPath grammar + * Expression.cs: new XPath expression objects + * Iterator.cs: new XPath result/context objects + * DefaultContext.cs: new XPath function binding context + 2002-05-08 Tim Coleman <tim@timcoleman.com> * XPathDocument.cs: * XPathException.cs: New stub files added. diff --git a/mcs/class/System.XML/System.Xml.XPath/DefaultContext.cs b/mcs/class/System.XML/System.Xml.XPath/DefaultContext.cs new file mode 100644 index 00000000000..37fcc29a7a6 --- /dev/null +++ b/mcs/class/System.XML/System.Xml.XPath/DefaultContext.cs @@ -0,0 +1,568 @@ +// +// System.Xml.XPath.DefaultContext & support classes +// +// Author: +// Piers Haken (piersh@friskit.com) +// +// (C) 2002 Piers Haken +// +using System; +using System.Collections; +using System.Xml; +using System.Xml.XPath; +using System.Xml.Xsl; + +namespace System.Xml.XPath +{ + /// <summary> + /// Summary description for DefaultContext. + /// </summary> + internal class DefaultContext : XsltContext + { + protected static Hashtable _htFunctions = new Hashtable (); + + static DefaultContext() + { + Add (new XPathFunctionLast ()); + Add (new XPathFunctionPosition ()); + Add (new XPathFunctionCount ()); + Add (new XPathFunctionId ()); + Add (new XPathFunctionLocalName ()); + Add (new XPathFunctionNamespaceUri ()); + Add (new XPathFunctionName ()); + Add (new XPathFunctionString ()); + Add (new XPathFunctionConcat ()); + Add (new XPathFunctionStartsWith ()); + Add (new XPathFunctionContains ()); + Add (new XPathFunctionSubstringBefore ()); + Add (new XPathFunctionSubstringAfter ()); + Add (new XPathFunctionSubstring ()); + Add (new XPathFunctionStringLength ()); + Add (new XPathFunctionNormalizeSpace ()); + Add (new XPathFunctionTranslate ()); + Add (new XPathFunctionBoolean ()); + Add (new XPathFunctionNot ()); + Add (new XPathFunctionTrue ()); + Add (new XPathFunctionFalse ()); + Add (new XPathFunctionLang ()); + Add (new XPathFunctionNumber ()); + Add (new XPathFunctionSum ()); + Add (new XPathFunctionFloor ()); + Add (new XPathFunctionCeil ()); + Add (new XPathFunctionRound ()); + } + + [MonoTODO] + public override IXsltContextFunction ResolveFunction (string prefix, string name, XPathResultType[] ArgTypes) + { + // match the prefix + if (prefix != null && prefix != "") // TODO: should we allow some namespaces here? + return null; + + // match the function name + XPathFunction fn = (XPathFunction) _htFunctions [name]; + if (fn == null) + return null; + + // check the number of arguments + int cArgs = ArgTypes.Length; + if (cArgs < fn.Minargs || cArgs > fn.Maxargs) + return null; + + // check the types of the arguments + XPathResultType [] rgTypes = fn.ArgTypes; + if (rgTypes == null) + { + if (cArgs != 0) + return null; + } + else + { + int cTypes = rgTypes.Length; + for (int iArg = 0; iArg < cArgs; iArg ++) + { + XPathResultType typeRequested = ArgTypes [iArg]; + XPathResultType typeDefined = (iArg >= cTypes) ? rgTypes [cTypes - 1] : rgTypes [iArg]; + if (typeDefined != XPathResultType.Any && typeDefined != typeRequested) + return null; + } + } + return fn; + } + public override IXsltContextVariable ResolveVariable (string prefix, string name) + { + return null; + } + [MonoTODO] + public override int CompareDocument (string baseUri, string nextBaseUri) { throw new NotImplementedException (); } + [MonoTODO] + public override bool PreserveWhitespace (XPathNavigator nav) { throw new NotImplementedException (); } + [MonoTODO] + public override bool Whitespace { get { throw new NotImplementedException (); }} + protected static void Add (XPathFunction fn) + { + _htFunctions.Add (fn.Name, fn); + } + } + + internal class XPathFunctions + { + public static bool ToBoolean (object arg) + { + if (arg == null) + throw new ArgumentNullException (); + if (arg is bool) + return (bool) arg; + if (arg is double) + { + double dArg = (double) arg; + return (dArg != 0.0 && !double.IsNaN (dArg)); + } + if (arg is string) + return ((string) arg).Length != 0; + if (arg is BaseIterator) + { + BaseIterator iter = (BaseIterator) arg; + return iter.MoveNext (); + } + throw new ArgumentException (); + } + [MonoTODO] + public static string ToString (object arg) + { + if (arg == null) + throw new ArgumentNullException (); + if (arg is string) + return (string) arg; + if (arg is bool) + return ((bool) arg) ? "true" : "false"; + if (arg is double) + return (string) XmlConvert.ToString ((double) arg); // TODO: spec? convert number to string + if (arg is BaseIterator) + { + BaseIterator iter = (BaseIterator) arg; + if (!iter.MoveNext ()) + return ""; + return iter.Current.Value; + } + throw new ArgumentException (); + } + [MonoTODO] + public static double ToNumber (object arg) + { + if (arg == null) + throw new ArgumentNullException (); + if (arg is BaseIterator) + arg = ToString (arg); // follow on + if (arg is string) + return XmlConvert.ToDouble ((string) arg); // TODO: spec? convert string to number + if (arg is double) + return (double) arg; + if (arg is bool) + return Convert.ToDouble ((bool) arg); + throw new ArgumentException (); + } + } + + internal abstract class XPathFunction : IXsltContextFunction + { + public abstract XPathResultType ReturnType { get; } + public abstract int Minargs { get; } + public abstract int Maxargs { get; } + public abstract XPathResultType [] ArgTypes { get; } + public object Invoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + return TypesafeInvoke (xsltContext, args, docContext); + } + + public abstract string Name { get; } + public abstract object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext); + } + + internal class XPathFunctionLast : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.Number; }} + public override int Minargs { get { return 0; }} + public override int Maxargs { get { return 0; }} + public override XPathResultType [] ArgTypes { get { return null; }} + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + throw new NotImplementedException (); // special-cased + } + public override string Name { get { return "last"; }} + } + internal class XPathFunctionPosition : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.Number; }} + public override int Minargs { get { return 0; }} + public override int Maxargs { get { return 0; }} + public override XPathResultType [] ArgTypes { get { return null; }} + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + throw new NotImplementedException (); // special-cased + } + public override string Name { get { return "position"; }} + } + internal class XPathFunctionCount : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.Number; }} + public override int Minargs { get { return 1; }} + public override int Maxargs { get { return 1; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.NodeSet }; }} + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + return ((BaseIterator) args [0]).Count; + } + public override string Name { get { return "count"; }} + } + internal class XPathFunctionId : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.Number; }} + public override int Minargs { get { return 1; }} + public override int Maxargs { get { return 1; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.Any }; }} + [MonoTODO] + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + throw new NotImplementedException (); + } + public override string Name { get { return "id"; }} + } + internal class XPathFunctionLocalName : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.NodeSet; }} + public override int Minargs { get { return 0; }} + public override int Maxargs { get { return 1; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.NodeSet }; }} + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + BaseIterator iter = (args.Length == 1) ? ((BaseIterator) args [0]) : new SelfIterator (docContext, xsltContext); + if (iter == null || !iter.MoveNext ()) + return ""; + return iter.Current.LocalName; + } + public override string Name { get { return "local-name"; }} + } + internal class XPathFunctionNamespaceUri : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.String; }} + public override int Minargs { get { return 0; }} + public override int Maxargs { get { return 1; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.NodeSet }; }} + [MonoTODO] + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + BaseIterator iter = (args.Length == 1) ? ((BaseIterator) args [0]) : new SelfIterator (docContext, xsltContext); + if (iter == null || !iter.MoveNext ()) + return ""; + return iter.Current.NamespaceURI; // TODO: should the namespace be expanded wrt. the given context? + } + public override string Name { get { return "namespace-uri"; }} + } + internal class XPathFunctionName : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.String; }} + public override int Minargs { get { return 0; }} + public override int Maxargs { get { return 1; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.NodeSet }; }} + [MonoTODO] + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + throw new NotImplementedException (); + } + public override string Name { get { return "name"; }} + } + internal class XPathFunctionString : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.String; }} + public override int Minargs { get { return 0; }} + public override int Maxargs { get { return 1; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.Any }; }} + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + return XPathFunctions.ToString (args [0]); + } + public override string Name { get { return "string"; }} + } + internal class XPathFunctionConcat : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.String; }} + public override int Minargs { get { return 2; }} + public override int Maxargs { get { return int.MaxValue; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String, XPathResultType.String, XPathResultType.String }; }} + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + String str = ""; + foreach (string strArg in args) + str += strArg; + return str; + } + public override string Name { get { return "concat"; }} + } + internal class XPathFunctionStartsWith : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.Boolean; }} + public override int Minargs { get { return 2; }} + public override int Maxargs { get { return 2; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String, XPathResultType.String }; }} + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + string str1 = (string) args [0]; + string str2 = (string) args [1]; + return str1.StartsWith (str2); + } + public override string Name { get { return "starts-with"; }} + } + internal class XPathFunctionContains : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.Boolean; }} + public override int Minargs { get { return 2; }} + public override int Maxargs { get { return 2; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String, XPathResultType.String }; }} + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + string str1 = (string) args [0]; + string str2 = (string) args [1]; + return str1.IndexOf (str2) != -1; + } + public override string Name { get { return "contains"; }} + } + internal class XPathFunctionSubstringBefore : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.String; }} + public override int Minargs { get { return 2; }} + public override int Maxargs { get { return 2; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String, XPathResultType.String }; }} + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + string str1 = (string) args [0]; + string str2 = (string) args [1]; + int ich = str1.IndexOf (str2); + if (ich <= 0) + return ""; + return str1.Substring (0, ich); + } + public override string Name { get { return "substring-before"; }} + } + internal class XPathFunctionSubstringAfter : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.String; }} + public override int Minargs { get { return 2; }} + public override int Maxargs { get { return 2; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String, XPathResultType.String }; }} + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + string str1 = (string) args [0]; + string str2 = (string) args [1]; + int ich = str1.IndexOf (str2); + if (ich <= 0) + return ""; + return str1.Substring (ich + str2.Length); + } + public override string Name { get { return "substring-after"; }} + } + internal class XPathFunctionSubstring : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.String; }} + public override int Minargs { get { return 2; }} + public override int Maxargs { get { return int.MaxValue; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String, XPathResultType.String, XPathResultType.String }; }} + [MonoTODO] + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + // TODO: check this, what the hell were they smoking? + string str = (string) args [0]; + double ich = Math.Round ((double) args [1]) - 1; + if (Double.IsNaN (ich) || ich >= (double) str.Length) + return ""; + + if (args.Length == 2) + { + if (ich < 0) + ich = 0.0; + return str.Substring ((int) ich); + } + else + { + double cch = Math.Round ((double) args [2]); + if (Double.IsNaN (cch)) + return ""; + if (ich < 0.0 || cch < 0.0) + { + cch = ich + cch; + if (cch <= 0.0) + return ""; + ich = 0.0; + } + double cchMax = (double) str.Length - ich; + if (cch > cchMax) + cch = cchMax; + return str.Substring ((int) ich, (int) cch); + } + } + public override string Name { get { return "substring"; }} + } + internal class XPathFunctionStringLength : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.Number; }} + public override int Minargs { get { return 0; }} + public override int Maxargs { get { return 1; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String }; }} + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + return (double) ((string) args [0]).Length; + } + public override string Name { get { return "string-length"; }} + } + internal class XPathFunctionNormalizeSpace : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.String; }} + public override int Minargs { get { return 0; }} + public override int Maxargs { get { return 1; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String }; }} + [MonoTODO] + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + throw new NotImplementedException (); + } + public override string Name { get { return "normalize-sace"; }} + } + internal class XPathFunctionTranslate : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.String; }} + public override int Minargs { get { return 3; }} + public override int Maxargs { get { return 3; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String, XPathResultType.String, XPathResultType.String }; }} + [MonoTODO] + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + throw new NotImplementedException (); + } + public override string Name { get { return "translate"; }} + } + internal class XPathFunctionBoolean : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.Boolean; }} + public override int Minargs { get { return 1; }} + public override int Maxargs { get { return 1; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.Any }; }} + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + return XPathFunctions.ToBoolean (args [0]); + } + public override string Name { get { return "boolean"; }} + } + internal class XPathFunctionNot : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.Boolean; }} + public override int Minargs { get { return 1; }} + public override int Maxargs { get { return 1; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.Boolean }; }} + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + return !((bool) args [0]); + } + public override string Name { get { return "not"; }} + } + internal class XPathFunctionTrue : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.Boolean; }} + public override int Minargs { get { return 0; }} + public override int Maxargs { get { return 0; }} + public override XPathResultType [] ArgTypes { get { return null; }} + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + return true; + } + public override string Name { get { return "true"; }} + } + internal class XPathFunctionFalse : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.Boolean; }} + public override int Minargs { get { return 0; }} + public override int Maxargs { get { return 0; }} + public override XPathResultType [] ArgTypes { get { return null; }} + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + return false; + } + public override string Name { get { return "false"; }} + } + internal class XPathFunctionLang : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.Boolean; }} + public override int Minargs { get { return 1; }} + public override int Maxargs { get { return 1; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.String }; }} + [MonoTODO] + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + throw new NotImplementedException (); + } + public override string Name { get { return "lang"; }} + } + internal class XPathFunctionNumber : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.Number; }} + public override int Minargs { get { return 0; }} + public override int Maxargs { get { return 1; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.Any }; }} + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + return XPathFunctions.ToNumber (args [0]); + } + public override string Name { get { return "number"; }} + } + internal class XPathFunctionSum : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.Number; }} + public override int Minargs { get { return 1; }} + public override int Maxargs { get { return 1; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.NodeSet }; }} + [MonoTODO] + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + throw new NotImplementedException (); + } + public override string Name { get { return "sum"; }} + } + internal class XPathFunctionFloor : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.Number; }} + public override int Minargs { get { return 1; }} + public override int Maxargs { get { return 1; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.Number }; }} + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + return Math.Floor ((double) args [0]); + } + public override string Name { get { return "floor"; }} + } + internal class XPathFunctionCeil : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.Number; }} + public override int Minargs { get { return 1; }} + public override int Maxargs { get { return 1; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.Number }; }} + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + return Math.Ceiling ((double) args [0]); + } + public override string Name { get { return "ceil"; }} + } + internal class XPathFunctionRound : XPathFunction + { + public override XPathResultType ReturnType { get { return XPathResultType.Number; }} + public override int Minargs { get { return 1; }} + public override int Maxargs { get { return 1; }} + public override XPathResultType [] ArgTypes { get { return new XPathResultType [] { XPathResultType.Number }; }} + public override object TypesafeInvoke (XsltContext xsltContext, object[] args, XPathNavigator docContext) + { + double arg = (double) args [0]; + if (arg < -0.5 || arg > 0) + return Math.Floor (arg + 0.5); + return Math.Round (arg); + } + public override string Name { get { return "round"; }} + } +} diff --git a/mcs/class/System.XML/System.Xml.XPath/Expression.cs b/mcs/class/System.XML/System.Xml.XPath/Expression.cs new file mode 100644 index 00000000000..e4e960243a6 --- /dev/null +++ b/mcs/class/System.XML/System.Xml.XPath/Expression.cs @@ -0,0 +1,1031 @@ +// +// System.Xml.XPath.XPathExpression support classes +// +// Author: +// Piers Haken (piersh@friskit.com) +// +// (C) 2002 Piers Haken +// +using System; +using System.IO; +using System.Collections; +using System.Xml; +using System.Xml.XPath; +using System.Xml.Xsl; + +namespace System.Xml.XPath +{ +/* + public class MonoTODOAttribute : Attribute + { + } + public abstract class XPathExpression + { + internal XPathExpression () {} + + public abstract void AddSort (Object obj, IComparer cmp); + public abstract void AddSort(object obj, XmlSortOrder sortOrder, XmlCaseOrder caseOrder, string str, XmlDataType type); + public abstract XPathExpression Clone (); + public abstract void SetContext (XmlNamespaceManager nsManager); + public abstract String Expression { get; } + public abstract XPathResultType ReturnType { get; } + } +*/ + + internal class CompiledExpression : XPathExpression + { + protected XmlNamespaceManager _nsm; + protected Expression _expr; + +/* + public static void Main (String [] rgstrArgs) + { + Tokenizer tokenizer = new Tokenizer ("/root/*[position() = last()]/@goo"); + XPathParser parser = new XPathParser (); +// Expression e = (Expression) parser.yyparse (tokenizer, new yydebug.yyDebugSimple ()); + Expression e = (Expression) parser.yyparse (tokenizer); + Console.WriteLine (e.ToString ()); + CompiledExpression expr = new CompiledExpression (e); + XmlDocument doc = new XmlDocument (); + doc.Load ("..\\doc.xml"); + XPathNavigator nav = doc.CreateNavigator (); + BaseIterator iter = new SelfIterator (nav, new DefaultContext ()); + + BaseIterator iterResult = expr._expr.EvaluateNodeSet (iter); + while (iterResult.MoveNext ()) + { + System.Diagnostics.Debug.WriteLine ("------"); + System.Diagnostics.Debug.WriteLine (iterResult.Current.Name); + System.Diagnostics.Debug.WriteLine (iterResult.Current.Value); + } + } +*/ + public CompiledExpression (Expression expr) + { + _expr = expr; + } + private CompiledExpression (CompiledExpression other) + { + _nsm = other._nsm; + _expr = other._expr; + } + public override XPathExpression Clone () { return new CompiledExpression (this); } + + public override void SetContext (XmlNamespaceManager nsManager) + { + _nsm = nsManager; + } + public override String Expression { get { return _expr.ToString (); }} + public override XPathResultType ReturnType { get { return _expr.ReturnType; }} + [MonoTODO] + public override void AddSort (Object obj, IComparer cmp) + { + throw new NotImplementedException (); + } + [MonoTODO] + public override void AddSort(object obj, XmlSortOrder sortOrder, XmlCaseOrder caseOrder, string str, XmlDataType type) + { + throw new NotImplementedException (); + } + + public object Evaluate (BaseIterator iter) + { + return _expr.Evaluate (iter); + } + public XPathNodeIterator EvaluateNodeSet (BaseIterator iter) + { + return _expr.EvaluateNodeSet (iter); + } + } + + + /// <summary> + /// Summary description for Expression. + /// </summary> + internal abstract class Expression + { + public Expression () + { + } + public abstract XPathResultType ReturnType { get; } + public virtual XPathResultType GetReturnType (BaseIterator iter) { return ReturnType; } + public virtual object Evaluate (BaseIterator iter) { return null; } + + public BaseIterator EvaluateNodeSet (BaseIterator iter) + { + if (GetReturnType (iter) == XPathResultType.NodeSet) + return (BaseIterator) Evaluate (iter); + throw new Exception ("expected nodeset: "+ToString ()); + } + [MonoTODO] + public double EvaluateNumber (BaseIterator iter) + { + object result; + XPathResultType type = GetReturnType (iter); + if (type == XPathResultType.NodeSet) + { + result = EvaluateString (iter); + type = XPathResultType.String; + } + else + result = Evaluate (iter); + + switch (type) + { + case XPathResultType.Number: + return (double) result; + case XPathResultType.Boolean: + return Convert.ToDouble ((bool) result); + case XPathResultType.String: + return XmlConvert.ToDouble ((string) result); // TODO: spec? convert string to number + default: + throw new Exception (); // TODO: handle other types + } + } + [MonoTODO] + public string EvaluateString (BaseIterator iter) + { + object result = Evaluate (iter); + switch (GetReturnType (iter)) + { + case XPathResultType.Number: + return (string) XmlConvert.ToString ((double) result); // TODO: spec? convert number to string + case XPathResultType.Boolean: + return ((bool) result) ? "true" : "false"; + case XPathResultType.String: + return (string) result; + case XPathResultType.NodeSet: + { + BaseIterator iterResult = (BaseIterator) result; + if (iterResult == null || !iterResult.MoveNext ()) + return ""; + return iterResult.Current.Value; + } + default: + throw new Exception (); // TODO: handle other types + } + } + [MonoTODO] + public bool EvaluateBoolean (BaseIterator iter) + { + object result = Evaluate (iter); + switch (GetReturnType (iter)) + { + case XPathResultType.Number: + { + double num = (double) result; + return (num != 0.0 && num != -0.0 && num != Double.NaN); + } + case XPathResultType.Boolean: + return (bool) result; + case XPathResultType.String: + return ((string) result).Length != 0; + case XPathResultType.NodeSet: + { + BaseIterator iterResult = (BaseIterator) result; + return (iterResult != null && iterResult.MoveNext ()); + } + default: + throw new Exception (); // TODO: handle other types + } + } + } + + internal abstract class ExprBinary : Expression + { + protected Expression _left, _right; + + public ExprBinary (Expression left, Expression right) + { + _left = left; + _right = right; + } + public override String ToString () + { + return _left.ToString () + ' ' + Operator + ' ' + _right.ToString (); + } + protected abstract String Operator { get; } + } + + internal abstract class ExprBoolean : ExprBinary + { + public ExprBoolean (Expression left, Expression right) : base (left, right) {} + public override XPathResultType ReturnType { get { return XPathResultType.Boolean; }} + } + + internal class ExprOR : ExprBoolean + { + public ExprOR (Expression left, Expression right) : base (left, right) {} + protected override String Operator { get { return "or"; }} + public override object Evaluate (BaseIterator iter) + { + if (_left.EvaluateBoolean (iter)) + return true; + return _right.EvaluateBoolean (iter); + } + } + internal class ExprAND : ExprBoolean + { + public ExprAND (Expression left, Expression right) : base (left, right) {} + protected override String Operator { get { return "and"; }} + public override object Evaluate (BaseIterator iter) + { + if (!_left.EvaluateBoolean (iter)) + return false; + return _right.EvaluateBoolean (iter); + } + } + + internal abstract class EqualityExpr : ExprBoolean + { + public EqualityExpr (Expression left, Expression right) : base (left, right) {} + [MonoTODO] + public override object Evaluate (BaseIterator iter) + { + XPathResultType typeL = _left.GetReturnType (iter); + XPathResultType typeR = _right.GetReturnType (iter); + if (typeL == XPathResultType.NodeSet || typeR == XPathResultType.NodeSet) + { + Expression left, right; + if (typeL != XPathResultType.NodeSet) + { + left = _right; + right = _left; + XPathResultType typeTmp = typeL; + typeL = typeR; + typeR = typeTmp; + } + else + { + left = _left; + right = _right; + } + if (typeR == XPathResultType.Boolean) + { + bool fL = left.EvaluateBoolean (iter); + bool fR = right.EvaluateBoolean (iter); + return Compare (Convert.ToDouble (fL), Convert.ToDouble (fR)); + } + else + { + BaseIterator iterL = left.EvaluateNodeSet (iter); + if (typeR == XPathResultType.Number) + { + double dR = right.EvaluateNumber (iter); + while (iterL.MoveNext ()) + if (Compare (XPathFunctions.ToNumber (iterL.Current.Value), dR)) + return true; + } + else if (typeR == XPathResultType.String) + { + string strR = right.EvaluateString (iter); + while (iterL.MoveNext ()) + if (Compare (iterL.Current.Value, strR)) + return true; + } + else if (typeR == XPathResultType.NodeSet) + { + throw new NotImplementedException (); // TODO: + } + return false; + } + } + else if (typeL == XPathResultType.Boolean || typeR == XPathResultType.Boolean) + {
+ return Compare (_left.EvaluateBoolean (iter), _right.EvaluateBoolean (iter)); + }
+ else if (typeL == XPathResultType.Number || typeR == XPathResultType.Number) + {
+ return Compare (_left.EvaluateNumber (iter), _right.EvaluateNumber (iter)); + }
+ else + {
+ return Compare (_left.EvaluateString (iter), _right.EvaluateString (iter)); + }
+ } + [MonoTODO] + public abstract bool Compare (object arg1, object arg2); // TODO: should probably have type-safe methods here + } + + internal class ExprEQ : EqualityExpr + { + public ExprEQ (Expression left, Expression right) : base (left, right) {} + protected override String Operator { get { return "="; }} + public override bool Compare (object arg1, object arg2) + { + return arg1.Equals (arg2); + } + } + internal class ExprNE : EqualityExpr + { + public ExprNE (Expression left, Expression right) : base (left, right) {} + protected override String Operator { get { return "!="; }} + public override bool Compare (object arg1, object arg2) + { + return !arg1.Equals (arg2); + } + } + + internal abstract class RelationalExpr : ExprBoolean + { + public RelationalExpr (Expression left, Expression right) : base (left, right) {} + [MonoTODO] + public override object Evaluate (BaseIterator iter) + { + XPathResultType typeL = _left.GetReturnType (iter); + XPathResultType typeR = _right.GetReturnType (iter); + if (typeL == XPathResultType.NodeSet || typeR == XPathResultType.NodeSet) + { + bool fReverse = false; + Expression left, right; + if (typeL != XPathResultType.NodeSet) + { + fReverse = true; + left = _right; + right = _left; + XPathResultType typeTmp = typeL; + typeL = typeR; + typeR = typeTmp; + } + else + { + left = _left; + right = _right; + } + if (typeR == XPathResultType.Boolean) + { + bool fL = left.EvaluateBoolean (iter); + bool fR = right.EvaluateBoolean (iter); + return Compare (Convert.ToDouble (fL), Convert.ToDouble (fR), fReverse); + } + else + { + BaseIterator iterL = left.EvaluateNodeSet (iter); + if (typeR == XPathResultType.Number || typeR == XPathResultType.String) + { + double dR = right.EvaluateNumber (iter); + while (iterL.MoveNext ()) + if (Compare (XPathFunctions.ToNumber (iterL.Current.Value), dR, fReverse)) + return true; + } + else if (typeR == XPathResultType.NodeSet) + { + throw new NotImplementedException (); // TODO: + } + return false; + } + } + else + return Compare (_left.EvaluateNumber (iter), _right.EvaluateNumber (iter)); + } + public abstract bool Compare (double arg1, double arg2); + public bool Compare (double arg1, double arg2, bool fReverse) + { + if (fReverse) + return Compare (arg2, arg1); + else + return Compare (arg1, arg2); + } + } + internal class ExprGT : RelationalExpr + { + public ExprGT (Expression left, Expression right) : base (left, right) {} + protected override String Operator { get { return ">"; }} + public override bool Compare (double arg1, double arg2) + { + return arg1 > arg2; + } + } + internal class ExprGE : RelationalExpr + { + public ExprGE (Expression left, Expression right) : base (left, right) {} + protected override String Operator { get { return ">="; }} + public override bool Compare (double arg1, double arg2) + { + return arg1 >= arg2; + } + } + internal class ExprLT : RelationalExpr + { + public ExprLT (Expression left, Expression right) : base (left, right) {} + protected override String Operator { get { return "<"; }} + public override bool Compare (double arg1, double arg2) + { + return arg1 < arg2; + } + } + internal class ExprLE : RelationalExpr + { + public ExprLE (Expression left, Expression right) : base (left, right) {} + protected override String Operator { get { return "<="; }} + public override bool Compare (double arg1, double arg2) + { + return arg1 <= arg2; + } + } + + + internal abstract class ExprNumeric : ExprBinary + { + public ExprNumeric (Expression left, Expression right) : base (left, right) {} + public override XPathResultType ReturnType { get { return XPathResultType.Number; }} + } + + internal class ExprPLUS : ExprNumeric + { + public ExprPLUS (Expression left, Expression right) : base (left, right) {} + protected override String Operator { get { return "+"; }} + public override object Evaluate (BaseIterator iter) + { + return _left.EvaluateNumber (iter) + _right.EvaluateNumber (iter); + } + } + internal class ExprMINUS : ExprNumeric + { + public ExprMINUS (Expression left, Expression right) : base (left, right) {} + protected override String Operator { get { return "-"; }} + public override object Evaluate (BaseIterator iter) + { + return _left.EvaluateNumber (iter) - _right.EvaluateNumber (iter); + } + } + internal class ExprMULT : ExprNumeric + { + public ExprMULT (Expression left, Expression right) : base (left, right) {} + protected override String Operator { get { return "*"; }} + public override object Evaluate (BaseIterator iter) + { + return _left.EvaluateNumber (iter) * _right.EvaluateNumber (iter); + } + } + internal class ExprDIV : ExprNumeric + { + public ExprDIV (Expression left, Expression right) : base (left, right) {} + protected override String Operator { get { return "/"; }} + public override object Evaluate (BaseIterator iter) + { + return _left.EvaluateNumber (iter) / _right.EvaluateNumber (iter); + } + } + internal class ExprMOD : ExprNumeric + { + public ExprMOD (Expression left, Expression right) : base (left, right) {} + protected override String Operator { get { return "%"; }} + [MonoTODO] + public override object Evaluate (BaseIterator iter) + { + return _left.EvaluateNumber (iter) % _right.EvaluateNumber (iter); // TODO: spec? + } + } + internal class ExprNEG : Expression + { + Expression _expr; + public ExprNEG (Expression expr) + { + _expr = expr; + } + public override String ToString () { return "- " + _expr.ToString (); } + public override XPathResultType ReturnType { get { return XPathResultType.Number; }} + public override object Evaluate (BaseIterator iter) + { + return - _expr.EvaluateNumber (iter); + } + } + + + internal abstract class NodeSet : Expression + { + public override XPathResultType ReturnType { get { return XPathResultType.NodeSet; }} + } + internal class ExprUNION : NodeSet + { + protected Expression _left, _right; + public ExprUNION (NodeSet left, NodeSet right) + { + _left = left; + _right = right; + } + public override String ToString () { return _left.ToString ()+ " | " + _right.ToString (); } + public override object Evaluate (BaseIterator iter) + { + UnionIterator iterUnion = new UnionIterator (iter); + iterUnion.Add (_left.EvaluateNodeSet (iter)); + iterUnion.Add (_right.EvaluateNodeSet (iter)); + return iterUnion; + } + } + internal class ExprSLASH : NodeSet + { + protected Expression _left, _right; + public ExprSLASH (NodeSet left, NodeSet right) + { + _left = left; + _right = right; + } + public override String ToString () { return _left.ToString ()+ "/" + _right.ToString (); } + public override object Evaluate (BaseIterator iter) + { + BaseIterator iterLeft = _left.EvaluateNodeSet (iter); + return new SlashIterator (iterLeft, _right); + } + } + internal class ExprRoot : NodeSet + { + public override String ToString () { return ""; } + public override object Evaluate (BaseIterator iter) + { + XPathNavigator navRoot = iter.Current.Clone (); + navRoot.MoveToRoot (); + return new SelfIterator (navRoot, iter.Context); + } + } + + internal enum Axes + { + Ancestor, + AncestorOrSelf, + Attribute, + Child, + Descendant, + DescendantOrSelf, + Following, + FollowingSibling, + Namespace, + Parent, + Preceding, + PrecedingSibling, + Self, + } + + internal class AxisSpecifier + { + protected Axes _axis; + public AxisSpecifier (Axes axis) + { + _axis = axis; + } + public XPathNodeType NodeType + { + get + { + switch (_axis) + { + case Axes.Namespace: + return XPathNodeType.Namespace; + case Axes.Attribute: + return XPathNodeType.Attribute; + default: + return XPathNodeType.Element; + } + } + } + public override string ToString () + { + switch (_axis) + { + case Axes.Ancestor: + return "ancestor"; + case Axes.AncestorOrSelf: + return "ancestor-or-self"; + case Axes.Attribute: + return "attribute"; + case Axes.Child: + return "child"; + case Axes.Descendant: + return "descendant"; + case Axes.DescendantOrSelf: + return "descendant-or-self"; + case Axes.Following: + return "following"; + case Axes.FollowingSibling: + return "following-sibling"; + case Axes.Namespace: + return "namespace"; + case Axes.Parent: + return "parent"; + case Axes.Preceding: + return "preceeding"; + case Axes.PrecedingSibling: + return "preceeding-sibling"; + case Axes.Self: + return "self"; + default: + throw new IndexOutOfRangeException (); + } + } + public Axes Axis { get { return _axis; }} + public virtual BaseIterator Evaluate (BaseIterator iter) + { + switch (_axis) + { + case Axes.Ancestor: + return new AncestorIterator (iter); + case Axes.AncestorOrSelf: + return new AncestorOrSelfIterator (iter); + case Axes.Attribute: + return new AttributeIterator (iter); + case Axes.Child: + return new ChildIterator (iter); + case Axes.Descendant: + return new DescendantIterator (iter); + case Axes.DescendantOrSelf: + return new DescendantOrSelfIterator (iter); + case Axes.Following: + return new FollowingIterator (iter); + case Axes.FollowingSibling: + return new FollowingSiblingIterator (iter); + case Axes.Namespace: + return new NamespaceIterator (iter); + case Axes.Parent: + return new ParentIterator (iter); + case Axes.Preceding: + return new PrecedingIterator (iter); + case Axes.PrecedingSibling: + return new PrecedingSiblingIterator (iter); + case Axes.Self: + return new SelfIterator (iter); + default: + throw new IndexOutOfRangeException (); + } + } + } + + internal abstract class NodeTest + { + protected AxisSpecifier _axis; + public NodeTest (AxisSpecifier axis) + { + _axis = axis; + } + public NodeTest (Axes axis) + { + _axis = new AxisSpecifier (axis); + } + public abstract bool Match (XsltContext context, XPathNavigator nav); + public AxisSpecifier Axis { get { return _axis; }} + public virtual BaseIterator Evaluate (BaseIterator iter) + { + BaseIterator iterAxis = _axis.Evaluate (iter); + return new AxisIterator (iterAxis, this); + } + } + + internal enum NodeTestTypes + { + Comment, + Text, + ProcessingInstruction, + Node, + Principal, + } + + internal class NodeTypeTest : NodeTest + { + protected NodeTestTypes _type; + protected String _param; + public NodeTypeTest (Axes axis, NodeTestTypes type) : base (axis) + { + _type = type; + } + [MonoTODO] + public NodeTypeTest (Axes axis, NodeTestTypes type, String param) : base (axis) + { + _type = type; + _param = param; + if (param != null && type != NodeTestTypes.ProcessingInstruction) + throw new Exception ("No argument allowed for "+ToString (_type)+"() test"); // TODO: better description + } + public override String ToString () + { + String strType = ToString (_type); + if (_type == NodeTestTypes.ProcessingInstruction && _param != null) + strType += "('" + _param + "')"; + else if (_type != NodeTestTypes.Principal) + strType += "()"; + + return _axis.ToString () + "::" + strType; + } + private static String ToString (NodeTestTypes type) + { + switch (type) + { + case NodeTestTypes.Comment: + return "comment"; + case NodeTestTypes.Text: + return "text"; + case NodeTestTypes.ProcessingInstruction: + return "processing-instruction"; + case NodeTestTypes.Node: + return "node"; + case NodeTestTypes.Principal: + return "*"; + default: + throw new NotImplementedException (); + } + } + public override bool Match (XsltContext context, XPathNavigator nav) + { + XPathNodeType nodeType = nav.NodeType; + switch (_type) + { + case NodeTestTypes.Comment: + return nodeType == XPathNodeType.Comment; + case NodeTestTypes.Text: + return nodeType == XPathNodeType.Text; + case NodeTestTypes.ProcessingInstruction: + if (nodeType != XPathNodeType.ProcessingInstruction) + return false; + if (_param != null && nav.Name != _param) + return false; + return true; + case NodeTestTypes.Node: + return true; + case NodeTestTypes.Principal: + return nodeType == _axis.NodeType; + default: + throw new NotImplementedException (); + } + } + } + internal class NodeNameTest : NodeTest + { + protected QName _name; + public NodeNameTest (Axes axis, QName name) : base (axis) + { + _name = name; + } + public override String ToString () { return _axis.ToString () + "::" + _name.ToString (); } + [MonoTODO] + public override bool Match (XsltContext context, XPathNavigator nav) + { + // must be the correct node type + if (nav.NodeType != _axis.NodeType) + return false; + + // test the local part of the name first + if (_name.Local != nav.LocalName) + return false; + + // get the prefix for the given name + String strURI1 = ""; + if (_name.Prefix != null) + { + strURI1 = context.LookupNamespace (_name.Prefix); // TODO: check to see if this returns null or "" + if (strURI1 == null) + throw new Exception ("Invalid namespace prefix: "+_name.Prefix); + } + + string strURI = nav.NamespaceURI; + if (strURI == null && strURI1 == "") // TODO: remove when bug #26855 fixed + return true; + + // test the prefixes + return strURI1 == nav.NamespaceURI; + } + } + + internal class NodeNameTestAny : NodeNameTest + { + public NodeNameTestAny (Axes axis, NCName name) : base (axis, name) {} + [MonoTODO] // TODO: this is a hack, the local part of the NCName is actually used as a prefix. + public override bool Match (XsltContext context, XPathNavigator nav) + { + // must be the correct node type + if (nav.NodeType != _axis.NodeType) + return false; + + // get the prefix for the given name + String strURI1 = context.LookupNamespace (_name.Local); // TODO: check to see if this returns null or "" + if (strURI1 == null) + throw new Exception ("Invalid namespace prefix: "+_name.Local); + + // just test the prefixes + return strURI1 == nav.NamespaceURI; + } + } + + + internal class ExprStep : NodeSet + { + protected NodeTest _test; + protected Expression [] _preds; + public ExprStep (NodeTest test, ExprPredicates preds) + { + _test = test; + if (preds != null) + _preds = preds.GetPredicates (); + } + public ExprStep (NodeTest test) + { + _test = test; + } + public override String ToString () + { + String strExpr = _test.ToString (); + if (_preds != null) + { + foreach (Expression pred in _preds) + { + strExpr += '[' + pred.ToString () + ']'; + } + } + return strExpr; + } + public override object Evaluate (BaseIterator iter) + { + BaseIterator iterStep = _test.Evaluate (iter); + if (_preds == null) + return iterStep; + + return new PredicateIterator (iterStep, _preds); + } + } + + + internal class ExprPredicates + { + protected Expression _pred; + protected ExprPredicates _tail; + public ExprPredicates (Expression pred, ExprPredicates tail) + { + _pred = pred; + _tail = tail; + } + public ExprPredicates (Expression pred) + { + _pred = pred; + } + public Expression [] GetPredicates () + { + ArrayList lstPreds = new ArrayList (); + ExprPredicates curr = this; + while (curr != null) + { + lstPreds.Add (curr._pred); + curr = curr._tail; + } + return (Expression []) lstPreds.ToArray (typeof (Expression)); + } + } + + internal class ExprFilter : Expression + { + protected Expression _expr; + protected Expression _pred; + public ExprFilter (Expression expr, Expression pred) + { + _expr = expr; + _pred = pred; + } + public override String ToString () { return "(" + _expr.ToString () + ")[" + _pred.ToString () + "]"; } + public override XPathResultType ReturnType { get { return XPathResultType.NodeSet; }} + } + + internal class QName + { + protected String _prefix; + protected String _local; + public QName (String prefix, String local) + { + _prefix = prefix; + _local = local; + } + public override String ToString () + { + if (_prefix != null) + return _prefix + ':' + _local; + return _local; + } + public String Prefix { get { return _prefix; } } + public String Local { get { return _local; } } + } + internal class NCName : QName + { + public NCName (String local) : base (null, local) {} + } + + internal class ExprNumber : Expression + { + protected double _value; + public ExprNumber (double value) + { + _value = value; + } + public override String ToString () { return _value.ToString (); } + public override XPathResultType ReturnType { get { return XPathResultType.Number; }} + public override object Evaluate (BaseIterator iter) + { + return _value; + } + } + internal class ExprLiteral : Expression + { + protected String _value; + public ExprLiteral (String value) + { + _value = value; + } + public override String ToString () { return "'" + _value + "'"; } + public override XPathResultType ReturnType { get { return XPathResultType.String; }} + public override object Evaluate (BaseIterator iter) + { + return _value; + } + } + + internal class ExprVariable : Expression + { + protected QName _name; + public ExprVariable (QName name) + { + _name = name; + } + public override String ToString () { return "$" + _name.ToString (); } + public override XPathResultType ReturnType { get { return XPathResultType.Any; }} + public override XPathResultType GetReturnType (BaseIterator iter) + { + IXsltContextVariable var = iter.Context.ResolveVariable (_name.Prefix, _name.Local); + return var.VariableType; + } + } + + internal class FunctionArguments + { + protected Expression _arg; + protected FunctionArguments _tail; + public FunctionArguments (Expression arg, FunctionArguments tail) + { + _arg = arg; + _tail = tail; + } + public Expression Arg + { + get { return _arg; } + } + public FunctionArguments Tail + { + get { return _tail; } + } + } + internal class ExprFunctionCall : Expression + { + protected QName _name; + protected ArrayList _args = new ArrayList (); + public ExprFunctionCall (String name, FunctionArguments args) + { + _name = new NCName (name); + while (args != null) + { + _args.Add (args.Arg); + args = args.Tail; + } + } + public override String ToString () + { + String strArgs = ""; + foreach (Expression arg in _args) + { + if (strArgs != "") + strArgs += ", "; + strArgs += arg.ToString (); + } + return _name.ToString () + '(' + strArgs + ')'; + } + public override XPathResultType ReturnType { get { return XPathResultType.Any; }} + public override XPathResultType GetReturnType (BaseIterator iter) + { + IXsltContextFunction func = iter.Context.ResolveFunction (_name.Prefix, _name.Local, GetArgTypes (iter)); + return func.ReturnType; + } + private XPathResultType [] GetArgTypes (BaseIterator iter) + { + // TODO: can we cache these? what if the types depend on the context? + XPathResultType [] rgArgs = new XPathResultType [_args.Count]; + for (int iArg = 0; iArg < _args.Count; iArg++) + rgArgs [iArg] = ((Expression) _args [iArg]).GetReturnType (iter); + return rgArgs; + } + public override object Evaluate (BaseIterator iter) + { + //special-case the 'last' and 'position' functions + if (_args.Count == 0 && _name.Prefix == null) + { + if (_name.Local == "last") + { + return (double) iter.Count; + } + else if (_name.Local == "position") + { + return (double) iter.CurrentPosition; + } + } + + XPathResultType [] rgTypes = GetArgTypes (iter); + IXsltContextFunction func = iter.Context.ResolveFunction (_name.Prefix, _name.Local, rgTypes); + object [] rgArgs = new object [_args.Count]; + for (int iArg = 0; iArg < _args.Count; iArg ++) + rgArgs [iArg] = ((Expression) _args [iArg]).Evaluate (iter); + return func.Invoke (iter.Context, rgArgs, iter.Current); + } + } +} diff --git a/mcs/class/System.XML/System.Xml.XPath/Iterator.cs b/mcs/class/System.XML/System.Xml.XPath/Iterator.cs new file mode 100644 index 00000000000..5a8a63782a3 --- /dev/null +++ b/mcs/class/System.XML/System.Xml.XPath/Iterator.cs @@ -0,0 +1,542 @@ +// +// System.Xml.XPath.BaseIterator +// +// Author: +// Piers Haken (piersh@friskit.com) +// +// (C) 2002 Piers Haken +// + +using System; +using System.Collections; +using System.Xml; +using System.Xml.XPath; +using System.Xml.Xsl; + +namespace System.Xml.XPath +{ +/* + internal abstract class XPathNodeIterator : ICloneable + { + private int _count; + + #region Constructor + + protected XPathNodeIterator () {} + + #endregion + + #region Properties + + public virtual int Count + { + get + { + if (_count == 0) + { + // compute and cache the count + XPathNodeIterator tmp = Clone (); + while (tmp.MoveNext ()) + ; + _count = tmp.CurrentPosition; + } + return _count; + } + } + + public abstract XPathNavigator Current { get; } + + public abstract int CurrentPosition { get; } + + #endregion + + #region Methods + + public abstract XPathNodeIterator Clone (); + + object ICloneable.Clone () + { + return Clone (); + } + + public abstract bool MoveNext (); + + #endregion + } +*/ + + internal abstract class BaseIterator : XPathNodeIterator + { + private XsltContext _context; + + internal BaseIterator (BaseIterator other) + { + _context = other._context; + } + internal BaseIterator (XsltContext context) + { + _context = context; + } + + public XsltContext Context { get { return _context; } } + + public override string ToString () + { + return Current.NodeType.ToString () + "[" + CurrentPosition + "] : " + Current.Name + " = " + Current.Value; + } + } + + internal class UnionIterator : BaseIterator + { + protected ArrayList _iters = new ArrayList (); + protected int _pos; + protected int _index; + + public UnionIterator (BaseIterator iter ) : base (iter) {} + protected UnionIterator (UnionIterator other) : base (other) + { + foreach (object obj in other._iters) + _iters.Add (obj); + _pos = other._pos; + _index = other._index; + } + public override XPathNodeIterator Clone () { return new UnionIterator (this); } + + public void Add (BaseIterator iter) + { + _iters.Add (iter); + } + + public override bool MoveNext () + { + while (_index < _iters.Count) + { + BaseIterator iter = (BaseIterator) _iters [_index]; + if (iter.MoveNext ()) + { + _pos ++; + return true; + } + _index ++; + } + return false; + } + public override XPathNavigator Current + { + get + { + if (_index >= _iters.Count) + return null; + BaseIterator iter = (BaseIterator) _iters [_index]; + return iter.Current; + } + } + public override int CurrentPosition { get { return _pos; }} + } + + internal abstract class SimpleIterator : BaseIterator + { + protected XPathNavigator _nav; + protected int _pos; + + public SimpleIterator (BaseIterator iter) : base (iter) + { + _nav = iter.Current.Clone (); + } + protected SimpleIterator (SimpleIterator other) : base (other) + { + _nav = other._nav.Clone (); + _pos = other._pos; + } + public SimpleIterator (XPathNavigator nav, XsltContext context) : base (context) + { + _nav = nav.Clone (); + } + + public override XPathNavigator Current { get { return _nav; }} + public override int CurrentPosition { get { return _pos; }} + } + + internal class SelfIterator : SimpleIterator + { + public SelfIterator (BaseIterator iter) : base (iter) {} + public SelfIterator (XPathNavigator nav, XsltContext context) : base (nav, context) {} + protected SelfIterator (SimpleIterator other) : base (other) {} + public override XPathNodeIterator Clone () { return new SelfIterator (this); } + public override bool MoveNext () + { + if (_pos == 0) + { + _pos = 1; + return true; + } + return false; + } + } + + internal class ParentIterator : SimpleIterator + { + public ParentIterator (BaseIterator iter) : base (iter) {} + protected ParentIterator (SimpleIterator other) : base (other) {} + public override XPathNodeIterator Clone () { return new ParentIterator (this); } + public override bool MoveNext () + { + if (_pos == 0 && _nav.MoveToParent ()) + { + _pos = 1; + return true; + } + return false; + } + } + + internal class ChildIterator : SimpleIterator + { + public ChildIterator (BaseIterator iter) : base (iter) {} + protected ChildIterator (SimpleIterator other) : base (other) {} + public override XPathNodeIterator Clone () { return new ChildIterator (this); } + public override bool MoveNext () + { + bool fSuccess = (_pos == 0) ? _nav.MoveToFirstChild () : _nav.MoveToNext (); + if (fSuccess) + _pos ++; + return fSuccess; + } + } + + internal class FollowingSiblingIterator : SimpleIterator + { + public FollowingSiblingIterator (BaseIterator iter) : base (iter) {} + protected FollowingSiblingIterator (SimpleIterator other) : base (other) {} + public override XPathNodeIterator Clone () { return new FollowingSiblingIterator (this); } + public override bool MoveNext () + { + if (_nav.MoveToNext ()) + { + _pos ++; + return true; + } + return false; + } + } + + internal class PrecedingSiblingIterator : SimpleIterator + { + public PrecedingSiblingIterator (BaseIterator iter) : base (iter) {} + protected PrecedingSiblingIterator (SimpleIterator other) : base (other) {} + public override XPathNodeIterator Clone () { return new PrecedingSiblingIterator (this); } + public override bool MoveNext () + { + if (_nav.MoveToPrevious ()) + { + _pos ++; + return true; + } + return false; + } + } + + internal class AncestorIterator : SimpleIterator + { + public AncestorIterator (BaseIterator iter) : base (iter) {} + protected AncestorIterator (SimpleIterator other) : base (other) {} + public override XPathNodeIterator Clone () { return new AncestorIterator (this); } + public override bool MoveNext () + { + if (_nav.MoveToParent ()) + { + _pos ++; + return true; + } + return false; + } + } + + internal class AncestorOrSelfIterator : UnionIterator + { + public AncestorOrSelfIterator (BaseIterator iter) : base (iter) + { + Add (new SelfIterator (iter)); + Add (new AncestorIterator (iter)); + } + protected AncestorOrSelfIterator (UnionIterator other) : base (other) {} + public override XPathNodeIterator Clone () { return new AncestorOrSelfIterator (this); } + } + + internal class DescendantIterator : SimpleIterator + { + protected int _depth; + public DescendantIterator (BaseIterator iter) : base (iter) {} + protected DescendantIterator (SimpleIterator other) : base (other) {} + public override XPathNodeIterator Clone () { return new DescendantIterator (this); } + [MonoTODO] + public override bool MoveNext () + { + if (_nav.MoveToFirstChild ()) + { + _depth ++; + _pos ++; + return true; + } + while (_depth != 0) + { + if (_nav.MoveToNext ()) + { + _pos ++; + return true; + } + if (!_nav.MoveToParent ()) // should NEVER fail! + throw new Exception ("unexpected depth"); // TODO: better message + _depth --; + } + return false; + } + } + + internal class DescendantOrSelfIterator : UnionIterator + { + public DescendantOrSelfIterator (BaseIterator iter) : base (iter) + { + Add (new SelfIterator (iter)); + Add (new DescendantIterator (iter)); + } + protected DescendantOrSelfIterator (UnionIterator other) : base (other) {} + public override XPathNodeIterator Clone () { return new DescendantOrSelfIterator (this); } + } + + internal class FollowingIterator : SimpleIterator + { + public FollowingIterator (BaseIterator iter) : base (iter) {} + protected FollowingIterator (SimpleIterator other) : base (other) {} + public override XPathNodeIterator Clone () { return new FollowingIterator (this); } + public override bool MoveNext () + { + if (_pos == 0) + { + if (_nav.MoveToNext ()) + { + _pos ++; + return true; + } + } + else + { + if (_nav.MoveToFirstChild ()) + { + _pos ++; + return true; + } + do + { + if (_nav.MoveToNext ()) + { + _pos ++; + return true; + } + } + while (_nav.MoveToParent ()); + } + return false; + } + } + + internal class PrecedingIterator : SimpleIterator + { + public PrecedingIterator (BaseIterator iter) : base (iter) {} + protected PrecedingIterator (SimpleIterator other) : base (other) {} + public override XPathNodeIterator Clone () { return new PrecedingIterator (this); } + public override bool MoveNext () + { + if (_pos == 0) + { + if (_nav.MoveToPrevious ()) + { + _pos ++; + return true; + } + } + else + { + if (_nav.MoveToFirstChild ()) + { + while (_nav.MoveToNext ()) + ; + _pos ++; + return true; + } + do + { + if (_nav.MoveToPrevious ()) + { + _pos ++; + return true; + } + } + while (_nav.MoveToParent ()); + } + return false; + } + } + + internal class NamespaceIterator : SimpleIterator + { + public NamespaceIterator (BaseIterator iter) : base (iter) {} + protected NamespaceIterator (SimpleIterator other) : base (other) {} + public override XPathNodeIterator Clone () { return new NamespaceIterator (this); } + public override bool MoveNext () + { + if (_pos == 0) + { + if (_nav.MoveToFirstNamespace ()) + { + _pos ++; + return true; + } + } + else if (_nav.MoveToNextNamespace ()) + { + _pos ++; + return true; + } + return false; + } + } + + internal class AttributeIterator : SimpleIterator + { + public AttributeIterator (BaseIterator iter) : base (iter) {} + protected AttributeIterator (SimpleIterator other) : base (other) {} + public override XPathNodeIterator Clone () { return new AttributeIterator (this); } + public override bool MoveNext () + { + if (_pos == 0) + { + if (_nav.MoveToFirstAttribute ()) + { + _pos += 1; + return true; + } + } + else if (_nav.MoveToNextAttribute ()) + { + _pos ++; + return true; + } + return false; + } + } + + internal class AxisIterator : BaseIterator + { + protected BaseIterator _iter; + protected NodeTest _test; + protected int _pos; + + public AxisIterator (BaseIterator iter, NodeTest test) : base (iter) + { + _iter = iter; + _test = test; + } + + protected AxisIterator (AxisIterator other) : base (other) + { + _iter = (BaseIterator) other._iter.Clone (); + _test = other._test; + _pos = other._pos; + } + public override XPathNodeIterator Clone () { return new AxisIterator (this); } + + public override bool MoveNext () + { + while (_iter.MoveNext ()) + { + if (_test.Match (Context, Current)) + { + _pos ++; + return true; + } + } + return false; + } + public override XPathNavigator Current { get { return _iter.Current; }} + public override int CurrentPosition { get { return _pos; }} + } + + internal class SlashIterator : BaseIterator + { + protected BaseIterator _iterLeft; + protected BaseIterator _iterRight; + protected Expression _expr; + protected int _pos; + + public SlashIterator (BaseIterator iter, Expression expr) : base (iter) + { + _iterLeft = iter; + _expr = expr; + } + + protected SlashIterator (SlashIterator other) : base (other) + { + _iterLeft = (BaseIterator) other._iterLeft.Clone (); + _iterRight = (BaseIterator) other._iterRight.Clone (); + _expr = other._expr; + _pos = other._pos; + } + public override XPathNodeIterator Clone () { return new SlashIterator (this); } + + public override bool MoveNext () + { + while (_iterRight == null || !_iterRight.MoveNext ()) + { + if (!_iterLeft.MoveNext ()) + return false; + _iterRight = _expr.EvaluateNodeSet (_iterLeft); + } + _pos ++; + return true; + } + public override XPathNavigator Current { get { return _iterRight.Current; }} + public override int CurrentPosition { get { return _pos; }} + } + internal class PredicateIterator : BaseIterator + { + protected BaseIterator _iter; + protected Expression [] _preds; + protected int _pos; + + public PredicateIterator (BaseIterator iter, Expression [] preds) : base (iter) + { + _iter = iter; + _preds = preds; + } + + protected PredicateIterator (PredicateIterator other) : base (other) + { + _iter = (BaseIterator) other._iter.Clone (); + _preds = other._preds; + _pos = other._pos; + } + public override XPathNodeIterator Clone () { return new PredicateIterator (this); } + + public override bool MoveNext () + { + while (_iter.MoveNext ()) + { + bool fTrue = true; + foreach (Expression pred in _preds) + { + if (!pred.EvaluateBoolean ((BaseIterator) _iter.Clone ())) + { + fTrue = false; + break; + } + } + if (fTrue) + return true; + } + return false; + } + public override XPathNavigator Current { get { return _iter.Current; }} + public override int CurrentPosition { get { return _pos; }} + } +} diff --git a/mcs/class/System.XML/System.Xml.XPath/Parser.cs b/mcs/class/System.XML/System.Xml.XPath/Parser.cs new file mode 100644 index 00000000000..d747e4c00a1 --- /dev/null +++ b/mcs/class/System.XML/System.Xml.XPath/Parser.cs @@ -0,0 +1,1086 @@ +// created by jay 0.7 (c) 1998 Axel.Schreiner@informatik.uni-osnabrueck.de + + // line 2 "Parser.jay" +// XPath parser +// +// Author - Piers Haken <piersh@friskit.com> +// + +// TODO: FUNCTION_CALL should be a QName, not just a NCName +// TODO: PROCESSING_INSTRUCTION's optional parameter +// TODO: flatten argument/predicate lists in place + +using System; + +namespace System.Xml.XPath +{ + public class XPathParser + { + + // line 21 "-" + + /** simplified error message. + @see <a href="#yyerror(java.lang.String, java.lang.String[])">yyerror</a> + */ + public 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. + */ + public void yyerror (string message, string[] expected) { + if ((expected != null) && (expected.Length > 0)) { + System.Console.Write (message+", expecting"); + for (int n = 0; n < expected.Length; ++ n) + System.Console.Write (" "+expected[n]); + System.Console.WriteLine (); + } else + System.Console.WriteLine (message); + } + + /** debugging support, requires the package jay.yydebug. + Set to null to suppress debugging messages. + */ + protected yydebug.yyDebug debug; + + protected static int yyFinal = 25; + public static string [] yyRule = { + "$accept : Expr", + "Expr : OrExpr", + "OrExpr : AndExpr", + "OrExpr : OrExpr OR AndExpr", + "AndExpr : EqualityExpr", + "AndExpr : AndExpr AND EqualityExpr", + "EqualityExpr : RelationalExpr", + "EqualityExpr : EqualityExpr EQ RelationalExpr", + "EqualityExpr : EqualityExpr NE RelationalExpr", + "RelationalExpr : AdditiveExpr", + "RelationalExpr : RelationalExpr LT AdditiveExpr", + "RelationalExpr : RelationalExpr GT AdditiveExpr", + "RelationalExpr : RelationalExpr LE AdditiveExpr", + "RelationalExpr : RelationalExpr GE AdditiveExpr", + "AdditiveExpr : MultiplicativeExpr", + "AdditiveExpr : AdditiveExpr PLUS MultiplicativeExpr", + "AdditiveExpr : AdditiveExpr MINUS MultiplicativeExpr", + "MultiplicativeExpr : UnaryExpr", + "MultiplicativeExpr : MultiplicativeExpr ASTERISK UnaryExpr", + "MultiplicativeExpr : MultiplicativeExpr DIV UnaryExpr", + "MultiplicativeExpr : MultiplicativeExpr MOD UnaryExpr", + "UnaryExpr : UnionExpr", + "UnaryExpr : MINUS UnaryExpr", + "UnionExpr : PathExpr", + "UnionExpr : UnionExpr BAR PathExpr", + "PathExpr : RelativeLocationPath", + "PathExpr : SLASH", + "PathExpr : SLASH RelativeLocationPath", + "PathExpr : SLASH2 RelativeLocationPath", + "PathExpr : FilterExpr", + "PathExpr : FilterExpr SLASH RelativeLocationPath", + "PathExpr : FilterExpr SLASH2 RelativeLocationPath", + "RelativeLocationPath : Step", + "RelativeLocationPath : RelativeLocationPath SLASH Step", + "RelativeLocationPath : RelativeLocationPath SLASH2 Step", + "Step : AxisSpecifier QName ZeroOrMorePredicates", + "Step : AxisSpecifier ASTERISK ZeroOrMorePredicates", + "Step : AxisSpecifier NCName COLON ASTERISK ZeroOrMorePredicates", + "Step : AxisSpecifier NodeType PAREN_OPEN OptionalLiteral PAREN_CLOSE ZeroOrMorePredicates", + "Step : DOT", + "Step : DOT2", + "AxisSpecifier :", + "AxisSpecifier : AT", + "AxisSpecifier : AxisName COLON2", + "NodeType : COMMENT", + "NodeType : TEXT", + "NodeType : PROCESSING_INSTRUCTION", + "NodeType : NODE", + "FilterExpr : PrimaryExpr", + "FilterExpr : FilterExpr Predicate", + "PrimaryExpr : DOLLAR QName", + "PrimaryExpr : PAREN_OPEN Expr PAREN_CLOSE", + "PrimaryExpr : LITERAL", + "PrimaryExpr : NUMBER", + "PrimaryExpr : FunctionCall", + "FunctionCall : FUNCTION_NAME PAREN_OPEN OptionalArgumentList PAREN_CLOSE", + "OptionalArgumentList :", + "OptionalArgumentList : Expr OptionalArgumentListTail", + "OptionalArgumentListTail :", + "OptionalArgumentListTail : COMMA Expr OptionalArgumentListTail", + "ZeroOrMorePredicates :", + "ZeroOrMorePredicates : Predicate ZeroOrMorePredicates", + "Predicate : BRACKET_OPEN Expr BRACKET_CLOSE", + "AxisName : ANCESTOR", + "AxisName : ANCESTOR_OR_SELF", + "AxisName : ATTRIBUTE", + "AxisName : CHILD", + "AxisName : DESCENDANT", + "AxisName : DESCENDANT_OR_SELF", + "AxisName : FOLLOWING", + "AxisName : FOLLOWING_SIBLING", + "AxisName : NAMESPACE", + "AxisName : PARENT", + "AxisName : PRECEDING", + "AxisName : PRECEDING_SIBLING", + "AxisName : SELF", + "OptionalLiteral :", + "OptionalLiteral : LITERAL", + "QName : NCName", + "QName : NCName COLON NCName", + }; + protected static string [] yyName = { + "end-of-file",null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,"ERROR","EOF","SLASH","SLASH2", + "DOT","DOT2","COLON","COLON2","COMMA","AT","FUNCTION_NAME", + "BRACKET_OPEN","BRACKET_CLOSE","PAREN_OPEN","PAREN_CLOSE","AND","OR", + "DIV","MOD","PLUS","MINUS","ASTERISK","DOLLAR","BAR","EQ","NE","LE", + "GE","LT","GT","ANCESTOR","ANCESTOR_OR_SELF","ATTRIBUTE","CHILD", + "DESCENDANT","DESCENDANT_OR_SELF","FOLLOWING","FOLLOWING_SIBLING", + "NAMESPACE","PARENT","PRECEDING","PRECEDING_SIBLING","SELF","COMMENT", + "TEXT","PROCESSING_INSTRUCTION","NODE","NUMBER","LITERAL","NCName", + }; + + /** index-checked interface to yyName[]. + @param token single character or %token value. + @return token name or [illegal] or [unknown]. + */ + public static string yyname (int token) { + if ((token < 0) || (token > yyName.Length)) return "[illegal]"; + string name; + if ((name = yyName[token]) != null) return name; + return "[unknown]"; + } + + /** computes list of expected tokens on error by tracing the tables. + @param state for which to compute the list. + @return list of token names. + */ + protected string[] yyExpecting (int state) { + int token, n, len = 0; + bool[] ok = new bool[yyName.Length]; + + if ((n = yySindex[state]) != 0) + for (token = n < 0 ? -n : 0; + (token < yyName.Length) && (n+token < yyTable.Length); ++ token) + if (yyCheck[n+token] == token && !ok[token] && yyName[token] != null) { + ++ len; + ok[token] = true; + } + if ((n = yyRindex[state]) != 0) + for (token = n < 0 ? -n : 0; + (token < yyName.Length) && (n+token < yyTable.Length); ++ token) + if (yyCheck[n+token] == token && !ok[token] && yyName[token] != null) { + ++ len; + ok[token] = true; + } + + string [] result = new string[len]; + for (n = token = 0; n < len; ++ token) + if (ok[token]) result[n++] = yyName[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. + */ + public Object yyparse (yyParser.yyInput yyLex, Object yyd) + { + 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(). + */ + protected 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. + */ + protected 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. + */ + public 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 + + int yyTop = 0; + goto skip; + yyLoop: + yyTop++; + skip: + for (;; ++ yyTop) { + if (yyTop >= yyStates.Length) { // dynamically increase + int[] i = new int[yyStates.Length+yyMax]; + System.Array.Copy(yyStates, i, 0); + yyStates = i; + Object[] o = new Object[yyVals.Length+yyMax]; + System.Array.Copy(yyVals, o, 0); + yyVals = o; + } + yyStates[yyTop] = yyState; + yyVals[yyTop] = yyVal; + 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; + if (debug != null) + debug.lex(yyState, yyToken, yyname(yyToken), yyLex.value()); + } + if ((yyN = yySindex[yyState]) != 0 && ((yyN += yyToken) >= 0) + && (yyN < yyTable.Length) && (yyCheck[yyN] == yyToken)) { + if (debug != null) + 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("syntax error", yyExpecting(yyState)); + 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) { + if (debug != null) + debug.shift(yyStates[yyTop], yyTable[yyN], 3); + yyState = yyTable[yyN]; + yyVal = yyLex.value(); + goto yyLoop; + } + if (debug != null) debug.pop(yyStates[yyTop]); + } while (-- yyTop >= 0); + if (debug != null) debug.reject(); + throw new yyParser.yyException("irrecoverable syntax error"); + + case 3: + if (yyToken == 0) { + if (debug != null) debug.reject(); + throw new yyParser.yyException("irrecoverable syntax error at end-of-file"); + } + if (debug != null) + debug.discard(yyState, yyToken, yyname(yyToken), + yyLex.value()); + yyToken = -1; + goto yyDiscarded; // leave stack alone + } + } + int yyV = yyTop + 1-yyLen[yyN]; + if (debug != null) + debug.reduce(yyState, yyStates[yyV-1], yyN, yyRule[yyN], yyLen[yyN]); + yyVal = yyDefault(yyV > yyTop ? null : yyVals[yyV]); + switch (yyN) { +case 3: + // line 106 "Parser.jay" + { + yyVal = new ExprOR ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + } + break; +case 5: + // line 114 "Parser.jay" + { + yyVal = new ExprAND ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + } + break; +case 7: + // line 122 "Parser.jay" + { + yyVal = new ExprEQ ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + } + break; +case 8: + // line 126 "Parser.jay" + { + yyVal = new ExprNE ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + } + break; +case 10: + // line 134 "Parser.jay" + { + yyVal = new ExprLT ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + } + break; +case 11: + // line 138 "Parser.jay" + { + yyVal = new ExprGT ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + } + break; +case 12: + // line 142 "Parser.jay" + { + yyVal = new ExprLE ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + } + break; +case 13: + // line 146 "Parser.jay" + { + yyVal = new ExprGE ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + } + break; +case 15: + // line 154 "Parser.jay" + { + yyVal = new ExprPLUS ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + } + break; +case 16: + // line 158 "Parser.jay" + { + yyVal = new ExprMINUS ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + } + break; +case 18: + // line 166 "Parser.jay" + { + yyVal = new ExprMULT ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + } + break; +case 19: + // line 170 "Parser.jay" + { + yyVal = new ExprDIV ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + } + break; +case 20: + // line 174 "Parser.jay" + { + yyVal = new ExprMOD ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]); + } + break; +case 22: + // line 182 "Parser.jay" + { + yyVal = new ExprNEG ((Expression) yyVals[0+yyTop]); + } + break; +case 24: + // line 190 "Parser.jay" + { + yyVal = new ExprUNION ((NodeSet) yyVals[-2+yyTop], (NodeSet) yyVals[0+yyTop]); + } + break; +case 26: + // line 198 "Parser.jay" + { + yyVal = new ExprRoot (); + } + break; +case 27: + // line 202 "Parser.jay" + { + yyVal = new ExprSLASH (new ExprRoot (), (NodeSet) yyVals[0+yyTop]); + } + break; +case 28: + // line 206 "Parser.jay" + { + ExprStep exprStep = new ExprStep (new NodeTypeTest (Axes.DescendantOrSelf, NodeTestTypes.Node)); + yyVal = new ExprSLASH (new ExprSLASH (new ExprRoot (), exprStep), (NodeSet) yyVals[0+yyTop]); + } + break; +case 30: + // line 212 "Parser.jay" + { + yyVal = new ExprSLASH ((NodeSet) yyVals[-2+yyTop], (NodeSet) yyVals[0+yyTop]); + } + break; +case 31: + // line 216 "Parser.jay" + { + ExprStep exprStep = new ExprStep (new NodeTypeTest (Axes.DescendantOrSelf, NodeTestTypes.Node)); + yyVal = new ExprSLASH (new ExprSLASH ((NodeSet) yyVals[-2+yyTop], exprStep), (NodeSet) yyVals[0+yyTop]); + } + break; +case 33: + // line 225 "Parser.jay" + { + yyVal = new ExprSLASH ((NodeSet) yyVals[-2+yyTop], (NodeSet) yyVals[0+yyTop]); + } + break; +case 34: + // line 229 "Parser.jay" + { + ExprStep exprStep = new ExprStep (new NodeTypeTest (Axes.DescendantOrSelf, NodeTestTypes.Node)); + yyVal = new ExprSLASH (new ExprSLASH ((NodeSet) yyVals[-2+yyTop], exprStep), (NodeSet) yyVals[0+yyTop]); + } + break; +case 35: + // line 237 "Parser.jay" + { + yyVal = new ExprStep (new NodeNameTest ((Axes) yyVals[-2+yyTop], (QName) yyVals[-1+yyTop]), (ExprPredicates) yyVals[0+yyTop]); + } + break; +case 36: + // line 241 "Parser.jay" + { + yyVal = new ExprStep (new NodeTypeTest ((Axes) yyVals[-2+yyTop], NodeTestTypes.Principal), (ExprPredicates) yyVals[0+yyTop]); + } + break; +case 37: + // line 245 "Parser.jay" + { + yyVal = new ExprStep (new NodeNameTestAny ((Axes) yyVals[-4+yyTop], (NCName) yyVals[-3+yyTop]), (ExprPredicates) yyVals[0+yyTop]); + } + break; +case 38: + // line 249 "Parser.jay" + { + yyVal = new ExprStep (new NodeTypeTest ((Axes) yyVals[-5+yyTop], (NodeTestTypes) yyVals[-4+yyTop], (String) yyVals[-2+yyTop]), (ExprPredicates) yyVals[0+yyTop]); + } + break; +case 39: + // line 253 "Parser.jay" + { + yyVal = new ExprStep (new NodeTypeTest (Axes.Self, NodeTestTypes.Node)); + } + break; +case 40: + // line 257 "Parser.jay" + { + yyVal = new ExprStep (new NodeTypeTest (Axes.Parent, NodeTestTypes.Node)); + } + break; +case 41: + // line 264 "Parser.jay" + { + yyVal = Axes.Child; + } + break; +case 42: + // line 268 "Parser.jay" + { + yyVal = Axes.Attribute; + } + break; +case 43: + // line 272 "Parser.jay" + { + yyVal = yyVals[-1+yyTop]; + } + break; +case 44: + // line 278 "Parser.jay" + { yyVal = NodeTestTypes.Comment; } + break; +case 45: + // line 279 "Parser.jay" + { yyVal = NodeTestTypes.Text; } + break; +case 46: + // line 280 "Parser.jay" + { yyVal = NodeTestTypes.ProcessingInstruction; } + break; +case 47: + // line 281 "Parser.jay" + { yyVal = NodeTestTypes.Node; } + break; +case 49: + // line 288 "Parser.jay" + { + yyVal = new ExprFilter ((Expression) yyVals[-1+yyTop], (Expression) yyVals[0+yyTop]); + } + break; +case 50: + // line 295 "Parser.jay" + { + yyVal = new ExprVariable ((QName) yyVals[0+yyTop]); + } + break; +case 51: + // line 299 "Parser.jay" + { + yyVal = yyVals[-1+yyTop]; + } + break; +case 52: + // line 303 "Parser.jay" + { + yyVal = new ExprLiteral ((String) yyVals[0+yyTop]); + } + break; +case 53: + // line 307 "Parser.jay" + { + yyVal = new ExprNumber ((double) yyVals[0+yyTop]); + } + break; +case 55: + // line 315 "Parser.jay" + { + yyVal = new ExprFunctionCall ((String) yyVals[-3+yyTop], (FunctionArguments) yyVals[-1+yyTop]); + } + break; +case 57: + // line 323 "Parser.jay" + { + yyVal = new FunctionArguments ((Expression) yyVals[-1+yyTop], (FunctionArguments) yyVals[0+yyTop]); + } + break; +case 59: + // line 331 "Parser.jay" + { + yyVal = new FunctionArguments ((Expression) yyVals[-1+yyTop], (FunctionArguments) yyVals[0+yyTop]); + } + break; +case 61: + // line 340 "Parser.jay" + { + yyVal = new ExprPredicates ((Expression) yyVals[-1+yyTop], (ExprPredicates) yyVals[0+yyTop]); + } + break; +case 62: + // line 347 "Parser.jay" + { + yyVal = yyVals[-1+yyTop]; + } + break; +case 63: + // line 353 "Parser.jay" + { yyVal = Axes.Ancestor; } + break; +case 64: + // line 354 "Parser.jay" + { yyVal = Axes.AncestorOrSelf; } + break; +case 65: + // line 355 "Parser.jay" + { yyVal = Axes.Attribute; } + break; +case 66: + // line 356 "Parser.jay" + { yyVal = Axes.Child; } + break; +case 67: + // line 357 "Parser.jay" + { yyVal = Axes.Descendant; } + break; +case 68: + // line 358 "Parser.jay" + { yyVal = Axes.DescendantOrSelf; } + break; +case 69: + // line 359 "Parser.jay" + { yyVal = Axes.Following; } + break; +case 70: + // line 360 "Parser.jay" + { yyVal = Axes.FollowingSibling; } + break; +case 71: + // line 361 "Parser.jay" + { yyVal = Axes.Namespace; } + break; +case 72: + // line 362 "Parser.jay" + { yyVal = Axes.Parent; } + break; +case 73: + // line 363 "Parser.jay" + { yyVal = Axes.Preceding; } + break; +case 74: + // line 364 "Parser.jay" + { yyVal = Axes.PrecedingSibling; } + break; +case 75: + // line 365 "Parser.jay" + { yyVal = Axes.Self; } + break; +case 77: + // line 371 "Parser.jay" + { + yyVal = yyVals[0+yyTop]; + } + break; +case 78: + // line 378 "Parser.jay" + { + yyVal = new NCName ((String) yyVals[0+yyTop]); + } + break; +case 79: + // line 382 "Parser.jay" + { + yyVal = new QName ((String) yyVals[-2+yyTop], (String) yyVals[0+yyTop]); + } + break; + // line 662 "-" + } + yyTop -= yyLen[yyN]; + yyState = yyStates[yyTop]; + int yyM = yyLhs[yyN]; + if (yyState == 0 && yyM == 0) { + if (debug != null) debug.shift(0, yyFinal); + yyState = yyFinal; + if (yyToken < 0) { + yyToken = yyLex.advance() ? yyLex.token() : 0; + if (debug != null) + debug.lex(yyState, yyToken,yyname(yyToken), yyLex.value()); + } + if (yyToken == 0) { + 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]; + if (debug != null) debug.shift(yyStates[yyTop], yyState); + goto yyLoop; + } + } + } + + static short [] yyLhs = { -1, + 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, + 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, + 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 10, 10, 10, 12, 12, 12, 12, 12, 12, + 13, 13, 13, 16, 16, 16, 16, 11, 11, 19, + 19, 19, 19, 19, 21, 22, 22, 23, 23, 15, + 15, 20, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 17, 17, 14, 14, + }; + static short [] yyLen = { 2, + 1, 1, 3, 1, 3, 1, 3, 3, 1, 3, + 3, 3, 3, 1, 3, 3, 1, 3, 3, 3, + 1, 2, 1, 3, 1, 1, 2, 2, 1, 3, + 3, 1, 3, 3, 3, 3, 5, 6, 1, 1, + 0, 1, 2, 1, 1, 1, 1, 1, 2, 2, + 3, 1, 1, 1, 4, 0, 2, 0, 3, 0, + 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 0, 1, 1, 3, + }; + static short [] yyDefRed = { 0, + 0, 0, 39, 40, 42, 0, 0, 0, 0, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 53, 52, 0, 0, 0, 0, 0, 0, + 0, 17, 0, 23, 0, 0, 32, 0, 0, 48, + 54, 0, 0, 0, 0, 22, 0, 50, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 49, 0, 44, + 45, 46, 47, 0, 0, 0, 43, 0, 0, 51, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 19, 20, 18, 24, 33, 34, 0, 0, 0, + 36, 0, 0, 35, 0, 0, 57, 55, 79, 62, + 61, 0, 77, 0, 0, 37, 0, 59, 38, + }; + protected static short [] yyDgoto = { 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 48, 101, 76, 114, 39, 40, 102, + 41, 79, 107, + }; + protected static short [] yySindex = { -174, + -104, -104, 0, 0, 0, -263, -174, -174, -297, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -262, -253, -265, -259, -248, + -260, 0, -250, 0, -203, -247, 0, -258, -242, 0, + 0, -203, -203, -174, -224, 0, -197, 0, -174, -174, + -174, -174, -174, -174, -174, -174, -174, -174, -174, -174, + -174, -124, -104, -104, -104, -104, -174, 0, -193, 0, + 0, 0, 0, -187, -193, -192, 0, -188, -191, 0, + -227, -253, -265, -259, -259, -248, -248, -248, -248, -260, + -260, 0, 0, 0, 0, 0, 0, -203, -203, -186, + 0, -193, -270, 0, -223, -174, 0, 0, 0, 0, + 0, -193, 0, -190, -188, 0, -193, 0, 0, + }; + protected static short [] yyRindex = { -239, + 1, -239, 0, 0, 0, 0, -239, -239, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 253, 65, 23, 435, 319, + 244, 0, 222, 0, 90, 112, 0, 0, 0, 0, + 0, 134, 156, -268, 0, 0, 40, 0, -239, -239, + -239, -239, -239, -239, -239, -239, -239, -239, -239, -239, + -239, -239, -239, -239, -239, -239, -239, 0, 68, 0, + 0, 0, 0, 40, 68, 0, 0, -182, 0, 0, + 0, 510, 501, 457, 479, 347, 369, 391, 413, 267, + 289, 0, 0, 0, 0, 0, 0, 178, 200, 0, + 0, 68, 0, 0, -180, -239, 0, 0, 0, 0, + 0, 68, 0, 0, -182, 0, 68, 0, 0, + }; + protected static short [] yyGindex = { -7, + 0, 35, 44, 7, -4, 14, -6, 0, 33, 4, + 0, 10, 0, 59, -71, 0, 0, 0, 0, 62, + 0, 0, -15, + }; + protected static short [] yyTable = { 45, + 26, 46, 56, 104, 42, 43, 44, 112, 47, 41, + 49, 65, 66, 59, 60, 51, 52, 61, 50, 69, + 67, 77, 4, 53, 54, 55, 56, 57, 58, 62, + 111, 41, 41, 41, 41, 109, 78, 41, 41, 78, + 116, 70, 71, 72, 73, 119, 80, 74, 86, 87, + 88, 89, 92, 93, 94, 63, 64, 84, 85, 100, + 41, 41, 41, 41, 2, 81, 41, 60, 98, 99, + 90, 91, 96, 97, 67, 103, 106, 105, 109, 108, + 117, 113, 110, 82, 1, 2, 3, 4, 58, 25, + 76, 5, 6, 83, 95, 7, 75, 68, 115, 118, + 0, 0, 8, 0, 9, 0, 0, 0, 0, 0, + 0, 29, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 0, 0, 0, 0, 23, + 24, 0, 0, 27, 1, 2, 3, 4, 0, 0, + 0, 5, 6, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 28, 3, 4, 0, 0, + 0, 5, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 0, 0, 30, 0, 23, + 24, 0, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 0, 0, 0, 0, 31, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 26, 15, 0, 0, 26, + 0, 26, 26, 26, 26, 26, 26, 26, 26, 0, + 26, 26, 26, 26, 26, 26, 26, 4, 16, 0, + 0, 4, 0, 4, 4, 4, 0, 0, 78, 78, + 41, 41, 41, 41, 78, 0, 41, 78, 78, 0, + 78, 78, 78, 78, 78, 78, 78, 78, 9, 78, + 78, 78, 78, 78, 78, 78, 60, 60, 0, 2, + 0, 0, 60, 2, 0, 2, 60, 2, 60, 60, + 60, 60, 60, 60, 60, 60, 12, 60, 60, 60, + 60, 60, 60, 60, 25, 0, 0, 0, 25, 0, + 25, 25, 25, 25, 25, 25, 25, 25, 13, 25, + 25, 25, 25, 25, 25, 25, 29, 0, 0, 0, + 29, 0, 29, 29, 29, 29, 29, 29, 29, 29, + 10, 29, 29, 29, 29, 29, 29, 29, 27, 0, + 0, 0, 27, 0, 27, 27, 27, 27, 27, 27, + 27, 27, 11, 27, 27, 27, 27, 27, 27, 27, + 28, 0, 0, 0, 28, 0, 28, 28, 28, 28, + 28, 28, 28, 28, 6, 28, 28, 28, 28, 28, + 28, 28, 30, 0, 0, 0, 30, 0, 30, 30, + 30, 30, 30, 30, 30, 30, 7, 30, 30, 30, + 30, 30, 30, 30, 31, 0, 0, 0, 31, 0, + 31, 31, 31, 31, 31, 31, 31, 31, 8, 31, + 31, 31, 31, 31, 31, 31, 21, 0, 0, 0, + 21, 0, 21, 21, 21, 21, 21, 21, 21, 21, + 5, 0, 21, 21, 21, 21, 21, 21, 14, 3, + 0, 0, 14, 0, 14, 14, 14, 1, 0, 14, + 14, 1, 0, 1, 14, 14, 14, 14, 14, 14, + 0, 15, 0, 0, 0, 15, 0, 15, 15, 15, + 0, 0, 15, 15, 0, 0, 0, 15, 15, 15, + 15, 15, 15, 16, 0, 0, 0, 16, 0, 16, + 16, 16, 0, 0, 16, 16, 0, 0, 0, 16, + 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 0, 0, 0, 9, 0, 9, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 12, 0, 0, 0, 12, 0, 12, 12, 12, + 0, 0, 0, 0, 0, 0, 0, 12, 12, 12, + 12, 12, 12, 13, 0, 0, 0, 13, 0, 13, + 13, 13, 0, 0, 0, 0, 0, 0, 0, 13, + 13, 13, 13, 13, 13, 10, 0, 0, 0, 10, + 0, 10, 10, 10, 0, 0, 0, 0, 0, 0, + 0, 10, 10, 10, 10, 10, 10, 11, 0, 0, + 0, 11, 0, 11, 11, 11, 0, 0, 0, 0, + 0, 0, 0, 11, 11, 11, 11, 11, 11, 6, + 0, 0, 0, 6, 0, 6, 6, 6, 0, 0, + 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, + 0, 7, 0, 0, 0, 7, 0, 7, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, + 0, 0, 0, 8, 0, 0, 0, 8, 0, 8, + 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, + 8, 0, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 5, 5, 5, 3, 0, 0, 0, 3, 0, + 3, 0, 3, + }; + protected static short [] yyCheck = { 7, + 0, 8, 271, 75, 1, 2, 270, 278, 306, 278, + 273, 259, 260, 274, 275, 281, 282, 278, 272, 278, + 268, 264, 0, 283, 284, 285, 286, 276, 277, 280, + 102, 300, 301, 302, 303, 306, 44, 306, 278, 0, + 112, 300, 301, 302, 303, 117, 271, 306, 53, 54, + 55, 56, 59, 60, 61, 259, 260, 51, 52, 67, + 300, 301, 302, 303, 0, 263, 306, 0, 65, 66, + 57, 58, 63, 64, 268, 263, 265, 270, 306, 271, + 271, 305, 269, 49, 259, 260, 261, 262, 271, 0, + 271, 266, 267, 50, 62, 270, 38, 36, 106, 115, + -1, -1, 277, -1, 279, -1, -1, -1, -1, -1, + -1, 0, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, -1, -1, -1, -1, 304, + 305, -1, -1, 0, 259, 260, 261, 262, -1, -1, + -1, 266, 267, -1, -1, 270, -1, -1, -1, -1, + -1, -1, -1, -1, 279, 0, 261, 262, -1, -1, + -1, 266, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, -1, -1, 0, -1, 304, + 305, -1, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, -1, -1, -1, -1, 0, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, + -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 265, 0, -1, -1, 269, + -1, 271, 272, 273, 274, 275, 276, 277, 278, -1, + 280, 281, 282, 283, 284, 285, 286, 265, 0, -1, + -1, 269, -1, 271, 272, 273, -1, -1, 259, 260, + 300, 301, 302, 303, 265, -1, 306, 268, 269, -1, + 271, 272, 273, 274, 275, 276, 277, 278, 0, 280, + 281, 282, 283, 284, 285, 286, 259, 260, -1, 265, + -1, -1, 265, 269, -1, 271, 269, 273, 271, 272, + 273, 274, 275, 276, 277, 278, 0, 280, 281, 282, + 283, 284, 285, 286, 265, -1, -1, -1, 269, -1, + 271, 272, 273, 274, 275, 276, 277, 278, 0, 280, + 281, 282, 283, 284, 285, 286, 265, -1, -1, -1, + 269, -1, 271, 272, 273, 274, 275, 276, 277, 278, + 0, 280, 281, 282, 283, 284, 285, 286, 265, -1, + -1, -1, 269, -1, 271, 272, 273, 274, 275, 276, + 277, 278, 0, 280, 281, 282, 283, 284, 285, 286, + 265, -1, -1, -1, 269, -1, 271, 272, 273, 274, + 275, 276, 277, 278, 0, 280, 281, 282, 283, 284, + 285, 286, 265, -1, -1, -1, 269, -1, 271, 272, + 273, 274, 275, 276, 277, 278, 0, 280, 281, 282, + 283, 284, 285, 286, 265, -1, -1, -1, 269, -1, + 271, 272, 273, 274, 275, 276, 277, 278, 0, 280, + 281, 282, 283, 284, 285, 286, 265, -1, -1, -1, + 269, -1, 271, 272, 273, 274, 275, 276, 277, 278, + 0, -1, 281, 282, 283, 284, 285, 286, 265, 0, + -1, -1, 269, -1, 271, 272, 273, 265, -1, 276, + 277, 269, -1, 271, 281, 282, 283, 284, 285, 286, + -1, 265, -1, -1, -1, 269, -1, 271, 272, 273, + -1, -1, 276, 277, -1, -1, -1, 281, 282, 283, + 284, 285, 286, 265, -1, -1, -1, 269, -1, 271, + 272, 273, -1, -1, 276, 277, -1, -1, -1, 281, + 282, 283, 284, 285, 286, -1, -1, -1, -1, -1, + -1, -1, -1, 265, -1, -1, -1, 269, -1, 271, + 272, 273, -1, -1, -1, -1, -1, -1, -1, 281, + 282, 283, 284, 285, 286, -1, -1, -1, -1, -1, + -1, 265, -1, -1, -1, 269, -1, 271, 272, 273, + -1, -1, -1, -1, -1, -1, -1, 281, 282, 283, + 284, 285, 286, 265, -1, -1, -1, 269, -1, 271, + 272, 273, -1, -1, -1, -1, -1, -1, -1, 281, + 282, 283, 284, 285, 286, 265, -1, -1, -1, 269, + -1, 271, 272, 273, -1, -1, -1, -1, -1, -1, + -1, 281, 282, 283, 284, 285, 286, 265, -1, -1, + -1, 269, -1, 271, 272, 273, -1, -1, -1, -1, + -1, -1, -1, 281, 282, 283, 284, 285, 286, 265, + -1, -1, -1, 269, -1, 271, 272, 273, -1, -1, + -1, -1, -1, -1, -1, 281, 282, -1, -1, -1, + -1, 265, -1, -1, -1, 269, -1, 271, 272, 273, + -1, -1, -1, -1, -1, -1, -1, 281, 282, -1, + -1, -1, -1, 265, -1, -1, -1, 269, -1, 271, + 272, 273, -1, -1, -1, -1, -1, -1, -1, 281, + 282, -1, -1, -1, -1, 265, -1, -1, -1, 269, + -1, 271, 272, 273, 265, -1, -1, -1, 269, -1, + 271, -1, 273, + }; + + // line 388 "Parser.jay" + } + // line 929 "-" +namespace yydebug { + using System; + public 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.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 { + public const int ERROR = 257; + public const int EOF = 258; + public const int SLASH = 259; + public const int SLASH2 = 260; + public const int DOT = 261; + public const int DOT2 = 262; + public const int COLON = 263; + public const int COLON2 = 264; + public const int COMMA = 265; + public const int AT = 266; + public const int FUNCTION_NAME = 267; + public const int BRACKET_OPEN = 268; + public const int BRACKET_CLOSE = 269; + public const int PAREN_OPEN = 270; + public const int PAREN_CLOSE = 271; + public const int AND = 272; + public const int OR = 273; + public const int DIV = 274; + public const int MOD = 275; + public const int PLUS = 276; + public const int MINUS = 277; + public const int ASTERISK = 278; + public const int DOLLAR = 279; + public const int BAR = 280; + public const int EQ = 281; + public const int NE = 282; + public const int LE = 283; + public const int GE = 284; + public const int LT = 285; + public const int GT = 286; + public const int ANCESTOR = 287; + public const int ANCESTOR_OR_SELF = 288; + public const int ATTRIBUTE = 289; + public const int CHILD = 290; + public const int DESCENDANT = 291; + public const int DESCENDANT_OR_SELF = 292; + public const int FOLLOWING = 293; + public const int FOLLOWING_SIBLING = 294; + public const int NAMESPACE = 295; + public const int PARENT = 296; + public const int PRECEDING = 297; + public const int PRECEDING_SIBLING = 298; + public const int SELF = 299; + public const int COMMENT = 300; + public const int TEXT = 301; + public const int PROCESSING_INSTRUCTION = 302; + public const int NODE = 303; + public const int NUMBER = 304; + public const int LITERAL = 305; + public const int NCName = 306; + public const int yyErrorCode = 256; + } + namespace yyParser { + using System; + /** thrown for irrecoverable syntax errors and stack overflow. + */ + public class yyException : System.Exception { + public yyException (string message) : base (message) { + } + } + + /** must be implemented by a scanner object to supply input to the parser. + */ + public 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 diff --git a/mcs/class/System.XML/System.Xml.XPath/Parser.jay b/mcs/class/System.XML/System.Xml.XPath/Parser.jay new file mode 100644 index 00000000000..c404d9d8e5a --- /dev/null +++ b/mcs/class/System.XML/System.Xml.XPath/Parser.jay @@ -0,0 +1,388 @@ +%{ +// XPath parser +// +// Author - Piers Haken <piersh@friskit.com> +// + +// TODO: FUNCTION_CALL should be a QName, not just a NCName +// TODO: PROCESSING_INSTRUCTION's optional parameter +// TODO: flatten argument/predicate lists in place + +using System; + +namespace System.Xml.XPath +{ + public class XPathParser + { + +%} + +%token ERROR +%token EOF + +%token SLASH +%token SLASH2 +%token DOT +%token DOT2 +%token COLON +%token COLON2 +%token COMMA +%token AT + +%token FUNCTION_NAME + +%token BRACKET_OPEN +%token BRACKET_CLOSE +%token PAREN_OPEN +%token PAREN_CLOSE + +%token AND +%token OR +%token DIV +%token MOD +%token PLUS +%token MINUS +%token ASTERISK +%token DOLLAR +%token BAR +%token EQ +%token NE +%token LE +%token GE +%token LT +%token GT + +%token ANCESTOR +%token ANCESTOR_OR_SELF +%token ATTRIBUTE +%token CHILD +%token DESCENDANT +%token DESCENDANT_OR_SELF +%token FOLLOWING +%token FOLLOWING_SIBLING +%token NAMESPACE +%token PARENT +%token PRECEDING +%token PRECEDING_SIBLING +%token SELF + +%token COMMENT +%token TEXT +%token PROCESSING_INSTRUCTION +%token NODE + +%token NUMBER +%token LITERAL +%token NCName + + +%start Expr + + +%left AND +%left OR +%left EQ +%left NE +%left LE +%left GE +%left LT +%left GT + +%left DIV +%left MOD +%left PLUS +%left MINUS + +%% + + +Expr + : OrExpr + ; + +OrExpr + : AndExpr + | OrExpr OR AndExpr + { + $$ = new ExprOR ((Expression) $1, (Expression) $3); + } + ; + +AndExpr + : EqualityExpr + | AndExpr AND EqualityExpr + { + $$ = new ExprAND ((Expression) $1, (Expression) $3); + } + ; + +EqualityExpr + : RelationalExpr + | EqualityExpr EQ RelationalExpr + { + $$ = new ExprEQ ((Expression) $1, (Expression) $3); + } + | EqualityExpr NE RelationalExpr + { + $$ = new ExprNE ((Expression) $1, (Expression) $3); + } + ; + +RelationalExpr + : AdditiveExpr + | RelationalExpr LT AdditiveExpr + { + $$ = new ExprLT ((Expression) $1, (Expression) $3); + } + | RelationalExpr GT AdditiveExpr + { + $$ = new ExprGT ((Expression) $1, (Expression) $3); + } + | RelationalExpr LE AdditiveExpr + { + $$ = new ExprLE ((Expression) $1, (Expression) $3); + } + | RelationalExpr GE AdditiveExpr + { + $$ = new ExprGE ((Expression) $1, (Expression) $3); + } + ; + +AdditiveExpr + : MultiplicativeExpr + | AdditiveExpr PLUS MultiplicativeExpr + { + $$ = new ExprPLUS ((Expression) $1, (Expression) $3); + } + | AdditiveExpr MINUS MultiplicativeExpr + { + $$ = new ExprMINUS ((Expression) $1, (Expression) $3); + } + ; + +MultiplicativeExpr + : UnaryExpr + | MultiplicativeExpr ASTERISK UnaryExpr + { + $$ = new ExprMULT ((Expression) $1, (Expression) $3); + } + | MultiplicativeExpr DIV UnaryExpr + { + $$ = new ExprDIV ((Expression) $1, (Expression) $3); + } + | MultiplicativeExpr MOD UnaryExpr + { + $$ = new ExprMOD ((Expression) $1, (Expression) $3); + } + ; + +UnaryExpr + : UnionExpr + | MINUS UnaryExpr + { + $$ = new ExprNEG ((Expression) $2); + } + ; + +UnionExpr + : PathExpr + | UnionExpr BAR PathExpr + { + $$ = new ExprUNION ((NodeSet) $1, (NodeSet) $3); + } + ; + +PathExpr + : RelativeLocationPath + | SLASH + { + $$ = new ExprRoot (); + } + | SLASH RelativeLocationPath + { + $$ = new ExprSLASH (new ExprRoot (), (NodeSet) $2); + } + | SLASH2 RelativeLocationPath + { + ExprStep exprStep = new ExprStep (new NodeTypeTest (Axes.DescendantOrSelf, NodeTestTypes.Node)); + $$ = new ExprSLASH (new ExprSLASH (new ExprRoot (), exprStep), (NodeSet) $2); + } + | FilterExpr + | FilterExpr SLASH RelativeLocationPath + { + $$ = new ExprSLASH ((NodeSet) $1, (NodeSet) $3); + } + | FilterExpr SLASH2 RelativeLocationPath + { + ExprStep exprStep = new ExprStep (new NodeTypeTest (Axes.DescendantOrSelf, NodeTestTypes.Node)); + $$ = new ExprSLASH (new ExprSLASH ((NodeSet) $1, exprStep), (NodeSet) $3); + } + ; + +RelativeLocationPath + : Step + | RelativeLocationPath SLASH Step + { + $$ = new ExprSLASH ((NodeSet) $1, (NodeSet) $3); + } + | RelativeLocationPath SLASH2 Step + { + ExprStep exprStep = new ExprStep (new NodeTypeTest (Axes.DescendantOrSelf, NodeTestTypes.Node)); + $$ = new ExprSLASH (new ExprSLASH ((NodeSet) $1, exprStep), (NodeSet) $3); + } + ; + +Step + : AxisSpecifier QName ZeroOrMorePredicates + { + $$ = new ExprStep (new NodeNameTest ((Axes) $1, (QName) $2), (ExprPredicates) $3); + } + | AxisSpecifier ASTERISK ZeroOrMorePredicates + { + $$ = new ExprStep (new NodeTypeTest ((Axes) $1, NodeTestTypes.Principal), (ExprPredicates) $3); + } + | AxisSpecifier NCName COLON ASTERISK ZeroOrMorePredicates + { + $$ = new ExprStep (new NodeNameTestAny ((Axes) $1, (NCName) $2), (ExprPredicates) $5); + } + | AxisSpecifier NodeType PAREN_OPEN OptionalLiteral PAREN_CLOSE ZeroOrMorePredicates + { + $$ = new ExprStep (new NodeTypeTest ((Axes) $1, (NodeTestTypes) $2, (String) $4), (ExprPredicates) $6); + } + | DOT + { + $$ = new ExprStep (new NodeTypeTest (Axes.Self, NodeTestTypes.Node)); + } + | DOT2 + { + $$ = new ExprStep (new NodeTypeTest (Axes.Parent, NodeTestTypes.Node)); + } + ; + +AxisSpecifier + : /* empty */ + { + $$ = Axes.Child; + } + | AT + { + $$ = Axes.Attribute; + } + | AxisName COLON2 + { + $$ = $1; + } + ; + +NodeType + : COMMENT { $$ = NodeTestTypes.Comment; } + | TEXT { $$ = NodeTestTypes.Text; } + | PROCESSING_INSTRUCTION { $$ = NodeTestTypes.ProcessingInstruction; } + | NODE { $$ = NodeTestTypes.Node; } + ; + + +FilterExpr + : PrimaryExpr + | FilterExpr Predicate + { + $$ = new ExprFilter ((Expression) $1, (Expression) $2); + } + ; + +PrimaryExpr + : DOLLAR QName + { + $$ = new ExprVariable ((QName) $2); + } + | PAREN_OPEN Expr PAREN_CLOSE + { + $$ = $2; + } + | LITERAL + { + $$ = new ExprLiteral ((String) $1); + } + | NUMBER + { + $$ = new ExprNumber ((double) $1); + } + | FunctionCall + ; + +FunctionCall + : FUNCTION_NAME PAREN_OPEN OptionalArgumentList PAREN_CLOSE + { + $$ = new ExprFunctionCall ((String) $1, (FunctionArguments) $3); + } + ; + +OptionalArgumentList + : /* empty */ + | Expr OptionalArgumentListTail + { + $$ = new FunctionArguments ((Expression) $1, (FunctionArguments) $2); + } + ; + +OptionalArgumentListTail + : /* empty */ + | COMMA Expr OptionalArgumentListTail + { + $$ = new FunctionArguments ((Expression) $2, (FunctionArguments) $3); + } + ; + + +ZeroOrMorePredicates + : /* empty */ + | Predicate ZeroOrMorePredicates + { + $$ = new ExprPredicates ((Expression) $1, (ExprPredicates) $2); + } + ; + +Predicate + : BRACKET_OPEN Expr BRACKET_CLOSE + { + $$ = $2; + } + ; + +AxisName + : ANCESTOR { $$ = Axes.Ancestor; } + | ANCESTOR_OR_SELF { $$ = Axes.AncestorOrSelf; } + | ATTRIBUTE { $$ = Axes.Attribute; } + | CHILD { $$ = Axes.Child; } + | DESCENDANT { $$ = Axes.Descendant; } + | DESCENDANT_OR_SELF { $$ = Axes.DescendantOrSelf; } + | FOLLOWING { $$ = Axes.Following; } + | FOLLOWING_SIBLING { $$ = Axes.FollowingSibling; } + | NAMESPACE { $$ = Axes.Namespace; } + | PARENT { $$ = Axes.Parent; } + | PRECEDING { $$ = Axes.Preceding; } + | PRECEDING_SIBLING { $$ = Axes.PrecedingSibling; } + | SELF { $$ = Axes.Self; } + ; + +OptionalLiteral + : /* empty */ + | LITERAL + { + $$ = $1; + } + ; + +QName + : NCName + { + $$ = new NCName ((String) $1); + } + | NCName COLON NCName + { + $$ = new QName ((String) $1, (String) $3); + } + ; + +%% + } diff --git a/mcs/class/System.XML/System.Xml.XPath/Tokenizer.cs b/mcs/class/System.XML/System.Xml.XPath/Tokenizer.cs new file mode 100644 index 00000000000..6e2dea9f66b --- /dev/null +++ b/mcs/class/System.XML/System.Xml.XPath/Tokenizer.cs @@ -0,0 +1,341 @@ +// +// System.Xml.XPath.Tokenizer +// +// Author: +// Piers Haken (piersh@friskit.com) +// +// (C) 2002 Piers Haken +// +using System; +using System.IO; +using System.Text; +using System.Collections; + +namespace System.Xml.XPath +{ + internal class Tokenizer : yyParser.yyInput + { + private char [] m_rgchInput; + private int m_ich; + private int m_cch; +// private System.IO.StreamReader m_input; + private int m_iToken; + private Object m_objToken; + private static Hashtable m_mapTokens = new Hashtable (); + private static readonly Object [] rgTokenMap = + { + Token.AND, "and", + Token.OR, "or", + Token.DIV, "div", + Token.MOD, "mod", + Token.ANCESTOR, "ancestor", + Token.ANCESTOR_OR_SELF, "ancestor-or-self", + Token.ATTRIBUTE, "attribute", + Token.CHILD, "child", + Token.DESCENDANT, "descendant", + Token.DESCENDANT_OR_SELF, "descendant-or-self", + Token.FOLLOWING, "following", + Token.FOLLOWING_SIBLING, "following-sibling", + Token.NAMESPACE, "namespace", + Token.PARENT, "parent", + Token.PRECEDING, "preceding", + Token.PRECEDING_SIBLING, "preceding-sibling", + Token.SELF, "self", + Token.COMMENT, "comment", + Token.TEXT, "text", + Token.PROCESSING_INSTRUCTION, "processing-instruction", + Token.NODE, "node", + }; + + static Tokenizer () + { + for (int i = 0; i < rgTokenMap.Length; i += 2) + m_mapTokens.Add (rgTokenMap [i + 1], rgTokenMap [i]); + } + +/* public Tokenizer (StreamReader input) + { + m_input = input; + SkipWhitespace (); + }*/ + public Tokenizer (string strInput) + { + m_rgchInput = strInput.ToCharArray (); + m_ich = 0; + m_cch = strInput.Length; + SkipWhitespace (); + } + + private int Peek () + { + if (m_ich >= m_cch) + return -1; + return m_rgchInput [m_ich]; + //return m_input.Peek (); + } + + private int GetChar () + { + if (m_ich >= m_cch) + return -1; + return m_rgchInput [m_ich++]; + //return m_input.Read (); + } + + private void SkipWhitespace () + { + while (IsWhitespace (Peek ())) + GetChar (); + } + + [MonoTODO] + private int ParseNumber () + { + StringBuilder sb = new StringBuilder (); + + while (IsDigit (Peek ())) + sb.Append ((char) GetChar ()); + + // TODO: doesn't handle '3.' error case + if (Peek () == '.') + { + sb.Append ((char) GetChar ()); + while (IsDigit (Peek ())) + sb.Append ((char) GetChar ()); + } + m_objToken = Double.Parse (sb.ToString ()); + return Token.NUMBER; + } + + private int ParseLiteral () + { + StringBuilder sb = new StringBuilder (); + + int chInit = GetChar (); + int ch; + while ((ch = Peek ()) != chInit) + { + if (ch == -1) + return Token.ERROR; + sb.Append ((char) GetChar ()); + } + GetChar (); + m_objToken = sb.ToString (); + return Token.LITERAL; + } + + private int ParseIdentifier () + { + StringBuilder sb = new StringBuilder (); + + while (true) + { + int ch = Peek (); + if (ch == '_' || + (ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z')) + { + sb.Append ((char) GetChar ()); + } + else + break; + } + String strToken = sb.ToString (); + Object objToken = m_mapTokens [strToken]; + if (objToken != null) + { + return (int) objToken; + } + else + { + m_objToken = strToken; + + SkipWhitespace (); + if (Peek () == '(') + return Token.FUNCTION_NAME; + return Token.NCName; + } + } + + private static bool IsWhitespace (int ch) + { + return (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); + } + + private static bool IsDigit (int ch) + { + return ch >= '0' && ch <= '9'; + } + + + int ParseToken () + { +// while (IsWhitespace (Peek ())) +// GetChar (); + switch (Peek ()) + { + case -1: + return Token.EOF; + + case '/': + GetChar (); + if (Peek () == '/') + { + GetChar (); + return Token.SLASH2; + } + return Token.SLASH; + + case '.': + GetChar (); + if (Peek () == '.') + { + GetChar (); + return Token.DOT2; + } + else if (Peek () >= '0' && Peek () <= '9') + { + return ParseNumber (); + } + return Token.DOT; + + case ':': + GetChar (); + if (Peek () == ':') + { + GetChar (); + return Token.COLON2; + } + return Token.COLON; + + case ',': + GetChar (); + return Token.COMMA; + + case '@': + GetChar (); + return Token.AT; + + case '[': + GetChar (); + return Token.BRACKET_OPEN; + + case ']': + GetChar (); + return Token.BRACKET_CLOSE; + + case '(': + GetChar (); + return Token.PAREN_OPEN; + + case ')': + GetChar (); + return Token.PAREN_CLOSE; + + case '+': + GetChar (); + return Token.PLUS; + + case '-': + GetChar (); + return Token.MINUS; + + case '*': + GetChar (); + return Token.ASTERISK; + + case '$': + GetChar (); + return Token.DOLLAR; + + case '|': + GetChar (); + return Token.BAR; + + case '=': + GetChar (); + return Token.EQ; + + case '!': + GetChar (); + if (Peek () == '=') + { + GetChar (); + return Token.NE; + } + break; + + case '>': + GetChar (); + if (Peek () == '=') + { + GetChar (); + return Token.GE; + } + return Token.GT; + + case '<': + GetChar (); + if (Peek () == '=') + { + GetChar (); + return Token.LE; + } + return Token.LT; + + case '\'': + return ParseLiteral (); + + case '\"': + return ParseLiteral (); + + default: + { + if (IsDigit (Peek ())) + { + return ParseNumber (); + } + else + { + return ParseIdentifier (); + } + } + } + return Token.ERROR; + } + + /////////////////////////// + // yyParser.yyInput methods + /////////////////////////// + + /** move on to next token. + @return false if positioned beyond tokens. + @throws IOException on input error. + */ + public bool advance () + { + m_objToken = null; + m_iToken = ParseToken (); + SkipWhitespace (); + return (m_iToken != Token.EOF); + } + + /** classifies current token. + Should not be called if advance() returned false. + @return current %token or single character. + */ + public int token () + { + return m_iToken; + } + + /** associated with current token. + Should not be called if advance() returned false. + @return value for token(). + */ + public Object value () + { + return m_objToken; + } + } +} diff --git a/mcs/class/System.XML/System.Xml.XPath/XPathNavigator.cs b/mcs/class/System.XML/System.Xml.XPath/XPathNavigator.cs index 1c6b06e3d1f..ee21e6da8e8 100644 --- a/mcs/class/System.XML/System.Xml.XPath/XPathNavigator.cs +++ b/mcs/class/System.XML/System.Xml.XPath/XPathNavigator.cs @@ -62,35 +62,38 @@ namespace System.Xml.XPath [MonoTODO] public virtual XPathExpression Compile (string xpath) { - throw new NotImplementedException (); + Tokenizer tokenizer = new Tokenizer (xpath); + XPathParser parser = new XPathParser (); + Expression expr = (Expression) parser.yyparse (tokenizer); + return new CompiledExpression (expr); } - [MonoTODO] public virtual object Evaluate (string xpath) { - throw new NotImplementedException (); + return Evaluate (Compile (xpath)); } - [MonoTODO] public virtual object Evaluate (XPathExpression expr) { - throw new NotImplementedException (); + return Evaluate (expr, null); } [MonoTODO] public virtual object Evaluate (XPathExpression expr, XPathNodeIterator context) { - throw new NotImplementedException (); + // TODO: check casts + if (context == null) + context = new SelfIterator (this, new DefaultContext ()); + return ((CompiledExpression) expr).Evaluate ((BaseIterator) context); } public abstract string GetAttribute (string localName, string namespaceURI); public abstract string GetNamespace (string name); - [MonoTODO] object ICloneable.Clone () { - throw new NotImplementedException (); + return Clone (); } [MonoTODO] @@ -104,7 +107,7 @@ namespace System.Xml.XPath [MonoTODO] public virtual bool Matches (string xpath) { - throw new NotImplementedException (); + return Matches (Compile (xpath)); } [MonoTODO] @@ -123,10 +126,9 @@ namespace System.Xml.XPath public abstract bool MoveToFirstChild (); - [MonoTODO] public bool MoveToFirstNamespace () { - throw new NotImplementedException (); + return MoveToFirstNamespace (XPathNamespaceScope.All); } public abstract bool MoveToFirstNamespace (XPathNamespaceScope namespaceScope); @@ -139,10 +141,9 @@ namespace System.Xml.XPath public abstract bool MoveToNextAttribute (); - [MonoTODO] public bool MoveToNextNamespace () { - throw new NotImplementedException (); + return MoveToNextNamespace (XPathNamespaceScope.All); } public abstract bool MoveToNextNamespace (XPathNamespaceScope namespaceScope); @@ -153,16 +154,16 @@ namespace System.Xml.XPath public abstract void MoveToRoot (); - [MonoTODO] public virtual XPathNodeIterator Select (string xpath) { - throw new NotImplementedException (); + return Select (Compile (xpath)); } [MonoTODO] public virtual XPathNodeIterator Select (XPathExpression expr) { - throw new NotImplementedException (); + BaseIterator iter = new SelfIterator (this, new DefaultContext ()); + return ((CompiledExpression) expr).EvaluateNodeSet (iter); } [MonoTODO] @@ -201,10 +202,9 @@ namespace System.Xml.XPath throw new NotImplementedException (); } - [MonoTODO] public override string ToString () { - throw new NotImplementedException (); + return Value; } #endregion diff --git a/mcs/class/System.XML/System.Xml.XPath/XPathNodeIterator.cs b/mcs/class/System.XML/System.Xml.XPath/XPathNodeIterator.cs index acfcb36aba4..661b6564467 100644 --- a/mcs/class/System.XML/System.Xml.XPath/XPathNodeIterator.cs +++ b/mcs/class/System.XML/System.Xml.XPath/XPathNodeIterator.cs @@ -13,6 +13,8 @@ namespace System.Xml.XPath { public abstract class XPathNodeIterator : ICloneable { + private int _count; + #region Constructor protected XPathNodeIterator () @@ -23,10 +25,19 @@ namespace System.Xml.XPath #region Properties - [MonoTODO] - public virtual int Count { - get { - throw new NotImplementedException (); + public virtual int Count + { + get + { + if (_count == 0) + { + // compute and cache the count + XPathNodeIterator tmp = Clone (); + while (tmp.MoveNext ()) + ; + _count = tmp.CurrentPosition; + } + return _count; } } diff --git a/mcs/class/System.XML/System.Xml.Xsl/ChangeLog b/mcs/class/System.XML/System.Xml.Xsl/ChangeLog new file mode 100644 index 00000000000..4043d3a0744 --- /dev/null +++ b/mcs/class/System.XML/System.Xml.Xsl/ChangeLog @@ -0,0 +1,4 @@ +2002-06-23 Piers Haken <piersh@friskit.com> + + * XsltContext.cs: added 'PreserveWhitespace' abstract method + diff --git a/mcs/class/System.XML/System.Xml.Xsl/XsltContext.cs b/mcs/class/System.XML/System.Xml.Xsl/XsltContext.cs index f2eb82ac27c..b47822ae7a3 100644 --- a/mcs/class/System.XML/System.Xml.Xsl/XsltContext.cs +++ b/mcs/class/System.XML/System.Xml.Xsl/XsltContext.cs @@ -30,6 +30,7 @@ namespace System.Xml.Xsl #region Properties
public abstract bool Whitespace { get; }
+ public abstract bool PreserveWhitespace (XPathNavigator nav);
#endregion
diff --git a/mcs/class/System.XML/System.Xml/ChangeLog b/mcs/class/System.XML/System.Xml/ChangeLog index c4a90709c57..8e0760b7a9c 100644 --- a/mcs/class/System.XML/System.Xml/ChangeLog +++ b/mcs/class/System.XML/System.Xml/ChangeLog @@ -1,3 +1,10 @@ +2002-06-23 Piers Haken <piersh@friskit.com> + + * XmlDocumentNavigator.cs: implement Clone() + * XmlElement.cs: remove bogus unimplemented override of InnerText + * XmlNode.cs: implment SelectNodes/SelectSingleNode + * XmlNodeArrayList.cs: new support class for SelectNodes + 2002-06-21 Ajay kumar Dwivedi <adwiv@yahoo.com> * XmlQualifiedName: Name and Namespaces are never null. If null is passed diff --git a/mcs/class/System.XML/System.Xml/XmlDocumentNavigator.cs b/mcs/class/System.XML/System.Xml/XmlDocumentNavigator.cs index 3ee415ddc45..bdd44a165f6 100644 --- a/mcs/class/System.XML/System.Xml/XmlDocumentNavigator.cs +++ b/mcs/class/System.XML/System.Xml/XmlDocumentNavigator.cs @@ -168,10 +168,9 @@ namespace System.Xml #region Methods - [MonoTODO] public override XPathNavigator Clone () { - throw new NotImplementedException (); + return new XmlDocumentNavigator (node); } [MonoTODO] @@ -305,6 +304,8 @@ namespace System.Xml node = node.OwnerDocument; } + internal XmlNode Node { get { return node; } } + #endregion }
}
diff --git a/mcs/class/System.XML/System.Xml/XmlElement.cs b/mcs/class/System.XML/System.Xml/XmlElement.cs index c352c96a1a4..58726978473 100644 --- a/mcs/class/System.XML/System.Xml/XmlElement.cs +++ b/mcs/class/System.XML/System.Xml/XmlElement.cs @@ -50,13 +50,6 @@ namespace System.Xml get { return attributes.Count > 0; } } - [MonoTODO] - public override string InnerText { - get { throw new NotImplementedException (); } - - set { throw new NotImplementedException (); } - } - [MonoTODO ("Setter.")] public override string InnerXml { get { diff --git a/mcs/class/System.XML/System.Xml/XmlNode.cs b/mcs/class/System.XML/System.Xml/XmlNode.cs index c5dbad00267..ca9df1ee022 100644 --- a/mcs/class/System.XML/System.Xml/XmlNode.cs +++ b/mcs/class/System.XML/System.Xml/XmlNode.cs @@ -323,28 +323,46 @@ namespace System.Xml throw new NotImplementedException (); } - [MonoTODO] public XmlNodeList SelectNodes (string xpath) { - throw new NotImplementedException (); + return SelectNodes (xpath, null); } [MonoTODO] public XmlNodeList SelectNodes (string xpath, XmlNamespaceManager nsmgr) { - throw new NotImplementedException (); + XPathNavigator nav = CreateNavigator (); + XPathExpression expr = nav.Compile (xpath); + if (nsmgr != null) + expr.SetContext (nsmgr); + XPathNodeIterator iter = nav.Select (expr); + if (!iter.MoveNext ()) + return null; + ArrayList rgNodes = new ArrayList (); + do + { + rgNodes.Add (((XmlDocumentNavigator) iter.Current).Node); + } + while (iter.MoveNext ()); + return new XmlNodeArrayList (rgNodes); } - [MonoTODO] public XmlNode SelectSingleNode (string xpath) { - throw new NotImplementedException (); + return SelectSingleNode (xpath, null); } [MonoTODO] public XmlNode SelectSingleNode (string xpath, XmlNamespaceManager nsmgr) { - throw new NotImplementedException (); + XPathNavigator nav = CreateNavigator (); + XPathExpression expr = nav.Compile (xpath); + if (nsmgr != null) + expr.SetContext (nsmgr); + XPathNodeIterator iter = nav.Select (expr); + if (!iter.MoveNext ()) + return null; + return ((XmlDocumentNavigator) iter.Current).Node; } internal void SetParentNode (XmlNode parent) diff --git a/mcs/class/System.XML/System.Xml/XmlNodeArrayList.cs b/mcs/class/System.XML/System.Xml/XmlNodeArrayList.cs new file mode 100644 index 00000000000..a62fd77f401 --- /dev/null +++ b/mcs/class/System.XML/System.Xml/XmlNodeArrayList.cs @@ -0,0 +1,36 @@ +// +// System.Xml.XmlNodeArrayList +// +// Author: +// Piers Haken <piersh@friskit.com> +// +// (C) 2002 Piers Haken +// + +using System; +using System.Collections; + +namespace System.Xml +{ + internal class XmlNodeArrayList : XmlNodeList + { + ArrayList _rgNodes; + + public XmlNodeArrayList (ArrayList rgNodes) + { + _rgNodes = rgNodes; + } + + public override int Count { get { return _rgNodes.Count; } } + + public override IEnumerator GetEnumerator () + { + return _rgNodes.GetEnumerator (); + } + + public override XmlNode Item (int index) + { + return (XmlNode) _rgNodes [index]; + } + } +} |