parsing - 德摩根定律与 yacc

标签 parsing logic yacc

A 有一个用 yacc 编写的简单语法,它从逻辑表达式构建一棵树,由子表达式以及 AND (&&)、OR (||) 和 NOT (!) 运算符组成。我不会在这里提供语法本身,因为它没有什么特别的,它与无数的 YACC 教程示例类似。

但是,我需要解析这些逻辑表达式,以便根据德摩根定律为 NOT 运算符扩展所有括号。例如,我需要处理表达式

!( ( A && B ) || C ) ) 

作为

( !A || !B ) && !C

是否可以通过修改现有的 yacc 语法来实现?

最佳答案

在构建 AST 时,可以在 YACC 对 not (!) 运算符的归约操作中执行此操作。您可以在语义操作中编写任何您想要的代码。您可以编写检查子节点以查看是否具有需要形状,如果是这样,则构造每个形状的德摩根等效树。执行此操作的代码有点困惑,因为它必须在树上爬上爬下,匹配节点并重新排列子树,但这只是令人讨厌而且还不错。请注意,德摩根定律可以说适用于形状都类似于 ( A && B ) || 的 child 。 C ) 和 ( A || B && C)),所以你要处理两个主要的子情况。

我同意莱恩的观点;您通常不会在解析器中执行此操作。它的目的是让您为更复杂的事件做好准备,除非 DeMorganizing 是唯一的目的,否则您将需要其他代码来在解析完成后以各种方式处理 AST,所以为什么不将所有处理留到那里呢?

按照这个想法,我的 recent SO answer on eliminating configured-dead code简化符号 bool 逻辑;它展示了一种使用模式匹配源到源转换来转换 bool 逻辑 AST 的方法。这种方法避免了令人讨厌的树检查/黑客代码。如何使用该技术编写可读变换来实现德摩根定律应该是显而易见的(事实上我们过去已经这样做过)。

关于parsing - 德摩根定律与 yacc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10515272/

相关文章:

java - 用 Java 创建自然 DSL 的最佳工具是什么?

更改枚举算法以首先显示更大的范围

parsing - 我应该如何在 yacc/bison 和 lex 中制定递归规则?

parsing - Flex/Lex 和 Yacc/Bison 有什么区别?

python - python 中的 XML 解析 : expaterror not well-formed

c++ - 使用 Boost::spirit 编写的解析器的性能问题

python - 如何将多个列表转换为python中的字典?

coldfusion - 我怎样才能总是四舍五入到最接近的 10 个整数?

javascript - 求解代数方程的思维过程?

_Atomic 类型说明符和限定符之间的 C11 语法歧义