private static Type GetExpressionType <T>(TokenSet set, ParameterExpression parameter, ICollection <ParameterExpression> lambdaParameters) { if (parameter == null) { throw new ArgumentNullException("parameter"); } if (lambdaParameters == null) { throw new ArgumentNullException("lambdaParameters"); } if (set == null) { return(null); } if (Regex.IsMatch(set.Left, @"^\(.*\)$") && set.Operation.IsCombinationOperation()) { return(null); } var property = GetPropertyExpression <T>(set.Left, parameter, lambdaParameters) ?? GetPropertyExpression <T>(set.Right, parameter, lambdaParameters); if (property != null) { return(property.Type); } var type = GetExpressionType <T>(set.Left.GetArithmeticToken(), parameter, lambdaParameters); return(type ?? GetExpressionType <T>(set.Right.GetArithmeticToken(), parameter, lambdaParameters)); }
public static ICollection <TokenSet> GetTokens(this string expression) { var tokens = new Collection <TokenSet>(); if (expression.IsNullOrWhiteSpace()) { return(tokens); } var cleanMatch = expression.EnclosedMatch(); if (cleanMatch.Success) { var match = cleanMatch.Groups[1].Value; if (!HasOrphanedOpenParenthesis(match)) { expression = match; } } if (expression.IsImpliedBoolean()) { return(tokens); } var blocks = expression.Split(new[] { ' ' }); var openGroups = 0; var startExpression = 0; var currentTokens = new TokenSet(); var processingString = false; for (int i = 0; i < blocks.Length; i++) { if (blocks[i].IsStringStart()) { processingString = true; } var netEnclosed = blocks[i].Count(c => c == '(') - blocks[i].Count(c => c == ')'); openGroups += netEnclosed; if (openGroups == 0) { if (!processingString && blocks[i].IsOperation()) { var expression1 = startExpression; if (currentTokens.Left.IsNullOrWhiteSpace()) { var i1 = i; Func <string, int, bool> leftPredicate = (x, j) => j >= expression1 && j < i1; currentTokens.Left = blocks.Where(leftPredicate).Join(" "); currentTokens.Operation = blocks[i]; startExpression = i + 1; if (blocks[i].IsCombinationOperation()) { currentTokens.Right = blocks.Where((x, j) => j > i).Join(" "); tokens.Add(currentTokens); return(tokens); } } else { var i2 = i; Func <string, int, bool> rightPredicate = (x, j) => j >= expression1 && j < i2; currentTokens.Right = blocks.Where(rightPredicate).Join(" "); tokens.Add(currentTokens); startExpression = i + 1; currentTokens = new TokenSet(); if (blocks[i].IsCombinationOperation()) { tokens.Add(new TokenSet { Operation = blocks[i].ToLowerInvariant() }); } } } } if (blocks[i].IsStringEnd()) { processingString = false; } } var remainingToken = blocks.Where((x, j) => j >= startExpression).Join(" "); if (!currentTokens.Left.IsNullOrWhiteSpace()) { currentTokens.Right = remainingToken; tokens.Add(currentTokens); } else if (remainingToken.IsEnclosed()) { currentTokens.Left = remainingToken; tokens.Add(currentTokens); } else if (tokens.Count > 0) { currentTokens.Left = remainingToken; tokens.Add(currentTokens); } return(tokens); }