Example #1
0
        /// <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);
        }
Example #2
0
 private void ValidateToken(QueryTokenKind tokenKind, Func <string> errorString)
 {
     if (this.lexer.Token.Kind != tokenKind)
     {
         this.ParseError(errorString(), this.lexer.Token.Position);
     }
 }
Example #3
0
        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);
        }
Example #4
0
 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());
 }
Example #5
0
        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);
        }
Example #6
0
        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);
     }
 }
Example #8
0
        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));
 }
Example #13
0
 /// <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;
 }
Example #14
0
 /// <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));
 }
Example #15
0
 /// <summary>
 /// Конструктор.
 /// </summary>
 /// <param name="kind">Тип токена.</param>
 /// <param name="value">Значение токена.</param>
 public QueryToken(QueryTokenKind kind, object value)
 {
     Kind  = kind;
     Value = value;
 }