对于简单的变换,我的AST应该是什么样的?

时间:2009-01-06 14:59:24

标签: compiler-construction abstract-syntax-tree

我有一个类似于javascript的最小玩具语言。我生成一个AST来尝试一些优化技术,如逃逸分析,类型推断。我尝试了一些方法,如概括运算符令牌而不是每个节点的类/函数,保持每个节点上的类型信息......但我仍然不觉得我会去任何地方。工作很快就变得笨拙......

我研究过lua5,neko,v8但是......好吧......我肯定不是最聪明的人之一。

有没有人有设计AST和在AST上实现转换的经验,这很容易使用?我会很感激让您的生活更轻松的提示和技巧吗?

(请不要告诉我去阅读龙书。我已经有了。)

4 个答案:

答案 0 :(得分:3)

正如艾伦所说,Appel的书很棒。我在ML 中有现代编译器实现,用于编译器的本科课程。

我个人会避免在AST上做很多转换,因为你可以拥有不同结构的数量以及可以表达同一事物的方式。您经常需要编写处理大量案例和子案例的代码,正如您所说,它很快就会变得笨拙。

最好将AST转换为更小的表示,例如控制流图中的基本块。然后可以将每个操作写为基本块中的简单语句。应该保持一小部分可能的操作。只需确保保留足够的信息,您仍然可以进行所需的所有转换(特别是不要丢弃类型)。您还可以使用单一静态分配表单,其中每个程序变量仅分配一次。这提供了一个不变量,简化了大量的转换和分析。

答案 1 :(得分:0)

我使用ANLTR.org,我觉得很容易。

答案 2 :(得分:0)

好的,我不推荐龙书,因为你已经拥有它。我可以推荐Appel本书吗?甚至有一些source code演示了这些概念,其中使用了访问者模式将抽象语法树转换为具体语法树。祝你好运,享受!

答案 3 :(得分:0)

AST表示程序的结构。对于复杂语言, 你的AST必然会很复杂。所以不要假设这一点 应该“容易”。

许多人认为拥有AST,生活会更容易。 但解析只是喜马拉雅山脉的山麓。 AST并不代表常见的推论, 例如标识符的含义,接下来执行的语句, 消耗此数据的位置。 除非你拥有所有这些,否则你不会这样做 能用真正的语言做很多事情,更不用说了 很容易做到。

最好将这些推断结果缓存或显式: 符号表,控制流,数据流,......

可以添加模式匹配语言来启用 识别语法结构,甚至编写转换 规则:

optimize_increment(x:exp):statement
= " \x=\x+1; " -->  " \x++ " if no_side_effects(x);

这些规则需要借鉴缓存的推论(例如, “side_effects”)。

尝试构建所有这些非常困难。一种方法 这种做法是分摊基础设施成本 许多语言和转换应用程序。 我们的DMS Software Reengineering Toolkit具有不同程度的所有这些机制,适用于各种语言,包括C,C ++,Java,C#和COBOL。