/// <summary>
        /// Check whether the current identifier is a function. If so, expand the token text to the function signature
        /// </summary>
        /// <returns>True if the current identifier is a function call</returns>
        internal bool ExpandIdentifierAsFunction()
        {
            // FUNCTION := (<ID> {<DOT>}) ... <ID> <OpenParen>
            // if we fail to match then we leave the token as it
            ExpressionTokenKind id = this.token.Kind;
            if (id != ExpressionTokenKind.Identifier)
            {
                return false;
            }

            int savedTextPos = this.textPos;
            char? savedChar = this.ch;
            ExpressionToken savedToken = this.token;
            bool savedIgnoreWs = this.ignoreWhitespace;
            this.ignoreWhitespace = false;

            // Expansion left anchor
            int tokenStartPos = this.token.Position;

            while (this.ExpandWhenMatch(ExpressionTokenKind.Dot) && this.ExpandWhenMatch(ExpressionTokenKind.Identifier))
            {
            }

            bool matched = this.CurrentToken.Kind == ExpressionTokenKind.Identifier && this.PeekNextToken().Kind == ExpressionTokenKind.OpenParen;

            if (matched)
            {
                this.token.Text = this.text.Substring(tokenStartPos, this.textPos - tokenStartPos);
                this.token.Position = tokenStartPos;
            }
            else
            {
                this.textPos = savedTextPos;
                this.ch = savedChar;
                this.token = savedToken;
            }

            this.ignoreWhitespace = savedIgnoreWs;

            return matched;
        }
        /// <summary>Returns the next token without advancing the lexer.</summary>
        /// <returns>The next token.</returns>
        internal ExpressionToken PeekNextToken()
        {
            int savedTextPos = this.textPos;
            char? savedChar = this.ch;
            ExpressionToken savedToken = this.token;

            this.NextToken();
            ExpressionToken result = this.token;

            this.textPos = savedTextPos;
            this.ch = savedChar;
            this.token = savedToken;

            return result;
        }
Exemple #3
0
        /// <summary>
        /// Tries to create a <see cref="ConstantNode"/> for the given token if it represents a literal.
        /// </summary>
        /// <param name="token">The token.</param>
        /// <param name="node">The node, if one was created.</param>
        /// <returns>Whether or not the token represented a literal.</returns>
        internal static bool TryCreateLiteral(ExpressionToken token, out ConstantNode node)
        {
            switch (token.Kind)
            {
            case ExpressionTokenKind.NullLiteral:
                node = new ConstantNode(null);
                break;

            case ExpressionTokenKind.BooleanLiteral:
                node = ParseTypedLiteral(typeof(bool), XmlConstants.EdmBooleanTypeName, token);
                break;

            case ExpressionTokenKind.DecimalLiteral:
                node = ParseTypedLiteral(typeof(decimal), XmlConstants.EdmDecimalTypeName, token);
                break;

            case ExpressionTokenKind.StringLiteral:
                node = ParseTypedLiteral(typeof(string), XmlConstants.EdmStringTypeName, token);
                break;

            case ExpressionTokenKind.Int64Literal:
                node = ParseTypedLiteral(typeof(Int64), XmlConstants.EdmInt64TypeName, token);
                break;

            case ExpressionTokenKind.IntegerLiteral:
                node = ParseTypedLiteral(typeof(Int32), XmlConstants.EdmInt32TypeName, token);
                break;

            case ExpressionTokenKind.DoubleLiteral:
                node = ParseTypedLiteral(typeof(double), XmlConstants.EdmDoubleTypeName, token);
                break;

            case ExpressionTokenKind.SingleLiteral:
                node = ParseTypedLiteral(typeof(Single), XmlConstants.EdmSingleTypeName, token);
                break;

            case ExpressionTokenKind.GuidLiteral:
                node = ParseTypedLiteral(typeof(Guid), XmlConstants.EdmGuidTypeName, token);
                break;

            case ExpressionTokenKind.BinaryLiteral:
                node = ParseTypedLiteral(typeof(byte[]), XmlConstants.EdmBinaryTypeName, token);
                break;

            case ExpressionTokenKind.DurationLiteral:
                node = ParseTypedLiteral(typeof(TimeSpan), XmlConstants.EdmDurationTypeName, token);
                break;

            case ExpressionTokenKind.DateTimeOffsetLiteral:
                node = ParseTypedLiteral(typeof(DateTimeOffset), XmlConstants.EdmDateTimeOffsetTypeName, token);
                break;

            case ExpressionTokenKind.GeographylLiteral:
                node = ParseTypedLiteral(typeof(Geography), XmlConstants.EdmGeographyTypeName, token);
                break;

            case ExpressionTokenKind.GeometryLiteral:
                node = ParseTypedLiteral(typeof(Geometry), XmlConstants.EdmGeometryTypeName, token);
                break;

            default:
                node = null;
                return(false);
            }

            Debug.Assert(token.IsLiteral, "Token must be a value.");
            return(true);
        }
Exemple #4
0
        /// <summary>
        /// Parses the given token into a constant node of the given target type.
        /// </summary>
        /// <param name="targetType">The tarket type.</param>
        /// <param name="targetTypeName">The target type name.</param>
        /// <param name="token">The token to parse.</param>
        /// <returns>The parsed constant node.</returns>
        private static ConstantNode ParseTypedLiteral(Type targetType, string targetTypeName, ExpressionToken token)
        {
            object literalValue;

            if (!LiteralParser.ForExpressions.TryParseLiteral(targetType, token.Text, out literalValue))
            {
                string message = Strings.RequestQueryParser_UnrecognizedLiteral(targetTypeName, token.Text);
                throw DataServiceException.CreateSyntaxError(message);
            }

            return(new ConstantNode(literalValue, token.Text));
        }
        /// <summary>
        /// Tries to create a <see cref="ConstantNode"/> for the given token if it represents a literal.
        /// </summary>
        /// <param name="token">The token.</param>
        /// <param name="node">The node, if one was created.</param>
        /// <returns>Whether or not the token represented a literal.</returns>
        internal static bool TryCreateLiteral(ExpressionToken token, out ConstantNode node)
        {
            switch (token.Kind)
            {
                case ExpressionTokenKind.NullLiteral:
                    node = new ConstantNode(null);
                    break;

                case ExpressionTokenKind.BooleanLiteral:
                    node = ParseTypedLiteral(typeof(bool), XmlConstants.EdmBooleanTypeName, token);
                    break;

                case ExpressionTokenKind.DecimalLiteral:
                    node = ParseTypedLiteral(typeof(decimal), XmlConstants.EdmDecimalTypeName, token);
                    break;

                case ExpressionTokenKind.StringLiteral:
                    node = ParseTypedLiteral(typeof(string), XmlConstants.EdmStringTypeName, token);
                    break;

                case ExpressionTokenKind.Int64Literal:
                    node = ParseTypedLiteral(typeof(Int64), XmlConstants.EdmInt64TypeName, token);
                    break;

                case ExpressionTokenKind.IntegerLiteral:
                    node = ParseTypedLiteral(typeof(Int32), XmlConstants.EdmInt32TypeName, token);
                    break;

                case ExpressionTokenKind.DoubleLiteral:
                    node = ParseTypedLiteral(typeof(double), XmlConstants.EdmDoubleTypeName, token);
                    break;

                case ExpressionTokenKind.SingleLiteral:
                    node = ParseTypedLiteral(typeof(Single), XmlConstants.EdmSingleTypeName, token);
                    break;

                case ExpressionTokenKind.GuidLiteral:
                    node = ParseTypedLiteral(typeof(Guid), XmlConstants.EdmGuidTypeName, token);
                    break;

                case ExpressionTokenKind.BinaryLiteral:
                    node = ParseTypedLiteral(typeof(byte[]), XmlConstants.EdmBinaryTypeName, token);
                    break;

                case ExpressionTokenKind.DurationLiteral:
                    node = ParseTypedLiteral(typeof(TimeSpan), XmlConstants.EdmDurationTypeName, token);
                    break;

                case ExpressionTokenKind.DateTimeOffsetLiteral:
                    node = ParseTypedLiteral(typeof(DateTimeOffset), XmlConstants.EdmDateTimeOffsetTypeName, token);
                    break;

                case ExpressionTokenKind.GeographylLiteral:
                    node = ParseTypedLiteral(typeof(Geography), XmlConstants.EdmGeographyTypeName, token);
                    break;

                case ExpressionTokenKind.GeometryLiteral:
                    node = ParseTypedLiteral(typeof(Geometry), XmlConstants.EdmGeometryTypeName, token);
                    break;

                default:
                    node = null;
                    return false;
            }

            Debug.Assert(token.IsLiteral, "Token must be a value.");
            return true;
        }
        /// <summary>
        /// Parses the given token into a constant node of the given target type.
        /// </summary>
        /// <param name="targetType">The tarket type.</param>
        /// <param name="targetTypeName">The target type name.</param>
        /// <param name="token">The token to parse.</param>
        /// <returns>The parsed constant node.</returns>
        private static ConstantNode ParseTypedLiteral(Type targetType, string targetTypeName, ExpressionToken token)
        {
            object literalValue;
            if (!LiteralParser.ForExpressions.TryParseLiteral(targetType, token.Text, out literalValue))
            {
                string message = Strings.RequestQueryParser_UnrecognizedLiteral(targetTypeName, token.Text);
                throw DataServiceException.CreateSyntaxError(message);
            }

            return new ConstantNode(literalValue, token.Text);
        }