从AST生成代码的最佳设计?

25
我正在研究一个相当复杂的DSL,并希望将其编译成几种高级语言。整个过程都是一个学习经验。编译器是用Java编写的。
我想知道是否有人知道代码生成器部分的最佳设计实践。我目前已将所有内容解析为抽象语法树。
我正在考虑使用模板系统,但我还没有深入研究这个方向,因为我想先听听stackoverflow社区的建议。
谢谢!

1
也许只是因为你很久以前就问过了。但截至今天(2013年),ANTLR(你似乎正在使用)已经内置了“字符串模板”。 - Ira Baxter
3个回答

12

当我在编程语言课上做这个项目时,我们最终使用了基于遵循访问者模式的发射器。它运行得相当不错 - 只要您的AST与您正在打印的内容相匹配,将其重新定位到新的输出语言就非常容易。


谢谢你的想法。我熟悉访问者模式,并将其用于在树中优化文字表达式。 - Sam Washburn
不是说你不熟悉它,只是建议它可能成为一个很好的代码生成器 :-) - Steven Schlansker
是的,我并不是要表现得自大。我正在调查这个问题,谢谢。 :) - Sam Washburn
2
访问者很有效,但原始。你看过像Stratego/XT这样的东西吗? - gatoatigrado

8
你真正需要的是一个程序转换系统,它可以将一种语言(你的DSL)中的语法结构映射到其他语言的语法模式中。这样的工具可以在代码生成项目期间执行任意转换(树重写概括了字符串重写,后者是Post系统,完全具备图灵能力),这意味着你生成的内容和生成过程的复杂性仅由你的野心决定,而不受“代码生成器框架”属性的限制。
复杂的程序转换系统结合了各种类型的作用域、流分析和/或自定义分析器来实现转换。这并没有增加任何理论上的能力,但增加了很多实际能力:大多数真实语言(甚至DSL)都有命名空间、控制和数据流、需要类型推断等等。
我们的DMS软件重构工具包就是这种转换系统。它已被用于分析/转换传统语言和DSL,适用于简单和复杂的语言,以及小型、大型甚至巨型软件系统。

关于OP提到的"将抽象语法树转换为其他语言",这可以通过DMS编写映射DSL(在其DSL的AST背后实现)的表面语法到目标语言的表面语法的转换来实现(使用目标语言的AST实现)。然后,DMS会自动将生成的目标语言AST进行漂亮打印,以提供与目标AST相对应的实际目标语言源代码。


4
如果您已经使用ANTLR并准备好AST,则可以查看StringTemplate: http://www.antlr.org/wiki/display/ST/StringTemplate+Documentation 此外,《ANTLR权威指南》的第9.6节对此进行了解释: http://www.pragprog.com/titles/tpantlr/the-definitive-antlr-reference 免费的代码示例可在http://media.pragprog.com/titles/tpantlr/code/tpantlr-code.tgz上找到。在code\templates\generator\2pass子文件夹中,您将找到一个将数学表达式转换为Java字节码的示例。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接