Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Compiler construction 重用语义分析阶段的符号表生成代码_Compiler Construction_Code Generation_Code Reuse_Semantic Analysis_Symbol Table - Fatal编程技术网

Compiler construction 重用语义分析阶段的符号表生成代码

Compiler construction 重用语义分析阶段的符号表生成代码,compiler-construction,code-generation,code-reuse,semantic-analysis,symbol-table,Compiler Construction,Code Generation,Code Reuse,Semantic Analysis,Symbol Table,我目前正在为一种具有全局变量和嵌套子例程特性的语言构建编译器。以前,我只为只有局部变量而没有嵌套子例程的语言构建过编译器 在代码生成阶段,我有一个关于如何重用语义分析阶段填充的符号表的问题。我将符号表作为一个链表堆栈,其中每个链表表示在特定范围内声明的标识符。每次它进入一个作用域时,都会创建一个新的列表并将其推送到堆栈中,从而成为当前作用域。同样,每次它离开作用域时,堆栈顶部的列表都会弹出。最后,在语义分析完成后,我实际上有了空的符号表,就像它开始时一样。但是,代码生成器需要完全填充的符号表才能

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


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

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


当你弹出你的作用域时,不是像我现在假设的那样删除它,而是把指向作用域数据的指针分配给你为该作用域生成代码所依据的数据的一个成员,这样代码生成器就可以得到它。

这将是一个有点抽象的问题——就像你的问题一样——因为我对编译器的内部数据结构一无所知


当你弹出你的作用域时,不是像我现在假设的那样删除它,而是把指向作用域数据的指针分配给你为该作用域生成代码所依据的数据的一个成员,因此,代码生成器可以访问它。

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

您可以构建一个纯动态代码生成器,它在离开某个作用域时丢弃符号表信息,前提是它已经生成了该作用域的所有代码或要生成的IR。如果您正在构建一个快速且脏的编译器,那么这可以工作,并且在您的计算机没有很多内存的情况下非常有用。在现代个人电脑上,你不能提出后一种观点

如果在解析过程结束之前不进行任何代码分析/优化/IR或代码生成,那么您将不得不在每个范围信息的符号表上保留更长的时间。在这种情况下,您将发现您也必须挂起AST,否则您将无法从中生成代码。在现代个人电脑上,这不是一个问题

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


所有这些的要点是,不要扔掉符号表。保存它们并将它们与代码生成所需的代码结构相关联。您有很多内存可以保存它们。

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

您可以构建一个纯动态代码生成器,它在离开某个作用域时丢弃符号表信息,前提是它已经生成了该作用域的所有代码或要生成的IR。如果您正在构建一个快速且脏的编译器,那么这可以工作,并且在您的计算机没有很多内存的情况下非常有用。在现代个人电脑上,你不能提出后一种观点

如果在解析过程结束之前不进行任何代码分析/优化/IR或代码生成,那么您将不得不在每个范围信息的符号表上保留更长的时间。在这种情况下,您将发现您也必须挂起AST,否则您将无法从中生成代码。在现代个人电脑上,这不是一个问题

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


所有这些的要点是,不要扔掉符号表。保存它们并将它们与代码生成所需的代码结构相关联。你有很多内存可以保存它们。

我太笨了,实际上我可以将指向作用域数据的指针作为相应AST节点成员的一部分。它可以在以后和AST一起扔掉。我太愚蠢了,事实上我可以将指向作用域数据的指针作为相应AST节点成员的一部分。这实际上与公认的答案相同,但需要在最后两段中进一步挖掘。因为我只能接受一个答案,所以我们给出了upvote。同意,但这也是一个更详细/更好的答案,有理由+1这实际上与公认的答案相同,但需要在最后两段中进一步挖掘。由于我只能接受一个答案,因此给出了upvote。同意,但这也是一个更详细/更好的答案,带有推理+1您是否考虑过将符号表构造为一棵树而不是一个堆栈,因此最后有一整棵作用域树?您的意思是它遵循AST层次结构?我认为,与公认的答案一样,将各自的范围数据作为AST节点的一部分更好,这就是为什么在进入/退出范围时不需要遍历两次。否,范围遵循其自己的层次结构。保留所有变量及其所属范围的原因很多,包括符号列表和调试器。AST仍应指向解析中使用的符号。您可以为嵌套过程实现的符号表添加另一个名为“嵌套级别”的字段。您是否考虑过将符号表结构化为树而不是堆栈,所以在最后有一个完整的作用域树?你是说它遵循AST层次结构吗?我认为,与公认的答案一样,将各自的范围数据作为AST节点的一部分更好,这就是为什么在进入/退出范围时不需要遍历两次。否,范围遵循其自己的层次结构。保留所有变量及其所属范围的原因很多,包括符号列表和调试器。AST仍应指向分析中使用的符号。您可以将另一个名为nesting level的字段添加到符号表中,以实现嵌套过程。