【问题标题】:Boolean and Math Expression Parser布尔和数学表达式解析器
【发布时间】:2010-02-18 20:33:38
【问题描述】:

我正在编写一个允许用户输入布尔表达式的应用程序。我需要能够在运行时评估输入的布尔表达式,并且正在寻找解析器和 expressoin 验证器。

解析器
解析器需要将布尔表达式作为字符串并返回真/假。

示例:

字符串表达式 = "(1 == 1) && (1 > 0)"; 解析器 parser = new Parser(); 布尔结果 = parser.parse(表达式); // 结果应该为真。

除了处理布尔表达式,我还需要它来处理数学。

表达式 = "((1 + 1 * 2) == 1)"; 结果 = parser.parse(表达式); // 结果应该是假的。

验证
为了告诉用户输入的表达式是否有问题,我还需要一种方法来验证语法。

我正在使用 .NET Compact Framework 在 C# 中工作,但如果您知道用另一种语言编写的内容可能会有所帮助。

感谢您提供的任何帮助。 汤姆

【问题讨论】:

    标签: .net compact-framework parsing boolean expression


    【解决方案1】:

    我们的项目使用NCalc(下面带有ANTLR 用于词法分析/解析),我们对此非常满意。

    NCalc 是一个数学表达式 .NET 中的评估器。 NCalc 可以解析任何 表达并评估结果, 包括静态或动态参数 和自定义函数。

    我们的应用程序需要针对完整框架和紧凑框架进行交叉编译。通过相对简单的调整,我们能够使 NCalc 和 ANTLR 都适用于两种框架风格。

    【讨论】:

      【解决方案2】:

      http://www.antlr.org

      Antlr 语法可以设计为允许解析和评估。

      这是一个例子:http://www.antlr.org/wiki/display/ANTLR3/Expression+evaluator

      【讨论】:

      • +1 用于 ANTLR。如果你看到这个并忽略它,认为这太麻烦了,请重新考虑。我建议您使用 ANTLRworks 作为语法开发工具,并将其词法分析器和解析器类输出到您的 Visual Studio 项目树中。它相对无缝,可以轻松地反复调整语法并快速查看其在 .NET 世界中的效果。
      • 上面的“你”是指托马斯大帝。
      • @Chris Farmer:这是针对 C# Compact Framework...可能有点重...
      • 我不知道。使用相对简单的表达式语法,生成的词法分析器和解析器将非常小。值得一试,IMO。如果它不起作用,Thomas 至少很容易预先意识到这一点,所以如果它不起作用,也不会浪费太多时间。
      【解决方案3】:

      假设您可以稍微更改语法,让嵌入式数据库使用类似 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
      

      【讨论】:

      • 根据问题,表达式实际上是用户输入的。因此,您的解决方案容易受到 SQL 注入的影响。
      【解决方案4】:

      我不知道有什么库可以让这更容易,但你真的只有两个子问题。你需要构建一个中缀到后缀的转换器,然后为布尔和数学运算编写一个基本的计算器。

      构建布尔树/堆栈后,开始执行操作。如果你有任何不是数字的东西,通过将字符串/表达式发送到算术计算器来计算它,该计算器执行中缀->后缀转换,然后返回一个值。

      如果你谷歌“infix to postfix”和“stack rpn calculator”,你可能会找到更多资源。

      【讨论】:

      • 但是,如果您可以使用“eval”转义到一种语言,那么问题就解决了。您寻找真假,其他一切,您都知道自己是无效的。
      • 我认为“eval”是完全错误的方式。这可能很容易,但让人们用你的语言编写任何合法的代码是有风险的。恕我直言,最好有可用于这些表达式的独特且有限的语法。
      【解决方案5】:

      您可以使用dotMath 库来执行此操作。

      【讨论】:

        【解决方案6】:

        这是Codeproject 上的一个出色的评估解析器,它使用 eval 方法并且不依赖于 CodeDOM 或类似的东西。这是一篇关于使用 Antlr 构建 expression evaluator 的优秀文章,也在同一个站点上..

        希望这会有所帮助, 最好的祝福, 汤姆。

        【讨论】:

          【解决方案7】:

          这种类型的东西是 F# 的生计。你可以试试看。对于解析,使用递归下降,然后你可以在结果树上运行。如果您可以控制输入语言,则可以使用引号操作。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-08-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-02-25
            • 2021-12-09
            相关资源
            最近更新 更多