/// <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); }
internal bool IsNext(Token.TokenType type) { return(lookahead.IsToken(type)); }