C#:如何将任意字符串解析为表达式树?

5

在我正在处理的项目中,我需要使用一种相当奇怪的数据源。我可以给它一个“查询”,然后它会返回给我一个DataTable。但是这个查询不是传统意义上的字符串。更像是一组方法调用,用于定义我想要的条件。大致如下:

var tbl = MySource.GetObject("TheTable");
tbl.AddFilterRow(new FilterRow("Column1", 123, FilterRow.Expression.Equals));
tbl.AddFilterRow(new FilterRow("Column2", 456, FilterRow.Expression.LessThan));
var result = tbl.GetDataTable();

实质上,它支持所有标准符号(布尔运算符,括号,一些函数等),但编写它的语法相当冗长和不适合日常使用。
我想制作一个小的解析器,可以解析给定的表达式(例如"Column1 = 123 AND Column2 < 456"),并将其转换为上面的函数调用。此外,如果我可以添加参数,那么我就能够避免受到注入攻击。最后一点小甜头是,如果它可以缓存解析结果,并在另一个对象上重新执行相同的查询时重复使用它们,那就太好了。
因此,我想知道 - 是否有任何现有的解决方案可供我使用,还是我必须自己编写表达式解析器?虽然不是太复杂,但如果我可以节省两三天的编程时间和大量要修复的错误,这将是值得的。
3个回答

7
尝试使用Irony。虽然文档不够详细,但示例将使您快速上手。Irony是一个用于解析代码和构建抽象语法树的项目,但您可能需要编写一些逻辑来创建适合您需求的表单。DLR可能是其补充,因为它可以从抽象语法树动态生成/执行代码(用于IronPython和IronRuby)。两者应该是很好的组合。
哦,它们都是一流的.NET解决方案,并且是开源的。

看起来很庞大,但我只需要一点点。 :P - Vilx-
Irony汇编大小为171 KB(调试版本)。 如果需要,您可以将其编译到您的应用程序中,因为源代码可用。 对于您的需求,使用它应该相当简单(即不需要太多代码)。我在一个表达式解析器/评估器项目中使用它,代码只有几百行,虽然我的表达式语言比您描述的要复杂得多。 另一方面,DLR确实大了一些,但对您来说并不是必需的 :) - OregonGhost
请点击此处访问Irony在Github上的主页。 - Andrew Matthews

0
Bison或JavaCC等工具将从语法中生成解析器。然后,您可以使用自己的代码增强树的节点来转换表达式。
OP评论: 我真的不想在我的软件中附带第三方可执行文件。我希望它编译在我的代码中。
这两个工具都会生成源代码,您可以将其链接起来。

我真的不想在我的软件中附带第三方可执行文件。我希望它能够在我的代码中编译。 - Vilx-

0

我手写了一个解析器,用于这个特定的使用和复杂度水平。花了大约两天时间。我很高兴我做到了,但我不会再这样做了。我会使用ANTLR或F#的Fslex。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接