抽象语法树上的代数简化

问题描述 投票:0回答:1

我已经在C语言中设计了一个能够生成AST的解析器,但是当我开始实现简化时,它真的很混乱。我已经成功实现了以下求和规则;

x + 0 -> x

x + x -> 2 * x

但是要花很多精力和代码才能做到。我要做的是搜索整棵树,然后尝试找到我可以使用的模式(很多递归),然后如果有一系列PLUS节点,我将它们添加到列表中,然后在该列表上工作(求和)然后合并变量等),然后从该列表中创建了另一棵树,并将其合并到现有树中。正是我用来实现它的paper。简而言之,给定表达式2*x+1+1+x+0,我得到了3*x+2。仅仅是总结使我陷入了很多麻烦,我什至可以想象高级的东西。所以我意识到自己在猜错。

我已经阅读了this线程,但是我对术语重写系统(实际上是什么,如何在C中实现)感到困惑。

是否有更通用,更有效的方法来简化AST?或如何在C中编写术语重写系统]

c abstract-syntax-tree algebra rewriting
1个回答
1
投票

术语重写(简单来说)就像您提供的2个示例。 (如何在AST中将x + 0转换为x?)。它与AST上的模式匹配有关,一旦存在匹配,即转换为等效表达式。它也称为术语重写规则。

请注意,具有术语重写规则不是代数简化的绝对或一般解决方案。通用解决方案涉及许多重写规则(您显示了其中两个),然后将它们重复应用于给定的AST中,直到没有一个成功为止。

然后,一般解决方案涉及重写规则的应用过程或协调。例如,为了避免重新应用以前失败的规则,例如。

没有唯一的方法。有几种系统。对于专有系统,它是保密的,因此未知,但是它们也存在开源系统,例如Mathomatica用C编写。

我建议您检查打开的系统Fōrmulæ。在这种情况下,重写规则的协调过程(称为“约简引擎”)相对简单。它是用Java编写的。该系统的优点是,重写规则在系统或归约引擎(它们为hot pluggable)中不经过硬连线/硬编码。编码重写规则涉及模式匹配和转换的过程,但不涉及调用它的时间或方式(它遵循Hollywood Principle)。

Fōrmulæ的特定情况下:

  1. 还原引擎(一般而言)基于post-order tree traversal algorithm。因此,当“访问”一个节点时,它的子节点已经被访问和(可能)进行了转换,但是可以更改这种流程(即解决分配x <- 5中变量的不必要引用)。请注意,这不仅是遍历树,而且实际上是在此过程中更改AST。

  2. 为了有效地管理(可能成百上千个)重写规则,每个规则在适用的地方都有一种表达类型,并且当“访问”单个节点时,仅检查相关联的规则是否存在比赛。例如,您的2条规则只能应用于AST的“添加”节点。

[重写规则不仅限于代数简化,它们还可以用于许多其他领域,例如编程(Fōrmulæ也是其编程语言,请参见examples of Fōrmulæ programs,或者用于自动或辅助定理证明。

© www.soinside.com 2019 - 2024. All rights reserved.