Expression Evaluator:一个轻量级的C#编译器服务

尽管.NET社区热切盼望Roslyn的正式版本,但工作还是要继续。所以今天我们来介绍另一个编译器服务——Expression Evaluator。虽然其他编译器服务都试图尽可能地全面,但它却独辟蹊径。

\u0026#xD;\n

InfoQ:你说C# Expression Evaluator是一个轻量级库,是什么让它成为一个轻量级的库?什么样的库又是重量级的呢?

\u0026#xD;\n
\u0026#xD;\n

Repert Avery:Expression Evaluator的目标是计算表达式,就此而言我认为它是轻量级的,因为它很小(不到1M),是自包含的,不依赖于其他非核心库(除了Antlr),并且功能独特。我认为Roslyn是重量级的,因为它需要很多库的支持。当然,每个库都有自己的目标,很多Roslyn能做的事Expression Evaluator可能永远都做不到,如编译整个程序集。但就计算小的表达式来说,我相信Expression Evaluator已经做得非常好了。

\u0026#xD;\n
\u0026#xD;\n

InfoQ:Antlr是什么?你为什么会将它包含在库里?

\u0026#xD;\n
\u0026#xD;\n

Rupert: Antlr(“又一个语言识别工具”的缩写)是一个最初用Java编写的库,可以根据特殊的语法(文法)来构建复杂的解析器代码。它就像是一个用于语言解析的加强版的正则表达式。你可以编写某种语言的语法规则,Antlr会为你生成代码。

\u0026#xD;\n

在使用Antlr之前我自己编写了这个解析器,它能做一个表达式解析器所需要的所有基础的工作。我能够支持“a + b.method(c,d[e] == f)”这样的表达式。它的规则十分简单。但当我想支持Lambda语法时,一切就变得复杂起来。例如表达式“(a,b) =\u0026gt; a==b”,(a,b)应该先解析为参数列表,然后再解析Lambda符号=\u0026gt;之后的所有内容(可能为块表达式),这难倒了我。我需要进行一些回溯并抛弃生成的token。我那手写的解析器显然无法完成这个任务。

\u0026#xD;\n

Antlr让一切变得简单。它能让我关注于编写处理各种语言的代码,而不用操心用于解析的代码。

\u0026#xD;\n

必须为我正使用的语法文件的作者点赞。我在https://antlrcsharp.codeplex.com/找到了这个十分完整的C# 4.0语法文件,我所要做的,就是对每种情况编写代码,来生成适当的表达式。

\u0026#xD;\n
\u0026#xD;\n

InfoQ:文档中提到了LINQ表达式树。能详细说说你是如何使用的吗?

\u0026#xD;\n
\u0026#xD;\n

Rupert:LINQ表达式能将解析好的表达式存储为某种数据结构。与其自己构建数据结构,不如使用.NET Framework提供的结构。表达式树还有一个优势是可以编译为.NET函数。当表达式被编译为实际的.NET CLR代码后,就可以通过调用该函数来计算表达式。预编译代码的好处是速度的提升。其他不使用LINQ表达式的库,在计算表达式时,会遍历等价的表达式树,通过执行代码来模拟正在执行的代码,这是一笔巨大的开销。

\u0026#xD;\n

比如这样的表达式:

\u0026#xD;\n

x == a + b

\u0026#xD;\n

它的表达式树可能为:

\u0026#xD;\n

根:

\u0026#xD;\n

节点类型:Equals

\u0026#xD;\n

左子节点: 参数表达式x 

\u0026#xD;\n

右子节点: (加法表达式)

\u0026#xD;\n

加法表达式:

\u0026#xD;\n

节点类型:Add

\u0026#xD;\n

左子结点:参数表达式a 

\u0026#xD;\n

右子节点:参数表达式b

\u0026#xD;\n

这在C#中可以写成:

\u0026#xD;\n
  Expression.Equals(Expression.Parameter('x'), Expression.Add(Expression.Parameter('a'), Expression.Parameter('b')); 
\u0026#xD;\n

Expression Evaluator接下来(使用Antlr)解析该表达式,生成适当的表达式树。构建完表达式树之后,可以通过LINQ将其编译为函数。使用这个库的应用程序可以执行这个函数,就像它已经在第一时间被编译过了一样。被编译为函数之后,表达式树就不再需要了,不过我们可以用它来分析表达式,我相信肯定会有人想要枚举表达式所用到的变量或属性。由于表达式树记录了每个表达式的类型,因此是可以通过这种方式提取这些信息的。

\u0026#xD;\n
\u0026#xD;\n

InfoQ:假设我们在编写一个客户端-服务器系统。我们需要从客户端向服务器发送搜索条件(如where子句)。你会对这样的系统使用这个库吗?如果会,那么将是什么样子的?

\u0026#xD;\n
\u0026#xD;\n

Rupert:在这种场景下,如果模型复杂,或查询逻辑复杂,并且客户端可以使用字符串自由地定义查询,那么Expression Evaluator就非常有用。Expression Evaluator将工作于服务器端,解析查询并转换为编译后的代码。

\u0026#xD;\n

我不清楚你所说的“将是什么样子”是指什么,不过使用了Expression Evaluator的Web应用程序可以让用户使用代码来定义查询,给用户提供一个可访问的参数集合,用户可以用C#代码来编写查询,并将原封不动地发送给服务器进行解析和编译。

\u0026#xD;\n

如果查询需要大量条件代码并且需要考虑性能,这将是Expression Evaluator发挥最大作用的时候。与其在查询中使用大量分支条件,不如基于必要的条件构建一个字符串表达式,并将其编译为可在查询中运行的委托。

\u0026#xD;\n

使用LINQ表达式树并没有将其局限于只能为LINQ表达式构建动态where子句。Expression Evaluator还可用于数据绑定。此时,用一个XML文件存储布局,并使用特性和特殊的符号来标记该文本用于数据绑定,而不是纯文本。XML元素模仿HTML,双花括号的符号模仿AngularJS。结果就是一个很像HTML/AngularJS的布局和模板引擎,输出的是PowerPoint幻灯片。布局引擎为开发者提供了HTML的灵活性,而Expression Evaluator允许数据绑定到布局上并控制布局,在PowerPoint中生成丰富的报告。

\u0026#xD;\n
\u0026#xD;\n

Expression Evaluator在CodePlex上以Simplified BSD协议开源。

\u0026#xD;\n

原文链接:Expression Evaluator: A Lightweight C# Compiler Service

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java Expression Evaluator一个用 Java 编写的库,可以解析和计算数学表达式,并支持自定义函数和变量。它可以用于在 Java 应用程序中动态计算数学表达式,例如计算器或科学计算应用程序。使用 Java Expression Evaluator,您可以轻松地解析和计算包含各种数学函数和运算符的表达式,并在运行时添加自定义函数和变量。 Java Expression Evaluator 支持各种数学函数和运算符,例如加法、减法、乘法、除法、幂运算、三角函数、对数函数等。它还支持自定义函数和变量,您可以在运行时添加自己的函数和变量,并将它们包含在表达式中计算。 Java Expression Evaluator 的使用非常简单。您只需要创建一个 ExpressionEvaluator 对象,然后使用 evaluate() 方法计算表达式。例如: ``` ExpressionEvaluator ee = new ExpressionEvaluator(); double result = ee.evaluate("2 + 3 * 4"); ``` 以上代码将计算表达式 2 + 3 * 4,结果为 14。您也可以添加自定义函数和变量,例如: ``` ExpressionEvaluator ee = new ExpressionEvaluator(); ee.putFunction("square", new Function() { public double apply(double... args) { return args[0] * args[0]; } }); ee.putVariable("x", 5); double result = ee.evaluate("square(x) + 3"); ``` 以上代码将添加一个名为 square 的自定义函数,该函数计算参数的平方。然后,它将添加一个名为 x 的变量,并将其设置为 5。最后,它将计算表达式 square(x) + 3,结果为 28。 Java Expression Evaluator一个非常有用的库,可以帮助您轻松地解析和计算数学表达式,并支持自定义函数和变量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值