/// <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); }
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); }