public void ExpressionLexerShouldThrows() { // Arrange ExpressionLexer lexer = new ExpressionLexer("name='xzg"); // Act lexer.NextToken(); // move to '=' Action test = () => lexer.NextToken(); // test 'xzg ExceptionAssert.Throws <ODataException>(test, "There is an unterminated string literal at position 9 in 'name='xzg'."); }
/// <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); }
/// <summary>Attempts to parse nullable values (only positional values, no name-value pairs) from the specified text.</summary> /// <param name='text'>Text to parse (not null).</param> /// <param name='values'>After invocation, the parsed skiptoken/etag values as strings.</param> /// <returns> /// true if the given values were parsed; false if there was a /// syntactic error. /// </returns> /// <remarks> /// The returned collection contains only string values. They must be converted later. /// </remarks> internal static bool TryParseNullableTokens(string text, out IList <object> values) { Debug.Assert(text != null, "text != null"); List <object> positionalValues = new List <object>(); values = positionalValues; #if ODATALIB ExpressionLexer lexer = new ExpressionLexer(text, true, false); #else ExpressionLexer lexer = new ExpressionLexer(text); #endif ExpressionToken currentToken = lexer.CurrentToken; if (currentToken.Kind == ExpressionTokenKind.End) { return(true); } do { if (currentToken.IsLiteral) { // Positional value. positionalValues.Add(lexer.CurrentToken.Text); } else { return(false); } // Read the next token. 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 == ExpressionTokenKind.End) { // Trailing comma. return(false); } } }while (currentToken.Kind != ExpressionTokenKind.End); return(true); }
private static List <List <string> > ReadExpandOrSelect(string value, bool select, IDataService dataService) { List <List <string> > list = new List <List <string> >(); List <string> list2 = null; ExpressionLexer lexer = new ExpressionLexer(value); while (lexer.CurrentToken.Id != TokenId.End) { string text; bool flag = false; if (select && (lexer.CurrentToken.Id == TokenId.Star)) { text = lexer.CurrentToken.Text; lexer.NextToken(); flag = true; } else if (select) { bool flag2; text = lexer.ReadDottedIdentifier(true); if (dataService.Provider.GetNameFromContainerQualifiedName(text, out flag2) == "*") { flag = true; } } else { text = lexer.ReadDottedIdentifier(false); } if (list2 == null) { list2 = new List <string> { }; } list2.Add(text); TokenId id = lexer.CurrentToken.Id; if (id != TokenId.End) { if (flag || (id != TokenId.Slash)) { lexer.ValidateToken(TokenId.Comma); list2 = null; } lexer.NextToken(); } } return(list); }
public void ExpressionLexerCanParseEqualStartingExpression() { // Arrange ExpressionLexer lexer = new ExpressionLexer(" = abc"); // Act Assert.Equal(ExpressionTokenKind.Equal, lexer.CurrentToken.Kind); lexer.NextToken(); Assert.Equal(ExpressionTokenKind.Literal, lexer.CurrentToken.Kind); Assert.Equal("abc", lexer.CurrentToken.Text); Assert.Equal(3, lexer.CurrentToken.Position); lexer.NextToken(); Assert.Equal(ExpressionTokenKind.TextEnd, lexer.CurrentToken.Kind); }
public void ShouldThrowWhenIncorrectCharacterAtStart() { ExpressionLexer lexer = new ExpressionLexer("#$*@#", false, false); Action nextToken = () => lexer.NextToken(); nextToken.Throws <ODataException>(ODataErrorStrings.ExpressionLexer_InvalidCharacter("#", "0", "#$*@#")); }
/// <summary> /// Parses parameter alias into token. /// </summary> /// <param name="lexer">The lexer to use.</param> /// <returns>The parameter alias token.</returns> private static FunctionParameterAliasToken ParseParameterAlias(ExpressionLexer lexer) { Debug.Assert(lexer != null, "lexer != null"); FunctionParameterAliasToken ret = new FunctionParameterAliasToken(lexer.CurrentToken.Text); lexer.NextToken(); return(ret); }
public void ShouldOutputNextTokenWhenItExists() { ExpressionLexer lexer = new ExpressionLexer("5", false, false); ExpressionToken result = lexer.NextToken(); result.Kind.Should().Be(ExpressionTokenKind.IntegerLiteral); lexer.CurrentToken.Should().Be(result); result.Text.Should().Be("5"); }
public void AdvanceThroughBalancedParentheticalExpressionWorks() { ExpressionLexer lexer = new ExpressionLexer("(expression)next", moveToFirstToken: true, useSemicolonDelimeter: true, parsingFunctionParameters: false); string result = lexer.AdvanceThroughBalancedParentheticalExpression(); result.Should().Be("(expression)"); // TODO: the state of the lexer is weird right now, see note in AdvanceThroughBalancedParentheticalExpression. lexer.NextToken().Text.Should().Be("next"); }
/// <summary> /// Parses null literals. /// </summary> /// <param name="lexer">The lexer to use.</param> /// <returns>The literal token produced by building the given literal.</returns> private static LiteralToken ParseNullLiteral(ExpressionLexer lexer) { Debug.Assert(lexer != null, "lexer != null"); Debug.Assert(lexer.CurrentToken.Kind == ExpressionTokenKind.NullLiteral, "this.lexer.CurrentToken.InternalKind == ExpressionTokenKind.NullLiteral"); LiteralToken result = new LiteralToken(null, lexer.CurrentToken.Text); lexer.NextToken(); return(result); }
public void ExpressionLexerCanParseCommaStartingExpression() { // Arrange ExpressionLexer lexer = new ExpressionLexer(" , ,abc"); // Act Assert.Equal(ExpressionTokenKind.Comma, lexer.CurrentToken.Kind); // first , lexer.NextToken(); Assert.Equal(ExpressionTokenKind.Comma, lexer.CurrentToken.Kind); // second , lexer.NextToken(); Assert.Equal(ExpressionTokenKind.Literal, lexer.CurrentToken.Kind); Assert.Equal("abc", lexer.CurrentToken.Text); Assert.Equal(4, lexer.CurrentToken.Position); lexer.NextToken(); Assert.Equal(ExpressionTokenKind.TextEnd, lexer.CurrentToken.Kind); }
public void ShouldOutputNextTokenWhenItExists() { ExpressionLexer lexer = new ExpressionLexer("5", false, false); ExpressionToken result = lexer.NextToken(); Assert.Equal(ExpressionTokenKind.IntegerLiteral, result.Kind); Assert.Equal(result, lexer.CurrentToken); Assert.Equal("5", result.Text); }
private static void ValidateTokenSequence(string expression, bool parsingFunctionParameters, params ExpressionToken[] expectTokens) { ExpressionLexer l = new ExpressionLexer(expression, moveToFirstToken: true, useSemicolonDelimeter: false, parsingFunctionParameters: parsingFunctionParameters); for (int i = 0; i < expectTokens.Length; ++i) { Assert.Equal(expectTokens[i].Kind, l.CurrentToken.Kind); Assert.Equal(expectTokens[i].Text, l.CurrentToken.Text); l.NextToken(); } Assert.Equal(ExpressionTokenKind.End, l.CurrentToken.Kind); }
private void ValidateLexerException <T>(string expression, string message) where T : Exception { Action test = () => { ExpressionLexer l = new ExpressionLexer(expression); while (l.CurrentToken.Kind != ExpressionTokenKind.End) { l.NextToken(); } }; test.ShouldThrow <T>().WithMessage(message); }
public void ExpressionLexerCanParseBracketsExpression() { // Arrange ExpressionLexer lexer = new ExpressionLexer(" [ abc ] "); // Act Assert.Equal(ExpressionTokenKind.Literal, lexer.CurrentToken.Kind); Assert.Equal("[ abc ]", lexer.CurrentToken.Text); Assert.Equal(2, lexer.CurrentToken.Position); lexer.NextToken(); Assert.Equal(ExpressionTokenKind.TextEnd, lexer.CurrentToken.Kind); }
private void ValidateTokenSequence(string expression, params ExpressionToken[] expectTokens) { ExpressionLexer l = new ExpressionLexer(expression); for (int i = 0; i < expectTokens.Length; ++i) { Assert.AreEqual(expectTokens[i].Kind, l.CurrentToken.Kind); Assert.AreEqual(expectTokens[i].Text, l.CurrentToken.Text); l.NextToken(); } Assert.AreEqual(ExpressionTokenKind.End, l.CurrentToken.Kind); }
private static void ValidateLexerException <T>(string expression, string message) where T : Exception { Action test = () => { ExpressionLexer l = new ExpressionLexer(expression, moveToFirstToken: true, useSemicolonDelimiter: false); while (l.CurrentToken.Kind != ExpressionTokenKind.End) { l.NextToken(); } }; test.Throws <T>(message); }
public void ExpressionLexerShouldParseComplexKeyValuePairs() { // Arrange string expression = " 123 = true, inOffice = 12345, name = 'abc,''efg' , 瑞갂థ్క= @p"; ExpressionLexer lexer = new ExpressionLexer(expression); // Act Action <string, string, bool> verifyAction = (key, value, hasComma) => { Assert.Equal(ExpressionTokenKind.Literal, lexer.CurrentToken.Kind); Assert.Equal(key, lexer.CurrentToken.Text); lexer.NextToken(); Assert.Equal(ExpressionTokenKind.Equal, lexer.CurrentToken.Kind); lexer.NextToken(); Assert.Equal(ExpressionTokenKind.Literal, lexer.CurrentToken.Kind); Assert.Equal(value, lexer.CurrentToken.Text); lexer.NextToken(); if (hasComma) { Assert.Equal(ExpressionTokenKind.Comma, lexer.CurrentToken.Kind); lexer.NextToken(); } else { Assert.Equal(ExpressionTokenKind.TextEnd, lexer.CurrentToken.Kind); } }; verifyAction("123", "true", true); verifyAction("inOffice", "12345", true); verifyAction("name", "'abc,''efg'", true); verifyAction("瑞갂థ్క", "@p", false); }
/// <summary> /// Parses a literal. /// </summary> /// <param name="lexer">The lexer to use.</param> /// <returns>The literal query token or null if something else was found.</returns> internal static LiteralToken TryParseLiteral(ExpressionLexer lexer) { Debug.Assert(lexer != null, "lexer != null"); switch (lexer.CurrentToken.Kind) { case ExpressionTokenKind.BooleanLiteral: case ExpressionTokenKind.DateLiteral: case ExpressionTokenKind.DecimalLiteral: case ExpressionTokenKind.StringLiteral: case ExpressionTokenKind.Int64Literal: case ExpressionTokenKind.IntegerLiteral: case ExpressionTokenKind.DoubleLiteral: case ExpressionTokenKind.SingleLiteral: case ExpressionTokenKind.GuidLiteral: case ExpressionTokenKind.BinaryLiteral: case ExpressionTokenKind.GeographyLiteral: case ExpressionTokenKind.GeometryLiteral: case ExpressionTokenKind.QuotedLiteral: case ExpressionTokenKind.DurationLiteral: case ExpressionTokenKind.TimeOfDayLiteral: case ExpressionTokenKind.DateTimeOffsetLiteral: case ExpressionTokenKind.CustomTypeLiteral: IEdmTypeReference literalEdmTypeReference = lexer.CurrentToken.GetLiteralEdmTypeReference(); // Why not using EdmTypeReference.FullName? (literalEdmTypeReference.FullName) string edmConstantName = GetEdmConstantNames(literalEdmTypeReference); return(ParseTypedLiteral(lexer, literalEdmTypeReference, edmConstantName)); case ExpressionTokenKind.BracketedExpression: { // TODO: need a BracketLiteralToken for real complex type vaule like [\"Barky\",\"Junior\"] or {...} LiteralToken result = new LiteralToken(lexer.CurrentToken.Text, lexer.CurrentToken.Text); lexer.NextToken(); return(result); } case ExpressionTokenKind.NullLiteral: return(ParseNullLiteral(lexer)); default: return(null); } }
/// <summary> /// Parses typed literals. /// </summary> /// <param name="lexer">The lexer to use.</param> /// <param name="targetTypeReference">Expected type to be parsed.</param> /// <param name="targetTypeName">The EDM type name of the expected type to be parsed.</param> /// <returns>The literal token produced by building the given literal.</returns> private static LiteralToken ParseTypedLiteral(ExpressionLexer lexer, IEdmTypeReference targetTypeReference, string targetTypeName) { Debug.Assert(lexer != null, "lexer != null"); UriLiteralParsingException typeParsingException; object targetValue = DefaultUriLiteralParser.Instance.ParseUriStringToType(lexer.CurrentToken.Text, targetTypeReference, out typeParsingException); if (targetValue == null) { string message; if (typeParsingException == null) { message = ODataErrorStrings.UriQueryExpressionParser_UnrecognizedLiteral( targetTypeName, lexer.CurrentToken.Text, lexer.CurrentToken.Position, lexer.ExpressionText); throw ParseError(message); } else { message = ODataErrorStrings.UriQueryExpressionParser_UnrecognizedLiteralWithReason( targetTypeName, lexer.CurrentToken.Text, lexer.CurrentToken.Position, lexer.ExpressionText, typeParsingException.Message); throw ParseError(message, typeParsingException); } } LiteralToken result = new LiteralToken(targetValue, lexer.CurrentToken.Text); lexer.NextToken(); return(result); }
/// <summary> /// Parses typed literals. /// </summary> /// <param name="lexer">The lexer to use.</param> /// <param name="targetTypeReference">Expected type to be parsed.</param> /// <param name="targetTypeName">The EDM type name of the expected type to be parsed.</param> /// <returns>The literal token produced by building the given literal.</returns> private static LiteralToken ParseTypedLiteral(ExpressionLexer lexer, IEdmPrimitiveTypeReference targetTypeReference, string targetTypeName) { Debug.Assert(lexer != null, "lexer != null"); object targetValue; string reason; if (!UriPrimitiveTypeParser.TryUriStringToPrimitive(lexer.CurrentToken.Text, targetTypeReference, out targetValue, out reason)) { string message; if (reason == null) { message = ODataErrorStrings.UriQueryExpressionParser_UnrecognizedLiteral( targetTypeName, lexer.CurrentToken.Text, lexer.CurrentToken.Position, lexer.ExpressionText); } else { message = ODataErrorStrings.UriQueryExpressionParser_UnrecognizedLiteralWithReason( targetTypeName, lexer.CurrentToken.Text, lexer.CurrentToken.Position, lexer.ExpressionText, reason); } throw ParseError(message); } LiteralToken result = new LiteralToken(targetValue, lexer.CurrentToken.Text); lexer.NextToken(); return(result); }
// parses $apply aggregate tranformation (.e.g. aggregate(UnitPrice with sum as TotalUnitPrice) internal AggregateToken ParseAggregate() { Debug.Assert(TokenIdentifierIs(ExpressionConstants.KeywordAggregate), "token identifier is aggregate"); lexer.NextToken(); // '(' if (this.lexer.CurrentToken.Kind != ExpressionTokenKind.OpenParen) { throw ParseError(ODataErrorStrings.UriQueryExpressionParser_OpenParenExpected(this.lexer.CurrentToken.Position, this.lexer.ExpressionText)); } this.lexer.NextToken(); // series of statements separates by commas var statements = new List <AggregateExpressionToken>(); while (true) { statements.Add(this.ParseAggregateExpression()); if (this.lexer.CurrentToken.Kind != ExpressionTokenKind.Comma) { break; } this.lexer.NextToken(); } // ")" if (this.lexer.CurrentToken.Kind != ExpressionTokenKind.CloseParen) { throw ParseError(ODataErrorStrings.UriQueryExpressionParser_CloseParenOrCommaExpected(this.lexer.CurrentToken.Position, this.lexer.ExpressionText)); } this.lexer.NextToken(); return(new AggregateToken(statements)); }
private static void ValidateIdentifierToken(ExpressionLexer lexer, string text) { Assert.Equal(ExpressionTokenKind.Identifier, lexer.CurrentToken.Kind); Assert.Equal(text, lexer.CurrentToken.Text); lexer.NextToken(); }
private static void ValidateTokenKind(ExpressionLexer lexer, ExpressionTokenKind kind) { Assert.Equal(kind, lexer.CurrentToken.Kind); lexer.NextToken(); }
/// <summary> /// Parses a literal. /// </summary> /// <param name="lexer">The lexer to use.</param> /// <returns>The literal query token or null if something else was found.</returns> internal static LiteralToken TryParseLiteral(ExpressionLexer lexer) { Debug.Assert(lexer != null, "lexer != null"); switch (lexer.CurrentToken.Kind) { case ExpressionTokenKind.BooleanLiteral: case ExpressionTokenKind.DateLiteral: case ExpressionTokenKind.DecimalLiteral: case ExpressionTokenKind.StringLiteral: case ExpressionTokenKind.Int64Literal: case ExpressionTokenKind.IntegerLiteral: case ExpressionTokenKind.DoubleLiteral: case ExpressionTokenKind.SingleLiteral: case ExpressionTokenKind.GuidLiteral: case ExpressionTokenKind.BinaryLiteral: case ExpressionTokenKind.GeographyLiteral: case ExpressionTokenKind.GeometryLiteral: case ExpressionTokenKind.QuotedLiteral: case ExpressionTokenKind.DurationLiteral: case ExpressionTokenKind.TimeOfDayLiteral: case ExpressionTokenKind.DateTimeOffsetLiteral: case ExpressionTokenKind.CustomTypeLiteral: IEdmTypeReference literalEdmTypeReference = lexer.CurrentToken.GetLiteralEdmTypeReference(); // Why not using EdmTypeReference.FullName? (literalEdmTypeReference.FullName) string edmConstantName = GetEdmConstantNames(literalEdmTypeReference); return ParseTypedLiteral(lexer, literalEdmTypeReference, edmConstantName); case ExpressionTokenKind.BracketedExpression: { // TODO: need a BracketLiteralToken for real complex type vaule like [\"Barky\",\"Junior\"] or {...} LiteralToken result = new LiteralToken(lexer.CurrentToken.Text, lexer.CurrentToken.Text); lexer.NextToken(); return result; } case ExpressionTokenKind.NullLiteral: return ParseNullLiteral(lexer); default: return null; } }
/// <summary> /// Parses a literal. /// </summary> /// <param name="lexer">The lexer to use.</param> /// <returns>The literal query token or null if something else was found.</returns> internal static LiteralToken TryParseLiteral(ExpressionLexer lexer) { Debug.Assert(lexer != null, "lexer != null"); switch (lexer.CurrentToken.Kind) { case ExpressionTokenKind.BooleanLiteral: return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetBoolean(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmBooleanTypeName)); case ExpressionTokenKind.DateLiteral: return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetDate(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDateTypeName)); case ExpressionTokenKind.DateTimeOffsetLiteral: return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetTemporal(EdmPrimitiveTypeKind.DateTimeOffset, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDateTimeOffsetTypeName)); case ExpressionTokenKind.DurationLiteral: return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetTemporal(EdmPrimitiveTypeKind.Duration, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDurationTypeName)); case ExpressionTokenKind.DecimalLiteral: return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetDecimal(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDecimalTypeName)); case ExpressionTokenKind.NullLiteral: return(ParseNullLiteral(lexer)); case ExpressionTokenKind.StringLiteral: return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetString(true), Microsoft.OData.Core.Metadata.EdmConstants.EdmStringTypeName)); case ExpressionTokenKind.Int64Literal: return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetInt64(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmInt64TypeName)); case ExpressionTokenKind.IntegerLiteral: return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetInt32(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmInt32TypeName)); case ExpressionTokenKind.DoubleLiteral: return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetDouble(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDoubleTypeName)); case ExpressionTokenKind.SingleLiteral: return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetSingle(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmSingleTypeName)); case ExpressionTokenKind.GuidLiteral: return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetGuid(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmGuidTypeName)); case ExpressionTokenKind.BinaryLiteral: return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetBinary(true), Microsoft.OData.Core.Metadata.EdmConstants.EdmBinaryTypeName)); case ExpressionTokenKind.GeographyLiteral: return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.Geography, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmGeographyTypeName)); case ExpressionTokenKind.GeometryLiteral: return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.Geometry, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmGeometryTypeName)); case ExpressionTokenKind.QuotedLiteral: return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetString(true), Microsoft.OData.Core.Metadata.EdmConstants.EdmStringTypeName)); case ExpressionTokenKind.BracketedExpression: { // TODO: need a BracketLiteralToken for real complex type vaule like [\"Barky\",\"Junior\"] or {...} LiteralToken result = new LiteralToken(lexer.CurrentToken.Text, lexer.CurrentToken.Text); lexer.NextToken(); return(result); } case ExpressionTokenKind.TimeOfDayLiteral: return(ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetTemporal(EdmPrimitiveTypeKind.TimeOfDay, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmTimeOfDayTypeName)); default: return(null); } }
/// <summary> /// Parses typed literals. /// </summary> /// <param name="lexer">The lexer to use.</param> /// <param name="targetTypeReference">Expected type to be parsed.</param> /// <param name="targetTypeName">The EDM type name of the expected type to be parsed.</param> /// <returns>The literal token produced by building the given literal.</returns> private static LiteralToken ParseTypedLiteral(ExpressionLexer lexer, IEdmTypeReference targetTypeReference, string targetTypeName) { Debug.Assert(lexer != null, "lexer != null"); UriLiteralParsingException typeParsingException; object targetValue = DefaultUriLiteralParser.Instance.ParseUriStringToType(lexer.CurrentToken.Text, targetTypeReference, out typeParsingException); if (targetValue == null) { string message; if (typeParsingException == null) { message = ODataErrorStrings.UriQueryExpressionParser_UnrecognizedLiteral( targetTypeName, lexer.CurrentToken.Text, lexer.CurrentToken.Position, lexer.ExpressionText); throw ParseError(message); } else { message = ODataErrorStrings.UriQueryExpressionParser_UnrecognizedLiteralWithReason( targetTypeName, lexer.CurrentToken.Text, lexer.CurrentToken.Position, lexer.ExpressionText, typeParsingException.Message); throw ParseError(message, typeParsingException); } } LiteralToken result = new LiteralToken(targetValue, lexer.CurrentToken.Text); lexer.NextToken(); return result; }
private static void ValidateTokenKind(ExpressionLexer lexer, ExpressionTokenKind kind) { lexer.CurrentToken.Kind.Should().Be(kind); lexer.NextToken(); }
/// <summary> /// Parses parameter alias into token. /// </summary> /// <param name="lexer">The lexer to use.</param> /// <returns>The parameter alias token.</returns> private static FunctionParameterAliasToken ParseParameterAlias(ExpressionLexer lexer) { Debug.Assert(lexer != null, "lexer != null"); FunctionParameterAliasToken ret = new FunctionParameterAliasToken(lexer.CurrentToken.Text); lexer.NextToken(); return ret; }
private static void ValidateStringLiteralToken(ExpressionLexer lexer, string text) { Assert.Equal(ExpressionTokenKind.StringLiteral, lexer.CurrentToken.Kind); Assert.Equal(text, lexer.CurrentToken.Text); lexer.NextToken(); }
private static void ValidateIdentifierToken(ExpressionLexer lexer, string text) { lexer.CurrentToken.Kind.Should().Be(ExpressionTokenKind.Identifier); lexer.CurrentToken.Text.Should().Be(text); lexer.NextToken(); }
private static void ValidateTokenKind(ExpressionLexer lexer, ExpressionTokenKind kind) { lexer.CurrentToken.Kind.Should().Be(kind); lexer.NextToken(); }
/// <summary>Attempts to parse key values from the specified text.</summary> /// <param name='text'>Text to parse (not null).</param> /// <param name="allowNamedValues">Set to true if the parser should accept named values /// so syntax like Name='value'. If this is false, the parsing will fail on such constructs.</param> /// <param name="allowNull">Set to true if the parser should accept null values. /// If set to false, the parser will fail on null values.</param> /// <param name='instance'>After invocation, the parsed key instance.</param> /// <returns> /// true if the key instance was parsed; false if there was a /// syntactic error. /// </returns> /// <remarks> /// The returned instance contains only string values. To get typed values, a call to /// <see cref="TryConvertValues"/> is necessary. /// </remarks> private static bool TryParseFromUri(string text, bool allowNamedValues, bool allowNull, out KeyInstance instance) { Debug.Assert(text != null, "text != null"); Dictionary <string, object> namedValues = null; List <object> positionalValues = null; ExpressionLexer lexer = new ExpressionLexer(text); Token currentToken = lexer.CurrentToken; if (currentToken.Id == TokenId.End) { instance = Empty; return(true); } instance = null; do { if (currentToken.Id == TokenId.Identifier && allowNamedValues) { // Name-value pair. if (positionalValues != null) { // We cannot mix named and non-named values. return(false); } string identifier = lexer.CurrentToken.GetIdentifier(); lexer.NextToken(); if (lexer.CurrentToken.Id != TokenId.Equal) { return(false); } lexer.NextToken(); if (!lexer.CurrentToken.IsKeyValueToken) { return(false); } string namedValue = lexer.CurrentToken.Text; WebUtil.CreateIfNull(ref namedValues); if (namedValues.ContainsKey(identifier)) { // Duplicate name. return(false); } namedValues.Add(identifier, namedValue); } else if (currentToken.IsKeyValueToken || (allowNull && currentToken.Id == TokenId.NullLiteral)) { // Positional value. if (namedValues != null) { // We cannot mix named and non-named values. return(false); } WebUtil.CreateIfNull(ref positionalValues); positionalValues.Add(lexer.CurrentToken.Text); } else { return(false); } // Read the next token. We should be at the end, or find // we have a comma followed by something. lexer.NextToken(); currentToken = lexer.CurrentToken; if (currentToken.Id == TokenId.Comma) { lexer.NextToken(); currentToken = lexer.CurrentToken; if (currentToken.Id == TokenId.End) { // Trailing comma. return(false); } } }while (currentToken.Id != TokenId.End); instance = new KeyInstance(namedValues, positionalValues); return(true); }
/// <summary> /// Parses null literals. /// </summary> /// <param name="lexer">The lexer to use.</param> /// <returns>The literal token produced by building the given literal.</returns> private static LiteralToken ParseNullLiteral(ExpressionLexer lexer) { Debug.Assert(lexer != null, "lexer != null"); Debug.Assert(lexer.CurrentToken.Kind == ExpressionTokenKind.NullLiteral, "this.lexer.CurrentToken.InternalKind == ExpressionTokenKind.NullLiteral"); LiteralToken result = new LiteralToken(null, lexer.CurrentToken.Text); lexer.NextToken(); return result; }
/// <summary> /// Parses typed literals. /// </summary> /// <param name="lexer">The lexer to use.</param> /// <param name="targetTypeReference">Expected type to be parsed.</param> /// <param name="targetTypeName">The EDM type name of the expected type to be parsed.</param> /// <returns>The literal token produced by building the given literal.</returns> private static LiteralToken ParseTypedLiteral(ExpressionLexer lexer, IEdmPrimitiveTypeReference targetTypeReference, string targetTypeName) { Debug.Assert(lexer != null, "lexer != null"); object targetValue; string reason; if (!UriPrimitiveTypeParser.TryUriStringToPrimitive(lexer.CurrentToken.Text, targetTypeReference, out targetValue, out reason)) { string message; if (reason == null) { message = ODataErrorStrings.UriQueryExpressionParser_UnrecognizedLiteral( targetTypeName, lexer.CurrentToken.Text, lexer.CurrentToken.Position, lexer.ExpressionText); } else { message = ODataErrorStrings.UriQueryExpressionParser_UnrecognizedLiteralWithReason( targetTypeName, lexer.CurrentToken.Text, lexer.CurrentToken.Position, lexer.ExpressionText, reason); } throw ParseError(message); } LiteralToken result = new LiteralToken(targetValue, lexer.CurrentToken.Text); lexer.NextToken(); return result; }
private static void ValidateStringLiteralToken(ExpressionLexer lexer, string text) { lexer.CurrentToken.Kind.Should().Be(ExpressionTokenKind.StringLiteral); lexer.CurrentToken.Text.Should().Be(text); lexer.NextToken(); }
private static void ValidateStringLiteralToken(ExpressionLexer lexer, string text) { lexer.CurrentToken.Kind.Should().Be(ExpressionTokenKind.StringLiteral); lexer.CurrentToken.Text.Should().Be(text); lexer.NextToken(); }
private static void ValidateIdentifierToken(ExpressionLexer lexer, string text) { lexer.CurrentToken.Kind.Should().Be(ExpressionTokenKind.Identifier); lexer.CurrentToken.Text.Should().Be(text); lexer.NextToken(); }
/// <summary> /// Parses a literal. /// </summary> /// <param name="lexer">The lexer to use.</param> /// <returns>The literal query token or null if something else was found.</returns> internal static LiteralToken TryParseLiteral(ExpressionLexer lexer) { Debug.Assert(lexer != null, "lexer != null"); switch (lexer.CurrentToken.Kind) { case ExpressionTokenKind.BooleanLiteral: return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetBoolean(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmBooleanTypeName); case ExpressionTokenKind.DateLiteral: return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetDate(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDateTypeName); case ExpressionTokenKind.DateTimeOffsetLiteral: return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetTemporal(EdmPrimitiveTypeKind.DateTimeOffset, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDateTimeOffsetTypeName); case ExpressionTokenKind.DurationLiteral: return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetTemporal(EdmPrimitiveTypeKind.Duration, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDurationTypeName); case ExpressionTokenKind.DecimalLiteral: return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetDecimal(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDecimalTypeName); case ExpressionTokenKind.NullLiteral: return ParseNullLiteral(lexer); case ExpressionTokenKind.StringLiteral: return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetString(true), Microsoft.OData.Core.Metadata.EdmConstants.EdmStringTypeName); case ExpressionTokenKind.Int64Literal: return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetInt64(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmInt64TypeName); case ExpressionTokenKind.IntegerLiteral: return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetInt32(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmInt32TypeName); case ExpressionTokenKind.DoubleLiteral: return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetDouble(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmDoubleTypeName); case ExpressionTokenKind.SingleLiteral: return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetSingle(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmSingleTypeName); case ExpressionTokenKind.GuidLiteral: return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetGuid(false), Microsoft.OData.Core.Metadata.EdmConstants.EdmGuidTypeName); case ExpressionTokenKind.BinaryLiteral: return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetBinary(true), Microsoft.OData.Core.Metadata.EdmConstants.EdmBinaryTypeName); case ExpressionTokenKind.GeographyLiteral: return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.Geography, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmGeographyTypeName); case ExpressionTokenKind.GeometryLiteral: return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.Geometry, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmGeometryTypeName); case ExpressionTokenKind.QuotedLiteral: return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetString(true), Microsoft.OData.Core.Metadata.EdmConstants.EdmStringTypeName); case ExpressionTokenKind.BracketedExpression: { // TODO: need a BracketLiteralToken for real complex type vaule like [\"Barky\",\"Junior\"] or {...} LiteralToken result = new LiteralToken(lexer.CurrentToken.Text, lexer.CurrentToken.Text); lexer.NextToken(); return result; } case ExpressionTokenKind.TimeOfDayLiteral: return ParseTypedLiteral(lexer, EdmCoreModel.Instance.GetTemporal(EdmPrimitiveTypeKind.TimeOfDay, false), Microsoft.OData.Core.Metadata.EdmConstants.EdmTimeOfDayTypeName); default: return null; } }