private Type GetExpressionType <T>(TokenSet set, ParameterExpression parameter, ICollection <ParameterExpression> lambdaParameters) { if (set == null) { return(null); } if (Regex.IsMatch(set.Left, @"^\(.*\)$") && set.Operation.IsCombinationOperation()) { return(null); } if (set.Left.IsFunction()) { var functionName = set.Left.GetFunctionName(); if (!string.IsNullOrWhiteSpace(functionName)) { return(functionName.GetFunctionType()); } } 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 (string.IsNullOrWhiteSpace(expression)) { 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 = GetBlocks(expression); var openGroups = 0; var startExpression = 0; var currentTokens = new TokenSet(); for (var i = 0; i < blocks.Count; i++) { var netEnclosed = blocks[i].Count(c => c == '(') - blocks[i].Count(c => c == ')'); openGroups += netEnclosed; if (openGroups == 0) { if (blocks[i].IsOperation()) { var expression1 = startExpression; if (string.IsNullOrWhiteSpace(currentTokens.Left)) { var i1 = i; Func <string, int, bool> leftPredicate = (x, j) => j >= expression1 && j < i1; currentTokens.Left = string.Join(" ", blocks.Where(leftPredicate)); currentTokens.Operation = blocks[i]; startExpression = i + 1; if (blocks[i].IsCombinationOperation()) { currentTokens.Right = string.Join(" ", blocks.Where((x, j) => j > i)); tokens.Add(currentTokens); return(tokens); } } else { var i2 = i; Func <string, int, bool> rightPredicate = (x, j) => j >= expression1 && j < i2; currentTokens.Right = string.Join(" ", blocks.Where(rightPredicate)); tokens.Add(currentTokens); startExpression = i + 1; currentTokens = new TokenSet(); if (blocks[i].IsCombinationOperation()) { tokens.Add(new TokenSet { Operation = blocks[i].ToLowerInvariant() }); } } } } } var remainingToken = string.Join(" ", blocks.Where((x, j) => j >= startExpression)); if (!string.IsNullOrWhiteSpace(currentTokens.Left)) { 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); }