转换为另一种语言

代码可以转换的典型方法是什么? 目前,我正在编写一种简单的编程语言,它的处理方式是递归的。 循环的节点列表,并说当前节点是一个变量节点,它将调用emit_variable_node函数,它将字面上的一些代码附加到字符串,例如:

以下代码是psuedo-ish,我在C中编写我的项目,并编译为C.

 char *file_contents; void emit_variable_node(VariableNode *var) { // I know += doesn't work on strings, just pretend it does. file_contents += var.getType(); file_contents += " "; // a space file_contents += var.getName(); // etc } 

我还假设我们给出的代码已经过语义分析,并且是正确的。 然后将file_contents字符串存储到临时文件中,该文件在由C编译器编译后删除。

这是一种不好的做法,还是有更好,更清洁的方法来做到这一点?

您可以通过任何方式编写解析器,并在解析时生成代码,不需要AST节点(“语法定向转换”)。 这通常会产生非常糟糕的代码,因为代码生成器没有机会将上下文考虑在内以生成更好的代码。

您可以构建一个解析器来构建抽象语法树(AST)作为第一遍,然后作为第二遍遍历树生成代码而不查看任何相邻节点。 这只是其中ASTs的前一个答案。 这是一个非常糟糕的例子,未经优化的转换器输出完成了这样的事情。

更好的是从AST生成代码,其中每个AST节点本地代码生成器检查其邻居,以决定做什么。 这将为您提供更好的代码。

更好的解决方案是遵循传统编译器的主导,为您的语言构建良好的前端,包括符号表和控制以及数据流分析。 然后,您可以使用它来生成更好的代码。

关于实际代码生成:是的,您可以打印文本字符串。 字符串模板更方便,但它们只是打印文本字符串的一种奇特方式,因此它们不会增加任何function或提高结果代码质量。

更好的解决方案是将源语言中的AST转换为目标语言中的AST,包括所有本地检查,并使用符号表和流分析中的信息。 这样做的好处是,通过在目标语言中生成AST,您现在可以在目标语言中应用源语言中无法实现的优化。 [真正的编译器会做这样的事情,但他们使用的术语是“将AST转换为IR(内部表示)”并且它们在IR上进行优化。]在完成目标AST的所有优化之后,你必须打印漂亮最终的AST …使用类似字符串模板的东西。

大多数人没有能力从头开始构建一个好的转换器。 所以他们做了一些像第一个建议(只是说’)的hacky事情。 但是,如果您想要将代码从一种语言转换为另一种语言,那么请查看我们的DMS软件再造工具包 。 DMS具有多种语言的解析器,可以实现自定义语言的解析器,自动构建AST,为解析后的生命提供了大量支持,例如,构建符号表和流分析,进行AST到AST转换,并且具有漂亮的打印机。 DMS旨在成为支持此类任务的平台 。 这意味着您可以专注于构建任务的高质量翻译部分,而不是尝试构建所有有用的基础架构。