我正在尝试为以下表达式创建一个逻辑表达式解析器: ((VariableA -> VariableB) AND NOT VariableC) 对于给定的变量值,无论结果是真还是假,解析器都应该能够返回。
基本上,表达式将只包含变量、逻辑运算符(或、和、蕴涵、等价、否定和括号)。
我想问一下实现这种解析器的最佳方法是什么(使用 AST 树或反向波兰表示法)?或者也许已经存在一些可以完成这项工作的开源解析器?
我正在尝试为以下表达式创建一个逻辑表达式解析器: ((VariableA -> VariableB) AND NOT VariableC) 对于给定的变量值,无论结果是真还是假,解析器都应该能够返回。
基本上,表达式将只包含变量、逻辑运算符(或、和、蕴涵、等价、否定和括号)。
我想问一下实现这种解析器的最佳方法是什么(使用 AST 树或反向波兰表示法)?或者也许已经存在一些可以完成这项工作的开源解析器?
你的目标是什么语言?
如果您想创建一个解析器,也许ANTLR会为您解决问题。它最初是基于 java 的,但它具有多种语言的生成器(例如,我用它来生成 C# 解析器)并且不难上手。它有一个很好的编辑器(ANTLRWorks),可以测试语法,这是一个很好的加分项。
如果我是你,我会使用 RPN。这应该可以在解析它时为您省去一些麻烦,并且算法应该像在运算符进入时推送和弹出一堆值一样简单。您也不必用括号来愚弄,这应该会让生活更轻松。唯一真正的缺点是大多数人不熟悉后缀(AKA RPN)表示法。
堆栈可能也比树更容易使用。
只是我的 2 美分 :)
如果您使用 Python,请尝试使用pyparsing编写的表达式 parser/evaluator作为起点。
这听起来像一个家庭作业:-)
首先,您必须递归地定义您的语言。
变量是良构形式 (WFF)
如果 X 是 WFF 则不是 X 是 WFF
如果 X 和 Y 是 WFF,则 (X -> Y) 是 WFF
如果 X 和 Y 是 WFF,那么(X AND Y 是)一个 WFF
定义语法后,使用 LEX 或 Flex 或 Java 的等效语言或您喜欢的语言来编写简单的扫描器。
使用 YACC 或 Bison 或等效物来编写后代递归解析器。
稍后将属性添加到语法中,以便以后代递归方式获得要评估的表达式的评估。
你看过http://ncalc.codeplex.com吗?
它是可扩展的、快速的(例如有自己的缓存),使您能够通过处理 EvaluateFunction/EvaluateParameter 事件在运行时提供自定义函数和变量。它可以解析的示例表达式:
表达式 e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)");
e.Parameters["Pi2"] = new Expression("Pi * Pi"); e.Parameters["X"] = 10;
e.EvaluateParameter += delegate(string name, ParameterArgs args) { if (name == "Pi") args.Result = 3.14; };
Debug.Assert(117.07 == e.Evaluate()); 它还原生处理 unicode 和许多数据类型。如果您想更改语法,它会附带一个 antler 文件。还有一个 fork 支持 MEF 加载新功能。