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

时间:2010-02-04 18:03:40

标签: java code-generation abstract-syntax-tree dsl

我正在开发一个非常复杂的DSL,我想将其编译成几种高级语言。整个过程一直是学习的经历。编译器是用java编写的。

我想知道是否有人知道代码生成器部分设计的最佳实践。我目前已将所有内容解析为抽象语法树。

我正在考虑使用模板系统,但我还没有研究过这个方向,因为我希望首先从堆栈溢出中听到一些智慧。

谢谢!

4 个答案:

答案 0 :(得分:9)

当我在编程语言课程中执行此操作时,我们最终使用基于visitor pattern的发射器。它工作得很好 - 只要你的AST与你打印的相当匹配,就可以很容易地将它重新定位到新的输出语言。

答案 1 :(得分:6)

你真正想要的是program transformation system,它将一种语言(你的DSL)的语法结构映射到其他语言中的语法模式。这样的工具可以在代码生成项目期间执行任意转换(树重写一般化的字符串重写,这是Post系统,具有完全图灵功能),这意味着您生成的内容和生成过程的复杂程度仅由您的野心决定,而不是“代码生成器框架”属性。

Sophtisticated程序转换系统结合了各种类型的范围,流量分析和/或自定义分析器来实现转换。这并没有增加任何理论能力,但它增加了许多实际功能:大多数真实语言(甚至DSL)都有命名空间,控制和数据流,需要类型推断等等。

我们的DMS Software Reengineering Toolkit就是这种转型系统。它已被用于分析/转换传统语言和DSL,简单和复杂的语言,以及小型,大型甚至是巨大的软件系统。

与OP关于"turning the AST into other languages", that is accomplished by DMS by writing transformations that map surface syntax for the DSL (implemented behind the scenes his DSL's AST) to surface syntax for the target language的评论相关(使用目标语言AST实现)。然后由DMS自动生成由此产生的目标语言AST,以提供目标语言的实际源代码,该代码对应于目标AST。

答案 2 :(得分:3)

如果您已经在使用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字节码的示例。

答案 3 :(得分:-1)

DSL是一件好事。写它们是一种很好的做法。

但我不确定在2010年实施自己的YACC和类似的是一个不错的选择,除非它只是为了娱乐或教育。

当您完成教育过程并开始寻找实施DSL的好方法时,您可以考虑使用动态语言。

例如,使用Groovy,您可以非常轻松,愉快地实现小型和大型DSL。
BTW Groovy内置了AST操作API。