转换为另一种语言

cha*_*man 1 c compiler-construction

代码可以转换的典型方法是什么?目前,我正在编写一种简单的编程语言,它的处理方式是递归的.循环的节点列表,并说当前节点是一个变量节点,它将调用一个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
}
Run Code Online (Sandbox Code Playgroud)

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

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

Ira*_*ter 5

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

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

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

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

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

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

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