Closed 。这个问题需要多问focused 。目前不接受答案。
代码转编译的典型方式有哪些?目前,我正在编写一种简单的编程语言,其处理方式是递归的。循环遍历一个节点列表,假设当前节点是一个变量节点,它会调用一个emit_variable_node
函数,它会将一些代码逐字附加到字符串中,例如:
以下代码是伪代码,我正在用 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),然后作为第二遍遍历树生成代码,而不查看任何相邻节点。这只是之前的答案,其中包含 AST。
这是一个未优化的转译器输出的极其糟糕的示例 做了这样的事情。
更好的方法是从 AST 生成代码,其中每个 AST 节点本地代码生成器检查其邻居,以决定要做什么。这将为您提供更好的代码。
更好的解决方案是效仿传统编译器,为您的语言构建一个良好的前端,包括符号表以及控制和数据流分析。然后您可以使用它来生成更好的代码。
关于实际代码生成:是的,您可以打印文本字符串。字符串模板更方便一些,但它们只是打印文本字符串的一种奇特方式,因此它们不会增加任何功能或提高生成的代码质量。
更好的解决方案是将源语言的 AST 转换为目标语言的 AST,包括所有本地检查以及使用符号表和流分析中的信息。这样做的好处是,通过用目标语言生成 AST,您现在可以在目标语言中应用源语言中无法实现的优化。 [真正的编译器会做这样的事情,但他们使用的术语是“将 AST 转换为 IR(内部表示)”,并且他们对 IR 进行优化。] 在目标 AST 上的所有优化完成后,您必须漂亮地打印最终的 AST...使用字符串模板之类的东西。
大多数人没有精力从头开始构建一个好的转译器。所以他们做了一些像第一个建议这样的黑客行为(只是说说而已)。但是,如果您想要将代码从一种语言转换为另一种语言的真正良好基础,请查看我们的DMS 软件再造工具包 。 DMS拥有多种语言的解析器,可以实现自定义语言的解析器,自动构建AST,提供大量支持解析后的生活 ,例如,构建符号表和流分析、进行 AST 到 AST 转换,并拥有漂亮的打印机。DMS 被设计为支持此类任务的平台 。这意味着您可以专注于构建任务的高质量翻译部分,而不是尝试构建所有有用的基础设施。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)