从语义分析阶段重用符号表以生成代码

时间:2016-02-03 19:05:33

标签: compiler-construction code-generation code-reuse semantic-analysis symbol-table

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

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

2 个答案:

答案 0 :(得分:4)

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

如果已生成将为该范围生成的所有代码(或IR),则可以构建一个纯粹的即时代码生成器,该代码生成器在离开范围时抛弃符号表信息。如果您正在构建一个快速而脏的编译器,这可以工作,并且当您的计算机没有大量内存时它很有用。 (在现代PC上,你无法做出后一种说法。)

如果在解析过程结束之前没有进行任何代码分析/优化/ IR或代码生成,那么您将不得不延长每个范围的符号表信息。你会发现在这种情况下你也必须挂在AST上,否则你将无法生成代码。 (在现代PC上,这不是问题)。

要构建具有简单体系结构的编译器,您可能希望无论如何都要分离解析,语义分析和代码生成过程。在这种情况下,您的解析器运行并只构建AST;不要打扰建立一个符号表。传递两个遍历树,并构建符合AST部分的符号表,并保持这种关系;现在你有AST和相关的符号表。传递3现在可以遍历AST并使用符号信息生成和IR。通过4优化IR;它仍然可以引用装饰有类型信息和可能的存储位置分配的符号表条目。之后,您可以进行优化和最终代码生成。

所有这一切的要点是,不要抛弃符号表。保存它们并将它们与代码生成所需的代码结构相关联。你有足够的记忆来保存它们。

答案 1 :(得分:1)

这有点抽象 - 作为您的问题 - 因为我不了解您的编译器内部数据结构的具体内容。

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