/// <summary> /// Creates an AnyNode or an AllNode from the given /// </summary> /// <param name="state">State of binding.</param> /// <param name="parent">Parent node to the lambda.</param> /// <param name="lambdaExpression">Bound Lambda expression.</param> /// <param name="newRangeVariable">The new range variable being added by this lambda node.</param> /// <param name="queryTokenKind">Token kind.</param> /// <returns>A new LambdaNode bound to metadata.</returns> internal static LambdaNode CreateLambdaNode( BindingState state, CollectionNode parent, SingleValueNode lambdaExpression, RangeVariable newRangeVariable, QueryTokenKind queryTokenKind) { LambdaNode lambdaNode; if (queryTokenKind == QueryTokenKind.Any) { lambdaNode = new AnyNode(new Collection <RangeVariable>(state.RangeVariables.ToList()), newRangeVariable) { Body = lambdaExpression, Source = parent, }; } else { Debug.Assert(queryTokenKind == QueryTokenKind.All, "LambdaQueryNodes must be Any or All only."); lambdaNode = new AllNode(new Collection <RangeVariable>(state.RangeVariables.ToList()), newRangeVariable) { Body = lambdaExpression, Source = parent, }; } return(lambdaNode); }
private void ValidateToken(QueryTokenKind tokenKind, Func <string> errorString) { if (this.lexer.Token.Kind != tokenKind) { this.ParseError(errorString(), this.lexer.Token.Position); } }
private QueryNode ParseMultiplicative() { QueryNode left = this.ParseUnary(); while (this.lexer.Token.Kind == QueryTokenKind.Multiply || this.lexer.Token.Kind == QueryTokenKind.Divide || this.lexer.Token.Kind == QueryTokenKind.Modulo) { QueryTokenKind opKind = this.lexer.Token.Kind; this.lexer.NextToken(); var right = this.ParseUnary(); switch (opKind) { case QueryTokenKind.Multiply: left = new BinaryOperatorNode(BinaryOperatorKind.Multiply, left, right); break; case QueryTokenKind.Divide: left = new BinaryOperatorNode(BinaryOperatorKind.Divide, left, right); break; case QueryTokenKind.Modulo: left = new BinaryOperatorNode(BinaryOperatorKind.Modulo, left, right); break; } } return(left); }
private QueryNode ParseUnary() { if (this.lexer.Token.Kind == QueryTokenKind.Minus || this.lexer.Token.Kind == QueryTokenKind.Not) { QueryTokenKind opKind = this.lexer.Token.Kind; int opPos = this.lexer.Token.Position; this.lexer.NextToken(); if (opKind == QueryTokenKind.Minus && (this.lexer.Token.Kind == QueryTokenKind.IntegerLiteral || this.lexer.Token.Kind == QueryTokenKind.RealLiteral)) { this.lexer.Token.Text = "-" + this.lexer.Token.Text; this.lexer.Token.Position = opPos; return(this.ParsePrimary()); } QueryNode expr = this.ParseUnary(); if (opKind == QueryTokenKind.Minus) { expr = new UnaryOperatorNode(UnaryOperatorKind.Negate, expr); } else { expr = new UnaryOperatorNode(UnaryOperatorKind.Not, expr); } return(expr); } return(this.ParsePrimary()); }
private QueryNode ParseComparison() { QueryNode left = this.ParseAdditive(); while (this.lexer.Token.Kind == QueryTokenKind.Equal || this.lexer.Token.Kind == QueryTokenKind.NotEqual || this.lexer.Token.Kind == QueryTokenKind.GreaterThan || this.lexer.Token.Kind == QueryTokenKind.GreaterThanEqual || this.lexer.Token.Kind == QueryTokenKind.LessThan || this.lexer.Token.Kind == QueryTokenKind.LessThanEqual) { QueryTokenKind opKind = this.lexer.Token.Kind; this.lexer.NextToken(); QueryNode right = this.ParseAdditive(); switch (opKind) { case QueryTokenKind.Equal: left = new BinaryOperatorNode(BinaryOperatorKind.Equal, left, right); break; case QueryTokenKind.NotEqual: left = new BinaryOperatorNode(BinaryOperatorKind.NotEqual, left, right); break; case QueryTokenKind.GreaterThan: left = new BinaryOperatorNode(BinaryOperatorKind.GreaterThan, left, right); break; case QueryTokenKind.GreaterThanEqual: left = new BinaryOperatorNode(BinaryOperatorKind.GreaterThanOrEqual, left, right); break; case QueryTokenKind.LessThan: left = new BinaryOperatorNode(BinaryOperatorKind.LessThan, left, right); break; case QueryTokenKind.LessThanEqual: left = new BinaryOperatorNode(BinaryOperatorKind.LessThanOrEqual, left, right); break; } } return(left); }
private QueryNode ParseAdditive() { QueryNode left = this.ParseMultiplicative(); while (this.lexer.Token.Kind == QueryTokenKind.Add || this.lexer.Token.Kind == QueryTokenKind.Sub) { QueryTokenKind opKind = this.lexer.Token.Kind; this.lexer.NextToken(); QueryNode right = this.ParseMultiplicative(); switch (opKind) { case QueryTokenKind.Add: left = new BinaryOperatorNode(BinaryOperatorKind.And, left, right); break; case QueryTokenKind.Sub: left = new BinaryOperatorNode(BinaryOperatorKind.Subtract, left, right); break; } } return(left); }
private void ValidateToken(QueryTokenKind tokenKind, Func<string> errorString) { if (this.lexer.Token.Kind != tokenKind) { this.ParseError(errorString(), this.lexer.Token.Position); } }
public QueryToken NextToken() { while (Char.IsWhiteSpace(this.CurrentChar)) { this.NextChar(); } QueryTokenKind t = QueryTokenKind.Unknown; int tokenPos = this.textPos; switch (this.CurrentChar) { case '(': this.NextChar(); t = QueryTokenKind.OpenParen; break; case ')': this.NextChar(); t = QueryTokenKind.CloseParen; break; case ',': this.NextChar(); t = QueryTokenKind.Comma; break; case '-': this.NextChar(); t = QueryTokenKind.Minus; break; case '/': this.NextChar(); t = QueryTokenKind.Dot; break; case '\'': char quote = this.CurrentChar; do { this.AdvanceToNextOccuranceOf(quote); if (this.textPos == this.textLen) { this.ParseError("The specified odata query has unterminated string literal.", this.textPos); } this.NextChar(); }while (this.CurrentChar == quote); t = QueryTokenKind.StringLiteral; break; default: if (this.IsIdentifierStart(this.CurrentChar) || this.CurrentChar == '@' || this.CurrentChar == '_') { do { this.NextChar(); }while (this.IsIdentifierPart(this.CurrentChar) || this.CurrentChar == '_'); t = QueryTokenKind.Identifier; break; } if (Char.IsDigit(this.CurrentChar)) { t = QueryTokenKind.IntegerLiteral; do { this.NextChar(); }while (Char.IsDigit(this.CurrentChar)); if (this.CurrentChar == '.') { t = QueryTokenKind.RealLiteral; this.NextChar(); this.ValidateDigit(); do { this.NextChar(); }while (Char.IsDigit(this.CurrentChar)); } if (this.CurrentChar == 'E' || this.CurrentChar == 'e') { t = QueryTokenKind.RealLiteral; this.NextChar(); if (this.CurrentChar == '+' || this.CurrentChar == '-') { this.NextChar(); } this.ValidateDigit(); do { this.NextChar(); }while (Char.IsDigit(this.CurrentChar)); } if (this.CurrentChar == 'F' || this.CurrentChar == 'f' || this.CurrentChar == 'M' || this.CurrentChar == 'm' || this.CurrentChar == 'D' || this.CurrentChar == 'd') { t = QueryTokenKind.RealLiteral; this.NextChar(); } break; } if (this.textPos == this.textLen) { t = QueryTokenKind.End; break; } this.ParseError("The specified odata query has syntax errors.", this.textPos); break; } this.Token.Kind = t; this.Token.Text = this.text.Substring(tokenPos, this.textPos - tokenPos); this.Token.Position = tokenPos; this.ReClassifyToken(); return(this.Token); }
/// <summary> /// Converts a <see cref="QueryTokenKind"/> to a <see cref="BinaryOperatorKind"/> where possible. /// </summary> /// <param name="kind">The <see cref="QueryTokenKind"/> to convert</param> /// <returns>The <see cref="BinaryOperatorKind"/> that is equivalent</returns> /// <exception cref="InvalidOperationException">if the token kind cannot be converted.</exception> internal static BinaryOperatorKind ToBinaryOperatorKind(this QueryTokenKind kind) => kind switch {
/// <summary> /// Returns <c>true</c> if the token kind is a number literal. /// </summary> /// <param name="kind">The <see cref="QueryTokenKind"/> to check.</param> /// <returns><c>true</c> if the token kind is a comparison operator.</returns> internal static bool IsNumberLiteral(this QueryTokenKind kind) => kind == QueryTokenKind.IntegerLiteral | kind == QueryTokenKind.RealLiteral;
/// <summary> /// Returns <c>true</c> if the token kind is a comparison operator. /// </summary> /// <param name="kind">The <see cref="QueryTokenKind"/> to check.</param> /// <returns><c>true</c> if the token kind is a comparison operator.</returns> internal static bool IsComparisonOperator(this QueryTokenKind kind) => kind == QueryTokenKind.Equal || kind == QueryTokenKind.NotEqual || kind == QueryTokenKind.LessThan || kind == QueryTokenKind.LessThanEqual || kind == QueryTokenKind.GreaterThan || kind == QueryTokenKind.GreaterThanEqual;
/// <summary> /// Throw ODataException on the given QueryTokenKind as not supported for writing to Uri. /// </summary> /// <param name="kind">QueryTokenKind that is not supported.</param> internal static void NotSupported(QueryTokenKind kind) { throw new ODataException(Strings.UriBuilder_NotSupportedQueryToken(kind)); }
/// <summary> /// Creates an AnyNode or an AllNode from the given /// </summary> /// <param name="state">State of binding.</param> /// <param name="parent">Parent node to the lambda.</param> /// <param name="lambdaExpression">Bound Lambda expression.</param> /// <param name="newRangeVariable">The new range variable being added by this lambda node.</param> /// <param name="queryTokenKind">Token kind.</param> /// <returns>A new LambdaNode bound to metadata.</returns> internal static LambdaNode CreateLambdaNode( BindingState state, CollectionNode parent, SingleValueNode lambdaExpression, RangeVariable newRangeVariable, QueryTokenKind queryTokenKind) { LambdaNode lambdaNode; if (queryTokenKind == QueryTokenKind.Any) { lambdaNode = new AnyNode(new Collection<RangeVariable>(state.RangeVariables.ToList()), newRangeVariable) { Body = lambdaExpression, Source = parent, }; } else { Debug.Assert(queryTokenKind == QueryTokenKind.All, "LambdaQueryNodes must be Any or All only."); lambdaNode = new AllNode(new Collection<RangeVariable>(state.RangeVariables.ToList()), newRangeVariable) { Body = lambdaExpression, Source = parent, }; } return lambdaNode; }
/// <summary> /// Throw ODataException on the given QueryTokenKind as not supported for writing to Uri. /// </summary> /// <param name="queryTokenKind">QueryTokenKind that is not supported.</param> internal static void NotSupportedQueryTokenKind(QueryTokenKind queryTokenKind) { DebugUtils.CheckNoExternalCallers(); throw new ODataException(Strings.UriBuilder_NotSupportedQueryToken(queryTokenKind)); }
/// <summary> /// Конструктор. /// </summary> /// <param name="kind">Тип токена.</param> /// <param name="value">Значение токена.</param> public QueryToken(QueryTokenKind kind, object value) { Kind = kind; Value = value; }