第 9章 符号表
9.1符号表的作用和地位
9.2符号的主要属性及作用
9.3符号表的组织符号表的作用和地位 -----语义检查的依据目标代码生成阶段地址分配的依据在编译程序中符号表用来存放语言程序中出现的有关标识符的属性信息,符号表中所登记的信息在编译的不同阶段都要用到。
在语义分析中,符号表所登记的内容将用于语义检查(如检查一个名字的使用和原先的说明是否一致)和产生中间代码。
在目标代码生成阶段,当对符号名进行地址分配时,符号表是地址分配的依据。对一个多遍扫描的编译程序,不同遍所用的符号表也往往各有不同。因为每遍所关心的信息各有差异。
一张符号表的每一项 ( 或称入口才包含两大栏 ( 或称区段,字域 ),即名字栏和信息栏 。
名字栏 (NAME)信息栏 ( INFORMATION)
第 1项 ( 入口 1)
第 2项 ( 入口 2)
…
第 n项 ( 入口 n)
信息栏包含许多子栏和标志位,用来记录相应名字和种种不同属性,由于查填符号表一般是通过匹配名字来寮现的,因此,名字栏也称主栏 。 主栏的内容称为关键字 ( key word) 。
在整个编译期间,对于符号表的操作大致可归纳为五类:
对给定名字,查询名字是否已在表中;
往表中填入一个新的名字;
对给定名字,访问它的某些信息;
对给定名字,填写或更新它的某些信息;
删除一个或一组无用的项 。
不同种类的表格所涉及的操作往往也是不同的 。 上述五个方面只是一些基本的共同操作 。
符号 属性 (信息)
几种通常都是需要的 。
1 符号名
2 符号的类型
3 符号的存储类别
4 符号的作用域及可视性
5 符号变量的存储分配信息
6 符号的其它属性 (1) 数组内情向量
(2) 记录结构型的成员信息 (3) 函数及过程的形参符号表的组织总体组织和表项属性信息组织第一种,把属性种类完全相同的那些符号组织在一起,构造出表项是分别为等长的多个符号表第二种,把所有语言中的符号都组织在一张符号表中。组成一张包括了所有属性的庞大的符号表第三种折衷方式是根据符号属性相似程度分类组织成若干张表,每张表中记录的符号都有比较多的相同属性。
编译程序按名字的不同种属分别使用许多符号表,如常数表、变量名表、过程名表等等。
SUBROUTINE INCWAP( M,N)
10 K= M+ 1
M= M+ 4
N= K
RETURN
END
经编译头三阶段后所产生的主要表格有:符号名表 SNT,常数表 CT,入口名表 ENT,标号表 LT和四元式表 QT
符号名表 SNT
NAME INFORMATION
( 1) M 哑元,整数,变量
( 2) N 哑元,整数,变量
( 3) K 整数,变量常数表 CT
值( VALUE)
(1) 1
( 2) 4
入口名表 ENT
NAME INFORMATION
( 1) INCWAP 二目子程序,入口 QT(1)
/*记录入口名 INCWAP的入口地址*/
标号表 LT
LABLE INFORMATION
( 1) 10 QT(4)
/*记录了标号 10对应的四元式序列号*/
四元式表 QT
符号表项的排列符号表作为一个多元组,表中元组的排列组织是构造符号表的重要成分 。 在编译程序的整个工作过程中,符号表被频繁地用来建立表项,找查表项,填充和引用表项的属性 。 因此表项的排列组织对该系统运行的效率起着十分重要的作用 。
在编译程序中,符号表项的组织传统上采用三种构造方法 。 即线性法,二分法及散列法 。
关键字域的组织符号表的关键字域(段)就是符号名称等长关键字域(段)符号表不等长关键字段符号表 ---采用关键字池的索引结构 。
分程序结构的符号表对于具有分程序型结构的语言程序,不同层次分程序中定义的标识符号具有不同的作用域和不同的可视性规则。通常对于具有分程序结构的语言可用两种方式组织它们的符号表,一是对每个分程序建立一个独立的分表结构的符号表;
一是把各分程序符号组织在一张单表结构的符号表中分表结构的组织管理其基本思想是,每当编译程序扫描到一个分程序结构开始时,为该分程序建立一张符号表,在该分程序中定义的标识符,
都被登录在该符号表中。而当编译程序扫描到一个分程序的结束时,编译程序释放为该分程序所建立的符号表。这种符号表的分表结构与源程序的分程序层次结构一一对应单表结构的组织管理其基本思想是,所有分程序中定义的标识符都集中在单张符号表中 。 为了实现分程序构造中标识符的作用域和可视性规则的要求,在符号表中可设立一个属性域用来登录符号所在分程序的层次进入分程序时,层次要增加一层,在退出一个分程序时,层次降低一层,且需要把符号表中,
所有在退出的分程序中登录的符号项清除 。
嵌套结构型程序设计语言 ( Pascal) 的特点,可采用的办法:
,将其符号表设计为栈符号表,当新的名字出现总是从栈顶填入 。 查找操作从符号表的栈顶往底部查 ( 保证先查最近出现的名字 ) 。 因为程序是分层的,并且一个过程结束时将释放相应的子符号表,因此查找范围与线性表比相对要小一些 。
,引入一个显示 ( DISPLAY) 层次关系表,称为过程的嵌套层次表 。 其作用是为了描述过程的嵌套层次,指出当前正在活动着的各嵌套的过程 ( 或函数 ) 相应的子符号表在栈符号表中的起始位置 ( 相对地址 ) 。 DISPLAY
表也是一个栈,栈顶指针为 level。 当进入一个新过程时,level增加 1;每当退出一个过程时,level减 1。 DISPLAY(level)总是指向当前正在处理的最内层的过程的子符号表在栈符号表中的起始位置 。
,在符号表的信息栏中引入一个指针域 ( previous) 用以链接它在同一过程内的前一域名字在表中的下标 ( 相对位置 ) 。 每一层的最后一个域名字,其
previous之值为 0 。 这样,每当需要查找一个新名字时,就能通过
DISPLAY找出当前正在处理的最内层的过程及所有外层的子符号表在栈符号表中的位置 。 然后,通过 previous可以找到同一过程内的所有被说明的名字 。
说明部分的分析 与处理
对每个过程 说明的对象 ( 变量,常量 和 过程 ) 造名字表
– 填写 标识符的 所在 层次,属性 和分配的 相对位置 。标识符的属性不同时,所需填入的信息也不同。登录信息由
ENTER过程完成。
说明部分的分析与处理( 程 序)
说明类型的定义:
object= (constant,variable,procedur)
( 定义 纯量 /枚举 类型)
名字表的定义
table:array[0..txmax] of record
name:alfa;
case kind:object of
constant:(val:integer);
variable:procedur:(level,adr,size:
integer);
NAME,A
NAME,B
NAME,C
NAME,D
NAME,E
NAME,P
KIND,CONSTANT
KIND,CONSTANT
KIND,VARIABLE
KIND,VARIABLE
KIND,VARIABLE
KIND,PROCEDUR
VAL,35
VAL,49
LEVEL,LEV
LEVEL,LEV
LEVEL,LEV
LEVEL,LEV
ADR,DX
ADR,DX+1
ADR,DX+2
ADR,
S I Z E,4
NAME,G
……
KIND,VARIABLE
……
LEV EL,L E V + 1
……
ADR,DX
……
例程序说明部分为:
CONST A=35,B=49;
VAR C,D,E;
PROCEDURE P;
VAR G ; …
名字 类型 层次 /值 地址 存储空间
Const( 常量) 无 层次对应名字表
PL/0编译程序
Table表的 下标指针 tx补充说明:
主程序
BLOCK
第 1次 调用 block
BLOCK( 0,0,… )
0
0
...
BLOCK BLOCK( LEV+1,TX,… )
(递归 进入 分程序 )
LEV
tx
LEV
tx
( 6)
6 ( 9)
1
tx是 BLOCK的实际 值参
9.1符号表的作用和地位
9.2符号的主要属性及作用
9.3符号表的组织符号表的作用和地位 -----语义检查的依据目标代码生成阶段地址分配的依据在编译程序中符号表用来存放语言程序中出现的有关标识符的属性信息,符号表中所登记的信息在编译的不同阶段都要用到。
在语义分析中,符号表所登记的内容将用于语义检查(如检查一个名字的使用和原先的说明是否一致)和产生中间代码。
在目标代码生成阶段,当对符号名进行地址分配时,符号表是地址分配的依据。对一个多遍扫描的编译程序,不同遍所用的符号表也往往各有不同。因为每遍所关心的信息各有差异。
一张符号表的每一项 ( 或称入口才包含两大栏 ( 或称区段,字域 ),即名字栏和信息栏 。
名字栏 (NAME)信息栏 ( INFORMATION)
第 1项 ( 入口 1)
第 2项 ( 入口 2)
…
第 n项 ( 入口 n)
信息栏包含许多子栏和标志位,用来记录相应名字和种种不同属性,由于查填符号表一般是通过匹配名字来寮现的,因此,名字栏也称主栏 。 主栏的内容称为关键字 ( key word) 。
在整个编译期间,对于符号表的操作大致可归纳为五类:
对给定名字,查询名字是否已在表中;
往表中填入一个新的名字;
对给定名字,访问它的某些信息;
对给定名字,填写或更新它的某些信息;
删除一个或一组无用的项 。
不同种类的表格所涉及的操作往往也是不同的 。 上述五个方面只是一些基本的共同操作 。
符号 属性 (信息)
几种通常都是需要的 。
1 符号名
2 符号的类型
3 符号的存储类别
4 符号的作用域及可视性
5 符号变量的存储分配信息
6 符号的其它属性 (1) 数组内情向量
(2) 记录结构型的成员信息 (3) 函数及过程的形参符号表的组织总体组织和表项属性信息组织第一种,把属性种类完全相同的那些符号组织在一起,构造出表项是分别为等长的多个符号表第二种,把所有语言中的符号都组织在一张符号表中。组成一张包括了所有属性的庞大的符号表第三种折衷方式是根据符号属性相似程度分类组织成若干张表,每张表中记录的符号都有比较多的相同属性。
编译程序按名字的不同种属分别使用许多符号表,如常数表、变量名表、过程名表等等。
SUBROUTINE INCWAP( M,N)
10 K= M+ 1
M= M+ 4
N= K
RETURN
END
经编译头三阶段后所产生的主要表格有:符号名表 SNT,常数表 CT,入口名表 ENT,标号表 LT和四元式表 QT
符号名表 SNT
NAME INFORMATION
( 1) M 哑元,整数,变量
( 2) N 哑元,整数,变量
( 3) K 整数,变量常数表 CT
值( VALUE)
(1) 1
( 2) 4
入口名表 ENT
NAME INFORMATION
( 1) INCWAP 二目子程序,入口 QT(1)
/*记录入口名 INCWAP的入口地址*/
标号表 LT
LABLE INFORMATION
( 1) 10 QT(4)
/*记录了标号 10对应的四元式序列号*/
四元式表 QT
符号表项的排列符号表作为一个多元组,表中元组的排列组织是构造符号表的重要成分 。 在编译程序的整个工作过程中,符号表被频繁地用来建立表项,找查表项,填充和引用表项的属性 。 因此表项的排列组织对该系统运行的效率起着十分重要的作用 。
在编译程序中,符号表项的组织传统上采用三种构造方法 。 即线性法,二分法及散列法 。
关键字域的组织符号表的关键字域(段)就是符号名称等长关键字域(段)符号表不等长关键字段符号表 ---采用关键字池的索引结构 。
分程序结构的符号表对于具有分程序型结构的语言程序,不同层次分程序中定义的标识符号具有不同的作用域和不同的可视性规则。通常对于具有分程序结构的语言可用两种方式组织它们的符号表,一是对每个分程序建立一个独立的分表结构的符号表;
一是把各分程序符号组织在一张单表结构的符号表中分表结构的组织管理其基本思想是,每当编译程序扫描到一个分程序结构开始时,为该分程序建立一张符号表,在该分程序中定义的标识符,
都被登录在该符号表中。而当编译程序扫描到一个分程序的结束时,编译程序释放为该分程序所建立的符号表。这种符号表的分表结构与源程序的分程序层次结构一一对应单表结构的组织管理其基本思想是,所有分程序中定义的标识符都集中在单张符号表中 。 为了实现分程序构造中标识符的作用域和可视性规则的要求,在符号表中可设立一个属性域用来登录符号所在分程序的层次进入分程序时,层次要增加一层,在退出一个分程序时,层次降低一层,且需要把符号表中,
所有在退出的分程序中登录的符号项清除 。
嵌套结构型程序设计语言 ( Pascal) 的特点,可采用的办法:
,将其符号表设计为栈符号表,当新的名字出现总是从栈顶填入 。 查找操作从符号表的栈顶往底部查 ( 保证先查最近出现的名字 ) 。 因为程序是分层的,并且一个过程结束时将释放相应的子符号表,因此查找范围与线性表比相对要小一些 。
,引入一个显示 ( DISPLAY) 层次关系表,称为过程的嵌套层次表 。 其作用是为了描述过程的嵌套层次,指出当前正在活动着的各嵌套的过程 ( 或函数 ) 相应的子符号表在栈符号表中的起始位置 ( 相对地址 ) 。 DISPLAY
表也是一个栈,栈顶指针为 level。 当进入一个新过程时,level增加 1;每当退出一个过程时,level减 1。 DISPLAY(level)总是指向当前正在处理的最内层的过程的子符号表在栈符号表中的起始位置 。
,在符号表的信息栏中引入一个指针域 ( previous) 用以链接它在同一过程内的前一域名字在表中的下标 ( 相对位置 ) 。 每一层的最后一个域名字,其
previous之值为 0 。 这样,每当需要查找一个新名字时,就能通过
DISPLAY找出当前正在处理的最内层的过程及所有外层的子符号表在栈符号表中的位置 。 然后,通过 previous可以找到同一过程内的所有被说明的名字 。
说明部分的分析 与处理
对每个过程 说明的对象 ( 变量,常量 和 过程 ) 造名字表
– 填写 标识符的 所在 层次,属性 和分配的 相对位置 。标识符的属性不同时,所需填入的信息也不同。登录信息由
ENTER过程完成。
说明部分的分析与处理( 程 序)
说明类型的定义:
object= (constant,variable,procedur)
( 定义 纯量 /枚举 类型)
名字表的定义
table:array[0..txmax] of record
name:alfa;
case kind:object of
constant:(val:integer);
variable:procedur:(level,adr,size:
integer);
NAME,A
NAME,B
NAME,C
NAME,D
NAME,E
NAME,P
KIND,CONSTANT
KIND,CONSTANT
KIND,VARIABLE
KIND,VARIABLE
KIND,VARIABLE
KIND,PROCEDUR
VAL,35
VAL,49
LEVEL,LEV
LEVEL,LEV
LEVEL,LEV
LEVEL,LEV
ADR,DX
ADR,DX+1
ADR,DX+2
ADR,
S I Z E,4
NAME,G
……
KIND,VARIABLE
……
LEV EL,L E V + 1
……
ADR,DX
……
例程序说明部分为:
CONST A=35,B=49;
VAR C,D,E;
PROCEDURE P;
VAR G ; …
名字 类型 层次 /值 地址 存储空间
Const( 常量) 无 层次对应名字表
PL/0编译程序
Table表的 下标指针 tx补充说明:
主程序
BLOCK
第 1次 调用 block
BLOCK( 0,0,… )
0
0
...
BLOCK BLOCK( LEV+1,TX,… )
(递归 进入 分程序 )
LEV
tx
LEV
tx
( 6)
6 ( 9)
1
tx是 BLOCK的实际 值参