zoukankan      html  css  js  c++  java
  • (C#) 表达式树

    需求是将一个string 表达式 转换成 逻辑 表达式 并得到结果。

    例如: bool result = (key1==val1) || (key2!=val2) && (key3==val3). 其中 keyN, valN 均为变量。

    基本的思路是先做Express string 验证,然后进行解析。

    验证可以用正则表达式。

    解析最基本的方法是用 表达式树 (Express Tree).  PostFix. 

    C# linq 提供了一个解决方案就是 Linq 语法树。

    https://www.codeproject.com/Articles/74018/How-to-Parse-and-Convert-a-Delegate-into-an-Expre

    目前较好的方法是用Microsoft 的  Dynamic Linq (http://msdn.microsoft.com/en-us/vcsharp/bb894665.aspx)

    static void Main(string[] args)
            {
                string[] exps = new string[]
                {
                    @" ""keyA"" !=""valA"" ",
                    @"keyA !=""valA""",
                    @"(keyA ==""valA"")",
                    @"keyA ==""val1"" || key2 ==""val2""",
                    @"key1 ==""val1"" && key2 ==""val2""",
                    @" key1 !=""val1"" || key2 ==""val2""&& key3 != ""val3""",
                    @"(key1 ==""val1"" || key2 ==""val2"")&& key3 != ""val3""",
                };
    
                string pattern = @"(?<key>[wd_]+)""*s*(?<equality>==|!=)s*""*(?<value>[wd_]+)";
    
                foreach (var exp in exps)
                {
                    // Parses to get the parameters.
                    string formattedExp = exp; 
                    var matches = Regex.Matches(exp, pattern);
                    ParameterExpression[] parameters = new ParameterExpression[matches.Count]; 
                    for (int i =0; i < matches.Count; i++)
                    {
                        Debug.Write(" key[" + matches[i].Groups["key"].Value);
                        Debug.Write("] equality[" + matches[i].Groups["equality"].Value);
                        Debug.Write("] value[" + matches[i].Groups["value"].Value +"]	
    ");
    
                        parameters[i] = Expression.Parameter(typeof(string), matches[i].Groups["key"].Value);
    
                        // Removing " if it has in keys.
                        if (exp.Contains(string.Format(@"""{0}""", matches[i].Groups["key"].Value)))
                        {
                            formattedExp = exp.Replace(string.Format(@"""{0}""", matches[i].Groups["key"].Value), matches[i].Groups["key"].Value); 
                        }
                    }
    
                    var e = System.Linq.Dynamic.DynamicExpression.ParseLambda(parameters, null, formattedExp);
    
                    string[] GotValues = new string[matches.Count]; 
                   if (GotValues.Length == 2)
                   {
                       GotValues[0] = "val1";
                       GotValues[1] = "val2";
                   }
    
                   if (GotValues.Length == 3)
                   {
                       GotValues[0] = "val1";
                       GotValues[1] = "val2";
                       GotValues[2] = "val3";
                   }
    
                    var result = e.Compile().DynamicInvoke(GotValues);
    
                    Debug.WriteLine("{0} ---> {1}", e.ToString(), result); 
                }
            }

    输出如下:

     keyA => (keyA != "valA") ---> True
     key[keyA] equality[!=] value[valA] 
    keyA => (keyA != "valA") ---> True
     key[keyA] equality[==] value[valA] 
    keyA => (keyA == "valA") ---> False
     key[keyA] equality[==] value[val1] 
     key[key2] equality[==] value[val2] 
    (keyA, key2) => ((keyA == "val1") OrElse (key2 == "val2")) ---> True
     key[key1] equality[==] value[val1] 
     key[key2] equality[==] value[val2] 
    (key1, key2) => ((key1 == "val1") AndAlso (key2 == "val2")) ---> True
     key[key1] equality[!=] value[val1] 
     key[key2] equality[==] value[val2] 
     key[key3] equality[!=] value[val3] 
    (key1, key2, key3) => ((key1 != "val1") OrElse ((key2 == "val2") AndAlso (key3 != "val3"))) ---> False
     key[key1] equality[==] value[val1] 
     key[key2] equality[==] value[val2] 
     key[key3] equality[!=] value[val3] 
    (key1, key2, key3) => (((key1 == "val1") OrElse (key2 == "val2")) AndAlso (key3 != "val3")) ---> False

     参考:

    https://stackoverflow.com/questions/821365/how-to-convert-a-string-to-its-equivalent-linq-expression-tree

  • 相关阅读:
    NOIP2008双栈排序[二分图染色|栈|DP]
    洛谷P1108 低价购买[DP | LIS方案数]
    洛谷P1330封锁阳光大学[二分图染色]
    NOIP模板整理计划
    期中考试
    UVA 10564 Paths through the Hourglass[DP 打印]
    UVA 11404 Palindromic Subsequence[DP LCS 打印]
    POJ2479 Maximum sum[DP|最大子段和]
    POJ3160 Father Christmas flymouse[强连通分量 缩点 DP]
    UVA11324 The Largest Clique[强连通分量 缩点 DP]
  • 原文地址:https://www.cnblogs.com/fdyang/p/7660184.html
Copyright © 2011-2022 走看看