Compiler construction 对于简单的转换,我的AST应该是什么样子?

Compiler construction 对于简单的转换,我的AST应该是什么样子?,compiler-construction,abstract-syntax-tree,Compiler Construction,Abstract Syntax Tree,我有一个类似于javascript的最小玩具语言。我生成一个AST来尝试一些优化技术,比如逃逸分析、类型推断。我尝试了一些方法,比如泛化操作符标记,而不是每个标记的类/函数,在每个节点上保留类型信息。。。但我还是觉得我哪儿也去不了。它很快变得难以处理 我学过lua5,neko,v8但是。。好。。。我肯定不是周围最聪明的人之一 有没有人有设计AST和在AST上实现转换的经验,这很容易操作?我会很感激能让你的生活更轻松的提示和技巧 (请不要告诉我去看龙书,我已经有了。)我用的是我觉得很简单的。好吧,

我有一个类似于javascript的最小玩具语言。我生成一个AST来尝试一些优化技术,比如逃逸分析、类型推断。我尝试了一些方法,比如泛化操作符标记,而不是每个标记的类/函数,在每个节点上保留类型信息。。。但我还是觉得我哪儿也去不了。它很快变得难以处理

我学过lua5,neko,v8但是。。好。。。我肯定不是周围最聪明的人之一

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


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

我用的是我觉得很简单的。好吧,我不推荐龙书,因为你已经有了。我能推荐这些书吗?甚至有一些演示了这些概念,其中包括使用访问者模式将抽象语法树转换为具体语法树。祝你好运,祝你愉快

正如艾伦所提到的,阿佩尔的书很棒。我在一门关于编译器的本科课程中用ML实现了现代编译器

我个人会避免在AST上进行许多转换,这仅仅是因为您可以使用的不同构造的数量以及同一事物可以表达的方式的数量。您经常需要编写处理大量案例和子案例的代码,正如您所说的,很快就会变得非常笨拙


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

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

许多人认为有了AST,生活会更轻松。 但这只是喜马拉雅山的山麓。 AST不代表常见的推论, 例如标识符的含义,接下来执行什么语句, 使用此数据的位置。 除非你有所有这些,否则你不会 能够用一门真正的语言做很多事情,更不用说 做起来容易

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

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

此类规则需要利用缓存的推论(例如。, “副作用”)

试图建立这一切真的很难。一种方法 这是一种实际的做法,即在整个项目中分摊基础设施成本 许多语言和转换应用程序。
我们有各种不同的机器,包括C、C++、爪哇、C和COBOL等各种各样的语言。

唯一的问题是“它变得笨重”。什么(什么事情,什么行动)变得笨拙?你在使用什么工具?我有一个ast作为javascript对象。例如,当我有一个操作符节点时,我有较少的常规左字段和右字段,而不是子数组。我不知道这是否是一个好的选择(例如:推断类型),即使我尝试了另一种方法。
optimize_increment(x:exp):statement
= " \x=\x+1; " -->  " \x++ " if no_side_effects(x);