示例#1
0
        private XPathAxis CheckAxis()
        {
            this.kind = LexKind.Axis;
            switch (name)
            {
            case "ancestor": return(XPathAxis.Ancestor);

            case "ancestor-or-self": return(XPathAxis.AncestorOrSelf);

            case "attribute": return(XPathAxis.Attribute);

            case "child": return(XPathAxis.Child);

            case "descendant": return(XPathAxis.Descendant);

            case "descendant-or-self": return(XPathAxis.DescendantOrSelf);

            case "following": return(XPathAxis.Following);

            case "following-sibling": return(XPathAxis.FollowingSibling);

            case "namespace": return(XPathAxis.Namespace);

            case "parent": return(XPathAxis.Parent);

            case "preceding": return(XPathAxis.Preceding);

            case "preceding-sibling": return(XPathAxis.PrecedingSibling);

            case "self": return(XPathAxis.Self);

            default: this.kind = LexKind.Name; return(XPathAxis.Unknown);
            }
        }
 public XPathScanner(string xpathExpr, int startFrom) {
     Debug.Assert(xpathExpr != null);
     this.xpathExpr = xpathExpr;
     this.kind = LexKind.Unknown;
     SetSourceIndex(startFrom);
     NextLex();
 }
示例#3
0
        // Six possible causes of exceptions in the builder:
        // 1. Undefined prefix in a node test.
        // 2. Undefined prefix in a variable reference, or unknown variable.
        // 3. Undefined prefix in a function call, or unknown function, or wrong number/types of arguments.
        // 4. Argument of Union operator is not a node-set.
        // 5. First argument of Predicate is not a node-set.
        // 6. Argument of Axis is not a node-set.

        public Node Parse(XPathScanner scanner, IXPathBuilder <Node> builder, LexKind endLex)
        {
            Debug.Assert(this.scanner == null && this.builder == null);
            Debug.Assert(scanner != null && builder != null);

            Node result = default(Node);

            this.scanner = scanner;
            this.builder = builder;
            this.posInfo.Clear();

            try {
                builder.StartBuild();
                result = ParseExpr();
                scanner.CheckToken(endLex);
            }
            catch (XPathCompileException e) {
                if (e.queryString == null)
                {
                    e.queryString = scanner.Source;
                    PopPosInfo(out e.startChar, out e.endChar);
                }
                throw;
            }
            finally {
                result = builder.EndBuild(result);
#if DEBUG
                this.builder = null;
                this.scanner = null;
#endif
            }
            Debug.Assert(posInfo.Count == 0, "PushPosInfo() and PopPosInfo() calls have been unbalanced");
            return(result);
        }
        private void ScanNumber()
        {
            Debug.Assert(xmlCharType.IsDigit(curChar));
            int start = curIndex;

            while (xmlCharType.IsDigit(curChar))
            {
                NextChar();
            }
            if (curChar == '.')
            {
                NextChar();
                while (xmlCharType.IsDigit(curChar))
                {
                    NextChar();
                }
            }
            if ((curChar & (~0x20)) == 'E')
            {
                NextChar();
                if (curChar == '+' || curChar == '-')
                {
                    NextChar();
                }
                while (xmlCharType.IsDigit(curChar))
                {
                    NextChar();
                }
                throw CreateException(Res.XPath_ScientificNotation);
            }
            this.kind        = LexKind.Number;
            this.numberValue = XPathConvert.StringToDouble(xpathExpr.Substring(start, curIndex - start));
        }
示例#5
0
        // May be called for the following tokens: Name, String, Eof, Comma, LParens, RParens, LBracket, RBracket, RBrace
        private string LexKindToString(LexKind t)
        {
            if (!(LexKind.FirstStringable <= t))
            {
                throw new Exception("XPath error: Unexpected xpathExpr = null");
            }

            if (LexKind.LastNonChar < t)
            {
                if (!("()[].@,*/$}".IndexOf((char)t) >= 0))
                {
                    throw new Exception("XPath error: missing last non char ()[].@,*/$} : " + (char)t);
                }

                return(new string((char)t, 1));
            }

            switch (t)
            {
            case LexKind.Name: return("<name>");

            case LexKind.String: return("<string literal>");

            case LexKind.Eof: return("<eof>");

            default:
                Debug.Fail("Unexpected LexKind: " + t.ToString());
                return(string.Empty);
            }
        }
示例#6
0
 private void ListAdd(string str, LexKind kind)
 {
     if (kind >= LexKind.Symbol00 && kind <= LexKind.Symbol11 && Expansions.ContainsKey(str))
     {
         object o;
         Expansions.TryGetValue(str, out o);
         if (o is string)
         {
             string so = o as string;
             o = LexList.Get(so);
         }
         if (o is LexList)
         {
             for (int i = 0; i < ((LexList)o).Count; i++)
             {
                 LexToken tok        = ((LexList)o)[i];
                 bool     toPrevious = (kind == LexKind.Symbol10 || kind == LexKind.Symbol11) && i == 0;
                 bool     toNext     = (kind == LexKind.Symbol01 || kind == LexKind.Symbol11) && i == ((LexList)o).Count - 1;
                 ListAddToken(toPrevious, new LexToken(tok), toNext);
             }
         }
         else
         {
             LexToken token = new LexToken(o, List, List.Count);
             List.Add(token);
         }
     }
     else
     {
         ListAddToken(kind == LexKind.Symbol10 || kind == LexKind.Symbol11, new LexToken(str, kind, List, List.Count), kind == LexKind.Symbol01 || kind == LexKind.Symbol11);
     }
 }
示例#7
0
 public LexToken(LexToken tok)
 {
     Str           = tok.Str;
     Kind          = tok.Kind;
     ErrorLocation = "";
     ActualObject  = tok.ActualObject;
     LinkOther     = -1;
 }
示例#8
0
 public XPathScanner(string xpathExpr, int startFrom)
 {
     Debug.Assert(xpathExpr != null);
     this.xpathExpr = xpathExpr;
     this.kind      = LexKind.Unknown;
     SetSourceIndex(startFrom);
     NextLex();
 }
示例#9
0
        private bool CheckOperator(bool star)
        {
            LexKind opKind;

            if (star)
            {
                opKind = LexKind.Multiply;
            }
            else
            {
                Debug.Assert(_prefix != null);
                Debug.Assert(_name != null);
                if (_prefix.Length != 0 || _name.Length > 3)
                {
                    return(false);
                }

                switch (_name)
                {
                case "or": opKind = LexKind.Or; break;

                case "and": opKind = LexKind.And; break;

                case "div": opKind = LexKind.Divide; break;

                case "mod": opKind = LexKind.Modulo; break;

                default: return(false);
                }
            }

            // If there is a preceding token and the preceding token is not one of '@', '::', '(', '[', ',' or an Operator,
            // then a '*' must be recognized as a MultiplyOperator and an NCName must be recognized as an OperatorName.
            if (_prevKind <= LexKind.LastOperator)
            {
                return(false);
            }

            switch (_prevKind)
            {
            case LexKind.Slash:
            case LexKind.SlashSlash:
            case LexKind.At:
            case LexKind.ColonColon:
            case LexKind.LParens:
            case LexKind.LBracket:
            case LexKind.Comma:
            case LexKind.Dollar:
                return(false);
            }

            _kind = opKind;
            return(true);
        }
        /**************************************************************************************************/
        /*  Location paths and node tests                                                                 */
        /**************************************************************************************************/

        private static bool IsStep(LexKind lexKind)
        {
            return(
                lexKind == LexKind.Dot ||
                lexKind == LexKind.DotDot ||
                lexKind == LexKind.At ||
                lexKind == LexKind.Axis ||
                lexKind == LexKind.Star ||
                lexKind == LexKind.Name   // NodeTest is also Name
                );
        }
示例#11
0
 public XPathScanner(string xpathExpr, int startFrom)
 {
     if (xpathExpr == null)
     {
         throw new Exception("XPath error: Unexpected xpathExpr = null");
     }
     this.xpathExpr = xpathExpr;
     this.kind      = LexKind.Unknown;
     SetSourceIndex(startFrom);
     NextLex();
 }
        private void ScanFraction()
        {
            Debug.Assert(xmlCharType.IsDigit(curChar));
            int start = curIndex - 1;

            Debug.Assert(0 <= start && xpathExpr[start] == '.');
            while (xmlCharType.IsDigit(curChar))
            {
                NextChar();
            }
            this.kind        = LexKind.Number;
            this.numberValue = XPathConvert.StringToDouble(xpathExpr.Substring(start, curIndex - start));
        }
示例#13
0
        public static bool IsBinaryOperator(LexKind lexKind)
        {
            switch (lexKind)
            {
            case LexKind.Add:
            case LexKind.Sub:
            case LexKind.Mul:
            case LexKind.Div:
                return(true);

            default:
                return(false);
            }
        }
 public void CheckToken(LexKind t)
 {
     if (kind != t)
     {
         if (t == LexKind.Eof)
         {
             throw CreateException(Res.XPath_EofExpected, RawValue);
         }
         else
         {
             throw CreateException(Res.XPath_TokenExpected, LexKindToString(t), RawValue);
         }
     }
 }
示例#15
0
        public LexToken(object value, List <LexToken> list, int index)
        {
            if (value == null)
            {
                throw new LexTokenException("LexToken called with a null value.");
            }
            Str          = value.ToString();
            ActualObject = value;
            Type theType = value.GetType();

            if (theType == typeof(double))
            {
                Kind = LexKind.Double;
            }
            else if (theType == typeof(int))
            {
                Kind = LexKind.Int;
            }
            else if (theType == typeof(float))
            {
                Kind = LexKind.Float;
            }
            else if (theType == typeof(long))
            {
                Kind = LexKind.Long;
            }
            else if (theType == typeof(bool))
            {
                Kind = LexKind.Bool;
            }
            else if (theType == typeof(char))
            {
                Kind = LexKind.Char;
                Str  = "'" + Str + "'";
            }
            else if (value is Type)
            {
                Kind = LexKind.Type;
                Str  = ((Type)value).Name;
            }
            else if (theType.IsEnum)
            {
                Kind = LexKind.Identifier;
            }
            else
            {
                throw new LexTokenException("LexToken cannot be called with the type of '" + value.GetType().Name + "'");
            }
        }
示例#16
0
 public void CheckToken(LexKind t)
 {
     Debug.Assert(LexKind.FirstStringable <= t);
     if (_kind != t)
     {
         if (t == LexKind.Eof)
         {
             throw CreateException(SR.XPath_EofExpected, RawValue);
         }
         else
         {
             throw CreateException(SR.XPath_TokenExpected, LexKindToString(t), RawValue);
         }
     }
 }
示例#17
0
 public void CheckToken(LexKind t)
 {
     Debug.Assert(LexKind.FirstStringable <= t);
     if (kind != t)
     {
         if (t == LexKind.Eof)
         {
             throw EofExpectedException(RawValue);
         }
         else
         {
             throw TokenExpectedException(LexKindToString(t), RawValue);
         }
     }
 }
        private void ScanString()
        {
            char endChar = curChar;
            int  start   = curIndex + 1;

            do
            {
                if (!NextChar())
                {
                    throw CreateException(Res.XPath_UnclosedString);
                }
            } while (curChar != endChar);

            this.kind        = LexKind.String;
            this.stringValue = xpathExpr.Substring(start, curIndex - start);
            NextChar();
        }
示例#19
0
        public void CheckToken(LexKind t)
        {
            if (!(LexKind.FirstStringable <= t))
            {
                throw new Exception("XPath error: Unexpected xpathExpr = null");
            }

            if (kind != t)
            {
                if (t == LexKind.Eof)
                {
                    throw EofExpectedException(RawValue);
                }
                else
                {
                    throw TokenExpectedException(LexKindToString(t), RawValue);
                }
            }
        }
示例#20
0
 /// <summary>
 /// Checks that the LexKind of the current token agrees with the parameter.
 /// If the Index is at one past the last token, then the LexKind of that non-existent token is assumed to be LexKind.End.
 /// </summary>
 public void CheckKind(LexKind kind)
 {
     if (Index >= TheTopCount)
     {
         if (kind != LexKind.End)
         {
             TheList[TheTopCount - 1].ThrowException("Expected a token of kind '" + kind + "' here.", this);
         }
     }
     else if (kind == LexKind.End && Index < TheTopCount)
     {
         TheList[Index].ThrowException("Expected the end of text here.", this);
     }
     else
     {
         if (kind != TheList[Index].Kind)
         {
             TheList[Index].ThrowException("Expected a token of kind '" + kind + "' here.", this);
         }
     }
 }
示例#21
0
        // May be called for the following tokens: Name, String, Eof, Comma, LParens, RParens, LBracket, RBracket, RBrace
        private string LexKindToString(LexKind t)
        {
            Debug.Assert(LexKind.FirstStringable <= t);

            if (LexKind.LastNonChar < t)
            {
                Debug.Assert("()[].@,*/$}".IndexOf((char)t) >= 0);
                return(new string((char)t, 1));
            }

            switch (t)
            {
            case LexKind.Name: return("<name>");

            case LexKind.String: return("<string literal>");

            case LexKind.Eof: return("<eof>");

            default:
                throw new Exception("Unexpected LexKind: " + t.ToString());
            }
        }
        public string LexKindToString(LexKind t)
        {
            const string OneCharLexemes = ",/@.()[]{}*+-=<>!$|";

            if (OneCharLexemes.IndexOf((char)t) >= 0)
            {
                return(((char)t).ToString());
            }

            switch (t)
            {
            case LexKind.Ne: return("!=");

            case LexKind.Le: return("<=");

            case LexKind.Ge: return(">=");

            case LexKind.DotDot: return("..");

            case LexKind.SlashSlash: return("//");

            case LexKind.Name: return("<name>");

            case LexKind.String: return("<string literal>");

            case LexKind.Number: return("<number literal>");

            case LexKind.Axis: return("<axis>");

            case LexKind.Unknown: return("<unknown>");

            case LexKind.Eof: return("<eof>");

            default:
                Debug.Fail("Must not get here");
                return(string.Empty);
            }
        }
示例#23
0
        // May be called for the following tokens: Name, String, Eof, Comma, LParens, RParens, LBracket, RBracket, RBrace
        private static string LexKindToString(LexKind t)
        {
            Debug.Assert(LexKind.FirstStringable <= t);

            if (LexKind.LastNonChar < t)
            {
                Debug.Assert("()[].@,*/$}".Contains((char)t));
                return(char.ToString((char)t));
            }

            switch (t)
            {
            case LexKind.Name: return("<name>");

            case LexKind.String: return("<string literal>");

            case LexKind.Eof: return("<eof>");

            default:
                Debug.Fail($"Unexpected LexKind: {t}");
                return(string.Empty);
            }
        }
示例#24
0
        private bool CheckOperator(bool star)
        {
            LexKind opKind;

            if (star) {
                opKind = LexKind.Multiply;
            } else {
                if (prefix.Length != 0 || name.Length > 3)
                    return false;

                switch (name) {
                case "or" : opKind = LexKind.Or;      break;
                case "and": opKind = LexKind.And;     break;
                case "div": opKind = LexKind.Divide;  break;
                case "mod": opKind = LexKind.Modulo;  break;
                default   : return false;
                }
            }

            // If there is a preceding token and the preceding token is not one of '@', '::', '(', '[', ',' or an Operator,
            // then a '*' must be recognized as a MultiplyOperator and an NCName must be recognized as an OperatorName.
            if (prevKind <= LexKind.LastOperator)
                return false;

            switch (prevKind) {
            case LexKind.Slash:
            case LexKind.SlashSlash:
            case LexKind.At:
            case LexKind.ColonColon:
            case LexKind.LParens:
            case LexKind.LBracket:
            case LexKind.Comma:
            case LexKind.Dollar:
                return false;
            }

            this.kind = opKind;
            return true;
        }
示例#25
0
 public void PassToken(LexKind t)
 {
     CheckToken(t);
     NextLex();
 }
示例#26
0
 private XPathAxis CheckAxis()
 {
     this.kind = LexKind.Axis;
     switch (name) {
     case "ancestor"           : return XPathAxis.Ancestor;
     case "ancestor-or-self"   : return XPathAxis.AncestorOrSelf;
     case "attribute"          : return XPathAxis.Attribute;
     case "child"              : return XPathAxis.Child;
     case "descendant"         : return XPathAxis.Descendant;
     case "descendant-or-self" : return XPathAxis.DescendantOrSelf;
     case "following"          : return XPathAxis.Following;
     case "following-sibling"  : return XPathAxis.FollowingSibling;
     case "namespace"          : return XPathAxis.Namespace;
     case "parent"             : return XPathAxis.Parent;
     case "preceding"          : return XPathAxis.Preceding;
     case "preceding-sibling"  : return XPathAxis.PrecedingSibling;
     case "self"               : return XPathAxis.Self;
     default                   :
         this.kind = LexKind.Name;
         return XPathAxis.Unknown;
     }
 }
示例#27
0
 public void CheckToken(LexKind t)
 {
     Debug.Assert(LexKind.FirstStringable <= t);
     if (kind != t) {
         if (t == LexKind.Eof) {
             throw EofExpectedException(RawValue);
         } else {
             throw TokenExpectedException(LexKindToString(t), RawValue);
         }
     }
 }
示例#28
0
        public void NextLex()
        {
            prevLexEnd = curIndex;
            prevKind = kind;
            SkipSpace();
            lexStart = curIndex;

            switch (curChar) {
            case '\0':
                kind = LexKind.Eof;
                return;
            case '(': case ')': case '[': case ']':
            case '@': case ',': case '$': case '}':
                kind = (LexKind)curChar;
                NextChar();
                break;
            case '.':
                NextChar();
                if (curChar == '.') {
                    kind = LexKind.DotDot;
                    NextChar();
                } else if (IsAsciiDigit(curChar)) {
                    SetSourceIndex(lexStart);
                    goto case '0';
                } else {
                    kind = LexKind.Dot;
                }
                break;
            case ':':
                NextChar();
                if (curChar == ':') {
                    kind = LexKind.ColonColon;
                    NextChar();
                } else {
                    kind = LexKind.Unknown;
                }
                break;
            case '*':
                kind = LexKind.Star;
                NextChar();
                CheckOperator(true);
                break;
            case '/':
                NextChar();
                if (curChar == '/') {
                    kind = LexKind.SlashSlash;
                    NextChar();
                } else {
                    kind = LexKind.Slash;
                }
                break;
            case '|':
                kind = LexKind.Union;
                NextChar();
                break;
            case '+':
                kind = LexKind.Plus;
                NextChar();
                break;
            case '-':
                kind = LexKind.Minus;
                NextChar();
                break;
            case '=':
                kind = LexKind.Eq;
                NextChar();
                break;
            case '!':
                NextChar();
                if (curChar == '=') {
                    kind = LexKind.Ne;
                    NextChar();
                } else {
                    kind = LexKind.Unknown;
                }
                break;
            case '<':
                NextChar();
                if (curChar == '=') {
                    kind = LexKind.Le;
                    NextChar();
                } else {
                    kind = LexKind.Lt;
                }
                break;
            case '>':
                NextChar();
                if (curChar == '=') {
                    kind = LexKind.Ge;
                    NextChar();
                } else {
                    kind = LexKind.Gt;
                }
                break;
            case '"':
            case '\'':
                kind = LexKind.String;
                ScanString();
                break;
            case '0': case '1': case '2': case '3':
            case '4': case '5': case '6': case '7':
            case '8': case '9':
                kind = LexKind.Number;
                ScanNumber();
                break;
            default:
                this.name = ScanNCName();
                if (this.name != null) {
                    kind = LexKind.Name;
                    this.prefix = string.Empty;
                    this.canBeFunction = false;
                    this.axis = XPathAxis.Unknown;
                    bool colonColon = false;
                    int saveSourceIndex = curIndex;

                    // "foo:bar" or "foo:*" -- one lexeme (no spaces allowed)
                    // "foo::" or "foo ::"  -- two lexemes, reported as one (AxisName)
                    // "foo:?" or "foo :?"  -- lexeme "foo" reported
                    if (curChar == ':') {
                        NextChar();
                        if (curChar == ':') {   // "foo::" -> OperatorName, AxisName
                            NextChar();
                            colonColon = true;
                            SetSourceIndex(saveSourceIndex);
                        } else {                // "foo:bar", "foo:*" or "foo:?"
                            if (curChar == '*')
                            {
                                NextChar();
                                this.prefix = this.name;
                                this.name = "*";
                            }
                            else
                            {
                                string ncName = ScanNCName();
                                if (ncName != null)
                                {
                                    this.prefix = this.name;
                                    this.name = ncName;
                                    // Look ahead for '(' to determine whether QName can be a FunctionName
                                    saveSourceIndex = curIndex;
                                    SkipSpace();
                                    this.canBeFunction = (curChar == '(');
                                    SetSourceIndex(saveSourceIndex);
                                }
                                else
                                {
                                    // "foo:?" -> OperatorName, NameTest
                                    // Return "foo" and leave ":" to be reported later as an unknown lexeme
                                    SetSourceIndex(saveSourceIndex);
                                }
                            }
                        }
                    } else {
                        SkipSpace();
                        if (curChar == ':') {   // "foo ::" or "foo :?"
                            NextChar();
                            if (curChar == ':') {
                                NextChar();
                                colonColon = true;
                            }
                            SetSourceIndex(saveSourceIndex);
                        } else {
                            this.canBeFunction = (curChar == '(');
                        }
                    }
                    if (!CheckOperator(false) && colonColon) {
                        this.axis = CheckAxis();
                    }
                } else {
                    kind = LexKind.Unknown;
                    NextChar();
                }
                break;
            }
        }
        public bool NextLex()
        {
            this.SkipSpace();
            switch (this.CurerntChar)
            {
                case '[':
                case ']':
                case '|':
                case '#':
                case '$':
                case '(':
                case ')':
                case '*':
                case '+':
                case ',':
                case '-':
                case '=':
                case '@':
                    this.kind = (LexKind) Convert.ToInt32(this.CurerntChar, CultureInfo.InvariantCulture);
                    this.NextChar();
                    break;

                case '!':
                    this.kind = LexKind.Bang;
                    this.NextChar();
                    if (this.CurerntChar == '=')
                    {
                        this.kind = LexKind.Ne;
                        this.NextChar();
                    }
                    break;

                case '"':
                case '\'':
                    this.kind = LexKind.String;
                    this.stringValue = this.ScanString();
                    break;

                case '.':
                    this.kind = LexKind.Dot;
                    this.NextChar();
                    if (this.CurerntChar != '.')
                    {
                        if (XmlCharType.IsDigit(this.CurerntChar))
                        {
                            this.kind = LexKind.Number;
                            this.numberValue = this.ScanFraction();
                        }
                    }
                    else
                    {
                        this.kind = LexKind.DotDot;
                        this.NextChar();
                    }
                    break;

                case '/':
                    this.kind = LexKind.Slash;
                    this.NextChar();
                    if (this.CurerntChar == '/')
                    {
                        this.kind = LexKind.SlashSlash;
                        this.NextChar();
                    }
                    break;

                case '<':
                    this.kind = LexKind.Lt;
                    this.NextChar();
                    if (this.CurerntChar == '=')
                    {
                        this.kind = LexKind.Le;
                        this.NextChar();
                    }
                    break;

                case '>':
                    this.kind = LexKind.Gt;
                    this.NextChar();
                    if (this.CurerntChar == '=')
                    {
                        this.kind = LexKind.Ge;
                        this.NextChar();
                    }
                    break;

                case '\0':
                    this.kind = LexKind.Eof;
                    return false;

                default:
                    if (XmlCharType.IsDigit(this.CurerntChar))
                    {
                        this.kind = LexKind.Number;
                        this.numberValue = this.ScanNumber();
                    }
                    else
                    {
                        if (!this.xmlCharType.IsStartNCNameSingleChar(this.CurerntChar))
                        {
                            throw XPathException.Create("Xp_InvalidToken", this.SourceText);
                        }
                        this.kind = LexKind.Name;
                        this.name = this.ScanName();
                        this.prefix = string.Empty;
                        if (this.CurerntChar == ':')
                        {
                            this.NextChar();
                            if (this.CurerntChar != ':')
                            {
                                this.prefix = this.name;
                                if (this.CurerntChar != '*')
                                {
                                    if (!this.xmlCharType.IsStartNCNameSingleChar(this.CurerntChar))
                                    {
                                        throw XPathException.Create("Xp_InvalidName", this.SourceText);
                                    }
                                    this.name = this.ScanName();
                                }
                                else
                                {
                                    this.NextChar();
                                    this.name = "*";
                                }
                            }
                            else
                            {
                                this.NextChar();
                                this.kind = LexKind.Axe;
                            }
                        }
                        else
                        {
                            this.SkipSpace();
                            if (this.CurerntChar == ':')
                            {
                                this.NextChar();
                                if (this.CurerntChar != ':')
                                {
                                    throw XPathException.Create("Xp_InvalidName", this.SourceText);
                                }
                                this.NextChar();
                                this.kind = LexKind.Axe;
                            }
                        }
                        this.SkipSpace();
                        this.canBeFunction = this.CurerntChar == '(';
                    }
                    break;
            }
            return true;
        }
示例#30
0
        public bool NextLex()
        {
            SkipSpace();
            switch (this.CurerntChar)
            {
            case '\0':
                kind = LexKind.Eof;
                return(false);

            case ',':
            case '@':
            case '(':
            case ')':
            case '|':
            case '*':
            case '[':
            case ']':
            case '+':
            case '-':
            case '=':
            case '#':
            case '$':
                kind = (LexKind)Convert.ToInt32(this.CurerntChar);
                NextChar();
                break;

            case '<':
                kind = LexKind.Lt;
                NextChar();
                if (this.CurerntChar == '=')
                {
                    kind = LexKind.Le;
                    NextChar();
                }
                break;

            case '>':
                kind = LexKind.Gt;
                NextChar();
                if (this.CurerntChar == '=')
                {
                    kind = LexKind.Ge;
                    NextChar();
                }
                break;

            case '!':
                kind = LexKind.Bang;
                NextChar();
                if (this.CurerntChar == '=')
                {
                    kind = LexKind.Ne;
                    NextChar();
                }
                break;

            case '.':
                kind = LexKind.Dot;
                NextChar();
                if (this.CurerntChar == '.')
                {
                    kind = LexKind.DotDot;
                    NextChar();
                }
                else if (XmlCharType.IsDigit(this.CurerntChar))
                {
                    kind        = LexKind.Number;
                    numberValue = ScanFraction();
                }
                break;

            case '/':
                kind = LexKind.Slash;
                NextChar();
                if (this.CurerntChar == '/')
                {
                    kind = LexKind.SlashSlash;
                    NextChar();
                }
                break;

            case '"':
            case '\'':
                this.kind        = LexKind.String;
                this.stringValue = ScanString();
                break;

            default:
                if (XmlCharType.IsDigit(this.CurerntChar))
                {
                    kind        = LexKind.Number;
                    numberValue = ScanNumber();
                }
                else if (XmlCharType.IsStartNCNameChar(this.CurerntChar))
                {
                    kind        = LexKind.Name;
                    this.name   = ScanName();
                    this.prefix = string.Empty;
                    // "foo:bar" is one lexem not three because it doesn't allow spaces in between
                    // We should distinct it from "foo::" and need process "foo ::" as well
                    if (this.CurerntChar == ':')
                    {
                        NextChar();
                        // can be "foo:bar" or "foo::"
                        if (this.CurerntChar == ':')     // "foo::"
                        {
                            NextChar();
                            kind = LexKind.Axe;
                        }
                        else                            // "foo:*", "foo:bar" or "foo: "
                        {
                            this.prefix = this.name;
                            if (this.CurerntChar == '*')
                            {
                                NextChar();
                                this.name = "*";
                            }
                            else if (XmlCharType.IsStartNCNameChar(this.CurerntChar))
                            {
                                this.name = ScanName();
                            }
                            else
                            {
                                throw new XPathException(Res.Xp_InvalidName, SourceText);
                            }
                        }
                    }
                    else
                    {
                        SkipSpace();
                        if (this.CurerntChar == ':')
                        {
                            NextChar();
                            // it can be "foo ::" or just "foo :"
                            if (this.CurerntChar == ':')
                            {
                                NextChar();
                                kind = LexKind.Axe;
                            }
                            else
                            {
                                throw new XPathException(Res.Xp_InvalidName, SourceText);
                            }
                        }
                    }
                    SkipSpace();
                    this.canBeFunction = (this.CurerntChar == '(');
                }
                else
                {
                    throw new XPathException(Res.Xp_InvalidToken, SourceText);
                }
                break;
            }
            return(true);
        }
示例#31
0
		public bool NextLexeme()
		{
			switch (_currChar)
			{
				case '\0':
					_kind = LexKind.Eof;
					return false;
				case '(':
				case ')':
				case '=':
				case '/':
					_kind = (LexKind)Convert.ToInt32(_currChar);
					NextChar();
					break;
				case '^':
					NextChar();
					if (_currChar == '^' || _currChar == '(' || _currChar == ')')
					{
						_kind = LexKind.EscapedData;
						NextChar();
					}
					else
						throw new XPointerSyntaxException(Properties.Resources.CircumflexCharMustBeEscaped);
					break;
				default:
					if (Char.IsDigit(_currChar))
					{
						_kind = LexKind.Number;
						int start = _ptrIndex - 1;
						int len = 0;
						while (Char.IsDigit(_currChar))
						{
							NextChar(); len++;
						}
						_number = XmlConvert.ToInt32(_ptr.Substring(start, len));
						break;
					}
					else if (LexUtils.IsStartNameChar(_currChar))
					{
						_kind = LexKind.NCName;
						_prefix = String.Empty;
						_ncname = ParseName();
						if (_currChar == ':')
						{
							//QName?
							NextChar();
							_prefix = _ncname;
							_kind = LexKind.QName;
							if (LexUtils.IsStartNCNameChar(_currChar))
								_ncname = ParseName();
							else
								throw new XPointerSyntaxException(String.Format(CultureInfo.CurrentCulture, Properties.Resources.InvalidNameToken, _prefix, _currChar));
						}
						_canBeSchemaName = _currChar == '(';
						break;
					}
					else if (LexUtils.IsWhitespace(_currChar))
					{
						_kind = LexKind.Space;
						while (LexUtils.IsWhitespace(_currChar))
							NextChar();
						break;
					}
					else
					{
						_kind = LexKind.EscapedData;
						break;
					}
			}
			return true;
		}
示例#32
0
        public void NextLex()
        {
            prevLexEnd = curIndex;
            prevKind   = kind;
            SkipSpace();
            lexStart = curIndex;

            switch (curChar)
            {
            case '\0':
                kind = LexKind.Eof;
                return;

            case '(':
            case ')':
            case '[':
            case ']':
            case '@':
            case ',':
            case '$':
            case '}':
                kind = (LexKind)curChar;
                NextChar();
                break;

            case '.':
                NextChar();
                if (curChar == '.')
                {
                    kind = LexKind.DotDot;
                    NextChar();
                }
                else if (IsAsciiDigit(curChar))
                {
                    SetSourceIndex(lexStart);
                    goto case '0';
                }
                else
                {
                    kind = LexKind.Dot;
                }
                break;

            case ':':
                NextChar();
                if (curChar == ':')
                {
                    kind = LexKind.ColonColon;
                    NextChar();
                }
                else
                {
                    kind = LexKind.Unknown;
                }
                break;

            case '*':
                kind = LexKind.Star;
                NextChar();
                CheckOperator(true);
                break;

            case '/':
                NextChar();
                if (curChar == '/')
                {
                    kind = LexKind.SlashSlash;
                    NextChar();
                }
                else
                {
                    kind = LexKind.Slash;
                }
                break;

            case '|':
                kind = LexKind.Union;
                NextChar();
                break;

            case '+':
                kind = LexKind.Plus;
                NextChar();
                break;

            case '-':
                kind = LexKind.Minus;
                NextChar();
                break;

            case '=':
                kind = LexKind.Eq;
                NextChar();
                break;

            case '!':
                NextChar();
                if (curChar == '=')
                {
                    kind = LexKind.Ne;
                    NextChar();
                }
                else
                {
                    kind = LexKind.Unknown;
                }
                break;

            case '<':
                NextChar();
                if (curChar == '=')
                {
                    kind = LexKind.Le;
                    NextChar();
                }
                else
                {
                    kind = LexKind.Lt;
                }
                break;

            case '>':
                NextChar();
                if (curChar == '=')
                {
                    kind = LexKind.Ge;
                    NextChar();
                }
                else
                {
                    kind = LexKind.Gt;
                }
                break;

            case '"':
            case '\'':
                kind = LexKind.String;
                ScanString();
                break;

            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                kind = LexKind.Number;
                ScanNumber();
                break;

            default:
                if (xmlCharType.IsStartNCNameSingleChar(curChar)
#if XML10_FIFTH_EDITION
                    || xmlCharType.IsNCNameHighSurrogateChar(curChar)
#endif
                    )
                {
                    kind               = LexKind.Name;
                    this.name          = ScanNCName();
                    this.prefix        = string.Empty;
                    this.canBeFunction = false;
                    this.axis          = XPathAxis.Unknown;
                    bool colonColon      = false;
                    int  saveSourceIndex = curIndex;

                    // "foo:bar" or "foo:*" -- one lexeme (no spaces allowed)
                    // "foo::" or "foo ::"  -- two lexemes, reported as one (AxisName)
                    // "foo:?" or "foo :?"  -- lexeme "foo" reported
                    if (curChar == ':')
                    {
                        NextChar();
                        if (curChar == ':')         // "foo::" -> OperatorName, AxisName
                        {
                            NextChar();
                            colonColon = true;
                            SetSourceIndex(saveSourceIndex);
                        }
                        else                        // "foo:bar", "foo:*" or "foo:?"
                        {
                            if (curChar == '*')
                            {
                                NextChar();
                                this.prefix = this.name;
                                this.name   = "*";
                            }
                            else if (xmlCharType.IsStartNCNameSingleChar(curChar)
#if XML10_FIFTH_EDITION
                                     || xmlCharType.IsNCNameHighSurrogateChar(curChar)
#endif
                                     )
                            {
                                this.prefix = this.name;
                                this.name   = ScanNCName();
                                // Look ahead for '(' to determine whether QName can be a FunctionName
                                saveSourceIndex = curIndex;
                                SkipSpace();
                                this.canBeFunction = (curChar == '(');
                                SetSourceIndex(saveSourceIndex);
                            }
                            else                    // "foo:?" -> OperatorName, NameTest
                            // Return "foo" and leave ":" to be reported later as an unknown lexeme
                            {
                                SetSourceIndex(saveSourceIndex);
                            }
                        }
                    }
                    else
                    {
                        SkipSpace();
                        if (curChar == ':')         // "foo ::" or "foo :?"
                        {
                            NextChar();
                            if (curChar == ':')
                            {
                                NextChar();
                                colonColon = true;
                            }
                            SetSourceIndex(saveSourceIndex);
                        }
                        else
                        {
                            this.canBeFunction = (curChar == '(');
                        }
                    }
                    if (!CheckOperator(false) && colonColon)
                    {
                        this.axis = CheckAxis();
                    }
                }
                else
                {
                    kind = LexKind.Unknown;
                    NextChar();
                }
                break;
            }
        }
示例#33
0
 public LexToken(string str, LexKind kind, List <LexToken> list, int index)
 {
     Str  = str;
     Kind = kind;
 }
示例#34
0
        public LexTokenList Analyze()
        {
            LexTokenList  LexTokens = new LexTokenList();
            StringBuilder sb        = new StringBuilder();
            int           Line      = 1;

            for (int i = 0; i < Input.Length; i++)
            {
                LexKind kind  = LexKind.Terminal;
                string  value = "";
                switch (Input[i])
                {
                case '(': kind = LexKind.ParentheseOpen; break;

                case ')': kind = LexKind.ParentheseClose; break;

                case '[': kind = LexKind.BracketOpen; break;

                case ']': kind = LexKind.BracketClose; break;

                case '{': kind = LexKind.BraceOpen; break;

                case '}': kind = LexKind.BraceClose; break;

                case '<': kind = LexKind.ChevronOpen; break;

                case '>': kind = LexKind.ChevronClose; break;


                case ':': kind = LexKind.Colon; break;

                case ';': kind = LexKind.Semicolon; break;

                case ',': kind = LexKind.Comma; break;

                case '"':
                {
                    i++;
                    while (Input[i] != '"')
                    {
                        if (Input[i] == '\\' && Input[i + 1] == '"')
                        {
                            i++;
                        }
                        sb.Append(Input[i]);
                        i++;
                    }
                    value = sb.ToString();
                    kind  = LexKind.String;
                    sb.Clear();

                    break;
                }

                case '=': kind = LexKind.Equals; break;

                case ' ':     // Discard
                case '\r':
                case '\t':
                    break;

                case '\n':
                    Line++;
                    break;

                case '?':
                {
                    kind = LexKind.Question;
                    break;
                }

                case '!':
                {
                    kind = LexKind.Exclamation;
                    break;
                }

                case '+':
                {
                    kind = LexKind.Add;
                    break;
                }

                case '-':
                {
                    kind = LexKind.Sub;
                    break;
                }

                case '*':
                {
                    kind = LexKind.Mul;
                    break;
                }

                case '/':
                {
                    if (Input.Length > i + 1 && Input[i + 1] == '/')
                    {
                        i += 2;
                        for (; Input[i] != '\n' && i < Input.Length; i++)
                        {
                            sb.Append(Input[i]);
                        }
                        value = sb.ToString();
                        kind  = LexKind.Comment;
                        sb.Clear();
                        Line++;
                    }
                    else
                    {
                        kind = LexKind.Div;
                    }
                    break;
                }

                default:
                {
                    if (Char.IsLetterOrDigit(Input[i]) ||
                        Input[i] == '.')
                    {
                        while (Input.Length > i && (Char.IsLetterOrDigit(Input[i]) || Input[i] == '.'))
                        {
                            sb.Append(Input[i++]);
                        }
                        i--;
                    }
                    value = sb.ToString();
                    kind  = Identify(value);

                    sb.Clear();
                    break;
                }
                }


                if (kind != LexKind.Terminal)
                {
                    LexTokens.Add(new LexToken()
                    {
                        Kind  = kind,
                        Value = value,
                        Line  = Line
                    });
                }
            }

            LexTokens.Add(new LexToken()
            {
                Kind = LexKind.Terminal
            });

            LexTokens.Add(new LexToken()
            {
                Kind = LexKind.EOF
            });

            return(LexTokens);
        }
示例#35
0
 public LexToken(string str, LexKind kind, LexList list) : this(str, kind, list.CopyList(), list.Index)
 {
 }
 public bool NextLex() {
     prevLexEnd = curIndex;
     SkipSpace();
     lexStart = curIndex;
     switch (curChar) {
     case '\0':
         kind = LexKind.Eof;
         return false;
     case ',': case '@': case '(': case ')':
     case '|': case '*': case '[': case ']':
     case '+': case '-': case '=': case '#':
     case '$': case '{': case '}':
         kind = (LexKind)curChar;
         NextChar();
         break;
     case '<':
         kind = LexKind.Lt;
         NextChar();
         if (curChar == '=') {
             kind = LexKind.Le;
             NextChar();
         }
         break;
     case '>':
         kind = LexKind.Gt;
         NextChar();
         if (curChar == '=') {
             kind = LexKind.Ge;
             NextChar();
         }
         break;
     case '!':
         kind = LexKind.Bang;
         NextChar();
         if (curChar == '=') {
             kind = LexKind.Ne;
             NextChar();
         }
         break;
     case '.':
         kind = LexKind.Dot;
         NextChar();
         if (curChar == '.') {
             kind = LexKind.DotDot;
             NextChar();
         } else if (xmlCharType.IsDigit(curChar)) {
             ScanFraction();
         }
         break;
     case '/':
         kind = LexKind.Slash;
         NextChar();
         if (curChar == '/') {
             kind = LexKind.SlashSlash;
             NextChar();
         }
         break;
     case '"':
     case '\'':
         ScanString();
         break;
     default:
         if (xmlCharType.IsDigit(curChar)) {
             ScanNumber();
         } else if (xmlCharType.IsStartNCNameChar(curChar)) {
             kind = LexKind.Name;
             this.name   = ScanNCName();
             this.prefix = string.Empty;
             int saveSourceIndex = curIndex;
             // "foo:bar" is one lexem not three because it doesn't allow spaces in between
             // We should distinct it from "foo::" and need process "foo ::" as well
             if (curChar == ':') {
                 NextChar();
                 // can be "foo:bar" or "foo::"
                 if (curChar == ':') {   // "foo::"
                     NextChar();
                     kind = LexKind.Axis;
                 } else {                // "foo:*", "foo:bar" or "foo: "
                     if (curChar == '*') {
                         NextChar();
                         this.prefix = this.name;
                         this.name = "*";
                     } else if (xmlCharType.IsStartNCNameChar(curChar)) {
                         this.prefix = this.name;
                         this.name = ScanNCName();
                     } else {
                         // this lex is something like "foo:?". Let's it be recognized as name "foo"
                         // and leave ":-" to be scaned late as unknown lex.
                         SetSourceIndex(saveSourceIndex);
                     }
                 }
             } else {
                 SkipSpace();
                 if (curChar == ':') {
                     NextChar();
                     // it can be "foo ::" or just "foo :"
                     if (curChar == ':') {
                         NextChar();
                         kind = LexKind.Axis;
                     } else {
                         // this lex is something like "foo :?". Let's it be recognized as name "foo"
                         // and leave ":-" to be scaned late as unknown lex.
                         SetSourceIndex(saveSourceIndex);
                     }
                 }
             }
             // look ahead for '('. I don't want curIndex to be moved by SkipSpace() here to be able to detect presize lexem size.
             saveSourceIndex = curIndex;
             SkipSpace();
             this.canBeFunction = (curChar == '(');
             SetSourceIndex(saveSourceIndex);
         } else {
             kind = LexKind.Unknown;
             NextChar();
         }
         break;
     }
     return true;
 }
 private void ScanNumber() {
     Debug.Assert(xmlCharType.IsDigit(curChar));
     int start = curIndex;
     while (xmlCharType.IsDigit(curChar)) {
         NextChar();
     }
     if (curChar == '.') {
         NextChar();
         while (xmlCharType.IsDigit(curChar)) {
             NextChar();
         }
     }
     if ((curChar & (~0x20)) == 'E') {
         NextChar();
         if (curChar == '+' || curChar == '-') {
             NextChar();
         }
         while (xmlCharType.IsDigit(curChar)) {
             NextChar();
         }
         throw CreateException(Res.XPath_ScientificNotation);
     }
     this.kind        = LexKind.Number;
     this.numberValue = XPathConvert.StringToDouble(xpathExpr.Substring(start, curIndex - start));
 }
示例#38
0
        // May be called for the following tokens: Name, String, Eof, Comma, LParens, RParens, LBracket, RBracket, RBrace
        private string LexKindToString(LexKind t)
        {
            Debug.Assert(LexKind.FirstStringable <= t);

            if (LexKind.LastNonChar < t) {
                Debug.Assert("()[].@,*/$}".IndexOf((char)t) >= 0);
                return new string((char)t, 1);
            }

            switch (t) {
            case LexKind.Name   : return "<name>";
            case LexKind.String : return "<string literal>";
            case LexKind.Eof    : return "<eof>";
            default:
                Debug.Fail("Unexpected LexKind: " + t.ToString());
                return string.Empty;
            }
        }
示例#39
0
 public void PassToken(LexKind t)
 {
     CheckToken(t);
     NextLex();
 }
示例#40
0
 public void CheckToken(LexKind t)
 {
     Debug.Assert(LexKind.FirstStringable <= t);
     if (_kind != t)
     {
         if (t == LexKind.Eof)
         {
             throw CreateException(SR.XPath_EofExpected, RawValue);
         }
         else
         {
             throw CreateException(SR.XPath_TokenExpected, LexKindToString(t), RawValue);
         }
     }
 }
 private void ScanFraction() {
     Debug.Assert(xmlCharType.IsDigit(curChar));
     int start = curIndex - 1;
     Debug.Assert(0 <= start && xpathExpr[start] == '.');
     while (xmlCharType.IsDigit(curChar)) {
         NextChar();
     }
     this.kind        = LexKind.Number;
     this.numberValue = XPathConvert.StringToDouble(xpathExpr.Substring(start, curIndex - start));
 }
示例#42
0
        public void NextLex()
        {
            _prevLexEnd = _curIndex;
            _prevKind = _kind;
            SkipSpace();
            _lexStart = _curIndex;

            switch (_curChar)
            {
                case '\0':
                    _kind = LexKind.Eof;
                    return;
                case '(':
                case ')':
                case '[':
                case ']':
                case '@':
                case ',':
                case '$':
                case '}':
                    _kind = (LexKind)_curChar;
                    NextChar();
                    break;
                case '.':
                    NextChar();
                    if (_curChar == '.')
                    {
                        _kind = LexKind.DotDot;
                        NextChar();
                    }
                    else if (IsAsciiDigit(_curChar))
                    {
                        SetSourceIndex(_lexStart);
                        goto case '0';
                    }
                    else
                    {
                        _kind = LexKind.Dot;
                    }
                    break;
                case ':':
                    NextChar();
                    if (_curChar == ':')
                    {
                        _kind = LexKind.ColonColon;
                        NextChar();
                    }
                    else
                    {
                        _kind = LexKind.Unknown;
                    }
                    break;
                case '*':
                    _kind = LexKind.Star;
                    NextChar();
                    CheckOperator(true);
                    break;
                case '/':
                    NextChar();
                    if (_curChar == '/')
                    {
                        _kind = LexKind.SlashSlash;
                        NextChar();
                    }
                    else
                    {
                        _kind = LexKind.Slash;
                    }
                    break;
                case '|':
                    _kind = LexKind.Union;
                    NextChar();
                    break;
                case '+':
                    _kind = LexKind.Plus;
                    NextChar();
                    break;
                case '-':
                    _kind = LexKind.Minus;
                    NextChar();
                    break;
                case '=':
                    _kind = LexKind.Eq;
                    NextChar();
                    break;
                case '!':
                    NextChar();
                    if (_curChar == '=')
                    {
                        _kind = LexKind.Ne;
                        NextChar();
                    }
                    else
                    {
                        _kind = LexKind.Unknown;
                    }
                    break;
                case '<':
                    NextChar();
                    if (_curChar == '=')
                    {
                        _kind = LexKind.Le;
                        NextChar();
                    }
                    else
                    {
                        _kind = LexKind.Lt;
                    }
                    break;
                case '>':
                    NextChar();
                    if (_curChar == '=')
                    {
                        _kind = LexKind.Ge;
                        NextChar();
                    }
                    else
                    {
                        _kind = LexKind.Gt;
                    }
                    break;
                case '"':
                case '\'':
                    _kind = LexKind.String;
                    ScanString();
                    break;
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    _kind = LexKind.Number;
                    ScanNumber();
                    break;
                default:
                    if (_xmlCharType.IsStartNCNameSingleChar(_curChar)
#if XML10_FIFTH_EDITION
                        || xmlCharType.IsNCNameHighSurrogateChar(curChar)
#endif
                        )
                    {
                        _kind = LexKind.Name;
                        _name = ScanNCName();
                        _prefix = string.Empty;
                        _canBeFunction = false;
                        _axis = XPathAxis.Unknown;
                        bool colonColon = false;
                        int saveSourceIndex = _curIndex;

                        // "foo:bar" or "foo:*" -- one lexeme (no spaces allowed)
                        // "foo::" or "foo ::"  -- two lexemes, reported as one (AxisName)
                        // "foo:?" or "foo :?"  -- lexeme "foo" reported
                        if (_curChar == ':')
                        {
                            NextChar();
                            if (_curChar == ':')
                            {   // "foo::" -> OperatorName, AxisName
                                NextChar();
                                colonColon = true;
                                SetSourceIndex(saveSourceIndex);
                            }
                            else
                            {                // "foo:bar", "foo:*" or "foo:?"
                                if (_curChar == '*')
                                {
                                    NextChar();
                                    _prefix = _name;
                                    _name = "*";
                                }
                                else if (_xmlCharType.IsStartNCNameSingleChar(_curChar)
#if XML10_FIFTH_EDITION
                                    || xmlCharType.IsNCNameHighSurrogateChar(curChar)
#endif
                                    )
                                {
                                    _prefix = _name;
                                    _name = ScanNCName();
                                    // Look ahead for '(' to determine whether QName can be a FunctionName
                                    saveSourceIndex = _curIndex;
                                    SkipSpace();
                                    _canBeFunction = (_curChar == '(');
                                    SetSourceIndex(saveSourceIndex);
                                }
                                else
                                {            // "foo:?" -> OperatorName, NameTest
                                    // Return "foo" and leave ":" to be reported later as an unknown lexeme
                                    SetSourceIndex(saveSourceIndex);
                                }
                            }
                        }
                        else
                        {
                            SkipSpace();
                            if (_curChar == ':')
                            {   // "foo ::" or "foo :?"
                                NextChar();
                                if (_curChar == ':')
                                {
                                    NextChar();
                                    colonColon = true;
                                }
                                SetSourceIndex(saveSourceIndex);
                            }
                            else
                            {
                                _canBeFunction = (_curChar == '(');
                            }
                        }
                        if (!CheckOperator(false) && colonColon)
                        {
                            _axis = CheckAxis();
                        }
                    }
                    else
                    {
                        _kind = LexKind.Unknown;
                        NextChar();
                    }
                    break;
            }
        }
示例#43
0
        public bool NextLexeme()
        {
            switch (_currChar)
            {
            case '\0':
                _kind = LexKind.Eof;
                return(false);

            case '(':
            case ')':
            case '=':
            case '/':
                _kind = (LexKind)Convert.ToInt32(_currChar);
                NextChar();
                break;

            case '^':
                NextChar();
                if (_currChar == '^' || _currChar == '(' || _currChar == ')')
                {
                    _kind = LexKind.EscapedData;
                    NextChar();
                }
                else
                {
                    throw new XPointerSyntaxException(Resources.CircumflexCharMustBeEscaped);
                }
                break;

            default:
                if (Char.IsDigit(_currChar))
                {
                    _kind = LexKind.Number;
                    var start = _ptrIndex - 1;
                    var len   = 0;
                    while (Char.IsDigit(_currChar))
                    {
                        NextChar();
                        len++;
                    }
                    Number = XmlConvert.ToInt32(_ptr.Substring(start, len));
                    break;
                }
                if (LexUtils.IsStartNameChar(_currChar))
                {
                    _kind  = LexKind.NcName;
                    Prefix = String.Empty;
                    NcName = ParseName();
                    if (_currChar == ':')
                    {
                        //QName?
                        NextChar();
                        Prefix = NcName;
                        _kind  = LexKind.QName;
                        if (LexUtils.IsStartNcNameChar(_currChar))
                        {
                            NcName = ParseName();
                        }
                        else
                        {
                            throw new XPointerSyntaxException(String.Format(CultureInfo.CurrentCulture, Resources.InvalidNameToken, Prefix, _currChar));
                        }
                    }
                    CanBeSchemaName = _currChar == '(';
                    break;
                }
                if (LexUtils.IsWhitespace(_currChar))
                {
                    _kind = LexKind.Space;
                    while (LexUtils.IsWhitespace(_currChar))
                    {
                        NextChar();
                    }
                    break;
                }
                _kind = LexKind.EscapedData;
                break;
            }
            return(true);
        }
 public void CheckToken(LexKind t) {
     if (kind != t) {
         if (t == LexKind.Eof) {
             throw CreateException(Res.XPath_EofExpected, RawValue);
         } else {
             throw CreateException(Res.XPath_TokenExpected, LexKindToString(t), RawValue);
         }
     }
 }
        private void ScanString() {
            char endChar = curChar;
            int  start   = curIndex + 1;

            do {
                if (!NextChar()) {
                    throw CreateException(Res.XPath_UnclosedString);
                }
            } while (curChar != endChar);

            this.kind        = LexKind.String;
            this.stringValue = xpathExpr.Substring(start, curIndex - start);
            NextChar();
        }
示例#46
0
        public bool NextLex() {
            SkipSpace();
            switch (this.CurerntChar) {
            case '\0'  : 
                kind = LexKind.Eof;
                return false;
            case ',': case '@': case '(': case ')': 
            case '|': case '*': case '[': case ']': 
            case '+': case '-': case '=': case '#': 
            case '$':
                kind =  (LexKind) Convert.ToInt32(this.CurerntChar, CultureInfo.InvariantCulture);
                NextChar();
                break;
            case '<': 
                kind = LexKind.Lt;
                NextChar();
                if (this.CurerntChar == '=') {
                    kind = LexKind.Le;
                    NextChar();
                }
                break;
            case '>': 
                kind = LexKind.Gt;
                NextChar();
                if (this.CurerntChar == '=') {
                    kind = LexKind.Ge;
                    NextChar();
                }
                break;
            case '!': 
                kind = LexKind.Bang;
                NextChar();
                if (this.CurerntChar == '=') {
                    kind = LexKind.Ne;
                    NextChar();
                }
                break;
            case '.': 
                kind = LexKind.Dot;
                NextChar();
                if (this.CurerntChar == '.') {
                    kind = LexKind.DotDot;
                    NextChar();
                }
                else if (XmlCharType.IsDigit(this.CurerntChar)) {
                    kind = LexKind.Number;
                    numberValue = ScanFraction();
                }
                break;
            case '/':
                kind = LexKind.Slash;
                NextChar();
                if (this.CurerntChar == '/') {
                    kind = LexKind.SlashSlash;
                    NextChar();
                }
                break;
            case '"': 
            case '\'': 
                this.kind = LexKind.String;
                this.stringValue = ScanString();
                break;
            default:
                if (XmlCharType.IsDigit(this.CurerntChar)) {
                    kind = LexKind.Number;
                    numberValue = ScanNumber();
                }
                else if (xmlCharType.IsStartNCNameSingleChar(this.CurerntChar) 
#if XML10_FIFTH_EDITION
                    || xmlCharType.IsNCNameHighSurrogateChar(this.CurerntChar) 
#endif
                    ) {
                    kind = LexKind.Name;
                    this.name   = ScanName();
                    this.prefix = string.Empty;
                    // "foo:bar" is one lexem not three because it doesn't allow spaces in between
                    // We should distinct it from "foo::" and need process "foo ::" as well
                    if (this.CurerntChar == ':') {
                        NextChar();
                        // can be "foo:bar" or "foo::"
                        if (this.CurerntChar == ':') {   // "foo::"
                            NextChar();
                            kind = LexKind.Axe;
                        }
                        else {                          // "foo:*", "foo:bar" or "foo: "
                            this.prefix = this.name;
                            if (this.CurerntChar == '*') {
	                            NextChar();
                                this.name = "*";
                            }
                            else if (xmlCharType.IsStartNCNameSingleChar(this.CurerntChar) 
#if XML10_FIFTH_EDITION
                                || xmlCharType.IsNCNameHighSurrogateChar(this.CurerntChar)
#endif
                                ) {
                                this.name = ScanName(); 
                            }
                            else {
                                throw XPathException.Create(Res.Xp_InvalidName, SourceText);
                            }
                        }

                    }
                    else {
                        SkipSpace();
                        if (this.CurerntChar == ':') {
                            NextChar();
                            // it can be "foo ::" or just "foo :"
                            if (this.CurerntChar == ':') {
                                NextChar();
                                kind = LexKind.Axe;
                            }
                            else {
                                throw XPathException.Create(Res.Xp_InvalidName, SourceText);
                            }
                        }
                    }
                    SkipSpace();
                    this.canBeFunction = (this.CurerntChar == '(');
                }
                else {
                    throw XPathException.Create(Res.Xp_InvalidToken, SourceText);
                }
		        break;
            }
            return true;
        }
        public string LexKindToString(LexKind t) {
            const string OneCharLexemes = ",/@.()[]{}*+-=<>!$|";

            if (OneCharLexemes.IndexOf((char)t) >= 0) {
                return ((char)t).ToString();
            }

            switch (t) {
            case LexKind.Ne         : return "!=";
            case LexKind.Le         : return "<=";
            case LexKind.Ge         : return ">=";
            case LexKind.DotDot     : return "..";
            case LexKind.SlashSlash : return "//";
            case LexKind.Name       : return "<name>";
            case LexKind.String     : return "<string literal>";
            case LexKind.Number     : return "<number literal>";
            case LexKind.Axis       : return "<axis>";
            case LexKind.Unknown    : return "<unknown>";
            case LexKind.Eof        : return "<eof>";
            default:
                Debug.Fail("Must not get here");
                return string.Empty;
            }
        }
示例#48
0
        public bool NextLex()
        {
            SkipSpace();
            switch (CurrentChar)
            {
            case '\0':
                _kind = LexKind.Eof;
                return(false);

            case ',':
            case '@':
            case '(':
            case ')':
            case '|':
            case '*':
            case '[':
            case ']':
            case '+':
            case '-':
            case '=':
            case '#':
            case '$':
                _kind = (LexKind)Convert.ToInt32(CurrentChar, CultureInfo.InvariantCulture);
                NextChar();
                break;

            case '<':
                _kind = LexKind.Lt;
                NextChar();
                if (CurrentChar == '=')
                {
                    _kind = LexKind.Le;
                    NextChar();
                }
                break;

            case '>':
                _kind = LexKind.Gt;
                NextChar();
                if (CurrentChar == '=')
                {
                    _kind = LexKind.Ge;
                    NextChar();
                }
                break;

            case '!':
                _kind = LexKind.Bang;
                NextChar();
                if (CurrentChar == '=')
                {
                    _kind = LexKind.Ne;
                    NextChar();
                }
                break;

            case '.':
                _kind = LexKind.Dot;
                NextChar();
                if (CurrentChar == '.')
                {
                    _kind = LexKind.DotDot;
                    NextChar();
                }
                else if (XmlCharType.IsDigit(CurrentChar))
                {
                    _kind        = LexKind.Number;
                    _numberValue = ScanFraction();
                }
                break;

            case '/':
                _kind = LexKind.Slash;
                NextChar();
                if (CurrentChar == '/')
                {
                    _kind = LexKind.SlashSlash;
                    NextChar();
                }
                break;

            case '"':
            case '\'':
                _kind        = LexKind.String;
                _stringValue = ScanString();
                break;

            default:
                if (XmlCharType.IsDigit(CurrentChar))
                {
                    _kind        = LexKind.Number;
                    _numberValue = ScanNumber();
                }
                else if (XmlCharType.IsStartNCNameSingleChar(CurrentChar))
                {
                    _kind   = LexKind.Name;
                    _name   = ScanName();
                    _prefix = string.Empty;
                    // "foo:bar" is one lexeme not three because it doesn't allow spaces in between
                    // We should distinct it from "foo::" and need process "foo ::" as well
                    if (CurrentChar == ':')
                    {
                        NextChar();
                        // can be "foo:bar" or "foo::"
                        if (CurrentChar == ':')
                        {       // "foo::"
                            NextChar();
                            _kind = LexKind.Axe;
                        }
                        else
                        {                              // "foo:*", "foo:bar" or "foo: "
                            _prefix = _name;
                            if (CurrentChar == '*')
                            {
                                NextChar();
                                _name = "*";
                            }
                            else if (XmlCharType.IsStartNCNameSingleChar(CurrentChar))
                            {
                                _name = ScanName();
                            }
                            else
                            {
                                throw XPathException.Create(SR.Xp_InvalidName, SourceText);
                            }
                        }
                    }
                    else
                    {
                        SkipSpace();
                        if (CurrentChar == ':')
                        {
                            NextChar();
                            // it can be "foo ::" or just "foo :"
                            if (CurrentChar == ':')
                            {
                                NextChar();
                                _kind = LexKind.Axe;
                            }
                            else
                            {
                                throw XPathException.Create(SR.Xp_InvalidName, SourceText);
                            }
                        }
                    }
                    SkipSpace();
                    _canBeFunction = (CurrentChar == '(');
                }
                else
                {
                    throw XPathException.Create(SR.Xp_InvalidToken, SourceText);
                }
                break;
            }
            return(true);
        }
示例#49
0
        public bool NextLex() {
            SkipSpace();
            switch (this.CurerntChar) {
            case '\0'  : 
                kind = LexKind.Eof;
                return false;
            case ',': case '@': case '(': case ')': 
            case '|': case '*': case '[': case ']': 
            case '+': case '-': case '=': case '#': 
            case '$':
                kind =  (LexKind) Convert.ToInt32(this.CurerntChar);
                NextChar();
                break;
            case '<': 
                kind = LexKind.Lt;
                NextChar();
                if (this.CurerntChar == '=') {
                    kind = LexKind.Le;
                    NextChar();
                }
                break;
            case '>': 
                kind = LexKind.Gt;
                NextChar();
                if (this.CurerntChar == '=') {
                    kind = LexKind.Ge;
                    NextChar();
                }
                break;
            case '!': 
                kind = LexKind.Bang;
                NextChar();
                if (this.CurerntChar == '=') {
                    kind = LexKind.Ne;
                    NextChar();
                }
                break;
            case '.': 
                kind = LexKind.Dot;
                NextChar();
                if (this.CurerntChar == '.') {
                    kind = LexKind.DotDot;
                    NextChar();
                }
                else if (XmlCharType.IsDigit(this.CurerntChar)) {
                    kind = LexKind.Number;
                    numberValue = ScanFraction();
                }
                break;
            case '/':
                kind = LexKind.Slash;
                NextChar();
                if (this.CurerntChar == '/') {
                    kind = LexKind.SlashSlash;
                    NextChar();
                }
                break;
            case '"': 
            case '\'': 
                this.kind = LexKind.String;
                this.stringValue = ScanString();
                break;
            default:
                if (XmlCharType.IsDigit(this.CurerntChar)) {
                    kind = LexKind.Number;
                    numberValue = ScanNumber();
                }
                else if (XmlCharType.IsStartNCNameChar(this.CurerntChar)) {
                    kind = LexKind.Name;
                    this.name   = ScanName();
                    this.prefix = string.Empty;
                    // "foo:bar" is one lexem not three because it doesn't allow spaces in between
                    // We should distinct it from "foo::" and need process "foo ::" as well
                    if (this.CurerntChar == ':') {
                        NextChar();
                        // can be "foo:bar" or "foo::"
                        if (this.CurerntChar == ':') {   // "foo::"
                            NextChar();
                            kind = LexKind.Axe;
                        }
                        else {                          // "foo:*", "foo:bar" or "foo: "
                            this.prefix = this.name;
                            if (this.CurerntChar == '*') {
	                            NextChar();
                                this.name = "*";
                            }
                            else if (XmlCharType.IsStartNCNameChar(this.CurerntChar)) {
                                this.name = ScanName(); 
                            }
                            else {
                                throw new XPathException(String.Format("'{0}' has an invalid qualified name.", SourceText));
                            }
                        }

                    }
                    else {
                        SkipSpace();
                        if (this.CurerntChar == ':') {
                            NextChar();
                            // it can be "foo ::" or just "foo :"
                            if (this.CurerntChar == ':') {
                                NextChar();
                                kind = LexKind.Axe;
                            }
                            else {
                                throw new XPathException(String.Format("'{0}' has an invalid qualified name.", SourceText));
                            }
                        }
                    }
                    SkipSpace();
                    this.canBeFunction = (this.CurerntChar == '(');
                }
                else {
                    throw new XPathException(String.Format("'{0}' has an invalid token.", SourceText));
                }
		        break;
            }
            return true;
        }