c# - 从字符串描述构建 bool 函数

标签 c# algorithm parsing expression-evaluation

我有一个大型 bool 值数据库,我想构建一个框架来轻松地对所有值运行查询。为此,我想编写一个函数,给定一个 bool 表达式的字符串表示形式,该函数将对数据库的所有元素评估该表达式。例如给定输入

(a && b) || c

该函数将构造另一个函数来评估

return (funcA() && funcB()) || funcC();

其中 funcAfuncBfuncC 是返回 bool 值的函数

最佳答案

这似乎最好分三步完成。

首先,您需要弄清楚您应该评估的具体内容。这通常分两个步骤完成,称为扫描解析。扫描的工作是将输入字符串分解为一系列标记,即构成文本的较小逻辑单元。例如,给定字符串

(a && b)

你会把它分解成标记

(
a
&&
b
)

通常,这是使用正则表达式完成的,但您也可以手动完成。主要思想是将确定字符串片段的任务与查看这些片段如何关联的任务分开。

扫描完输入后,您需要对其进行解析以确定所说的内容。也就是说,您会将标记重新组合成一个完整的数学表达式编码运算符优先级、正在使用的操作数等。有很多算法可以做到这一点,但其中最简单的可能是 Dijkstra 的 shunting yard algorithm,这很容易实现。您可能会使用抽象语法树(一种对输入结构进行编码的树结构)存储此解析步骤的输出。

此时,您对要评估的表达式的含义有了明确的解释,您需要实际评估它!为此,您可能会为每个 AST 节点定义一些函数以从该节点生成值。对于像 && 这样的运算符,您将评估左右子表达式,然后计算它们的 AND(或者可能使用短路来避免在 lhs 为假时计算 rhs)。对于单个字母,您可以使用反射来调用相应的方法,或者可以有一个表将名称映射到函数(取决于您想要的安全性。)

作为编码方面的潜在优化,您可能需要考虑省略 AST 的构造,而只计算您想要的值。调车场算法(以及许多其他解析器,例如自上而下的 LL(1) 或自下而上的 LR(1) 解析器)通常让您根据表达式的组成表达式计算表达式的一些总体值,并且它以这种方式编写代码可能更容易。但是,如果您计划在像数据库这样的巨大数据集上使用所描述的函数,计算 AST 将为您提供一个对象,您可以调用数据库中的每个值来生成您想要的值。

如果您计划对大量数据运行非常复杂的查询,您甚至可能想更进一步,将生成的表达式实际转换为 C# 代码,然后编译并加载到正在运行的程序中。我在 Java 中看到过这样的示例,其中使用它效果很好,但这是针对非常高性能的应用程序的,除非您已经用尽所有其他选项,否则可能有点矫枉过正。

希望这对您有所帮助!

关于c# - 从字符串描述构建 bool 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7253937/

相关文章:

algorithm - 后缀树 VS 尝试 - 用简单的英语来说,有什么区别?

c# - 如何分割这个字符串

javascript - 如何将 HTML 字符串转换成 HTML 文档?

javascript - 逗号插入无限小数中

c# - 手动终止递归

javascript - MOD 10 算法的 JQuery 或 Javascript 函数

c# - 计算给定时间段内的正常工作日

c# - 在 Windows 窗体中加载没有 CrystalReportViewer 的 Crystal 报表模板

c# - 运行 CMD 和 ffmpeg Windows 窗体

c++ - Qt-Creator 无法解析通用 Qt-project,但包含 OK