Пример #1
0
        /// <summary>
        /// Advance
        /// returns true on successful advance
        ///     and false on an erroneous token
        ///
        /// Doesn't return error until the bogus input is encountered.
        /// Advance() returns true even after EndOfInput is encountered.
        /// </summary>
        internal bool Advance()
        {
            if (errorState)
            {
                return(false);
            }

            if (lookahead?.IsToken(Token.TokenType.EndOfInput) == true)
            {
                return(true);
            }

            SkipWhiteSpace();

            // Update error position after skipping whitespace
            errorPosition = parsePoint + 1;

            if (parsePoint >= expression.Length)
            {
                lookahead = new Token(Token.TokenType.EndOfInput, null /* end of input */);
            }
            else
            {
                switch (expression[parsePoint])
                {
                case ',':
                    lookahead = new Token(Token.TokenType.Comma, comma);
                    parsePoint++;
                    break;

                case '(':
                    lookahead = new Token(Token.TokenType.LeftParenthesis, leftParenthesis);
                    parsePoint++;
                    break;

                case ')':
                    lookahead = new Token(Token.TokenType.RightParenthesis, rightParenthesis);
                    parsePoint++;
                    break;

                case '$':
                    if (!ParseProperty())
                    {
                        return(false);
                    }
                    break;

                case '%':
                    // If the caller specified that he DOESN'T want to allow item metadata ...
                    if ((this.options & ParserOptions.AllowItemMetadata) == 0)
                    {
                        errorPosition     = this.parsePoint;
                        errorState        = true;
                        errorResource     = "UnexpectedCharacterInCondition";
                        unexpectedlyFound = "%";
                        return(false);
                    }
                    if (!ParseItemMetadata())
                    {
                        return(false);
                    }
                    break;

                case '@':
                    int start = this.parsePoint;
                    // If the caller specified that he DOESN'T want to allow item lists ...
                    if ((this.options & ParserOptions.AllowItemLists) == 0)
                    {
                        if ((parsePoint + 1) < expression.Length && expression[parsePoint + 1] == '(')
                        {
                            errorPosition = start + 1;
                            errorState    = true;
                            errorResource = "ItemListNotAllowedInThisConditional";
                            return(false);
                        }
                    }
                    if (!ParseItemList())
                    {
                        return(false);
                    }
                    break;

                case '!':
                    // negation and not-equal
                    if ((parsePoint + 1) < expression.Length && expression[parsePoint + 1] == '=')
                    {
                        lookahead   = new Token(Token.TokenType.NotEqualTo, notEqualTo);
                        parsePoint += 2;
                    }
                    else
                    {
                        lookahead = new Token(Token.TokenType.Not, not);
                        parsePoint++;
                    }
                    break;

                case '>':
                    // gt and gte
                    if ((parsePoint + 1) < expression.Length && expression[parsePoint + 1] == '=')
                    {
                        lookahead   = new Token(Token.TokenType.GreaterThanOrEqualTo, greaterThanOrEqualTo);
                        parsePoint += 2;
                    }
                    else
                    {
                        lookahead = new Token(Token.TokenType.GreaterThan, greaterThan);
                        parsePoint++;
                    }
                    break;

                case '<':
                    // lt and lte
                    if ((parsePoint + 1) < expression.Length && expression[parsePoint + 1] == '=')
                    {
                        lookahead   = new Token(Token.TokenType.LessThanOrEqualTo, lessThanOrEqualTo);
                        parsePoint += 2;
                    }
                    else
                    {
                        lookahead = new Token(Token.TokenType.LessThan, lessThan);
                        parsePoint++;
                    }
                    break;

                case '=':
                    if ((parsePoint + 1) < expression.Length && expression[parsePoint + 1] == '=')
                    {
                        lookahead   = new Token(Token.TokenType.EqualTo, equalTo);
                        parsePoint += 2;
                    }
                    else
                    {
                        errorPosition = parsePoint + 2;     // expression[parsePoint + 1], counting from 1
                        errorResource = "IllFormedEqualsInCondition";
                        if ((parsePoint + 1) < expression.Length)
                        {
                            // store the char we found instead
                            unexpectedlyFound = Convert.ToString(expression[parsePoint + 1], CultureInfo.InvariantCulture);
                        }
                        else
                        {
                            unexpectedlyFound = EndOfInput;
                        }
                        parsePoint++;
                        errorState = true;
                        return(false);
                    }
                    break;

                case '\'':
                    if (!ParseQuotedString())
                    {
                        return(false);
                    }
                    break;

                default:
                    // Simple strings, function calls, decimal numbers, hex numbers
                    if (!ParseRemaining())
                    {
                        return(false);
                    }
                    break;
                }
            }
            return(true);
        }
Пример #2
0
 internal bool IsNext(Token.TokenType type)
 {
     return(lookahead.IsToken(type));
 }