理论教育 编译器设计之路中的符号表含义及问题

编译器设计之路中的符号表含义及问题

时间:2023-11-04 理论教育 版权反馈
【摘要】:在编译过程中,编译器根据源程序声明语句收集各类语法元素的信息,并在符号表中建立相应的表项记录。从应用的角度来说,寄希望于从符号表获得一切关于输入源程序的符号信息的思想是可以理解的,但是,当符号表成为一本万宝全书时,问题也就随之而来了。因此,C编译器的符号表必须存在描述此信息的字段,而Pascal编译器则不必考虑。由于Neo Pascal语言是一种命令式语言,所以本书所讨论的符号表更多情况下适用于命令式语言编译器的构造。

编译器设计之路中的符号表含义及问题

符号表(symbol table)是一种供编译器存储关于源程序各种元素信息的数据结构。在编译过程中,编译器自动收集所需的信息,将其组织存储在符号表中,同时,依据这些信息完成代码优化和目标代码生成等。

符号表的功能包括以下几个方面:

(1)收集源程序中各元素的信息。在编译过程中,编译器根据源程序声明语句收集各类语法元素的信息,并在符号表中建立相应的表项记录。

(2)上下文语义相关性检查的依据。例如,表达式a%8中,编译器必须通过检索符号表获取标识符a的信息,尤其是其类型信息,只有当a是整型变量或符号常量时才符合取模运算的语义。

(3)存储分配的依据。在生成目标代码时,编译器必须最终为每个变量(包括用户变量和编译器产生的临时变量)分配存储空间。由于符号表完整地记录了所有变量的信息,因此它是目标代码生成器进行存储分配的重要依据之一。

实际上,符号表就是编译器的中心信息库。符号表收集信息的完备与否,直接影响编译器后续决策的质量。尤其是在优化代码及目标代码生成时,某些符号信息对于个别算法是极为重要的。例如,C语言中volatile修饰符对优化算法就提出了一定的要求。

从应用的角度来说,寄希望于从符号表获得一切关于输入源程序的符号信息的思想是可以理解的,但是,当符号表成为一本万宝全书时,问题也就随之而来了。为了达到这一目标,不得不以牺牲存储空间与检索访问时间为代价,这并不是设计者愿意看到的结果。早期编译器设计者对此极其关注,因为效率有时决定了该编译器的命运。优秀的编译器不仅要完成正确的翻译工作,时间、空间复杂度也是评价一个编译器的重要指标。虽然今天看来这些因素的重要性有所弱化,但是,它们仍然是系统软件(操作系统、编译器)的重要性能指标。通常,编译器设计者必须权衡两者的关系,并作出抉择。

那么,哪些信息需要保存到符号表中呢?这是根据具体程序设计语言而定的。不同程序设计语言的语法、语义规则都可能存在较大差异。对于不同范型的语言而言,由于它们的语言模型差别巨大,应用领域与设计目标也各不相同,因此,符号表的结构也必定存在差异。例如,C语言中可以使用static、register等修饰变量,而Pascal语言则不存在这种语法机制。因此,C编译器的符号表必须存在描述此信息的字段,而Pascal编译器则不必考虑。由于Neo Pascal语言是一种命令式(或称为过程式)语言,所以本书所讨论的符号表更多情况下适用于命令式语言(例如,C、Fortran等)编译器的构造。(www.daowen.com)

通常,编译器的符号表可能包含如下信息:

(1)变量(名字、类型描述、作用域、种类、存储地址等)

(2)常量(名字、常量类型、作用域、值等)

(3)函数(名字、形参列表、返回类型、存储地址、种类、中间代码列表等)

(4)标号(名字、作用域等)

符号表的信息收集工作主要集中在词法分析、语义分析两个阶段,其中,词法分析阶段主要是将识别得到的字面常量直接登记入常量表,其余更多的信息收集工作都是由语义分析完成的。在编译过程中,各个模块都可以从符号表中检索获取所需的信息,并不局限于编译器本身。有些编译器也会将符号表输出成一些标准的格式文件,供汇编器、链接器、调试器使用。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈