2002-06-23 Piers Haken <piersh@friskit.com>
authorPiers Haken <piers@mono-cvs.ximian.com>
Sun, 23 Jun 2002 16:52:58 +0000 (16:52 -0000)
committerPiers Haken <piers@mono-cvs.ximian.com>
Sun, 23 Jun 2002 16:52:58 +0000 (16:52 -0000)
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

17 files changed:
mcs/class/System.XML/Mono.System.XML.csproj
mcs/class/System.XML/System.Xml.XPath/ChangeLog
mcs/class/System.XML/System.Xml.XPath/DefaultContext.cs [new file with mode: 0644]
mcs/class/System.XML/System.Xml.XPath/Expression.cs [new file with mode: 0644]
mcs/class/System.XML/System.Xml.XPath/Iterator.cs [new file with mode: 0644]
mcs/class/System.XML/System.Xml.XPath/Parser.cs [new file with mode: 0644]
mcs/class/System.XML/System.Xml.XPath/Parser.jay [new file with mode: 0644]
mcs/class/System.XML/System.Xml.XPath/Tokenizer.cs [new file with mode: 0644]
mcs/class/System.XML/System.Xml.XPath/XPathNavigator.cs
mcs/class/System.XML/System.Xml.XPath/XPathNodeIterator.cs
mcs/class/System.XML/System.Xml.Xsl/ChangeLog [new file with mode: 0644]
mcs/class/System.XML/System.Xml.Xsl/XsltContext.cs
mcs/class/System.XML/System.Xml/ChangeLog
mcs/class/System.XML/System.Xml/XmlDocumentNavigator.cs
mcs/class/System.XML/System.Xml/XmlElement.cs
mcs/class/System.XML/System.Xml/XmlNode.cs
mcs/class/System.XML/System.Xml/XmlNodeArrayList.cs [new file with mode: 0644]

index 21d3819c1ef94e30a0db6834db03de9cc99c17ae..18ecafccdaecdd798a55b7af470a31635c027420 100644 (file)
                     SubType = "Code"\r
                     BuildAction = "Compile"\r
                 />\r
+                <File\r
+                    RelPath = "System.Xml\IHasXmlNode.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
                 <File\r
                     RelPath = "System.Xml\IXmlLineInfo.cs"\r
                     SubType = "Code"\r
                     SubType = "Code"\r
                     BuildAction = "Compile"\r
                 />\r
+                <File\r
+                    RelPath = "System.Xml\XmlConstructs.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "System.Xml\XmlConvert.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
                 <File\r
                     RelPath = "System.Xml\XmlDeclaration.cs"\r
                     SubType = "Code"\r
                     SubType = "Code"\r
                     BuildAction = "Compile"\r
                 />\r
+                <File\r
+                    RelPath = "System.Xml\XmlEntity.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
                 <File\r
                     RelPath = "System.Xml\XmlEntityReference.cs"\r
                     SubType = "Code"\r
                     SubType = "Code"\r
                     BuildAction = "Compile"\r
                 />\r
+                <File\r
+                    RelPath = "System.Xml\XmlNodeReader.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
                 <File\r
                     RelPath = "System.Xml\XmlNodeType.cs"\r
                     SubType = "Code"\r
                     BuildAction = "Compile"\r
                 />\r
+                <File\r
+                    RelPath = "System.Xml\XmlNotation.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
                 <File\r
                     RelPath = "System.Xml\XmlParserContext.cs"\r
                     SubType = "Code"\r
                     RelPath = "System.Xml.XPath\ChangeLog"\r
                     BuildAction = "None"\r
                 />\r
+                <File\r
+                    RelPath = "System.Xml.XPath\DefaultContext.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "System.Xml.XPath\Expression.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "System.Xml.XPath\Iterator.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
                 <File\r
                     RelPath = "System.Xml.XPath\IXPathNavigable.cs"\r
                     SubType = "Code"\r
                     BuildAction = "Compile"\r
                 />\r
+                <File\r
+                    RelPath = "System.Xml.XPath\Parser.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "System.Xml.XPath\Parser.jay"\r
+                    BuildAction = "None"\r
+                />\r
+                <File\r
+                    RelPath = "System.Xml.XPath\Tokenizer.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
                 <File\r
                     RelPath = "System.Xml.XPath\XmlCaseOrder.cs"\r
                     SubType = "Code"\r
                     SubType = "Code"\r
                     BuildAction = "Compile"\r
                 />\r
+                <File\r
+                    RelPath = "System.Xml.XPath\XPathDocument.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
+                <File\r
+                    RelPath = "System.Xml.XPath\XPathException.cs"\r
+                    SubType = "Code"\r
+                    BuildAction = "Compile"\r
+                />\r
                 <File\r
                     RelPath = "System.Xml.XPath\XPathExpression.cs"\r
                     SubType = "Code"\r
index e6597f62d20579fb3ace7720a488878e61ed08e2..03cc6a385c8211b9ceb5fe37d73ef11182d1271c 100644 (file)
@@ -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 (file)
index 0000000..37fcc29
--- /dev/null
@@ -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 (file)
index 0000000..e4e9602
--- /dev/null
@@ -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)
+                       {\r
+                               return Compare (_left.EvaluateBoolean (iter), _right.EvaluateBoolean (iter));
+                       }\r
+                       else if (typeL == XPathResultType.Number || typeR == XPathResultType.Number)
+                       {\r
+                               return Compare (_left.EvaluateNumber (iter), _right.EvaluateNumber (iter));
+                       }\r
+                       else
+                       {\r
+                               return Compare (_left.EvaluateString (iter), _right.EvaluateString (iter));
+                       }\r
+               }
+               [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 (file)
index 0000000..5a8a637
--- /dev/null
@@ -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 (file)
index 0000000..d747e4c
--- /dev/null
@@ -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 (file)
index 0000000..c404d9d
--- /dev/null
@@ -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 (file)
index 0000000..6e2dea9
--- /dev/null
@@ -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;
+               }
+       }
+}
index 1c6b06e3d1ff399633ad0d0292cc8bc45c150c5e..ee21e6da8e8716269688663351477fbacbedb1aa 100644 (file)
@@ -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
index acfcb36aba44476f664cb870e26da34debef74ce..661b65644670060a8e43e2ff6a54ff802e693148 100644 (file)
@@ -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 (file)
index 0000000..4043d3a
--- /dev/null
@@ -0,0 +1,4 @@
+2002-06-23  Piers Haken <piersh@friskit.com>
+       
+       * XsltContext.cs: added 'PreserveWhitespace' abstract method
+
index f2eb82ac27c05c661dc7b1b9a5b85e439f53ced5..b47822ae7a3528912f63e199bc682a28e8e57149 100644 (file)
@@ -30,6 +30,7 @@ namespace System.Xml.Xsl
                #region Properties\r
 \r
                public abstract bool Whitespace { get; }\r
+               public abstract bool PreserveWhitespace (XPathNavigator nav);\r
 \r
                #endregion\r
 \r
index c4a90709c57f9df93bef892bd1645bc80ac0361f..8e0760b7a9cd841551fc98fd021b3be9debfe15a 100644 (file)
@@ -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
index 3ee415ddc45b51ddc7b85ef0da4f9989cd667089..bdd44a165f651deb7b6dbfe6ed5d0e17eee60dcb 100644 (file)
@@ -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
        }\r
 }\r
index c352c96a1a4f5e477e644c0d28796e8dbcd43e67..58726978473a8c52a38cac7b1e5687aabed29d97 100644 (file)
@@ -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 {
index c5dbad00267a808e9e5ac5a2b66d9806bd344c4a..ca9df1ee0225764807db51b09a706549e18475bf 100644 (file)
@@ -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 (file)
index 0000000..a62fd77
--- /dev/null
@@ -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];
+               }
+       }
+}