internal void Clear()
 {
     this.number  = double.NaN;
     this.prefix  = string.Empty;
     this.name    = string.Empty;
     this.tokenID = XPathTokenID.Unknown;
 }
 internal void Clear()
 {
     this.number = double.NaN;
     this.prefix = string.Empty;
     this.name = string.Empty;
     this.tokenID = XPathTokenID.Unknown;
 }
        private void TokenizeNumber()
        {
            XPathTokenID id = XPathTokenID.Integer;

            // Read all the digits
            for (; XPathCharTypes.IsDigit(this.ch); AdvanceChar())
            {
                ;
            }
            if (this.ch == '.')
            {
                AdvanceChar();
                if (XPathCharTypes.IsDigit(this.ch))
                {
                    id = XPathTokenID.Decimal;
                    // Read all the digits after the decimal point
                    for (; XPathCharTypes.IsDigit(this.ch); AdvanceChar())
                    {
                        ;
                    }
                }
            }
            PutbackChar();

            // The converted double
            double d = QueryValueModel.Double(CurrentSubstring());

            // flip the sign if we're negative
            token.Set(id, d);
        }
Ejemplo n.º 4
0
        private void TokenizeNumber()
        {
            XPathTokenID integer = XPathTokenID.Integer;

            while (XPathCharTypes.IsDigit(this.ch))
            {
                this.AdvanceChar();
            }
            if (this.ch == '.')
            {
                this.AdvanceChar();
                if (XPathCharTypes.IsDigit(this.ch))
                {
                    integer = XPathTokenID.Decimal;
                    while (XPathCharTypes.IsDigit(this.ch))
                    {
                        this.AdvanceChar();
                    }
                }
            }
            this.PutbackChar();
            double number = QueryValueModel.Double(this.CurrentSubstring());

            this.token.Set(integer, number);
        }
        private XPathExprList ParseAbsolutePath()
        {
            XPathExprList path  = null;
            XPathToken    token = this.NextToken();

            if (token != null)
            {
                XPathTokenID tokenID = token.TokenID;
                if (tokenID == XPathTokenID.Slash)
                {
                    path = new XPathExprList();
                    path.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.Child, NodeQName.Empty, QueryNodeType.Root)));
                }
                else if (tokenID == XPathTokenID.DblSlash)
                {
                    path = new XPathExprList();
                    path.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.Child, NodeQName.Empty, QueryNodeType.Root)));
                    path.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.DescendantOrSelf, NodeQName.Empty, QueryNodeType.All)));
                }
                else
                {
                    this.PushToken(token);
                }
            }
            if (path != null)
            {
                this.ParseRelativePath(path);
            }
            return(path);
        }
        internal void Set(XPathTokenID id, string name)
        {
            Fx.Assert(null != name, "");

            this.Clear();
            this.tokenID = id;
            this.name    = name;
        }
 private XPathToken NextToken(XPathTokenID id, QueryCompileError error)
 {
     XPathToken token = this.NextToken(id);
     if (token == null)
     {
         this.ThrowError(error);
     }
     return token;
 }
        private XPathToken NextToken(XPathTokenID id, QueryCompileError error)
        {
            XPathToken token = this.NextToken(id);

            if (token == null)
            {
                this.ThrowError(error);
            }
            return(token);
        }
Ejemplo n.º 9
0
 internal XPathLexer(string xpath, bool resolveKeywords)
 {
     this.resolveKeywords = resolveKeywords;
     this.xpath           = string.Copy(xpath);
     this.xpathLength     = this.xpath.Length;
     this.tokenStart      = 0;
     this.currChar        = 0;
     this.ch         = '\0';
     this.previousID = XPathTokenID.Unknown;
     this.token      = new XPathToken();
     this.ConsumeWhitespace();
 }
 internal XPathLexer(string xpath, bool resolveKeywords)
 {
     this.resolveKeywords = resolveKeywords;
     this.xpath = string.Copy(xpath);
     this.xpathLength = this.xpath.Length;
     this.tokenStart = 0;
     this.currChar = 0;
     this.ch = '\0';
     this.previousID = XPathTokenID.Unknown;
     this.token = new XPathToken();
     this.ConsumeWhitespace();
 }
 private XPathToken NextTokenClass(XPathTokenID tokenClass)
 {
     XPathToken token = this.NextToken();
     if (token != null)
     {
         if ((token.TokenID & tokenClass) != XPathTokenID.Unknown)
         {
             return token;
         }
         this.readToken = token;
     }
     return null;
 }
 private XPathToken NextToken(XPathTokenID id)
 {
     XPathToken token = this.NextToken();
     if (token != null)
     {
         if (id == token.TokenID)
         {
             return token;
         }
         this.readToken = token;
     }
     return null;
 }
Ejemplo n.º 13
0
        private XPathTokenID GetAxisName(XPathParser.QName qname)
        {
            if (qname.Prefix.Length != 0)
            {
                this.ThrowError(QueryCompileError.InvalidAxisSpecifier, qname.Prefix + ":" + qname.Name);
            }
            XPathTokenID namedType = this.GetNamedType(qname.Name);

            if (this.resolveKeywords && ((namedType & XPathTokenID.Axis) == XPathTokenID.Unknown))
            {
                this.ThrowError(QueryCompileError.UnsupportedAxis, qname.Name);
            }
            return(namedType);
        }
Ejemplo n.º 14
0
        private XPathTokenID GetNamedOperator(XPathParser.QName qname)
        {
            if (qname.Prefix.Length != 0)
            {
                this.ThrowError(QueryCompileError.InvalidOperatorName, qname.Prefix + ":" + qname.Name);
            }
            XPathTokenID namedType = this.GetNamedType(qname.Name);

            if (this.resolveKeywords && ((namedType & XPathTokenID.NamedOperator) == XPathTokenID.Unknown))
            {
                this.ThrowError(QueryCompileError.UnsupportedOperator, this.previousID.ToString() + "->" + qname.Name);
            }
            return(namedType);
        }
Ejemplo n.º 15
0
        private XPathTokenID GetNodeTypeOrFunction(XPathParser.QName qname)
        {
            XPathTokenID namedType = this.GetNamedType(qname.Name);

            if ((namedType & XPathTokenID.NodeType) == XPathTokenID.Unknown)
            {
                return(XPathTokenID.Function);
            }
            if (qname.Prefix.Length > 0)
            {
                this.ThrowError(QueryCompileError.InvalidNodeType, qname.Prefix + ":" + qname.Name);
            }
            return(namedType);
        }
        private XPathToken NextTokenClass(XPathTokenID tokenClass)
        {
            XPathToken token = this.NextToken();

            if (token != null)
            {
                if ((token.TokenID & tokenClass) != XPathTokenID.Unknown)
                {
                    return(token);
                }
                this.readToken = token;
            }
            return(null);
        }
        private XPathToken NextToken(XPathTokenID id)
        {
            XPathToken token = this.NextToken();

            if (token != null)
            {
                if (id == token.TokenID)
                {
                    return(token);
                }
                this.readToken = token;
            }
            return(null);
        }
Ejemplo n.º 18
0
        XPathToken NextToken(XPathTokenID id)
        {
            XPathToken token = this.NextToken();

            if (null != token)
            {
                if (id == token.TokenID)
                {
                    return token;
                }

                this.readToken = token;
            }

            return null;
        }
Ejemplo n.º 19
0
        XPathToken NextTokenClass(XPathTokenID tokenClass)
        {
            XPathToken token = this.NextToken();

            if (null != token)
            {
                if (0 != (token.TokenID & tokenClass))
                {
                    return(token);
                }

                this.readToken = token;
            }

            return(null);
        }
        private XPathTokenID GetNodeTypeOrFunction(XPathParser.QName qname)
        {
            XPathTokenID id = GetNamedType(qname.Name);

            // If it's not a node type, it's lexed as a function
            if ((id & XPathTokenID.NodeType) == 0)
            {
                id = XPathTokenID.Function;
            }
            else if (qname.Prefix.Length > 0)
            {
                // Node types don't have prefixes
                ThrowError(QueryCompileError.InvalidNodeType, qname.Prefix + ":" + qname.Name);
            }

            return(id);
        }
        private XPathTokenID GetNamedOperator(XPathParser.QName qname)
        {
            // Named operators can't have prefixes
            if (qname.Prefix.Length != 0)
            {
                ThrowError(QueryCompileError.InvalidOperatorName, qname.Prefix + ":" + qname.Name);
            }

            // Make sure the type is 'NamedOperator'
            XPathTokenID id = GetNamedType(qname.Name);

            if (this.resolveKeywords && (id & XPathTokenID.NamedOperator) == 0)
            {
                ThrowError(QueryCompileError.UnsupportedOperator, this.previousID.ToString() + "->" + qname.Name);
            }

            return(id);
        }
        private XPathTokenID GetAxisName(XPathParser.QName qname)
        {
            // Axes can't have prefixes
            if (qname.Prefix.Length != 0)
            {
                ThrowError(QueryCompileError.InvalidAxisSpecifier, qname.Prefix + ":" + qname.Name);
            }

            // Make sure the type is 'Axis'
            XPathTokenID id = GetNamedType(qname.Name);

            if (this.resolveKeywords && (id & XPathTokenID.Axis) == 0)
            {
                ThrowError(QueryCompileError.UnsupportedAxis, qname.Name);
            }

            return(id);
        }
        private XPathExpr ParseMultiplicativeExpression()
        {
            XPathExpr left = this.ParseUnaryExpression();

            if (left != null)
            {
                MathOperator none;
                do
                {
                    none = MathOperator.None;
                    XPathToken token = this.NextToken();
                    if (token != null)
                    {
                        XPathTokenID tokenID = token.TokenID;
                        if (tokenID == XPathTokenID.Multiply)
                        {
                            none = MathOperator.Multiply;
                        }
                        else if (tokenID == XPathTokenID.Mod)
                        {
                            none = MathOperator.Mod;
                        }
                        else if (tokenID == XPathTokenID.Div)
                        {
                            none = MathOperator.Div;
                        }
                        else
                        {
                            this.PushToken(token);
                        }
                        if (none != MathOperator.None)
                        {
                            XPathExpr right = this.ParseUnaryExpression();
                            if (right == null)
                            {
                                this.ThrowError(QueryCompileError.InvalidExpression);
                            }
                            left = new XPathMathExpr(none, left, right);
                        }
                    }
                }while (none != MathOperator.None);
            }
            return(left);
        }
        internal XPathLexer(string xpath, bool resolveKeywords)
        {
            this.resolveKeywords = resolveKeywords;

            // Hold on to a copy of the string so it can't be changed out from under us
            this.xpath       = string.Copy(xpath);
            this.xpathLength = this.xpath.Length;

            // Start at the beginning
            this.tokenStart = 0;
            this.currChar   = 0;

            this.ch         = char.MinValue;
            this.previousID = XPathTokenID.Unknown;

            // We will not create new tokens, we will simply change the old one.
            // This will be the only XPathToken instance created by the lexer
            // The 'next token' data can be more quickly communicated to the parser if they both hold a reference to the data.
            this.token = new XPathToken();

            // Strip leading whitespace
            ConsumeWhitespace();
        }
Ejemplo n.º 25
0
 internal XPathToken()
 {
     this.tokenID = XPathTokenID.Unknown;
 }
Ejemplo n.º 26
0
        private void TokenizeQName()
        {
            while (XPathCharTypes.IsNCName(this.PeekChar()))
            {
                this.AdvanceChar();
            }
            string       prefix  = this.CurrentSubstring();
            XPathTokenID unknown = XPathTokenID.Unknown;

            XPathParser.QName qname = new XPathParser.QName("", "");
            if ((this.PeekChar() == ':') && (this.PeekChar(2) != ':'))
            {
                this.AdvanceChar();
                this.ConsumeToken();
                this.AdvanceChar();
                if (XPathCharTypes.IsNCNameStart(this.ch))
                {
                    while (XPathCharTypes.IsNCName(this.PeekChar()))
                    {
                        this.AdvanceChar();
                    }
                    unknown = XPathTokenID.NameTest;
                    qname   = new XPathParser.QName(prefix, this.CurrentSubstring());
                }
                else if (this.ch == '*')
                {
                    unknown = XPathTokenID.NameWildcard;
                    qname   = new XPathParser.QName(prefix, QueryDataModel.Wildcard);
                }
                else
                {
                    this.ThrowError(QueryCompileError.InvalidNCName, (this.ch == '\0') ? "" : this.CurrentSubstring());
                }
            }
            else
            {
                unknown = XPathTokenID.NameTest;
                qname   = new XPathParser.QName(string.Empty, prefix);
            }
            this.ConsumeWhitespace();
            if (this.IsSpecialPrev())
            {
                this.token.Set(this.GetNamedOperator(qname));
            }
            else if (qname.Prefix.Length == 0)
            {
                if (this.PeekChar() == '(')
                {
                    unknown = this.GetNodeTypeOrFunction(qname);
                    if (unknown != XPathTokenID.Function)
                    {
                        this.token.Set(unknown);
                    }
                    else
                    {
                        this.token.Set(unknown, qname);
                    }
                }
                else if ((this.PeekChar() == ':') && (this.PeekChar(2) == ':'))
                {
                    this.token.Set(this.GetAxisName(qname));
                }
                else
                {
                    this.token.Set(unknown, qname);
                }
            }
            else
            {
                if (this.PeekChar() == '(')
                {
                    unknown = XPathTokenID.Function;
                }
                this.token.Set(unknown, qname);
            }
        }
Ejemplo n.º 27
0
 internal void Set(XPathTokenID id)
 {
     this.Clear();
     this.tokenID = id;
 }
Ejemplo n.º 28
0
        internal bool MoveNext()
        {
            this.previousID = this.token.TokenID;
            if (!this.AdvanceChar())
            {
                return(false);
            }
            if (XPathCharTypes.IsNCNameStart(this.ch))
            {
                this.TokenizeQName();
            }
            else if (XPathCharTypes.IsDigit(this.ch))
            {
                this.TokenizeNumber();
            }
            else
            {
                switch (this.ch)
                {
                case '!':
                    if (this.PeekChar() != '=')
                    {
                        this.ThrowError(QueryCompileError.UnsupportedOperator, this.CurrentSubstring());
                    }
                    else
                    {
                        this.AdvanceChar();
                        this.token.Set(XPathTokenID.Neq);
                    }
                    goto Label_03FB;

                case '"':
                    this.TokenizeLiteral('"');
                    goto Label_03FB;

                case '$':
                {
                    XPathParser.QName qName = this.GetQName();
                    if ((qName.Prefix.Length == 0) && (qName.Name.Length == 0))
                    {
                        this.AdvanceChar();
                        this.ThrowError(QueryCompileError.InvalidVariable, (this.ch == '\0') ? string.Empty : this.CurrentSubstring());
                    }
                    this.token.Set(XPathTokenID.Variable, qName);
                    goto Label_03FB;
                }

                case '\'':
                    this.TokenizeLiteral('\'');
                    goto Label_03FB;

                case '(':
                    this.token.Set(XPathTokenID.LParen);
                    goto Label_03FB;

                case ')':
                    this.token.Set(XPathTokenID.RParen);
                    goto Label_03FB;

                case '*':
                    if (!this.IsSpecialPrev())
                    {
                        this.token.Set(XPathTokenID.Wildcard, new XPathParser.QName(string.Empty, QueryDataModel.Wildcard));
                    }
                    else
                    {
                        this.token.Set(XPathTokenID.Multiply);
                    }
                    goto Label_03FB;

                case '+':
                    this.token.Set(XPathTokenID.Plus);
                    goto Label_03FB;

                case ',':
                    this.token.Set(XPathTokenID.Comma);
                    goto Label_03FB;

                case '-':
                    this.token.Set(XPathTokenID.Minus);
                    goto Label_03FB;

                case '.':
                    if (this.PeekChar() != '.')
                    {
                        if (XPathCharTypes.IsDigit(this.PeekChar()))
                        {
                            this.TokenizeNumber();
                        }
                        else
                        {
                            this.token.Set(XPathTokenID.Period);
                        }
                    }
                    else
                    {
                        this.AdvanceChar();
                        this.token.Set(XPathTokenID.DblPeriod);
                    }
                    goto Label_03FB;

                case '/':
                    if (this.PeekChar() != '/')
                    {
                        this.token.Set(XPathTokenID.Slash);
                    }
                    else
                    {
                        this.AdvanceChar();
                        this.token.Set(XPathTokenID.DblSlash);
                    }
                    goto Label_03FB;

                case ':':
                    if (this.PeekChar() != ':')
                    {
                        this.ThrowError(QueryCompileError.UnexpectedToken, this.CurrentSubstring());
                    }
                    else
                    {
                        this.AdvanceChar();
                        this.token.Set(XPathTokenID.DblColon);
                    }
                    goto Label_03FB;

                case '<':
                    if (this.PeekChar() != '=')
                    {
                        this.token.Set(XPathTokenID.Lt);
                    }
                    else
                    {
                        this.AdvanceChar();
                        this.token.Set(XPathTokenID.Lte);
                    }
                    goto Label_03FB;

                case '=':
                    this.token.Set(XPathTokenID.Eq);
                    goto Label_03FB;

                case '>':
                    if (this.PeekChar() != '=')
                    {
                        this.token.Set(XPathTokenID.Gt);
                    }
                    else
                    {
                        this.AdvanceChar();
                        this.token.Set(XPathTokenID.Gte);
                    }
                    goto Label_03FB;

                case '@':
                    this.token.Set(XPathTokenID.AtSign);
                    goto Label_03FB;

                case '[':
                    this.token.Set(XPathTokenID.LBracket);
                    goto Label_03FB;

                case ']':
                    this.token.Set(XPathTokenID.RBracket);
                    goto Label_03FB;

                case '|':
                    this.token.Set(XPathTokenID.Pipe);
                    goto Label_03FB;
                }
                this.token.Set(XPathTokenID.Unknown);
            }
Label_03FB:
            this.ConsumeWhitespace();
            return(true);
        }
Ejemplo n.º 29
0
        internal void Set(XPathTokenID id, string name)
        {
            Fx.Assert(null != name, "");

            this.Clear();
            this.tokenID = id;
            this.name = name;
        }
Ejemplo n.º 30
0
 internal void Set(XPathTokenID id, double number)
 {
     this.Set(id);
     this.number = number;
 }
 internal void Set(XPathTokenID id, string name)
 {
     this.Clear();
     this.tokenID = id;
     this.name = name;
 }
Ejemplo n.º 32
0
 internal void Set(XPathTokenID id, XPathParser.QName qname)
 {
     this.Set(id, qname.Name);
     this.prefix = qname.Prefix;
 }
 internal XPathToken()
 {
     this.tokenID = XPathTokenID.Unknown;
 }
 internal void Set(XPathTokenID id, string name)
 {
     this.Clear();
     this.tokenID = id;
     this.name    = name;
 }
 internal void Set(XPathTokenID id, XPathParser.QName qname)
 {
     this.Set(id, qname.Name);
     this.prefix = qname.Prefix;
 }
Ejemplo n.º 36
0
        internal XPathLexer(string xpath, bool resolveKeywords)
        {
            this.resolveKeywords = resolveKeywords;

            // Hold on to a copy of the string so it can't be changed out from under us
            this.xpath = string.Copy(xpath);
            this.xpathLength = this.xpath.Length;

            // Start at the beginning
            this.tokenStart = 0;
            this.currChar = 0;

            this.ch = char.MinValue;
            this.previousID = XPathTokenID.Unknown;

            // We will not create new tokens, we will simply change the old one.
            // This will be the only XPathToken instance created by the lexer
            // The 'next token' data can be more quickly communicated to the parser if they both hold a reference to the data.
            this.token = new XPathToken();

            // Strip leading whitespace
            ConsumeWhitespace();
        }
 internal void Set(XPathTokenID id, double number)
 {
     this.Set(id);
     this.number = number;
 }
 internal void Set(XPathTokenID id)
 {
     this.Clear();
     this.tokenID = id;
 }
Ejemplo n.º 39
0
        // Move to the next token
        // This updates the values in the token instance and returns true if successful.
        internal bool MoveNext()
        {
            // Hold onto the ID of the last token.
            // It will be needed by some of the special cases.
            this.previousID = this.token.TokenID;

            // If there are no more characters, we can't get another token.
            if (!AdvanceChar())
            {
                return false;
            }

            if (XPathCharTypes.IsNCNameStart(this.ch))
            {
                // Extract a QName if we've got the start of an NCName
                TokenizeQName();
            }
            else if (XPathCharTypes.IsDigit(this.ch))
            {
                // Extract a number
                TokenizeNumber();
            }
            else
            {
                // Everything else is a single/double character token, or a variable.
                switch (this.ch)
                {
                    case '(':
                        token.Set(XPathTokenID.LParen);
                        break;

                    case ')':
                        token.Set(XPathTokenID.RParen);
                        break;

                    case '[':
                        token.Set(XPathTokenID.LBracket);
                        break;

                    case ']':
                        token.Set(XPathTokenID.RBracket);
                        break;

                    case '.':
                        // Watch for a double period
                        if (PeekChar() == '.')
                        {
                            AdvanceChar();
                            token.Set(XPathTokenID.DblPeriod);
                        }
                        else
                        {
                            // Check if the period is the start of a number
                            if (XPathCharTypes.IsDigit(PeekChar()))
                            {
                                TokenizeNumber();
                            }
                            else
                            {
                                token.Set(XPathTokenID.Period);
                            }
                        }
                        break;

                    case '@':
                        token.Set(XPathTokenID.AtSign);
                        break;

                    case ',':
                        token.Set(XPathTokenID.Comma);
                        break;

                    case ':':
                        // Only a double colon is permitted.
                        // The single colon part of the QName is consumed in TokenizeQName if it is valid
                        if (PeekChar() == ':')
                        {
                            AdvanceChar();
                            token.Set(XPathTokenID.DblColon);
                        }
                        else
                        {
                            ThrowError(QueryCompileError.UnexpectedToken, CurrentSubstring());
                        }
                        break;



                    case '/':
                        // Check for a double slash
                        if (PeekChar() == '/')
                        {
                            AdvanceChar();
                            token.Set(XPathTokenID.DblSlash);
                        }
                        else
                        {
                            token.Set(XPathTokenID.Slash);
                        }
                        break;

                    case '|':
                        token.Set(XPathTokenID.Pipe);
                        break;

                    case '+':
                        token.Set(XPathTokenID.Plus);
                        break;

                    case '-':
                        token.Set(XPathTokenID.Minus);
                        break;

                    case '=':
                        token.Set(XPathTokenID.Eq);
                        break;

                    case '!':
                        // This can only be the start of a '!='
                        // 'not' is a negation in XPath
                        if (PeekChar() == '=')
                        {
                            AdvanceChar();
                            token.Set(XPathTokenID.Neq);
                        }
                        else
                        {
                            ThrowError(QueryCompileError.UnsupportedOperator, CurrentSubstring());
                        }
                        break;

                    case '<':
                        // Watch for '<='
                        if (PeekChar() == '=')
                        {
                            AdvanceChar();
                            token.Set(XPathTokenID.Lte);
                        }
                        else
                        {
                            token.Set(XPathTokenID.Lt);
                        }
                        break;

                    case '>':
                        // Watch for '>='
                        if (PeekChar() == '=')
                        {
                            AdvanceChar();
                            token.Set(XPathTokenID.Gte);
                        }
                        else
                        {
                            token.Set(XPathTokenID.Gt);
                        }
                        break;


                    case '*':
                        // Check if we're supposed to parse a '*' as a multiply
                        if (IsSpecialPrev())
                        {
                            token.Set(XPathTokenID.Multiply);
                        }
                        else
                        {
                            token.Set(XPathTokenID.Wildcard, new XPathParser.QName(string.Empty, QueryDataModel.Wildcard));
                        }
                        break;

                    case '$':
                        // Make sure '$' was followed by something that counts as a variable name
                        XPathParser.QName qname = GetQName();
                        if (qname.Prefix.Length == 0 && qname.Name.Length == 0)
                        {
                            AdvanceChar();
                            ThrowError(QueryCompileError.InvalidVariable, this.ch == char.MinValue ? string.Empty : CurrentSubstring());
                        }
                        token.Set(XPathTokenID.Variable, qname);
                        break;

                    case '\"':
                        TokenizeLiteral('\"');
                        break;

                    case '\'':
                        TokenizeLiteral('\'');
                        break;

                    default:
                        // Unrecognized character
                        token.Set(XPathTokenID.Unknown);
                        break;
                }
            }

            // Whitespace can mark the end of a token, but is not part of the XPath syntax
            ConsumeWhitespace();

            return true;
        }
        internal bool MoveNext()
        {
            this.previousID = this.token.TokenID;
            if (!this.AdvanceChar())
            {
                return false;
            }
            if (XPathCharTypes.IsNCNameStart(this.ch))
            {
                this.TokenizeQName();
            }
            else if (XPathCharTypes.IsDigit(this.ch))
            {
                this.TokenizeNumber();
            }
            else
            {
                switch (this.ch)
                {
                    case '!':
                        if (this.PeekChar() != '=')
                        {
                            this.ThrowError(QueryCompileError.UnsupportedOperator, this.CurrentSubstring());
                        }
                        else
                        {
                            this.AdvanceChar();
                            this.token.Set(XPathTokenID.Neq);
                        }
                        goto Label_03FB;

                    case '"':
                        this.TokenizeLiteral('"');
                        goto Label_03FB;

                    case '$':
                    {
                        XPathParser.QName qName = this.GetQName();
                        if ((qName.Prefix.Length == 0) && (qName.Name.Length == 0))
                        {
                            this.AdvanceChar();
                            this.ThrowError(QueryCompileError.InvalidVariable, (this.ch == '\0') ? string.Empty : this.CurrentSubstring());
                        }
                        this.token.Set(XPathTokenID.Variable, qName);
                        goto Label_03FB;
                    }
                    case '\'':
                        this.TokenizeLiteral('\'');
                        goto Label_03FB;

                    case '(':
                        this.token.Set(XPathTokenID.LParen);
                        goto Label_03FB;

                    case ')':
                        this.token.Set(XPathTokenID.RParen);
                        goto Label_03FB;

                    case '*':
                        if (!this.IsSpecialPrev())
                        {
                            this.token.Set(XPathTokenID.Wildcard, new XPathParser.QName(string.Empty, QueryDataModel.Wildcard));
                        }
                        else
                        {
                            this.token.Set(XPathTokenID.Multiply);
                        }
                        goto Label_03FB;

                    case '+':
                        this.token.Set(XPathTokenID.Plus);
                        goto Label_03FB;

                    case ',':
                        this.token.Set(XPathTokenID.Comma);
                        goto Label_03FB;

                    case '-':
                        this.token.Set(XPathTokenID.Minus);
                        goto Label_03FB;

                    case '.':
                        if (this.PeekChar() != '.')
                        {
                            if (XPathCharTypes.IsDigit(this.PeekChar()))
                            {
                                this.TokenizeNumber();
                            }
                            else
                            {
                                this.token.Set(XPathTokenID.Period);
                            }
                        }
                        else
                        {
                            this.AdvanceChar();
                            this.token.Set(XPathTokenID.DblPeriod);
                        }
                        goto Label_03FB;

                    case '/':
                        if (this.PeekChar() != '/')
                        {
                            this.token.Set(XPathTokenID.Slash);
                        }
                        else
                        {
                            this.AdvanceChar();
                            this.token.Set(XPathTokenID.DblSlash);
                        }
                        goto Label_03FB;

                    case ':':
                        if (this.PeekChar() != ':')
                        {
                            this.ThrowError(QueryCompileError.UnexpectedToken, this.CurrentSubstring());
                        }
                        else
                        {
                            this.AdvanceChar();
                            this.token.Set(XPathTokenID.DblColon);
                        }
                        goto Label_03FB;

                    case '<':
                        if (this.PeekChar() != '=')
                        {
                            this.token.Set(XPathTokenID.Lt);
                        }
                        else
                        {
                            this.AdvanceChar();
                            this.token.Set(XPathTokenID.Lte);
                        }
                        goto Label_03FB;

                    case '=':
                        this.token.Set(XPathTokenID.Eq);
                        goto Label_03FB;

                    case '>':
                        if (this.PeekChar() != '=')
                        {
                            this.token.Set(XPathTokenID.Gt);
                        }
                        else
                        {
                            this.AdvanceChar();
                            this.token.Set(XPathTokenID.Gte);
                        }
                        goto Label_03FB;

                    case '@':
                        this.token.Set(XPathTokenID.AtSign);
                        goto Label_03FB;

                    case '[':
                        this.token.Set(XPathTokenID.LBracket);
                        goto Label_03FB;

                    case ']':
                        this.token.Set(XPathTokenID.RBracket);
                        goto Label_03FB;

                    case '|':
                        this.token.Set(XPathTokenID.Pipe);
                        goto Label_03FB;
                }
                this.token.Set(XPathTokenID.Unknown);
            }
        Label_03FB:
            this.ConsumeWhitespace();
            return true;
        }
        // Move to the next token
        // This updates the values in the token instance and returns true if successful.
        internal bool MoveNext()
        {
            // Hold onto the ID of the last token.
            // It will be needed by some of the special cases.
            this.previousID = this.token.TokenID;

            // If there are no more characters, we can't get another token.
            if (!AdvanceChar())
            {
                return(false);
            }

            if (XPathCharTypes.IsNCNameStart(this.ch))
            {
                // Extract a QName if we've got the start of an NCName
                TokenizeQName();
            }
            else if (XPathCharTypes.IsDigit(this.ch))
            {
                // Extract a number
                TokenizeNumber();
            }
            else
            {
                // Everything else is a single/double character token, or a variable.
                switch (this.ch)
                {
                case '(':
                    token.Set(XPathTokenID.LParen);
                    break;

                case ')':
                    token.Set(XPathTokenID.RParen);
                    break;

                case '[':
                    token.Set(XPathTokenID.LBracket);
                    break;

                case ']':
                    token.Set(XPathTokenID.RBracket);
                    break;

                case '.':
                    // Watch for a double period
                    if (PeekChar() == '.')
                    {
                        AdvanceChar();
                        token.Set(XPathTokenID.DblPeriod);
                    }
                    else
                    {
                        // Check if the period is the start of a number
                        if (XPathCharTypes.IsDigit(PeekChar()))
                        {
                            TokenizeNumber();
                        }
                        else
                        {
                            token.Set(XPathTokenID.Period);
                        }
                    }
                    break;

                case '@':
                    token.Set(XPathTokenID.AtSign);
                    break;

                case ',':
                    token.Set(XPathTokenID.Comma);
                    break;

                case ':':
                    // Only a double colon is permitted.
                    // The single colon part of the QName is consumed in TokenizeQName if it is valid
                    if (PeekChar() == ':')
                    {
                        AdvanceChar();
                        token.Set(XPathTokenID.DblColon);
                    }
                    else
                    {
                        ThrowError(QueryCompileError.UnexpectedToken, CurrentSubstring());
                    }
                    break;



                case '/':
                    // Check for a double slash
                    if (PeekChar() == '/')
                    {
                        AdvanceChar();
                        token.Set(XPathTokenID.DblSlash);
                    }
                    else
                    {
                        token.Set(XPathTokenID.Slash);
                    }
                    break;

                case '|':
                    token.Set(XPathTokenID.Pipe);
                    break;

                case '+':
                    token.Set(XPathTokenID.Plus);
                    break;

                case '-':
                    token.Set(XPathTokenID.Minus);
                    break;

                case '=':
                    token.Set(XPathTokenID.Eq);
                    break;

                case '!':
                    // This can only be the start of a '!='
                    // 'not' is a negation in XPath
                    if (PeekChar() == '=')
                    {
                        AdvanceChar();
                        token.Set(XPathTokenID.Neq);
                    }
                    else
                    {
                        ThrowError(QueryCompileError.UnsupportedOperator, CurrentSubstring());
                    }
                    break;

                case '<':
                    // Watch for '<='
                    if (PeekChar() == '=')
                    {
                        AdvanceChar();
                        token.Set(XPathTokenID.Lte);
                    }
                    else
                    {
                        token.Set(XPathTokenID.Lt);
                    }
                    break;

                case '>':
                    // Watch for '>='
                    if (PeekChar() == '=')
                    {
                        AdvanceChar();
                        token.Set(XPathTokenID.Gte);
                    }
                    else
                    {
                        token.Set(XPathTokenID.Gt);
                    }
                    break;


                case '*':
                    // Check if we're supposed to parse a '*' as a multiply
                    if (IsSpecialPrev())
                    {
                        token.Set(XPathTokenID.Multiply);
                    }
                    else
                    {
                        token.Set(XPathTokenID.Wildcard, new XPathParser.QName(string.Empty, QueryDataModel.Wildcard));
                    }
                    break;

                case '$':
                    // Make sure '$' was followed by something that counts as a variable name
                    XPathParser.QName qname = GetQName();
                    if (qname.Prefix.Length == 0 && qname.Name.Length == 0)
                    {
                        AdvanceChar();
                        ThrowError(QueryCompileError.InvalidVariable, this.ch == char.MinValue ? string.Empty : CurrentSubstring());
                    }
                    token.Set(XPathTokenID.Variable, qname);
                    break;

                case '\"':
                    TokenizeLiteral('\"');
                    break;

                case '\'':
                    TokenizeLiteral('\'');
                    break;

                default:
                    // Unrecognized character
                    token.Set(XPathTokenID.Unknown);
                    break;
                }
            }

            // Whitespace can mark the end of a token, but is not part of the XPath syntax
            ConsumeWhitespace();

            return(true);
        }
        private void TokenizeQName()
        {
            for (; XPathCharTypes.IsNCName(PeekChar()); AdvanceChar())
            {
                ;
            }

            string       name1 = this.CurrentSubstring();
            XPathTokenID id    = XPathTokenID.Unknown;

            XPathParser.QName qname = new XPathParser.QName("", "");

            if (PeekChar() == ':' && PeekChar(2) != ':')
            {
                AdvanceChar();
                ConsumeToken();
                AdvanceChar();
                if (XPathCharTypes.IsNCNameStart(this.ch))
                {
                    // It's a full QName
                    for (; XPathCharTypes.IsNCName(PeekChar()); AdvanceChar())
                    {
                        ;
                    }
                    id    = XPathTokenID.NameTest;
                    qname = new XPathParser.QName(name1, this.CurrentSubstring());
                }
                else if (this.ch == '*')
                {
                    // We've got a wildcard
                    id    = XPathTokenID.NameWildcard;
                    qname = new XPathParser.QName(name1, QueryDataModel.Wildcard);
                }
                else
                {
                    ThrowError(QueryCompileError.InvalidNCName, this.ch == char.MinValue ? "" : CurrentSubstring());
                }
            }
            else
            {
                // It's a name test without a prefix
                id    = XPathTokenID.NameTest;
                qname = new XPathParser.QName(string.Empty, name1);
            }

            // Handle special cases
            ConsumeWhitespace();
            if (IsSpecialPrev())
            {
                // If we're in the the first special case of the lexer, a qname MUST
                // be a NamedOperator
                token.Set(GetNamedOperator(qname));
                return;
            }
            else if (qname.Prefix.Length == 0)
            {
                if (this.PeekChar() == '(')
                {
                    // An NCName followed by a '(' MUST be eiter a node type or function name
                    id = GetNodeTypeOrFunction(qname);
                    if (id != XPathTokenID.Function)
                    {
                        token.Set(id);
                    }
                    else
                    {
                        token.Set(id, qname);
                    }
                }
                else if (this.PeekChar() == ':' && this.PeekChar(2) == ':')
                {
                    // An NCName followed by a '::' MUST be an axis
                    token.Set(GetAxisName(qname));
                }
                else
                {
                    token.Set(id, qname);
                }
            }
            else
            {
                if (this.PeekChar() == '(')
                {
                    id = XPathTokenID.Function;
                }
                token.Set(id, qname);
            }
        }
Ejemplo n.º 43
0
        XPathToken NextTokenClass(XPathTokenID tokenClass)
        {
            XPathToken token = this.NextToken();

            if (null != token)
            {
                if (0 != (token.TokenID & tokenClass))
                {
                    return token;
                }

                this.readToken = token;
            }

            return null;
        }