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; }
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); }
public void TokenSetToStringWritesLeftOperationRight() { var set = new TokenSet { Left = "Left", Operation = "Operation", Right = "Right" }; Assert.AreEqual("Left Operation Right", set.ToString()); }