/// <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>Handles typed literals.</summary> /// <param name="targetType">Expected type to be parsed.</param> /// <param name="targetTypeName">Expected type name.</param> /// <param name="l">Lexer to use for reading tokens</param> /// <returns>The constants expression produced by building the given literal.</returns> private Expression ParseTypedLiteral(Type targetType, string targetTypeName, ExpressionLexer l) { object targetValue; if (!WebConvert.TryKeyStringToPrimitive(l.CurrentToken.Text, targetType, out targetValue)) { string message = Strings.RequestQueryParser_UnrecognizedLiteral(targetTypeName, l.CurrentToken.Text, l.CurrentToken.Position); throw ParseError(message); } Expression result = this.CreateLiteral(targetValue, l.CurrentToken.Text); l.NextToken(); return result; }
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; }
/// <summary>Handles 'null' literals.</summary> /// <param name="l">Lexer to use for reading tokens</param> /// <returns>The parsed expression.</returns> private static Expression ParseNullLiteral(ExpressionLexer l) { Debug.Assert(l.CurrentToken.Id == TokenId.NullLiteral, "l.CurrentToken.Id == TokenId.NullLiteral"); l.NextToken(); return WebUtil.NullLiteral; }
private static bool TryParseFromUri(string text, bool allowNamedValues, bool allowNull, out KeyInstance instance) { Dictionary<string, object> dictionary = null; List<object> list = 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) { if (list != null) { 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 str2 = lexer.CurrentToken.Text; WebUtil.CreateIfNull<Dictionary<string, object>>(ref dictionary); if (dictionary.ContainsKey(identifier)) { return false; } dictionary.Add(identifier, str2); } else { if (!currentToken.IsKeyValueToken && (!allowNull || (currentToken.Id != TokenId.NullLiteral))) { return false; } if (dictionary != null) { return false; } WebUtil.CreateIfNull<List<object>>(ref list); list.Add(lexer.CurrentToken.Text); } lexer.NextToken(); currentToken = lexer.CurrentToken; if (currentToken.Id == TokenId.Comma) { lexer.NextToken(); currentToken = lexer.CurrentToken; if (currentToken.Id == TokenId.End) { return false; } } } while (currentToken.Id != TokenId.End); instance = new KeyInstance(dictionary, list); return true; }