我目前正在为一种具有全局变量和嵌套子例程功能的语言构建编译器。以前,我只为只有局部变量而没有嵌套子例程的语言构建过编译器。
我有一个关于如何重用在代码生成阶段的语义分析阶段填充的符号表的问题。我将符号表作为链表堆栈,其中每个链表代表在特定范围内声明的标识符。每次进入一个作用域时,都会创建一个新列表并将其推入堆栈,并成为当前作用域。同样,每次离开作用域时,堆栈顶部的列表都会弹出。最后,语义分析完成后,我几乎有空的符号表,就像它开始时一样。然而,代码生成器需要完全填充的符号表才能正确生成代码。如何在不重新执行语义分析期间所做的事情(即向符号表中输入标识符)的情况下完成此操作?
您必须决定编译器将保留多少上下文来支持优化和代码生成。
您可以构建一个纯粹的动态代码生成器,如果它已生成将为该范围生成的所有代码(或 IR),则该生成器会在离开范围时丢弃符号表信息。如果您正在构建一个快速而肮脏的编译器,那么这可以工作,并且当您的计算机没有大量内存时,这很有用。 (在现代 PC 上,您不能提出后一种说法)。
如果您在到达解析过程结束之前不进行任何代码分析/优化/IR 或代码生成,那么您将不得不更长时间地保留每个范围的符号表信息。在这种情况下,您会发现您还必须保留 AST,否则您将无法生成代码。 (在现代 PC 上,这不是问题)。
要构建具有简单架构的编译器,您可能希望隔离解析、语义分析和代码生成过程。在这种情况下,您的解析器运行并仅构建一个 AST;不必费心构建符号表。通过两次遍历树,构建与 AST 部分相对应的符号表,并保持这种关系;现在您有了 AST 和关联的符号表。第 3 遍现在可以遍历 AST 并使用符号信息来生成 IR。 Pass 4优化IR;它仍然可以引用用类型信息和可能的存储位置分配修饰的符号表条目。之后,您可以进行优化和最终代码生成。
这一切的要点是,不要扔掉符号表。保存它们并将它们与代码生成所需的代码结构相关联。你有足够的内存来保存它们。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)