Parsing 逻辑表达式解析器

Parsing 逻辑表达式解析器,parsing,logic,expression,Parsing,Logic,Expression,我正在尝试为以下表达式创建逻辑表达式解析器: ((变量A->变量B)和非变量C) 解析器应该能够返回给定变量值的结果,无论结果是true还是false 基本上,表达式只包含变量、逻辑运算符(或、和、蕴涵、等价、否定和括号) 我想问一下实现这种解析器(使用AST树或反向波兰符号)的最佳方法是什么?或者可能已经有一些开源解析器可以完成这项工作?如果我是你,我会使用RPN。这将在解析时为您省去一些麻烦,而且算法应该简单到在运算符进入时推送和弹出一堆值。你也不必在括号里胡闹,这会让生活更轻松。唯一的缺点

我正在尝试为以下表达式创建逻辑表达式解析器: ((变量A->变量B)和非变量C) 解析器应该能够返回给定变量值的结果,无论结果是true还是false

基本上,表达式只包含变量、逻辑运算符(或、和、蕴涵、等价、否定和括号)


我想问一下实现这种解析器(使用AST树或反向波兰符号)的最佳方法是什么?或者可能已经有一些开源解析器可以完成这项工作?

如果我是你,我会使用RPN。这将在解析时为您省去一些麻烦,而且算法应该简单到在运算符进入时推送和弹出一堆值。你也不必在括号里胡闹,这会让生活更轻松。唯一的缺点是大多数人不熟悉后缀(又名RPN)符号

堆栈可能也比树更容易使用


就我的2;)

你的目标语言是什么

如果你想创建一个解析器,也许可以帮你。它最初是基于java的,但它有多种语言的生成器(例如,我使用它来生成C#解析器),并且不太难掌握。
它有一个很好的编辑器(AntlWorks),允许测试语法,这是一个很好的优点。

我确信已经有一些工具可以做到这一点(逻辑求值),但我找不到任何工具。如果您使用(YACC,用于C)或(生成许多语言,但使用Java)之类的工具,您就不必太担心解析。是另一个可以生成多种不同语言的解析器生成器。如果您想自己做,我会使用RPN或前缀表示法(我认为这比RPN简单)。这将使解析变得更加简单,但会让用户感到烦恼。

这听起来像是一个家庭作业:-)

首先,你必须递归地定义你的语言

变量是格式良好的形式(WFF)

如果X是WFF,那么不是X是WFF

如果X和Y是WFF,那么(X->Y)是WFF

如果X和Y是WFF,那么(X和Y)是WFF

一旦定义了语法,就使用LEX或Flex或Java的等效工具 或者你喜欢的语言来编写一个简单的扫描器

使用YACC或Bison或等效工具来编写后代递归解析器


稍后,将属性添加到语法中,以便以子代递归方式获得要计算的表达式的计算结果。

如果您使用Python,请尝试使用作为起点编写。

您看到了吗

它是可扩展的、快速的(例如有自己的缓存),使您能够通过处理EvaluateFunction/EvaluateParameter事件在运行时提供自定义函数和变量。它可以解析的示例表达式:

表达式e=新表达式(“圆形(Pow(Pi,2)+Pow([Pi2],2)+X,2”)

e、 参数[“Pi2”]=新表达式(“Pi*Pi”); e、 参数[“X”]=10

e、 EvaluateParameter+=委托(字符串名称、参数args args) { 如果(名称=“Pi”) 参数结果=3.14; };

Assert(117.07==e.Evaluate());
它还以本机方式处理unicode和许多数据类型。如果你想更改语法,它附带一个鹿角锉。还有一个fork支持MEF加载新函数

Yacc和Bison不创建递归下降解析器,但是表驱动的shift-reduce(即自底向上)解析器。真的!touchee。从一段时间以来,我不再使用lex和yacc。实现一个递归下降解析器。逻辑表达式非常简单,很容易用这种方式解析。解析操作可以从堆栈中计算变量、push/pop中间值。这应该是~~ 50行C代码。