次意的 编译程序工作的过程中,需要不断收集、 记录和使用源程序中一些语法符号的类 型和特征等相关信息 这些信息一般以表格形式存储于系统中 如常教表、变量名表、组名表、过程 名表、标号表等等,统称为号。 的号感组织、构造和管理方法的好坏会 直接影响编舜系统的运行效率
第六章 符号表 编译程序工作的过程中, 需要不断收集、 记录和使用源程序中一些语法符号的类 型和特征等相关信息. 这些信息一般以表格形式存储于系统中. 如常数表、变量名表、数组名表、过程 名表、标号表等等,统称为符号表。 符号表组织、构造和管理方法的好坏会 直接影响编译系统的运行效率
6.1符号表的组织 对符号表的访问常见操作有: (1)定一给定的名字是否在表中; (2在表中填入一个新名字; (3动问与给定名字相灵的信息; (4为给定的名字填入或更新其某些信戛 (5从表中删除一个或一组名字 在很多程序设计语言中.对名字的作用域有相应的规定, 即同一名字的标识符,在不同的作用城里标识了不同的 对象,且占用了不同的存储空间 因此,在组织符号表时,应能反映各个标识符的作用域
6.1 符号表的组织 对符号表的访问常见操作有: (1)判定一给定的名字是否在表中; (2)在表中填入一个新名字; (3)访问与给定名字相关的信息; (4)为给定的名字填入或更新其某些信息; (5)从表中删除一个或一组名字 在很多程序设计语言中,对名字的作用域有相应的规定, 即同一名字的标识符,在不同的作用域里标识了不同的 对象,且占用了不同的存储空间. 因此,在组织符号表时,应能反映各个标识符的作用域
6.2分程结的符号表的建妥 分程序结构语言用其所写的程序单元( program unit) 中,可以再包含嵌套的程序单元且其中每个程序单元均 可定义属于自己的一组局部变量如 PASCAL中的过程 说明C中花用括{}号括起来的分程序或复合语句等 程序草元的嵌套导致了变量作用域的嵌套故把允许名 字作用域嵌套的语言称为具有分序枃言的语ˉ PASCAL是典型的分程序靠构语言之一 对于嵌套的作用域同名变量在不同处代表了不同的实 体,因此需采用分层建立和处理符号表的方式
6.2 分程序结构语言符号表的建立 分程序结构语言 用其所写的程序单元(program unit) 中,可以再包含嵌套的程序单元,且其中每个程序单元均 可定义属于自己的一组局部变量.如PASCAL中的过程 说明,C中花用括{}号括起来的分程序或复合语句等. 程序单元的嵌套导致了变量作用域的嵌套,故把允许名 字作用域嵌套的语言称为具有分程序结构语言的语言. PASCAL是典型的分程序结构语言之一. 对于嵌套的作用域,同名变量在不同处代表了不同的实 体,因此,需采用分层建立和处理符号表的方式
宣填表方案 若一标识符在某分程序首部已作说明,则它在整个 分程序内均有定义除非它在某内层分程序被再次 定义即它的作用减是整个分程海,是本层分程序及 内层分程序的全局量; 1.当在一分程序首部某说明中扫描到一个标识符时,以此标识 符查相应于本层分程序的符号表,若表中已有此项,则它被 重复说明,出错;否则,在表中新登记一项,将该符号及其相 关信息填入 2.在分程序执行语句中遇一标识符时,首先查本层表,若找不 到,则查直接外层的符号表,如此等等,若在某层查到,则可 使用相关信息;若遍查所有外层均未找到,则无定义,出错
查填表方案 若一标识符在某分程序首部已作说明,则它在整个 分程序内均有定义,除非它在某内层分程序被再次 定义.即它的作用域是整个分程序,是本层分程序及 内层分程序的全局量; 1. 当在一分程序首部某说明中扫描到一个标识符时,以此标识 符查相应于本层分程序的符号表,若表中已有此项,则它被 重复说明,出错;否则,在表中新登记一项,将该符号及其相 关信息填入. 2. 在分程序执行语句中遇一标识符时,首先查本层表,若找不 到,则查直接外层的符号表,如此等等,若在某层查到,则可 使用相关信息;若遍查所有外层均未找到,则无定义,出错
程序6-1一个嵌套的分程序结构 名字信息栏 PROCEDURE… IF VAR A, B. C, D: REAL+ 2E PROCEDURE OUTERN ECOUNT POINTER 3L1 LABEL L. VAR E,F: REAL 4341 5H 6 G BEGIN 31 7L3 10L2 3 11D END: 12c PROCEDURE 分程序表 13B LABEL L2, L3 符号表 VAR G, H: REAL: FUNCTION 图6-3按分程序的自然顺序建立的分程序表和符号表 VAR A: INTEGER: BEGIN 各分程序的符号表登记项按B2B4B3B1的顺 END 序连续存放, BEGIN ① OUTERN指明分程序直接外层分程序的编号; (ECOUNT记录分程序在符号表登记项个数 END: ⑦ POINTER指向分程序在符号表中的起始位置 BEGIN END
各分程序的符号表登记项按B2,B4,B3,B1的顺 序连续存放, ①OUTERN指明分程序直接外层分程序的编号; ②ECOUNT记录分程序在符号表登记项个数; ③POINTER指向分程序在符号表中的起始位置;
CURRBL OUTERN ECOUNT POINTER 名字信息 使用栈存放临时符号表 当遇到一分程序的END时,j 将出现在栈顶的相应符号移 TOPENT 至正式表中 将表本身的空白区用作栈 URRBL 并用 TOPENT及 LASENT指 LASENT CURRBL- LASTBL TOPENT LASTBL-2□ 明临时栈的栈顶及符号表的 231 n-6 当前最末项 用 CURRBLLASTBL指明当 n-IlB TOPENT 前正在处理的分程序编号及 (c) 已处理完的最高层分程序的 CURRBL LASENT LASENT 编号 LASTBI 1【3 □31 n-5L3 nnnnnn n-IB TOPEN'T TOPENT
使用栈存放临时符号表. 当遇到一分程序的END时, j 将出现在栈顶的相应符号移 至正式表中. 将表本身的空白区用作栈, 并用TOPENT及LASENT指 明临时栈的栈顶及符号表的 当前最末项. 用CURRBL,LASTBL指明当 前正在处理的分程序编号及 已处理完的最高层分程序的 编号
构缆符号痃的算法 1初始化: CURRBL=0 LASENT=O; LASTBL=OF (3)遇到END时: TOPENT=0/*注:以上各量 BICB] POINTERELE+1; 在下面的程序中分别简记为 for(k=li k<=B[CB].ECi CB,LELTTER/ k++) S[++LE]=S[TE++]i 2.(1)当进入分程序的首符号或 CB=BICBL.; 过程时: 3重复2直到扫描结束 B[++LT].OUTERN=CB; 对于前面的程序结构,其构造符 BLLT].ECOUNT=O; BLLT]. POINTERETE 号表的过程见教材中P266图 6-5 CBELT (2)遇到分程序中的定义性出现 时:TP-S[TE]=相关信息; BICRTECOUTN++ BICRI. POINTERETEr
构造符号表的算法 1.初始化: CURRBL =0; LASENT=0; LASTBL=0; TOPENT=0; /*注:以上各量 在下面的程序中分别简记为 CB,LE,LT,TE*/ 2.(1)当进入分程序的首符号或 过程时: B[++LT].OUTERN=CB; B[LT].ECOUNT=0; B[LT].POINTER=TE; CB=LT; (2) 遇到分程序中的定义性出现 时: TP--;S[TE]=相关信息; B[CR].ECOUTN++; B[CR].POINTER=TE; (3)遇到END时: B[CB].POINTER=LE+1; for(k=1; k<=B[CB].EC; k++) S[++LE]=S[TE++]; CB=B[CB].OUTERN; 3.重复2.,直到扫描结束. 对于前面的程序结构,其构造符 号表的过程见教材中P266图 6-5
6.3非分程感结的语官的号最的建远 FORTRAN是块结构语言 FORTRAN程序由一或多个 相对独立的程序段组成其中有唯一的主程序段,其余为 子程序段( FUNTTON SUBROUTINE BLOCK DATA 程序段间的信息传递是由形实结合及公共数据区实现 的因此程序段名及公共区名是全局量,而各段中定义 的变量均是局部量 T FORTRAN语言的编译一般是把每个段视为独立程序 单元进行的为各段产生相应的代码,再连接装配成一 整的目标程序 一程序段编译完毕,该段的局部量已完成使命,可从表中 删除,但全局量仍需保留
6.3 非分程序结构语言符号表的建立 FORTRAN是块结构语言.FORTRAN程序由一或多个 相对独立的程序段组成,其中有唯一的主程序段,其余为 子程序段(FUNTION,SUBROUTINE,BLOCK DATA). 程序段间的信息传递是由形实结合及公共数据区实现 的.因此,程序段名及公共区名是全局量,而各段中定义 的变量均是局部量. FORTRAN语言的编译一般是把每个段视为独立程序 单元进行的.为各段产生相应的代码,再连接装配成一完 整的目标程序. 一程序段编译完毕,该段的局部量已完成使命,可从表中 删除,但全局量仍需保留
建立两个表:全局符号表及局部符 号表,其中局部表是可重复使用的; 局部名表 r较灵活的方法是将表数据区从两 名字信息栏 头使用,用指针 AVAIL1及 AVAIL2 分别指向局部名表空自区和全局名NM- 表空白区 AVAIL2 需指出,有时为实现程序全局优化, 局部名表要保留到优化结束才释放 全局名表
建立两个表:全局符号表及局部符 号表.其中局部表是可重复使用的; 较灵活的方法是,将表数据区从两 头使用,用指针AVAIL1及AVAIL2 分别指向局部名表空白区和全局名 表空白区. 需指出,有时为实现程序全局优化, 局部名表要保留到优化结束才释放. 名字 信息栏 局部名表 1 ... 2 ... 3 ... 2 ... 1 ... 全局名表 AVAIL1 AVAIL2
结束语 号感窅是编译程序很重要的组成部分,在整个编译过程 都要使用.因此,应考虑如何设置表信息栏的内容这一因素 对常见程序设计语言而言,变量表信息栏一般含有如下内容: 种厭(简单变量,数组,结构等)裘型(整型,实型等),数据区地 址(相对,绝对),內向量地址(对数组而言)分量首址(结构 类型)是否是形参公共及等价,定义引用唑幽现,是 否赋过值等等 过程名表:是否外部画数类型,是否处理过其定以,是否递归, 形参信息等等
结束语 符号表管理是编译程序很重要的组成部分,在整个编译过程 都要使用.因此,应考虑如何设置表信息栏的内容这一因素. 对常见程序设计语言而言,变量表信息栏一般含有如下内容: 种属(简单变量,数组,结构等),类型(整型,实型等),数据区地 址(相对,绝对),内情向量地址(对数组而言),分量首址(结构 类型),是否是形参,公共链及等价链,定义性及引用性出现,是 否赋过值.等等. 过程名表:是否外部,函数类型,是否处理过其定义,是否递归, 形参信息等等