我正在研究一个非常复杂的 DSL,我想将它编译成一些高级语言。整个过程是一次学习经历。编译器是用java编写的。
我想知道是否有人知道代码生成器部分设计的最佳实践。我目前已将所有内容解析为抽象语法树。
我正在考虑使用模板系统,但我还没有深入研究这个方向,因为我想先从堆栈溢出中听到一些智慧。
谢谢!
我正在研究一个非常复杂的 DSL,我想将它编译成一些高级语言。整个过程是一次学习经历。编译器是用java编写的。
我想知道是否有人知道代码生成器部分设计的最佳实践。我目前已将所有内容解析为抽象语法树。
我正在考虑使用模板系统,但我还没有深入研究这个方向,因为我想先从堆栈溢出中听到一些智慧。
谢谢!
当我在我的编程语言课上做这件事时,我们最终使用了基于访问者模式的发射器。它工作得很好——只要您的 AST 与您正在打印的内容相当匹配,就可以很容易地将其重新定位到新的输出语言。
您真正想要的是一个程序转换系统,它将一种语言(您的 DSL)中的语法结构映射到其他语言中的语法模式。这样的工具可以在代码生成项目期间进行任意转换(树重写概括了字符串重写,它们是具有完全图灵能力的 Post 系统),这意味着您生成的内容和生成过程的复杂程度仅由您的野心决定,而不是由“代码生成器框架”属性。
复杂的程序转换系统结合了各种类型的范围界定、流分析和/或自定义分析器来实现转换。这并没有增加任何理论能力,但增加了很多实际能力:大多数真实语言(甚至 DSL)都有命名空间、控制和数据流、需要类型推断等。
我们的DMS Software Reengineering Toolkit就是这种类型的转换系统。它已被用于分析/转换传统语言和 DSL、简单和复杂的语言,以及小型、大型甚至巨大的软件系统。
与 OP 关于“将 AST 转换为其他语言”的评论相关,这是由 DMS 通过编写将 DSL 的表面语法(在他的 DSL 的 AST 幕后实现)映射到目标语言的表面语法(使用 target 实现)来完成的语言 AST)。然后,DMS 会自动对生成的目标语言 AST 进行漂亮打印,以提供与目标 AST 对应的目标语言的实际源代码。
如果您已经在使用 ANTLR 并准备好 AST,您可能想看看 StringTemplate: http ://www.antlr.org/wiki/display/ST/StringTemplate+Documentation
The Definitive ANTLR Reference: Building Domain-Specific Languages 的第 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 字节码的示例。