第六章符号表 在编译程序工作的过程中,需要不断收集、 记录和使用源程序中一些语法符号的类型 和特征等相关信息. ·这些住处一般以表格形式存储于系统中如 常数表、变量名表、数组名表、过程名表、 标号表等等,统称为符号表。 对于符号表组织、构造和管理方法的好坏 会直接影响编泽系统的运行效率
第六章 符号表 • 在编译程序工作的过程中,需要不断收集、 记录和使用源程序中一些语法符号的类型 和特征等相关信息. • 这些住处一般以表格形式存储于系统中.如 常数表、变量名表、数组名表、过程名表、 标号表等等,统称为符号表。 • 对于符号表组织、构造和管理方法的好坏 会直接影响编译系统的运行效率
6.1符号表的组织 ·符号表的组织涉及数据结构方面知识(略) 。对符号表的访问常见操作有: ()制定一给定的名字是否在表中; 2)在表中填入一个新名字: 3)访问与给定名字相关的信息, (④)为给定的名字填入或更新其某些信息,; )从表中刷除一个或一组名字 · 领指出,在很多程序设计语言中,对名字的作用域有相应的 规定,即同一名字的标积符,在不同的作用域里标积了不同 的对象,且占用了不同的存储空间. ·因比,在组积符号表时,应能反映各个标积符的作用域
6.1 符号表的组织 • 符号表的组织涉及数据结构方面知识(略) • 对符号表的访问常见操作有: (1)判定一给定的名字是否在表中; (2)在表中填入一个新名字; (3)访问与给定名字相关的信息; (4)为给定的名字填入或更新其某些信息; (5)从表中删除一个或一组名字 • 须指出,在很多程序设计语言中,对名字的作用域有相应的 规定,即同一名字的标识符,在不同的作用域里标识了不同 的对象,且占用了不同的存储空间. • 因此,在组织符号表时,应能反映各个标识符的作用域
6.2分程序结构语言符号表的建乒 分程序结构语言用其所写的程序单元(program unit)中, 可以再包含嵌套的程序单元,且其中每个程序单元均可定 义属于自己的一组局部变量.如PASCAL中的过程说明,C 中花用括号括起来的分程序或复合语句等 。 程序单元的嵌套导致了变量作用域的嵌套,故把允许名字 作用域嵌套的语言称为具有~的语言.PASCAL是典型的~ 之一 ·虽然C不是~的语言,但其函数定义中的函数体可以是 一个 嵌套的分程序,因而也涉及到各个局部变量的作用域 对于嵌套的作用域,同名变量在不同处代表了不同的实体, 因此,需采用分层建立和处理符号表的方式:
6.2 分程序结构语言符号表的建立 • 分程序结构语言 用其所写的程序单元(program unit)中, 可以再包含嵌套的程序单元,且其中每个程序单元均可定 义属于自己的一组局部变量.如PASCAL中的过程说明,C 中花用括{}号括起来的分程序或复合语句等. • 程序单元的嵌套导致了变量作用域的嵌套,故把允许名字 作用域嵌套的语言称为具有~的语言. PASCAL是典型的~ 之一. • 虽然C不是~的语言,但其函数定义中的函数体可以是一个 嵌套的分程序,因而也涉及到各个局部变量的作用域. • 对于嵌套的作用域,同名变量在不同处代表了不同的实体, 因此,需采用分层建立和处理符号表的方式
PASCAL语言符号表的构造 ·在PASCAL程序中,标识符的作用域是包含说明 (定义)该标识符的最小分程序即: ①若一标识符在某分程序首部已作说明,则它在整个 分程序内均有定义,除非它在某内层分程序被再次 定义.即它的作用域是整个分程序,是本层分程序及 内层分程序的全局量; ②程序中的标号局限于定义该标号的最小分程序; ③我们可将PASCAL的每个过程视为分程序,其参数 总是局限于相寇的过程体内
PASCAL语言符号表的构造 • 在PASCAL程序中,标识符的作用域是包含说明 (定义)该标识符的最小分程序.即: ①若一标识符在某分程序首部已作说明,则它在整个 分程序内均有定义,除非它在某内层分程序被再次 定义.即它的作用域是整个分程序,是本层分程序及 内层分程序的全局量; ②程序中的标号局限于定义该标号的最小分程序; ③我们可将PASCAL的每个过程视为分程序,其参数 总是局限于相应的过程体内
查填表方案 为了表征一PASCAL程序中各个分程序的嵌套层次关系, 我们可将分程序按其开始符号出现的顺序编号,在扫描源 程序时亦可按这一顺序进行处理.方法是 1. 当在一分程序首部某说明中扫描到一个标识符时,以此 标识符查相应于本层分程序的符号表,若表中已有此项, 则它被重复说明,出错;否则,在表中新登记一项,将该符 号及其相关信息填入. 2. 在分程序执行语句中遇一标识符时,首先查本层表,若找 不到,则查直接外层的符号表,如此等等,若在某层查到, 则可使用相关信息;若遍查所有外层均未找到,则无定义, 出错
查填表方案 • 为了表征一PASCAL程序中各个分程序的嵌套层次关系, 我们可将分程序按其开始符号出现的顺序编号,在扫描源 程序时亦可按这一顺序进行处理.方法是 1. 当在一分程序首部某说明中扫描到一个标识符时,以此 标识符查相应于本层分程序的符号表,若表中已有此项, 则它被重复说明,出错;否则,在表中新登记一项,将该符 号及其相关信息填入. 2. 在分程序执行语句中遇一标识符时,首先查本层表,若找 不到,则查直接外层的符号表,如此等等,若在某层查到, 则可使用相关信息;若遍查所有外层均未找到,则无定义, 出错
符号表组织方式 为实现上述方案,应这样组织符号表: 1. 分层组织特号表的登记项,使各分程序的符号表 登记项连续存放,而不被内层分程序的待号表分 割; 2. 建立一个“分程序表”,用来记录各层分程序特 号表的有关信息、该表有三个域: ①OUTERN指明该分程序的直接外层分程序的编号: ②ECOUNT记录该分程序在符号表登记项个数: ③POINTER指向该分程序在符号表中的起始位置;
符号表组织方式 • 为实现上述方案,应这样组织符号表: 1. 分层组织符号表的登记项,使各分程序的符号表 登记项连续存放,而不被内层分程序的符号表分 割; 2. 建立一个“分程序表” ,用来记录各层分程序符 号表的有关信息.该表有三个域: ①OUTERN 指明该分程序的直接外层分程序的编号; ②ECOUNT记录该分程序在符号表登记项个数; ③POINTER 指向该分程序在符号表中的起始位置;
PROCEDURE B1; VAR A,B,C,D:REAL: F PROCEDURE B2: OU EC POI LABELLI; TER OU NTE N NT R VAR E,F:REAL: 0 4 BEGIN...END; PROCEDURE B3: 2 3 LABEL L2,L3; H VAR G,H:REAL; 3 FUNTION B4(...); L2 VARA:INTEGER; BEGIN ..END; BEGIN ..END; BEGIN ..END. AO<
PROCEDUREB1; VAR A,B,C,D:REAL ; PROCEDURE B2; LABEL L1; VAR E,F:REAL ; BEGIN … END ; PROCEDUREB3; LABEL L2,L3; VAR G,H:REAL ; FUNTION B4(…); VAR A:INTEGER ; BEGIN … END; BEGIN … END; BEGIN … END . OU TERN EC OU NT POI NTER 1 0 4 2 1 3 3 1 4 4 3 1 FEL 1 AHGL3L2 DCBA
·在前图中,各分程序符号表是按B2,B4,B3,B1的顺序(即各分 程序的END出现顺序)排列的. · 为使各分程序的符号表登记项连续地排列,利用嵌套结构的 特点,可使用一栈存放临时符号表 ·当遇到一分程序的END时,它的所有符号已出现在栈顶,可将 其移至正式表中 ·我们可将表本身的空白区用作栈,并用整型变量TOPENT及 LASENT指明临时栈的栈顶及符号表的当前最末项. 设符号表区可容纳n个登记项S[1n,其中S[n,S[n-1],.用 作栈;B[1~m]为分程序表.用CURRBL,LASTBL指明当前正 在处理的分程序编号及已处理完的最高层分程序的编号
• 在前图中,各分程序符号表是按B2,B4,B3,B1的顺序 (即各分 程序的END出现顺序)排列的. • 为使各分程序的符号表登记项连续地排列,利用嵌套结构的 特点,可使用一栈存放临时符号表. • 当遇到一分程序的END时,它的所有符号已出现在栈顶,可将 其移至正式表中. • 我们可将表本身的空白区用作栈,并用整型变量TOPENT及 LASENT指明临时栈的栈顶及符号表的当前最末项. • 设符号表区可容纳n个登记项S[1~n],其中 S[n],S[n-1],…用 作栈;B[1~m]为分程序表.用CURRBL,LASTBL指明当前正 在处理的分程序编号及已处理完的最高层分程序的编号
构造符号表的算法 1.初始化:CURRBL=0; (3)遇到END时: LASENT=0:LASTBL=0: B[CB].POINTER=LE+1; TOPENT=O;*注:以上各量在 for(k=1;K<=B[CB].EC;k++) 下面的程序中分别简记为 CB,LE,LT,TE*/ S[++LE]=STE++]: CB=B[CB].OUTERN; 2(1)当进入分程序的首符号或过程 时:B[++LT].OUTERN=CB; 3.重复2.,直到扫描结束 B[LT].ECOUNT=0; 对于前面的程序结构,其构造符号 B[LT].POINTER=TE;CB=LT; 表的过程见教材中P266图6-5 (2)遇到分程序中的定义性出现时: TP-;STE=相关信息; B[CR].ECOUTN++; B[CR].POINTER=TE;
构造符号表的算法 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是块结构语言.FORTRAN程序由一或多个相对 独立的程序段组成,其中有唯一的主程序段,其余为子程序 (FUNTION,SUBROUTINE,BLOCK DATA). ·程序段间的信息传递是由形实结合及公共数据区实现的 因此,程序段名及公共区名是全局量,而各段中定义的变量 均是局部量 ·FORTRAN语言的编译一般是把每个段视为独立程序单元 进行的.为各段产生相应的代码,再连接装配成一完整的目 标程序
6.3 非分程序结构语言符号表的建立 • 我们以FORTRAN语言为例,介绍其符号表的构造. • FORTRAN是块结构语言.FORTRAN程序由一或多个相对 独立的程序段组成,其中有唯一的主程序段,其余为子程序 段(FUNTION,SUBROUTINE,BLOCK DATA). • 程序段间的信息传递是由形实结合及公共数据区实现的. 因此,程序段名及公共区名是全局量,而各段中定义的变量 均是局部量. • FORTRAN语言的编译一般是把每个段视为独立程序单元 进行的.为各段产生相应的代码,再连接装配成一完整的目 标程序