布尔和数学表达式解析器

9
我正在编写一个应用程序,允许用户输入布尔表达式。我需要在运行时评估输入的布尔表达式,并寻找解析器和表达式验证器。
解析器 解析器需要将布尔表达式作为字符串输入并返回true/false。
例如:
string expression = "(1 == 1) && (1 > 0)"; Parser parser = new Parser(); boolean result = parser.parse(expression); // 结果应该是True。
除了处理布尔表达式外,我还需要它处理数学问题。
expression = "((1 + 1 * 2) == 1)"; result = parser.parse(expression); // 结果应该是False。
验证 为了告诉用户输入的表达式是否有问题,我还需要一种验证语法的方法。
我正在使用.NET Compact Framework中的C#进行工作,但如果您知道其他语言编写的东西可能会有所帮助。
感谢您提供的任何帮助。 Tom
7个回答

6
我们的项目正在使用NCalc(在其下方使用ANTLR进行词法分析/语法分析),我们对它非常满意。
NCalc是.NET中的数学表达式求值器。 NCalc可以解析任何表达式并计算结果,包括静态或动态参数和自定义函数。
我们的应用程序要求进行全框架和紧凑框架的交叉编译。通过相对简单的调整,我们能够使NCalc和ANTLR适用于两种框架版本。

3

如果你看到这个并且觉得这太麻烦了,想要放弃,请再考虑一下。我建议你使用ANTLRworks作为语法开发工具,并将其输出的词法分析器和解析器类放入你的Visual Studio项目树中。这相对无缝,并且可以轻松地迭代调整你的语法,并快速在你的.NET世界中看到它的效果。+1 for ANTLR. - Chris Farmer
以上的“你”指的是发帖者Thomas。 - Chris Farmer
@Chris Farmer:这是针对 C# Compact Framework 的目标...可能有点过于沉重了... - t0mm13b
1
我不知道。使用相对简单的表达式语法,生成的词法分析器和语法分析器将非常小。在我看来,这值得一试。如果它行不通,至少Thomas很容易就能意识到这一点,因此如果失败了,也不会浪费太多时间。 - Chris Farmer

2

假设您可以稍微调整一下语法,使用类似以下T-SQL查询的嵌入式数据库来为您完成工作:

select case when <Expression> then 1 else 0 end as Result

使用您的示例:

select case when ((1 = 1) and (1 > 0)) then 1 else 0 end as Result
select case when ((1 + 1 * 2) = 1) then 1 else 0 end as Result

1
根据问题,表达式实际上是由用户输入的。因此,您的解决方案容易受到SQL注入攻击的影响。 - Christian.K

0

我不知道有什么库可以让这个过程更容易,但你只需要解决两个子问题。你需要构建一个中缀表达式转后缀表达式的转换器,然后编写一个基本的计算器来处理布尔和数学运算。

一旦你构建好了布尔树/堆栈,就可以开始执行操作。如果你有任何不是数字的东西,将其发送到算术计算器进行评估,该计算器执行中缀转后缀转换,然后返回一个值。

如果你在谷歌上搜索“中缀表达式转后缀表达式”和“堆栈逆波兰计算器”,你可能会找到更多资源。


2
如果你可以使用带有"eval"的语言,则问题得以解决。你寻找true或false,对于其他所有内容,你知道它们都是无效的。 - Stefan Kendall
我认为使用"eval"完全是错误的方式。虽然它可能很简单,但让人们编写在您的语言中合法的任何代码都存在风险。在我看来,更好的做法是为这些表达式提供一个独特且有限的语法。 - Chris Farmer

0

您可以尝试使用dotMath库来实现此功能。


0
这是一个在Codeproject上的优秀评估解析器,它使用eval方法而不依赖于CodeDOM或其他类似的东西。这是一篇关于如何使用Antlr构建表达式求值器的优秀文章,同样也在该网站上。
希望对你有所帮助, 最好的问候, 汤姆。

0

这种事情是F#的拿手好戏。你可以试试看。对于解析,使用递归下降,然后你可以运行生成的树。如果你掌握输入语言,你可以用引号操作。


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