代码之家  ›  专栏  ›  技术社区  ›  Niels Bosma

C编译数值表达式

  •  2
  • Niels Bosma  · 技术社区  · 16 年前

    假设我允许用户输入允许使用显式函数集和预定义变量的任意数字表达式。

    解释这一点非常直接,但如果性能是一个关键因素呢?

    我需要一种方法来编译(在运行时)一个带有表达式的字符串,使其可以用变量上的不同值执行20K次。

    3 回复  |  直到 16 年前
        1
  •  2
  •   Marc Gravell    16 年前

    所以您真的想将字符串解析成(最终)类型化委托。

    一个选项,然后将字符串解析为 Expression ,然后可以编译为lambda。这是非常复杂的,但是我有一些代码可以完成大部分工作——但是可能有一些现有的解析器已经完成了全部工作。

    微不足道 表情 例子:

        var x = Expression.Parameter(typeof(double), "x");
        var y = Expression.Parameter(typeof(double), "y");
        var body = Expression.Multiply(x, y);
        var func = Expression.Lambda<Func<double, double,double>>(body, x, y).Compile();
    
        double z = func(123.45, 678.90);
    

    问题是解析代码的其余部分;-p

    我写了一篇 string 表情 解析器上周,但它比我通常在这里发布的代码要多…超过300行(不包括识别定制的外部函数或命名参数(它当前使用匿名“?”持仓人)。

    但是,如果(如您所说)解释很容易,那么可能使用类似的代码编写一个 表情 你能编译吗?

        2
  •  2
  •   Rinat Abdullin    16 年前

    Microsoft的LINQ示例已经包含可扩展LINQ解析器的实现。

    sealed class Order
    {
      public double SubTotal { get; set; }
      public double Shipping { get; set; }
    }
    static void Main()
    {
      var calculateTotal = DynamicExpression
        .ParseLambda<Order, double>("SubTotal*@0+Shipping", 0.12)
        .Compile();
    
      var order = new Order
      {
        SubTotal = 124.99,
        Shipping = 7.99
      };
      Console.WriteLine(calculateTotal(order));
      Console.ReadLine();
    }
    

    您可以查看 DbLinq project 有关来源或此文章的详细信息: Dynamic Linq and Expression Parsing in .NET as a hint of C# compiler extensibility

        3
  •  1
  •   Mehrdad Afshari    16 年前

    在C 4.0中,它将变得非常简单和简单。但是,在C 4.0之前,我建议您使用 Microsoft.JScript 图书馆来完成它。

    这就是你想要的: http://www.odetocode.com/Articles/80.aspx