Esempio n. 1
0
 /// <summary>Whether the specified token identifier is a numeric literal.</summary>
 /// <param name="id">Token to check.</param>
 /// <returns>true if it's a numeric literal; false otherwise.</returns>
 internal static bool IsNumeric(ExpressionTokenKind id)
 {
     return
         id == ExpressionTokenKind.IntegerLiteral || id == ExpressionTokenKind.DecimalLiteral ||
         id == ExpressionTokenKind.DoubleLiteral || id == ExpressionTokenKind.Int64Literal ||
         id == ExpressionTokenKind.SingleLiteral;
 }
Esempio n. 2
0
        /// <summary>
        /// Returns whether the <paramref name="tokenKind"/> is a primitive literal type:
        /// Binary, Boolean, DateTime, Decimal, Double, Guid, In64, Integer, Null, Single, or String.
        /// Internal for test use only
        /// </summary>
        /// <param name="tokenKind">InternalKind of token.</param>
        /// <returns>Whether the <paramref name="tokenKind"/> is a literal type.</returns>
        internal static Boolean IsLiteralType(this ExpressionTokenKind tokenKind)
        {
            switch (tokenKind)
            {
            case ExpressionTokenKind.BinaryLiteral:
            case ExpressionTokenKind.BooleanLiteral:
            case ExpressionTokenKind.DateTimeLiteral:
            case ExpressionTokenKind.DecimalLiteral:
            case ExpressionTokenKind.DoubleLiteral:
            case ExpressionTokenKind.GuidLiteral:
            case ExpressionTokenKind.Int64Literal:
            case ExpressionTokenKind.IntegerLiteral:
            case ExpressionTokenKind.NullLiteral:
            case ExpressionTokenKind.SingleLiteral:
            case ExpressionTokenKind.StringLiteral:
            case ExpressionTokenKind.TimeOfDayLiteral:
            case ExpressionTokenKind.DateLiteral:
            case ExpressionTokenKind.DateTimeOffsetLiteral:
            case ExpressionTokenKind.DurationLiteral:
            case ExpressionTokenKind.GeographyLiteral:
            case ExpressionTokenKind.GeometryLiteral:
                return(true);

            default:
                return(false);
            }
        }
Esempio n. 3
0
 /// <summary>Validates the current token is of the specified kind.</summary>
 /// <param name="t">Expected token kind.</param>
 internal void ValidateToken(ExpressionTokenKind t)
 {
     if (this.token.Kind != t)
     {
         throw ParseError(ODataErrorStrings.ExpressionLexer_SyntaxError(this.textPos, this.Text));
     }
 }
 /// <summary>Whether the specified token identifier is a numeric literal.</summary>
 /// <param name="id">Token to check.</param>
 /// <returns>true if it's a numeric literal; false otherwise.</returns>
 internal static bool IsNumeric(ExpressionTokenKind id)
 {
     return
         (id == ExpressionTokenKind.IntegerLiteral || id == ExpressionTokenKind.DecimalLiteral ||
          id == ExpressionTokenKind.DoubleLiteral || id == ExpressionTokenKind.Int64Literal ||
          id == ExpressionTokenKind.SingleLiteral);
 }
Esempio n. 5
0
 /// <summary>Validates the current token is of the specified kind.</summary>
 /// <param name="t">Expected token kind.</param>
 internal void ValidateToken(ExpressionTokenKind t)
 {
     if (this.token.Kind != t)
     {
         throw ParseError(Strings.RequestQueryParser_SyntaxError);
     }
 }
Esempio n. 6
0
 /// <summary>Validates the current token is of the specified kind.</summary>
 /// <param name="t">Expected token kind.</param>
 internal void ValidateId(ExpressionTokenKind t)
 {
     if (this.Kind != t)
     {
         throw DataServiceException.CreateSyntaxError(Strings.RequestQueryParser_SyntaxError);
     }
 }
Esempio n. 7
0
 internal static bool IsNumeric(ExpressionTokenKind id)
 {
     if (((id != ExpressionTokenKind.IntegerLiteral) && (id != ExpressionTokenKind.DecimalLiteral)) && ((id != ExpressionTokenKind.DoubleLiteral) && (id != ExpressionTokenKind.Int64Literal)))
     {
         return(id == ExpressionTokenKind.SingleLiteral);
     }
     return(true);
 }
Esempio n. 8
0
        /// <summary>Validates the current token is of the specified kind.</summary>
        /// <param name="t">Expected token kind.</param>
        internal void ValidateToken(ExpressionTokenKind t)
        {
            DebugUtils.CheckNoExternalCallers();

            if (this.token.Kind != t)
            {
                throw ParseError(ODataErrorStrings.ExpressionLexer_SyntaxError(this.textPos, this.text));
            }
        }
Esempio n. 9
0
        /// <summary>Whether the specified token identifier is a numeric literal.</summary>
        /// <param name="id">Token to check.</param>
        /// <returns>true if it's a numeric literal; false otherwise.</returns>
        internal static bool IsNumeric(ExpressionTokenKind id)
        {
            DebugUtils.CheckNoExternalCallers();

            return
                (id == ExpressionTokenKind.IntegerLiteral || id == ExpressionTokenKind.DecimalLiteral ||
                 id == ExpressionTokenKind.DoubleLiteral || id == ExpressionTokenKind.Int64Literal ||
                 id == ExpressionTokenKind.SingleLiteral);
        }
Esempio n. 10
0
        /// <summary>
        /// Tries to parse a collection of function parameters. Allows path and filter to share the core algorithm while representing parameters differently.
        /// </summary>
        /// <param name="lexer">The lexer to read from.</param>
        /// <param name="endTokenKind">The token kind that marks the end of the parameters.</param>
        /// <param name="splitParameters">The parameters if they were successfully split.</param>
        /// <returns>Whether the parameters could be split.</returns>
        private static bool TrySplitFunctionParameters(this ExpressionLexer lexer, ExpressionTokenKind endTokenKind, out ICollection <FunctionParameterToken> splitParameters)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(lexer != null, "lexer != null");

            var parameters = new List <FunctionParameterToken>();

            splitParameters = parameters;

            ExpressionToken currentToken = lexer.CurrentToken;

            if (currentToken.Kind == endTokenKind)
            {
                return(true);
            }

            if (currentToken.Kind != ExpressionTokenKind.Identifier || lexer.PeekNextToken().Kind != ExpressionTokenKind.Equal)
            {
                return(false);
            }

            while (currentToken.Kind != endTokenKind)
            {
                lexer.ValidateToken(ExpressionTokenKind.Identifier);
                string identifier = lexer.CurrentToken.GetIdentifier();
                lexer.NextToken();

                lexer.ValidateToken(ExpressionTokenKind.Equal);
                lexer.NextToken();

                QueryToken parameterValue;
                if (!TryCreateParameterValueToken(lexer.CurrentToken, out parameterValue))
                {
                    throw new ODataException(ODataErrorStrings.ExpressionLexer_SyntaxError(lexer.Position, lexer.ExpressionText));
                }

                parameters.Add(new FunctionParameterToken(identifier, parameterValue));

                // Read the next parameterToken. We should be at the end, or find
                // we have a comma followed by something.
                lexer.NextToken();
                currentToken = lexer.CurrentToken;
                if (currentToken.Kind == ExpressionTokenKind.Comma)
                {
                    lexer.NextToken();
                    currentToken = lexer.CurrentToken;
                    if (currentToken.Kind == endTokenKind)
                    {
                        // Trailing comma.
                        throw new ODataException(ODataErrorStrings.ExpressionLexer_SyntaxError(lexer.Position, lexer.ExpressionText));
                    }
                }
            }

            return(true);
        }
Esempio n. 11
0
        /// <summary>Handles lexemes that are formed by an identifier followed by a quoted string.</summary>
        /// <remarks>This method modified the token field as necessary.</remarks>
        private void HandleTypePrefixedLiterals()
        {
            ExpressionTokenKind id = this.token.Kind;

            if (id != ExpressionTokenKind.Identifier)
            {
                return;
            }

            bool quoteFollows = this.ch == '\'';

            if (!quoteFollows)
            {
                return;
            }

            string tokenText = this.token.Text;

            if (String.Equals(tokenText, XmlConstants.LiteralPrefixBinary, StringComparison.OrdinalIgnoreCase) || tokenText == "X" || tokenText == "x")
            {
                id = ExpressionTokenKind.BinaryLiteral;
            }
            else if (String.Equals(tokenText, XmlConstants.LiteralPrefixGeography, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.GeographylLiteral;
            }
            else if (String.Equals(tokenText, XmlConstants.LiteralPrefixGeometry, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.GeometryLiteral;
            }
            else if (String.Equals(tokenText, XmlConstants.LiteralPrefixDuration, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.DurationLiteral;
            }
            else
            {
                return;
            }

            int tokenPos = this.token.Position;

            do
            {
                this.NextChar();
            }while (this.ch.HasValue && this.ch != '\'');

            if (this.ch == null)
            {
                throw ParseError(Strings.RequestQueryParser_UnterminatedLiteral(this.text));
            }

            this.NextChar();
            this.token.Kind = id;
            this.token.Text = this.text.Substring(tokenPos, this.textPos - tokenPos);
        }
Esempio n. 12
0
        internal static IEdmTypeReference GetLiteralEdmTypeReference(ExpressionTokenKind tokenKind)
        {
            switch (tokenKind)
            {
            case ExpressionTokenKind.BooleanLiteral:
                return(EdmCoreModel.Instance.GetBoolean(false));

            case ExpressionTokenKind.DecimalLiteral:
                return(EdmCoreModel.Instance.GetDecimal(false));

            case ExpressionTokenKind.StringLiteral:
                return(EdmCoreModel.Instance.GetString(true));

            case ExpressionTokenKind.Int64Literal:
                return(EdmCoreModel.Instance.GetInt64(false));

            case ExpressionTokenKind.IntegerLiteral:
                return(EdmCoreModel.Instance.GetInt32(false));

            case ExpressionTokenKind.DoubleLiteral:
                return(EdmCoreModel.Instance.GetDouble(false));

            case ExpressionTokenKind.SingleLiteral:
                return(EdmCoreModel.Instance.GetSingle(false));

            case ExpressionTokenKind.GuidLiteral:
                return(EdmCoreModel.Instance.GetGuid(false));

            case ExpressionTokenKind.BinaryLiteral:
                return(EdmCoreModel.Instance.GetBinary(true));

            case ExpressionTokenKind.DateLiteral:
                return(EdmCoreModel.Instance.GetDate(false));

            case ExpressionTokenKind.DateTimeOffsetLiteral:
                return(EdmCoreModel.Instance.GetDateTimeOffset(false));

            case ExpressionTokenKind.DurationLiteral:
                return(EdmCoreModel.Instance.GetTemporal(EdmPrimitiveTypeKind.Duration, false));

            case ExpressionTokenKind.GeographyLiteral:
                return(EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.Geography, false));

            case ExpressionTokenKind.GeometryLiteral:
                return(EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.Geometry, false));

            case ExpressionTokenKind.QuotedLiteral:
                return(EdmCoreModel.Instance.GetString(true));

            case ExpressionTokenKind.TimeOfDayLiteral:
                return(EdmCoreModel.Instance.GetTimeOfDay(false));
            }

            return(null);
        }
Esempio n. 13
0
        /// <summary>
        /// Standard Constructor (all types except operators)
        /// </summary>
        public ExpressionToken(string name, ExpressionTokenKind kind)
        {
            if (kind == ExpressionTokenKind.Operator)
            {
                throw new InvalidOperationException("Priority must be specified for an operator.");
            }

            Name     = name;
            Priority = 0;
            Kind     = kind;
        }
Esempio n. 14
0
        /// <summary>
        /// Expand the token selection if the next token matches the input token
        /// </summary>
        /// <param name="id">the list of token id to match</param>
        /// <returns>true if matched</returns>
        private bool MoveNextWhenMatch(ExpressionTokenKind id)
        {
            ExpressionToken next = this.PeekNextToken();

            if (id == next.Kind)
            {
                this.NextToken();
                return(true);
            }

            return(false);
        }
Esempio n. 15
0
        /// <summary>Reads a $select clause.</summary>
        /// <param name="value">Value to read.</param>
        /// <param name="dataServiceProviderWrapper">The provider wrapper for the service.</param>
        /// <returns>A list of paths, each of which is a list of identifiers.</returns>
        private static IList <IList <string> > SplitSelect(string value, DataServiceProviderWrapper dataServiceProviderWrapper)
        {
            Debug.Assert(!String.IsNullOrEmpty(value), "!String.IsNullOrEmpty(value)");

            List <IList <string> > result      = new List <IList <string> >();
            List <string>          currentPath = null;
            ExpressionLexer        lexer       = new ExpressionLexer(value);

            while (lexer.CurrentToken.Kind != ExpressionTokenKind.End)
            {
                string identifier;
                bool   lastSegment = false;
                if (lexer.CurrentToken.Kind == ExpressionTokenKind.Star)
                {
                    identifier = lexer.CurrentToken.Text;
                    lexer.NextToken();
                    lastSegment = true;
                }
                else
                {
                    identifier = lexer.ReadDottedIdentifier(true /*allowEndWithDotStar*/);
                    bool nameIsContainerQualifed;
                    if (dataServiceProviderWrapper.GetNameFromContainerQualifiedName(identifier, out nameIsContainerQualifed) == "*")
                    {
                        lastSegment = true;
                    }
                }

                if (currentPath == null)
                {
                    currentPath = new List <string>();
                    result.Add(currentPath);
                }

                currentPath.Add(identifier);

                // Check whether we're at the end, whether we're drilling in,
                // or whether we're finishing with this path.
                ExpressionTokenKind tokenId = lexer.CurrentToken.Kind;
                if (tokenId != ExpressionTokenKind.End)
                {
                    if (lastSegment || tokenId != ExpressionTokenKind.Slash)
                    {
                        lexer.ValidateToken(ExpressionTokenKind.Comma);
                        currentPath = null;
                    }

                    lexer.NextToken();
                }
            }

            return(result);
        }
Esempio n. 16
0
        /// <summary>Handles lexemes that are formed by an identifier followed by a quoted string.</summary>
        /// <remarks>This method modified the token field as necessary.</remarks>
        private void HandleTypePrefixedLiterals()
        {
            ExpressionTokenKind id = this.token.Kind;

            if (id != ExpressionTokenKind.Identifier)
            {
                return;
            }

            bool quoteFollows = this.ch == '\'';

            if (!quoteFollows)
            {
                return;
            }

            string tokenText = this.token.Text;

            if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixDateTime, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.DateTimeLiteral;
            }
            else if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixGuid, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.GuidLiteral;
            }
            else if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixBinary, StringComparison.OrdinalIgnoreCase) ||
                     String.Equals(tokenText, ExpressionConstants.LiteralPrefixShortBinary, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.BinaryLiteral;
            }
            else
            {
                return;
            }

            int tokenPos = this.token.Position;

            do
            {
                this.NextChar();
            }while (this.ch != '\0' && this.ch != '\'');

            if (this.ch == '\0')
            {
                throw ParseError(Strings.ExpressionLexer_UnterminatedLiteral(this.textPos, this.text));
            }

            this.NextChar();
            this.token.Kind = id;
            this.token.Text = this.text.Substring(tokenPos, this.textPos - tokenPos);
        }
Esempio n. 17
0
        /// <summary>
        /// Parses identifiers which have been recognizes as function calls.
        /// </summary>
        /// <returns>The lexical token representing the expression.</returns>
        private QueryToken ParseIdentifierAsFunction()
        {
            ExpressionToken functionToken = this.lexer.CurrentToken;

            Debug.Assert(functionToken.Kind == ExpressionTokenKind.Identifier, "Only identifier tokens can be treated as function calls.");
            string funcName = this.lexer.CurrentToken.GetIdentifier();

            this.lexer.NextToken();
            ExpressionTokenKind splitToken = funcName == "any" ? ExpressionTokenKind.Colon : ExpressionTokenKind.Comma;

            QueryToken[] arguments = this.ParseArgumentList(splitToken);

            return(new FunctionCallQueryToken(functionToken.Text, arguments));
        }
        /// <summary>
        /// Tries to parse a collection of function parameters. Allows path and filter to share the core algorithm while representing parameters differently.
        /// </summary>
        /// <param name="parser">The UriQueryExpressionParser to read from.</param>
        /// <param name="endTokenKind">The token kind that marks the end of the parameters.</param>
        /// <param name="splitParameters">The parameters if they were successfully split.</param>
        /// <returns>Whether the parameters could be split.</returns>
        private static bool TrySplitOperationParameters(this UriQueryExpressionParser parser, ExpressionTokenKind endTokenKind, out ICollection<FunctionParameterToken> splitParameters)
        {
            Debug.Assert(parser != null, "parser != null");
            var lexer = parser.Lexer;
            var parameters = new List<FunctionParameterToken>();
            splitParameters = parameters;

            ExpressionToken currentToken = lexer.CurrentToken;
            if (currentToken.Kind == endTokenKind)
            {
                return true;
            }

            if (currentToken.Kind != ExpressionTokenKind.Identifier || lexer.PeekNextToken().Kind != ExpressionTokenKind.Equal)
            {
                return false;
            }

            while (currentToken.Kind != endTokenKind)
            {
                lexer.ValidateToken(ExpressionTokenKind.Identifier);
                string identifier = lexer.CurrentToken.GetIdentifier();
                lexer.NextToken();

                lexer.ValidateToken(ExpressionTokenKind.Equal);
                lexer.NextToken();

                // the below UriQueryExpressionParser.ParseExpression() is able to parse common expression per ABNF:
                //      functionExprParameter  = parameterName EQ ( parameterAlias / parameterValue )
                //      parameterValue = arrayOrObject
                //                       / commonExpr
                QueryToken parameterValue = parser.ParseExpression();
                parameters.Add(new FunctionParameterToken(identifier, parameterValue));

                // the above parser.ParseExpression() already moves to the next token, now get CurrentToken checking a comma followed by something
                currentToken = lexer.CurrentToken;
                if (currentToken.Kind == ExpressionTokenKind.Comma)
                {
                    lexer.NextToken();
                    currentToken = lexer.CurrentToken;
                    if (currentToken.Kind == endTokenKind)
                    {
                        // Trailing comma.
                        throw new ODataException(ODataErrorStrings.ExpressionLexer_SyntaxError(lexer.Position, lexer.ExpressionText));
                    }
                }
            }

            return true;
        }
Esempio n. 19
0
        /// <summary>
        /// Parses argument lists.
        /// </summary>
        /// <param name="splitToken">The token to split the argument list by.</param>
        /// <returns>The lexical tokens representing the arguments.</returns>
        private QueryToken[] ParseArgumentList(ExpressionTokenKind splitToken)
        {
            if (this.lexer.CurrentToken.Kind != ExpressionTokenKind.OpenParen)
            {
                throw ParseError(Strings.UriQueryExpressionParser_OpenParenExpected(this.lexer.CurrentToken.Position, this.lexer.ExpressionText));
            }

            this.lexer.NextToken();
            QueryToken[] arguments = this.lexer.CurrentToken.Kind != ExpressionTokenKind.CloseParen ? this.ParseArguments(splitToken) : QueryToken.EmptyTokens;
            if (this.lexer.CurrentToken.Kind != ExpressionTokenKind.CloseParen)
            {
                throw ParseError(Strings.UriQueryExpressionParser_CloseParenOrCommaExpected(this.lexer.CurrentToken.Position, this.lexer.ExpressionText));
            }

            this.lexer.NextToken();
            return(arguments);
        }
Esempio n. 20
0
        /// <summary>
        /// Parses comma-separated arguments.
        /// </summary>
        /// <param name="splitToken">The token to split the argument list by.</param>
        /// <returns>The lexical tokens representing the arguments.</returns>
        private QueryToken[] ParseArguments(ExpressionTokenKind splitToken)
        {
            List <QueryToken> argList = new List <QueryToken>();

            while (true)
            {
                argList.Add(this.ParseExpression());
                if (this.lexer.CurrentToken.Kind != splitToken)
                {
                    break;
                }

                this.lexer.NextToken();
            }

            return(argList.ToArray());
        }
Esempio n. 21
0
        /// <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()
        {
            DebugUtils.CheckNoExternalCallers();

            // 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 == null ? (char?)null : this.ch.Value;
            ExpressionToken savedToken    = this.token;
            bool            savedIgnoreWs = this.ignoreWhitespace;

            this.ignoreWhitespace = false;

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

            while (this.MoveNextWhenMatch(ExpressionTokenKind.Dot) && this.MoveNextWhenMatch(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);
        }
Esempio n. 22
0
 private static bool IsLiteralType(ExpressionTokenKind tokenKind)
 {
     switch (tokenKind)
     {
     case ExpressionTokenKind.NullLiteral:
     case ExpressionTokenKind.BooleanLiteral:
     case ExpressionTokenKind.StringLiteral:
     case ExpressionTokenKind.IntegerLiteral:
     case ExpressionTokenKind.Int64Literal:
     case ExpressionTokenKind.SingleLiteral:
     case ExpressionTokenKind.DateTimeLiteral:
     case ExpressionTokenKind.DateTimeOffsetLiteral:
     case ExpressionTokenKind.TimeLiteral:
     case ExpressionTokenKind.DecimalLiteral:
     case ExpressionTokenKind.DoubleLiteral:
     case ExpressionTokenKind.GuidLiteral:
     case ExpressionTokenKind.BinaryLiteral:
     case ExpressionTokenKind.GeographyLiteral:
     case ExpressionTokenKind.GeometryLiteral:
         return(true);
     }
     return(false);
 }
Esempio n. 23
0
        /// <summary>Validates the current token is of the specified kind.</summary>
        /// <param name="t">Expected token kind.</param>
        internal void ValidateToken(ExpressionTokenKind t)
        {
            DebugUtils.CheckNoExternalCallers();

            if (this.token.Kind != t)
            {
                throw ParseError(Strings.ExpressionLexer_SyntaxError(this.textPos, this.text));
            }
        }
Esempio n. 24
0
 /// <summary>Validates the current token is of the specified kind.</summary>
 /// <param name="t">Expected token kind.</param>
 internal void ValidateId(ExpressionTokenKind t)
 {
     if (this.Kind != t)
     {
         throw DataServiceException.CreateSyntaxError(Strings.RequestQueryParser_SyntaxError);
     }
 }
Esempio n. 25
0
 internal void SetCustomEdmTypeLiteral(IEdmTypeReference edmType)
 {
     this.Kind           = ExpressionTokenKind.CustomTypeLiteral;
     this.LiteralEdmType = edmType;
 }
        /// <summary>
        /// Parses comma-separated arguments.
        /// </summary>
        /// <param name="splitToken">The token to split the argument list by.</param>
        /// <returns>The lexical tokens representing the arguments.</returns>
        private QueryToken[] ParseArguments(ExpressionTokenKind splitToken)
        {
            List<QueryToken> argList = new List<QueryToken>();
            while (true)
            {
                argList.Add(this.ParseExpression());
                if (this.lexer.CurrentToken.Kind != splitToken)
                {
                    break;
                }

                this.lexer.NextToken();
            }

            return argList.ToArray();
        }
Esempio n. 27
0
 private static bool IsLiteralType(ExpressionTokenKind tokenKind)
 {
     switch (tokenKind)
     {
         case ExpressionTokenKind.NullLiteral:
         case ExpressionTokenKind.BooleanLiteral:
         case ExpressionTokenKind.StringLiteral:
         case ExpressionTokenKind.IntegerLiteral:
         case ExpressionTokenKind.Int64Literal:
         case ExpressionTokenKind.SingleLiteral:
         case ExpressionTokenKind.DateTimeLiteral:
         case ExpressionTokenKind.DateTimeOffsetLiteral:
         case ExpressionTokenKind.TimeLiteral:
         case ExpressionTokenKind.DecimalLiteral:
         case ExpressionTokenKind.DoubleLiteral:
         case ExpressionTokenKind.GuidLiteral:
         case ExpressionTokenKind.BinaryLiteral:
         case ExpressionTokenKind.GeographyLiteral:
         case ExpressionTokenKind.GeometryLiteral:
             return true;
     }
     return false;
 }
Esempio n. 28
0
 internal static bool IsNumeric(ExpressionTokenKind id)
 {
     if (((id != ExpressionTokenKind.IntegerLiteral) && (id != ExpressionTokenKind.DecimalLiteral)) && ((id != ExpressionTokenKind.DoubleLiteral) && (id != ExpressionTokenKind.Int64Literal)))
     {
         return (id == ExpressionTokenKind.SingleLiteral);
     }
     return true;
 }
Esempio n. 29
0
        /// <summary>
        /// Expand the token selection if the next token matches the input token
        /// </summary>
        /// <param name="id">the list of token id to match</param>
        /// <returns>true if matched</returns>
        private bool ExpandWhenMatch(ExpressionTokenKind id)
        {
            ExpressionToken next = this.PeekNextToken();

            if (id == next.Kind)
            {
                this.NextToken();
                return true;
            }

            return false;
        }
Esempio n. 30
0
        /// <summary>Handles lexemes that are formed by an identifier followed by a quoted string.</summary>
        /// <remarks>This method modified the token field as necessary.</remarks>
        private void HandleTypePrefixedLiterals()
        {
            ExpressionTokenKind id = this.token.Kind;

            if (id != ExpressionTokenKind.Identifier)
            {
                return;
            }

            bool quoteFollows = this.ch == '\'';

            if (!quoteFollows)
            {
                return;
            }

            string tokenText = this.token.Text;

            if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixDuration, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.DurationLiteral;
            }
            else if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixBinary, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.BinaryLiteral;
            }
            else if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixGeography, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.GeographyLiteral;
            }
            else if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixGeometry, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.GeometryLiteral;
            }
            else if (string.Equals(tokenText, ExpressionConstants.KeywordNull, StringComparison.OrdinalIgnoreCase))
            {
                // typed null literals are not supported.
                throw ParseError(ODataErrorStrings.ExpressionLexer_SyntaxError(this.textPos, this.Text));
            }
            else
            {
                // treat as quoted literal
                id = ExpressionTokenKind.QuotedLiteral;
            }

            int tokenPos = this.token.Position;

            do
            {
                this.NextChar();
            }while (this.ch.HasValue && this.ch != '\'');

            if (this.ch == null)
            {
                throw ParseError(ODataErrorStrings.ExpressionLexer_UnterminatedLiteral(this.textPos, this.Text));
            }

            this.NextChar();
            this.token.Kind = id;
            this.token.Text = this.Text.Substring(tokenPos, this.textPos - tokenPos);
        }
        /// <summary>
        /// Tries to parse a collection of function parameters. Allows path and filter to share the core algorithm while representing parameters differently.
        /// </summary>
        /// <param name="parser">The UriQueryExpressionParser to read from.</param>
        /// <param name="endTokenKind">The token kind that marks the end of the parameters.</param>
        /// <param name="splitParameters">The parameters if they were successfully split.</param>
        /// <returns>Whether the parameters could be split.</returns>
        private static bool TrySplitOperationParameters(this UriQueryExpressionParser parser, ExpressionTokenKind endTokenKind, out ICollection <FunctionParameterToken> splitParameters)
        {
            Debug.Assert(parser != null, "parser != null");
            var lexer      = parser.Lexer;
            var parameters = new List <FunctionParameterToken>();

            splitParameters = parameters;

            ExpressionToken currentToken = lexer.CurrentToken;

            if (currentToken.Kind == endTokenKind)
            {
                return(true);
            }

            if (currentToken.Kind != ExpressionTokenKind.Identifier || lexer.PeekNextToken().Kind != ExpressionTokenKind.Equal)
            {
                return(false);
            }

            while (currentToken.Kind != endTokenKind)
            {
                lexer.ValidateToken(ExpressionTokenKind.Identifier);
                string identifier = lexer.CurrentToken.GetIdentifier();
                lexer.NextToken();

                lexer.ValidateToken(ExpressionTokenKind.Equal);
                lexer.NextToken();

                // the below UriQueryExpressionParser.ParseExpression() is able to parse common expression per ABNF:
                //      functionExprParameter  = parameterName EQ ( parameterAlias / parameterValue )
                //      parameterValue = arrayOrObject
                //                       / commonExpr
                QueryToken parameterValue = parser.ParseExpression();
                parameters.Add(new FunctionParameterToken(identifier, parameterValue));

                // the above parser.ParseExpression() already moves to the next token, now get CurrentToken checking a comma followed by something
                currentToken = lexer.CurrentToken;
                if (currentToken.Kind == ExpressionTokenKind.Comma)
                {
                    lexer.NextToken();
                    currentToken = lexer.CurrentToken;
                    if (currentToken.Kind == endTokenKind)
                    {
                        // Trailing comma.
                        throw new ODataException(ODataErrorStrings.ExpressionLexer_SyntaxError(lexer.Position, lexer.ExpressionText));
                    }
                }
            }

            return(true);
        }
Esempio n. 32
0
        /// <summary>
        /// Makes best guess on numeric string without trailing letter like L, F, M, D
        /// </summary>
        /// <param name="numericStr">The numeric string.</param>
        /// <param name="guessedKind">The possbile kind (IntegerLiteral or DoubleLiteral) from ParseFromDigit() method.</param>
        /// <returns>A more accurate ExpressionTokenKind</returns>
        private static ExpressionTokenKind MakeBestGuessOnNoSuffixStr(string numericStr, ExpressionTokenKind guessedKind)
        {
            // no suffix, so
            // (1) make a best guess (note: later we support promoting each to later one: int32->int64->single->double->decimal).
            // look at value:       "2147483647" may be Int32/long, "2147483649" must be long.
            // look at precision:   "3258.67876576549" may be sinle/double/decimal, "3258.678765765489753678965390" must be decimal.
            // (2) then let MetadataUtilsCommon.CanConvertPrimitiveTypeTo() method does further promotion when knowing expected sematics type.
            int     tmpInt     = 0;
            long    tmpLong    = 0;
            float   tmpFloat   = 0;
            double  tmpDouble  = 0;
            decimal tmpDecimal = 0;

            if (guessedKind == ExpressionTokenKind.IntegerLiteral)
            {
                if (int.TryParse(numericStr, NumberStyles.Integer, CultureInfo.InvariantCulture, out tmpInt))
                {
                    return(ExpressionTokenKind.IntegerLiteral);
                }

                if (long.TryParse(numericStr, NumberStyles.Integer, CultureInfo.InvariantCulture, out tmpLong))
                {
                    return(ExpressionTokenKind.Int64Literal);
                }
            }

            bool canBeSingle  = float.TryParse(numericStr, NumberStyles.Float, CultureInfo.InvariantCulture, out tmpFloat);
            bool canBeDouble  = double.TryParse(numericStr, NumberStyles.Float, CultureInfo.InvariantCulture, out tmpDouble);
            bool canBeDecimal = decimal.TryParse(numericStr, NumberStyles.Integer | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out tmpDecimal);

            // 1. try high precision -> low precision
            if (canBeDouble && canBeDecimal)
            {
                decimal doubleToDecimalR;
                decimal doubleToDecimalN;

                // To keep the full precision of the current value, which if necessary is all 17 digits of precision supported by the Double type.
                bool doubleCanBeDecimalR = decimal.TryParse(tmpDouble.ToString("R", CultureInfo.InvariantCulture), NumberStyles.Float, CultureInfo.InvariantCulture, out doubleToDecimalR);

                // To cover the scientific notation case, such as 1e+19 in the tmpDouble
                bool doubleCanBeDecimalN = decimal.TryParse(tmpDouble.ToString("N29", CultureInfo.InvariantCulture), NumberStyles.Number, CultureInfo.InvariantCulture, out doubleToDecimalN);

                if ((doubleCanBeDecimalR && doubleToDecimalR != tmpDecimal) || (!doubleCanBeDecimalR && doubleCanBeDecimalN && doubleToDecimalN != tmpDecimal))
                {
                    // losing precision as double, so choose decimal
                    return(ExpressionTokenKind.DecimalLiteral);
                }
            }

            // here can't use normal casting like the above double VS decimal.
            // prevent losing precision in float -> double, e.g. (double)1.234f will be 1.2339999675750732d not 1.234d
            if (canBeSingle && canBeDouble && (double.Parse(tmpFloat.ToString("R", CultureInfo.InvariantCulture), CultureInfo.InvariantCulture) != tmpDouble))
            {
                // losing precision as single, so choose double
                return(ExpressionTokenKind.DoubleLiteral);
            }

            // 2. try most compatible -> least compatible
            if (canBeSingle)
            {
                return(ExpressionTokenKind.SingleLiteral);
            }

            if (canBeDouble)
            {
                return(ExpressionTokenKind.DoubleLiteral);
            }

            throw new ODataException(ODataErrorStrings.ExpressionLexer_InvalidNumericString(numericStr));
        }
Esempio n. 33
0
 /// <summary>Validates the current token is of the specified kind.</summary>
 /// <param name="t">Expected token kind.</param>
 internal void ValidateToken(ExpressionTokenKind t)
 {
     if (this.token.Kind != t)
     {
         throw ParseError(Strings.RequestQueryParser_SyntaxError);
     }
 }
Esempio n. 34
0
 private static void ValidateTokenKind(ExpressionLexer lexer, ExpressionTokenKind kind)
 {
     Assert.Equal(kind, lexer.CurrentToken.Kind);
     lexer.NextToken();
 }
Esempio n. 35
0
 /// <summary>
 /// Standard Constructor
 /// </summary>
 public ExpressionToken(string name, int priority, ExpressionTokenKind kind)
 {
     Name     = name;
     Priority = priority;
     Kind     = kind;
 }
        /// <summary>
        /// Parses argument lists.
        /// </summary>
        /// <param name="splitToken">The token to split the argument list by.</param>
        /// <returns>The lexical tokens representing the arguments.</returns>
        private QueryToken[] ParseArgumentList(ExpressionTokenKind splitToken)
        {
            if (this.lexer.CurrentToken.Kind != ExpressionTokenKind.OpenParen)
            {
                throw ParseError(Strings.UriQueryExpressionParser_OpenParenExpected(this.lexer.CurrentToken.Position, this.lexer.ExpressionText));
            }

            this.lexer.NextToken();
            QueryToken[] arguments = this.lexer.CurrentToken.Kind != ExpressionTokenKind.CloseParen ? this.ParseArguments(splitToken) : QueryToken.EmptyTokens;
            if (this.lexer.CurrentToken.Kind != ExpressionTokenKind.CloseParen)
            {
                throw ParseError(Strings.UriQueryExpressionParser_CloseParenOrCommaExpected(this.lexer.CurrentToken.Position, this.lexer.ExpressionText));
            }

            this.lexer.NextToken();
            return arguments;
        }
Esempio n. 37
0
 private static void ValidateTokenKind(ExpressionLexer lexer, ExpressionTokenKind kind)
 {
     lexer.CurrentToken.Kind.Should().Be(kind);
     lexer.NextToken();
 }
Esempio n. 38
0
        /// <summary>
        /// Makes best guess on numeric string without trailing letter like L, F, M, D.
        /// </summary>
        /// <param name="numericStr">numeric string</param>
        /// <param name="guessedKind">The possbile kind (IntegerLiteral or DoubleLiteral) from ParseFromDigit() method.</param>
        /// <returns>ExpressionTokenKind</returns>
        private ExpressionTokenKind MakeBestGuessOnNoSuffixStr(string numericStr, ExpressionTokenKind guessedKind)
        {
            // no suffix, so
            // (1) make a best guess (note: later we support promoting each to later one: int32->int64->single->double->decimal).
            // look at value:       "2147483647" may be Int32/long, "2147483649" must be long.
            // look at precision:   "3258.67876576549" may be sinle/double/decimal, "3258.678765765489753678965390" must be decimal.
            // (2) then let MetadataUtilsCommon.CanConvertPrimitiveTypeTo() method does further promotion when knowing expected sematics type.
            int     tmpInt     = 0;
            long    tmpLong    = 0;
            float   tmpFloat   = 0;
            double  tmpDouble  = 0;
            decimal tmpDecimal = 0;

            if (guessedKind == ExpressionTokenKind.IntegerLiteral)
            {
                if (int.TryParse(numericStr, out tmpInt))
                {
                    return(ExpressionTokenKind.IntegerLiteral);
                }

                if (long.TryParse(numericStr, out tmpLong))
                {
                    return(ExpressionTokenKind.Int64Literal);
                }
            }

            bool canBeSingle  = float.TryParse(numericStr, out tmpFloat);
            bool canBeDouble  = double.TryParse(numericStr, out tmpDouble);
            bool canBeDecimal = decimal.TryParse(numericStr, out tmpDecimal);

            // 1. try high precision -> low precision
            if (canBeDouble && canBeDecimal)
            {
                decimal doubleToDecimalR;
                decimal doubleToDecimalN;
                bool    doubleCanBeDecimalR = decimal.TryParse(tmpDouble.ToString("R", CultureInfo.InvariantCulture), out doubleToDecimalR);
                bool    doubleCanBeDecimalN = decimal.TryParse(tmpDouble.ToString("N29", CultureInfo.InvariantCulture), out doubleToDecimalN);
                if ((doubleCanBeDecimalR && doubleToDecimalR != tmpDecimal) || (!doubleCanBeDecimalR && doubleCanBeDecimalN && doubleToDecimalN != tmpDecimal))
                {
                    // losing precision as double, so choose decimal
                    return(ExpressionTokenKind.DecimalLiteral);
                }
            }

            // here can't use normal casting like the above double VS decimal.
            // e.g. for text "123.2", 123.2f should be == 123.2d, but normal casting (double)(123.2f) will return 123.19999694824219 thus becomes != 123.2d
            if (canBeSingle && canBeDouble && (double.Parse(tmpFloat.ToString("R", CultureInfo.InvariantCulture), CultureInfo.InvariantCulture) != tmpDouble))
            {
                // losing precision as single, so choose double
                return(ExpressionTokenKind.DoubleLiteral);
            }

            // 2. try most compatible -> least compatible
            if (canBeSingle)
            {
                return(ExpressionTokenKind.SingleLiteral);
            }

            if (canBeDouble)
            {
                return(ExpressionTokenKind.DoubleLiteral);
            }

            throw new Microsoft.OData.ODataException(Strings.RequestQueryParser_InvalidNumericString(numericStr));
        }
Esempio n. 39
0
        /// <summary>Whether the specified token identifier is a numeric literal.</summary>
        /// <param name="id">Token to check.</param>
        /// <returns>true if it's a numeric literal; false otherwise.</returns>
        internal static bool IsNumeric(ExpressionTokenKind id)
        {
            DebugUtils.CheckNoExternalCallers();

            return 
                id == ExpressionTokenKind.IntegerLiteral || id == ExpressionTokenKind.DecimalLiteral ||
                id == ExpressionTokenKind.DoubleLiteral || id == ExpressionTokenKind.Int64Literal ||
                id == ExpressionTokenKind.SingleLiteral;
        }
Esempio n. 40
0
 internal void ValidateToken(ExpressionTokenKind t)
 {
     if (this.token.Kind != t)
     {
         throw ParseError(Microsoft.Data.OData.Strings.ExpressionLexer_SyntaxError(this.textPos, this.text));
     }
 }
Esempio n. 41
0
        /// <summary>
        /// Makes best guess on numeric string without trailing letter like L, F, M, D.
        /// </summary>
        /// <param name="numericStr">numeric string</param>
        /// <param name="guessedKind">The possbile kind (IntegerLiteral or DoubleLiteral) from ParseFromDigit() method.</param>
        /// <returns>ExpressionTokenKind</returns>
        private ExpressionTokenKind MakeBestGuessOnNoSuffixStr(string numericStr, ExpressionTokenKind guessedKind)
        {
            // no suffix, so 
            // (1) make a best guess (note: later we support promoting each to later one: int32->int64->single->double->decimal).
            // look at value:       "2147483647" may be Int32/long, "2147483649" must be long.
            // look at precision:   "3258.67876576549" may be sinle/double/decimal, "3258.678765765489753678965390" must be decimal.
            // (2) then let MetadataUtilsCommon.CanConvertPrimitiveTypeTo() method does further promotion when knowing expected sematics type. 
            int tmpInt = 0;
            long tmpLong = 0;
            float tmpFloat = 0;
            double tmpDouble = 0;
            decimal tmpDecimal = 0;
            if (guessedKind == ExpressionTokenKind.IntegerLiteral)
            {
                if (int.TryParse(numericStr, out tmpInt))
                {
                    return ExpressionTokenKind.IntegerLiteral;
                }

                if (long.TryParse(numericStr, out tmpLong))
                {
                    return ExpressionTokenKind.Int64Literal;
                }
            }

            bool canBeSingle = float.TryParse(numericStr, out tmpFloat);
            bool canBeDouble = double.TryParse(numericStr, out tmpDouble);
            bool canBeDecimal = decimal.TryParse(numericStr, out tmpDecimal);

            // 1. try high precision -> low precision
            if (canBeDouble && canBeDecimal)
            {
                decimal doubleToDecimalR;
                decimal doubleToDecimalN;
                bool doubleCanBeDecimalR = decimal.TryParse(tmpDouble.ToString("R", CultureInfo.InvariantCulture), out doubleToDecimalR);
                bool doubleCanBeDecimalN = decimal.TryParse(tmpDouble.ToString("N29", CultureInfo.InvariantCulture), out doubleToDecimalN);
                if ((doubleCanBeDecimalR && doubleToDecimalR != tmpDecimal) || (!doubleCanBeDecimalR && doubleCanBeDecimalN && doubleToDecimalN != tmpDecimal))
                {
                    // losing precision as double, so choose decimal
                    return ExpressionTokenKind.DecimalLiteral;
                }
            }

            // here can't use normal casting like the above double VS decimal.
            // e.g. for text "123.2", 123.2f should be == 123.2d, but normal casting (double)(123.2f) will return 123.19999694824219 thus becomes != 123.2d
            if (canBeSingle && canBeDouble && (double.Parse(tmpFloat.ToString("R", CultureInfo.InvariantCulture), CultureInfo.InvariantCulture) != tmpDouble))
            {
                // losing precision as single, so choose double
                return ExpressionTokenKind.DoubleLiteral;
            }

            // 2. try most compatible -> least compatible
            if (canBeSingle)
            {
                return ExpressionTokenKind.SingleLiteral;
            }

            if (canBeDouble)
            {
                return ExpressionTokenKind.DoubleLiteral;
            }

            throw new Microsoft.OData.Core.ODataException(Strings.RequestQueryParser_InvalidNumericString(numericStr));
        }
Esempio n. 42
0
 private static void ValidateTokenKind(ExpressionLexer lexer, ExpressionTokenKind kind)
 {
     lexer.CurrentToken.Kind.Should().Be(kind);
     lexer.NextToken();
 }
Esempio n. 43
0
        internal static IEdmTypeReference GetLiteralEdmTypeReference(ExpressionTokenKind tokenKind)
        {
            switch (tokenKind)
            {
                case ExpressionTokenKind.BooleanLiteral:
                    return EdmCoreModel.Instance.GetBoolean(false);
                case ExpressionTokenKind.DecimalLiteral:
                    return EdmCoreModel.Instance.GetDecimal(false);
                case ExpressionTokenKind.StringLiteral:
                    return EdmCoreModel.Instance.GetString(true);
                case ExpressionTokenKind.Int64Literal:
                    return EdmCoreModel.Instance.GetInt64(false);
                case ExpressionTokenKind.IntegerLiteral:
                    return EdmCoreModel.Instance.GetInt32(false);
                case ExpressionTokenKind.DoubleLiteral:
                    return EdmCoreModel.Instance.GetDouble(false);
                case ExpressionTokenKind.SingleLiteral:
                    return EdmCoreModel.Instance.GetSingle(false);
                case ExpressionTokenKind.GuidLiteral:
                    return EdmCoreModel.Instance.GetGuid(false);
                case ExpressionTokenKind.BinaryLiteral:
                    return EdmCoreModel.Instance.GetBinary(true);
                case ExpressionTokenKind.DateLiteral:
                    return EdmCoreModel.Instance.GetDate(false);
                case ExpressionTokenKind.DateTimeOffsetLiteral:
                    return EdmCoreModel.Instance.GetDateTimeOffset(false);
                case ExpressionTokenKind.DurationLiteral:
                    return EdmCoreModel.Instance.GetTemporal(EdmPrimitiveTypeKind.Duration, false);
                case ExpressionTokenKind.GeographyLiteral:
                    return EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.Geography, false);
                case ExpressionTokenKind.GeometryLiteral:
                    return EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.Geometry, false);
                case ExpressionTokenKind.QuotedLiteral:
                    return EdmCoreModel.Instance.GetString(true);
                case ExpressionTokenKind.TimeOfDayLiteral:
                    return EdmCoreModel.Instance.GetTimeOfDay(false);
            }

            return null;
        }
Esempio n. 44
0
        /// <summary>Handles lexemes that are formed by an identifier followed by a quoted string.</summary>
        /// <remarks>This method modified the token field as necessary.</remarks>
        private void HandleTypePrefixedLiterals()
        {
            ExpressionTokenKind id = this.token.Kind;

            if (id != ExpressionTokenKind.Identifier)
            {
                return;
            }

            bool quoteFollows = this.ch == '\'';

            if (!quoteFollows)
            {
                return;
            }

            string tokenText = this.token.Text;

            if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixDateTime, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.DateTimeLiteral;
            }
            else if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixDateTimeOffset, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.DateTimeOffsetLiteral;
            }
            else if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixTime, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.TimeLiteral;
            }
            else if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixGuid, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.GuidLiteral;
            }
            else if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixBinary, StringComparison.OrdinalIgnoreCase) ||
                     String.Equals(tokenText, ExpressionConstants.LiteralPrefixShortBinary, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.BinaryLiteral;
            }
            else if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixGeography, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.GeographyLiteral;
            }
            else if (String.Equals(tokenText, ExpressionConstants.LiteralPrefixGeometry, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.GeometryLiteral;
            }
            else if (this.parsingFunctionParameters && string.Equals(tokenText, ExpressionConstants.KeywordNull, StringComparison.OrdinalIgnoreCase))
            {
                id = ExpressionTokenKind.NullLiteral;
            }
            else
            {
                return;
            }

            int tokenPos = this.token.Position;

            do
            {
                this.NextChar();
            }while (this.ch.HasValue && this.ch != '\'');

            if (this.ch == null)
            {
                throw ParseError(ODataErrorStrings.ExpressionLexer_UnterminatedLiteral(this.textPos, this.text));
            }

            this.NextChar();
            this.token.Kind = id;
            this.token.Text = this.text.Substring(tokenPos, this.textPos - tokenPos);
        }
Esempio n. 45
0
 internal void SetCustomEdmTypeLiteral(IEdmTypeReference edmType)
 {
     this.Kind = ExpressionTokenKind.CustomTypeLiteral;
     this.LiteralEdmType = edmType;
 }