重用语义分析阶段的符号 table 进行代码生成

Reusing symbol table from semantic analysis phase for code generation

我目前正在为一种具有全局变量和嵌套子例程功能的语言构建编译器。以前,我只为只有局部变量而没有嵌套子程序的语言构建了一个编译器。

我有一个关于如何重用在代码生成阶段的语义分析阶段填充的符号 table 的问题。我把符号 table 做成一个链表的栈,其中每个链表代表在特定范围内声明的标识符。每次进入范围时,都会创建一个新列表并将其推送到堆栈,它成为当前范围。同样,每次它离开一个作用域时,栈顶的列表就会被弹​​出。最后,在语义分析完成后,我实际上有一个空符号 table,就像它开始时一样。但是,代码生成器需要一个完全填充的符号 table 才能正确生成代码。如何在不重新做语义分析期间所做的事情的情况下完成这项工作(即为符号输入标识符table)?

这将有点抽象 - 正如你的问题 - 因为我对你的编译器的内部数据结构一无所知。

当你弹出你的范围时,而不是删除它,就像我假设你现在做的那样,将指向范围数据的指针分配给你为该范围生成代码的数据成员,这样代码生成器可以得到它。

您必须决定您的编译器将保留多少上下文以支持优化和代码生成。

您可以构建一个纯粹的动态代码生成器,如果它已经生成了所有它将要访问的代码(或 IR),那么它会丢弃有关离开范围的符号 table 信息为该范围生成。如果您正在构建一个快速而肮脏的编译器,这可能会起作用,并且当您的计算机没有很多内存时它很有用。 (在现代 PC 上,你不能做出后一个论点)。

如果您在解析过程结束之前不执行任何代码 analysis/optimization/IR 或代码生成,那么您将不得不挂在符号 -tables-per -范围信息更长。在这种情况下,您会发现您还必须依赖 AST,否则您将无法从中生成代码。 (在现代 PC 上,这不是问题)。

要构建具有简单体系结构的编译器,您可能想要隔离解析、语义分析和代码生成过程。在这种情况下,您的解析器运行并仅构建一个 AST;不要费心构建符号 table。通过两次遍历树,并构建对应于 AST 部分的符号 tables,并保持这种关系;现在你有 ASTs 和关联的符号 tables。第 3 轮现在可以遍历 AST 并使用符号信息生成 IR。第 4 遍优化 IR;它可能仍然引用用类型信息和可能的存储位置分配修饰的符号 table 条目。之后,您可以进行优化和最终代码生成。

所有这一切的要点是,不要丢弃符号 tables。保存它们并将它们与代码生成所需的代码结构相关联。你有很多内存可以保存它们。