第7章 符号表
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
编译原理
第7章 符号表
安庆师范学院计算机与信息学院
本章目标
解释符号表的作用 阐明符号表的内容 介绍符号表的基本操作 介绍符号表的组织结构
说明符号表的构造与查找方法
解释名字的作用范围
教学内容
7.1 符号表的作用与内容
7.2 符号表的组织与管理
7.3 名字的作用范围
7.4 本章小结
NULL
link
NULL
2、 符号表的构造与查找
(3)杂凑技术
①方法
构造一个地址函数H,对任何名字SYM,H(SYM)取值于0~N-1, 不论对SYM查表或填表,都希望能从H(SYM)获得它在表中的位置。 ②Hash函数构造方法 直接定址法 取关键字或关键字的某个线性函数值为Hash地址。 H(key)=key或H(key)=a· key+b 数字分析法
f
(function)
7.3 名字的作用范围
(3)实现最近嵌套作用域规则的办法
返回
还有其它的方式可以实现嵌套的作用域。其中的一种策略是对每个
作用域建立一张新的符号表,把它们按照作用域自里向外连接起来,这 样,查找操作如果不能在当前表中找到一个名字,就自动在外面包含它
它适合于规定标识符长度的程序语言。
名字 Sentence Data … … … … 信息
1、 符号表的组织结构
②间接方式
用一个独立的字符串数组,把所有标识符都连续存放在其中。在符 号表的主栏放一个指示器和一个整数,或在主栏仅放一个指示器,在标 识符前放一个整数。指示器指出标识将在字符串数组中的位置,整数代 表此标识符的长度。 符号表
规则;为同一个名字可以给定几个不同的说明,被引用的说明是最接近
引用的那个嵌套块。
7.3 名字的作用范围
(3)实现最近嵌套作用域规则的办法
对每个过程指定一个惟一的编号,即过程的顺序号,以便跟踪过程
里的局部名字。一个过程的编号(层次)作为本过程中说明的全部局部 量的组成部分,即编号被看成是名字的一个组成部分。于是,在符号表
②处理完f体内的复合语句B之后:
桶 i j 同义词表 (char) (char *) i (int) (int) j (int)
size
temp f
(char)
(function)
7.3 名字的作用范围
(3)实现最近嵌套作用域规则的办法
③退出函数f以后:
桶 i j 同义词表 (char) (int)
若关键字是以r为基的数,且Hash表中可能出现的关键字都是事先知
道的,则可取关键字的若干数位组成Hash地址。
2、 符号表的构造与查找
折迭法
将关键字分割成位数相同的几部分,然后取这几部分的迭加和作为
Hash地址。 除留余数法
取关键字被某个不大于哈希表表长m的数P除后所得余数为Hash地址。
Βιβλιοθήκη Baidu
1 2 3 4 AVAILABLE
… … … …
2、 符号表的构造与查找
③提高线性表查找效率(自适应线性表)
给每项附设一个指示器,这些指示器把所有的项按“最新最近”访
问原则连接成一条链,使得在任何时候,这条链的第一个元素所指的项 是那个最新最近被查询过的项,第二个元素所指的项是那个次新次近被
查询过的项如此等等,每次查表时都按这条链所指的顺序,一旦查到之
1、 符号表的组织结构
例如,对数组标识符需要存 储有关数组维数,每维上、下界 值,数组类型及数组存放的起始 地址等信息。如果将信息与名字 一起全部放在符号表中,则因维 数不同而使记录该信息的空间大 小不易确定,因此,通常给它们 另外安排一个内情向量表来记录 数组的全部信息,同时在符号表 的信息栏设置一指针指向内情向 量的入口地址(见图8-4)。此外, 对像函数名、过程名等含有较多 信息且不容易规范信息长度的名 字都可以采取这种办法。
NAME a b c INFORMATION 整型,变量,形参 整型,变量,形参 整型,变量 VALUE 1 0 NAME f INFORMATION 二目子程序,入口地址
(a)简单变量名表
(b)常数表
(c)函数入口名表
1、 符号表的组织结构
(2)信息栏组织方式
根据符号表名字栏的组织特点,符号表信息栏的组织方式也分为两
表并选择好的查表、填表方法是提高编译程序工作效率的有效办法。
2、 符号表的内容与操作
(1)符号表的组成
一张符号表的每一项(入口)包含两大栏(区段,字域),即名字
栏和信息栏。
名字(NAME 第1项(入口1) ) 信息(INFORMATION)
第2项(入口2) …… 第n 项(入口n)
……
……
2、 符号表的内容与操作
名字 信息
· 8 · 4
s
e
n 符号表
t
e
n
c
e
d
a
t
a
名字
信息
· ·
8
s
e
n
t
e
n
c
e
4
d
a
t
a
1、 符号表的组织结构
③按标识符的种属建立不同的符号表
如对简单变量、数组、过程等分别建立简单变量名表、数组名表、 过程名表等。例如,下面的函数:
int f(int a,int b)
{
int c; if(a>b) c=1; else c=0; return c; }
(1)名字栏组织方式
按照处理对象的特点,符号表的组织方式一般可分为直接方式和间
接方式。也按标识符的种属分别建立不同的符号表。 ①直接方式
直接方式是指在符号表中直接填入源程序中定义的标识符及相关信
息。在下图所示的符号表中,名字栏的长度是固定的,这种栏目长度固 定的表格易于组织、填写或查找,因而是最简单的一种符号表组织方式,
H(key) = key MOD P (P≤m) 平方取中法 取关键字平方的中间几位为Hash地址。 随机数法 选择一个随机函数,取关键字的随机函数值为它的Hash地址。
2、 符号表的构造与查找
③处理冲突的方法
返回
开放定址法
Hi=(H(key)+di) MOD m 再哈希法 Hi=R Hi(key) 链地址法 将所有关键字为同义词的记录存储在同一线性链中。 建立一个公共溢出区 i=1,2,…,k i=1,2,….,k(k≤m-1)
有n项,要查找某项SYM时,首先把SYM和中项(即第 n 2 1 项)作 比较:
若相等,则宣布查到。
若SYM小于中项,则继续在 若SYM大于中项,则就到
1 ~ n 2 的各项中去查找。
n n 2 2 ~ 的各项中去查找。
使用这种查找法每查找一项最多只需作
1 log2 N
7.1 符号表的作用与内容
1 符号表的作用
2 符号表的内容与操作
1、 符号表的作用
返回
在编译程序工作的过程中,需要不断收集、记录、查证和使用源程 序中的一些语法符号(简称为符号)的类型和特征等相关信息。为方便 起见,一般的做法是让编译程序在其工作过程中建立并保存一批表格, 如常数表、变量名表、数组内情向量表、过程或子程序名表及标号表等,
分析要解决的问题。
7.3 名字的作用范围
(2)编程语言中的作用域规则
①使用前说明(declaration before use)
在C,Java和Pascal等众多程序设计语言中广泛使用,要求程序中出 现的名字要在对它的任何引用之前进行说明。使用前说明允许符号表在
分析期间建立,当程序中遇到对名字的引用时进行查找,如果查找失败,
7.3 名字的作用范围
(3)实现最近嵌套作用域规则的办法
下面以C语言中的符号表的组织为例,以说明块结构语言的名字作
用域分析。
int i,j; int f(int size) { char i,temp; … A:{ double j; … } … B:{ char *j; … } }
B4
B3 B2 B1
②查找
从第一项开始顺序查找,若一直查找到AVAILBLE项还未找到,说 明该名字不在表中。对于一张含n项的线性表来说,欲从中查找一项,平 线性符号表 均来说需要做 n/2 次的比较。
项 数 NAME pointer data x link INFORMATION
AVAILABLE总是指向 空白区的首地址
类:固定信息内容和仅记录信息存放地址。 如果名字栏中的标识符按种属分类,则因同类标识符其基本特征一 致,故可将这些信息一一记录在信息栏中。 如果符号表的名字不分种属,则由于不同种属的标识符其特征不一
致,也即它们所需存储的信息不一致,因而不容易确定一个固定长度的
空间来统一安排。这时,可在符号表外另设一组存储空间,并在符号表 信息栏中放一指针来指向这个存储空间始址。
次比较
2、 符号表的构造与查找
③符号表组织成二叉树
令每项是一个结点,每个结点附设两个 指示器栏,分别为LEFT,RIGHT。每个结点 主栏内码值被看成是代表该结点的值,任何 结点P右枝所有结点值均应小于结点P的值, 而左枝任何结点值均应大于结点P的值。 ④二叉树形成过程
NULL data
·
NULL
符号表 信息 名字 种属 地址
返回
· · ·
… 数组 … 内情向量表 维数 数组首地址 界差 d1 … 界差 d n 下界 l1 … 下界 l n 上界 u1 … 上界 u n
·
2、 符号表的构造与查找
符号表主要有三种构造和处理方式:线性查找、二叉树和杂凑技术。
(1)线性表
①构造 按关键字出现顺序填写各个项, “先来者先填”。
意味着未经说明就直接使用了,这是一种说明错误,编译器给出相应的 出错消息。因此可以看出,使用前说明有助于实现一遍编译。
7.3 名字的作用范围
(2)编程语言中的作用域规则
②最近嵌套规则(most closely nest rule)
一种语言是块结构的,如果它允许在块的内部嵌入块,并且一个块 中说明的作用域限制在本块以及包含在本块的其它块中,服从最近嵌套
后就即时改造这条链,使得链头指向刚才查到的那个项。每当填入新项 时,总让链头指向这个最新项。含有这种链的线性表叫做自适应线性表。
(2)对折查找与二叉树
①整理 为了提高查表的速度,可以在造表的同时把表格中的项按名字的 “大小”顺序整理排列。
2、 符号表的构造与查找
②对折查找(折半查找)
对于这种经顺序化整理了的表格的查找可用对折法。假定表中已含
(2)符号表的基本操作
① 对给定名字,查询此名是否已在表中(查表)
② 填入新名(填表) ③ 对给定名字,访问它的信息(访表信息) ④ 对给定名字,往表中填写或更新它的某些信息(更新) ⑤ 删除一个或一组无用的项(删除)
返回
7.2 符号表的组织与管理
1 符号表的组织结构
2 符号表的构造与查找
1、 符号表的组织结构
7.3 名字的作用范围
(1)名字的作用域分析
程序语言中,名字往往有一个确定的作用范围,一般是和它所处的
那个过程(它在这个过程中被说明了的)相联系的。这意味着,在一个 程序里,同一个标识符在不同的地方可能被说明为标识不同的对象,也 就是说,同一个标识符,具有不同的性质,要求分配不同的存储空间。 于是便产生了这样的问题,如何组织符号表,使得同一个标识符在不同 的作用域中能得到正确地引用,而不会产生混乱?这就是名字的作用域
将它们统称为符号表或名字表。
语义分析时,符号表中的信息可用于语义检查;代码优化时,编译 程序利用符号表提供的信息选出恰当的代码进行优化;目标代码生成时,
编译程序将依据符号表中的符号名来分配目标地址。可见,几乎在编译
程序工作的全过程中,都需要对符号表进行频繁地访问(查表或填表),其 耗费的时间在整个编译过程中占有很大的比例。因此,合理地组织符号
pointer
· ·
x NULL
令第一个碰到的名字作为“根“结点, 它的左,右指示器均置为null.当要加入新结 点时,首先把它和根结点值作比较,小者放 在右枝上,大者放在左枝上,如果根结点的 左(右)枝已成子树,则让新结点和子树的 根再作比较,重复直至把新结点插入使它成 为二叉树的一个端末结点(叶子)为止。
B5
7.3 名字的作用范围
(3)实现最近嵌套作用域规则的办法
以散列组织符号表:
①处理完过程f的声明之后、进入复合语句A之前
桶 i
同义词表 (char) size (int) i j (int) (int)
temp f
(char)
(function)
7.3 名字的作用范围
(3)实现最近嵌套作用域规则的办法
中表示局部名字用一个二元组:(名字,过程编号)。这种办法意味着
我们把整个符号表按不同的过程逻辑地划分为相应的不同段落。在查找 每个名字时,先查对过程编号,确定所属的表区段落,然后,再从此段
落中查对标识符。也就是说,对一个名字查找符号表是指:只有当表项
中的名字其字符逐个匹配,并且该记录相关的编号和当前所处理的过程 的编号匹配时,才能确定查找成功。
第7章 符号表
安庆师范学院计算机与信息学院
本章目标
解释符号表的作用 阐明符号表的内容 介绍符号表的基本操作 介绍符号表的组织结构
说明符号表的构造与查找方法
解释名字的作用范围
教学内容
7.1 符号表的作用与内容
7.2 符号表的组织与管理
7.3 名字的作用范围
7.4 本章小结
NULL
link
NULL
2、 符号表的构造与查找
(3)杂凑技术
①方法
构造一个地址函数H,对任何名字SYM,H(SYM)取值于0~N-1, 不论对SYM查表或填表,都希望能从H(SYM)获得它在表中的位置。 ②Hash函数构造方法 直接定址法 取关键字或关键字的某个线性函数值为Hash地址。 H(key)=key或H(key)=a· key+b 数字分析法
f
(function)
7.3 名字的作用范围
(3)实现最近嵌套作用域规则的办法
返回
还有其它的方式可以实现嵌套的作用域。其中的一种策略是对每个
作用域建立一张新的符号表,把它们按照作用域自里向外连接起来,这 样,查找操作如果不能在当前表中找到一个名字,就自动在外面包含它
它适合于规定标识符长度的程序语言。
名字 Sentence Data … … … … 信息
1、 符号表的组织结构
②间接方式
用一个独立的字符串数组,把所有标识符都连续存放在其中。在符 号表的主栏放一个指示器和一个整数,或在主栏仅放一个指示器,在标 识符前放一个整数。指示器指出标识将在字符串数组中的位置,整数代 表此标识符的长度。 符号表
规则;为同一个名字可以给定几个不同的说明,被引用的说明是最接近
引用的那个嵌套块。
7.3 名字的作用范围
(3)实现最近嵌套作用域规则的办法
对每个过程指定一个惟一的编号,即过程的顺序号,以便跟踪过程
里的局部名字。一个过程的编号(层次)作为本过程中说明的全部局部 量的组成部分,即编号被看成是名字的一个组成部分。于是,在符号表
②处理完f体内的复合语句B之后:
桶 i j 同义词表 (char) (char *) i (int) (int) j (int)
size
temp f
(char)
(function)
7.3 名字的作用范围
(3)实现最近嵌套作用域规则的办法
③退出函数f以后:
桶 i j 同义词表 (char) (int)
若关键字是以r为基的数,且Hash表中可能出现的关键字都是事先知
道的,则可取关键字的若干数位组成Hash地址。
2、 符号表的构造与查找
折迭法
将关键字分割成位数相同的几部分,然后取这几部分的迭加和作为
Hash地址。 除留余数法
取关键字被某个不大于哈希表表长m的数P除后所得余数为Hash地址。
Βιβλιοθήκη Baidu
1 2 3 4 AVAILABLE
… … … …
2、 符号表的构造与查找
③提高线性表查找效率(自适应线性表)
给每项附设一个指示器,这些指示器把所有的项按“最新最近”访
问原则连接成一条链,使得在任何时候,这条链的第一个元素所指的项 是那个最新最近被查询过的项,第二个元素所指的项是那个次新次近被
查询过的项如此等等,每次查表时都按这条链所指的顺序,一旦查到之
1、 符号表的组织结构
例如,对数组标识符需要存 储有关数组维数,每维上、下界 值,数组类型及数组存放的起始 地址等信息。如果将信息与名字 一起全部放在符号表中,则因维 数不同而使记录该信息的空间大 小不易确定,因此,通常给它们 另外安排一个内情向量表来记录 数组的全部信息,同时在符号表 的信息栏设置一指针指向内情向 量的入口地址(见图8-4)。此外, 对像函数名、过程名等含有较多 信息且不容易规范信息长度的名 字都可以采取这种办法。
NAME a b c INFORMATION 整型,变量,形参 整型,变量,形参 整型,变量 VALUE 1 0 NAME f INFORMATION 二目子程序,入口地址
(a)简单变量名表
(b)常数表
(c)函数入口名表
1、 符号表的组织结构
(2)信息栏组织方式
根据符号表名字栏的组织特点,符号表信息栏的组织方式也分为两
表并选择好的查表、填表方法是提高编译程序工作效率的有效办法。
2、 符号表的内容与操作
(1)符号表的组成
一张符号表的每一项(入口)包含两大栏(区段,字域),即名字
栏和信息栏。
名字(NAME 第1项(入口1) ) 信息(INFORMATION)
第2项(入口2) …… 第n 项(入口n)
……
……
2、 符号表的内容与操作
名字 信息
· 8 · 4
s
e
n 符号表
t
e
n
c
e
d
a
t
a
名字
信息
· ·
8
s
e
n
t
e
n
c
e
4
d
a
t
a
1、 符号表的组织结构
③按标识符的种属建立不同的符号表
如对简单变量、数组、过程等分别建立简单变量名表、数组名表、 过程名表等。例如,下面的函数:
int f(int a,int b)
{
int c; if(a>b) c=1; else c=0; return c; }
(1)名字栏组织方式
按照处理对象的特点,符号表的组织方式一般可分为直接方式和间
接方式。也按标识符的种属分别建立不同的符号表。 ①直接方式
直接方式是指在符号表中直接填入源程序中定义的标识符及相关信
息。在下图所示的符号表中,名字栏的长度是固定的,这种栏目长度固 定的表格易于组织、填写或查找,因而是最简单的一种符号表组织方式,
H(key) = key MOD P (P≤m) 平方取中法 取关键字平方的中间几位为Hash地址。 随机数法 选择一个随机函数,取关键字的随机函数值为它的Hash地址。
2、 符号表的构造与查找
③处理冲突的方法
返回
开放定址法
Hi=(H(key)+di) MOD m 再哈希法 Hi=R Hi(key) 链地址法 将所有关键字为同义词的记录存储在同一线性链中。 建立一个公共溢出区 i=1,2,…,k i=1,2,….,k(k≤m-1)
有n项,要查找某项SYM时,首先把SYM和中项(即第 n 2 1 项)作 比较:
若相等,则宣布查到。
若SYM小于中项,则继续在 若SYM大于中项,则就到
1 ~ n 2 的各项中去查找。
n n 2 2 ~ 的各项中去查找。
使用这种查找法每查找一项最多只需作
1 log2 N
7.1 符号表的作用与内容
1 符号表的作用
2 符号表的内容与操作
1、 符号表的作用
返回
在编译程序工作的过程中,需要不断收集、记录、查证和使用源程 序中的一些语法符号(简称为符号)的类型和特征等相关信息。为方便 起见,一般的做法是让编译程序在其工作过程中建立并保存一批表格, 如常数表、变量名表、数组内情向量表、过程或子程序名表及标号表等,
分析要解决的问题。
7.3 名字的作用范围
(2)编程语言中的作用域规则
①使用前说明(declaration before use)
在C,Java和Pascal等众多程序设计语言中广泛使用,要求程序中出 现的名字要在对它的任何引用之前进行说明。使用前说明允许符号表在
分析期间建立,当程序中遇到对名字的引用时进行查找,如果查找失败,
7.3 名字的作用范围
(3)实现最近嵌套作用域规则的办法
下面以C语言中的符号表的组织为例,以说明块结构语言的名字作
用域分析。
int i,j; int f(int size) { char i,temp; … A:{ double j; … } … B:{ char *j; … } }
B4
B3 B2 B1
②查找
从第一项开始顺序查找,若一直查找到AVAILBLE项还未找到,说 明该名字不在表中。对于一张含n项的线性表来说,欲从中查找一项,平 线性符号表 均来说需要做 n/2 次的比较。
项 数 NAME pointer data x link INFORMATION
AVAILABLE总是指向 空白区的首地址
类:固定信息内容和仅记录信息存放地址。 如果名字栏中的标识符按种属分类,则因同类标识符其基本特征一 致,故可将这些信息一一记录在信息栏中。 如果符号表的名字不分种属,则由于不同种属的标识符其特征不一
致,也即它们所需存储的信息不一致,因而不容易确定一个固定长度的
空间来统一安排。这时,可在符号表外另设一组存储空间,并在符号表 信息栏中放一指针来指向这个存储空间始址。
次比较
2、 符号表的构造与查找
③符号表组织成二叉树
令每项是一个结点,每个结点附设两个 指示器栏,分别为LEFT,RIGHT。每个结点 主栏内码值被看成是代表该结点的值,任何 结点P右枝所有结点值均应小于结点P的值, 而左枝任何结点值均应大于结点P的值。 ④二叉树形成过程
NULL data
·
NULL
符号表 信息 名字 种属 地址
返回
· · ·
… 数组 … 内情向量表 维数 数组首地址 界差 d1 … 界差 d n 下界 l1 … 下界 l n 上界 u1 … 上界 u n
·
2、 符号表的构造与查找
符号表主要有三种构造和处理方式:线性查找、二叉树和杂凑技术。
(1)线性表
①构造 按关键字出现顺序填写各个项, “先来者先填”。
意味着未经说明就直接使用了,这是一种说明错误,编译器给出相应的 出错消息。因此可以看出,使用前说明有助于实现一遍编译。
7.3 名字的作用范围
(2)编程语言中的作用域规则
②最近嵌套规则(most closely nest rule)
一种语言是块结构的,如果它允许在块的内部嵌入块,并且一个块 中说明的作用域限制在本块以及包含在本块的其它块中,服从最近嵌套
后就即时改造这条链,使得链头指向刚才查到的那个项。每当填入新项 时,总让链头指向这个最新项。含有这种链的线性表叫做自适应线性表。
(2)对折查找与二叉树
①整理 为了提高查表的速度,可以在造表的同时把表格中的项按名字的 “大小”顺序整理排列。
2、 符号表的构造与查找
②对折查找(折半查找)
对于这种经顺序化整理了的表格的查找可用对折法。假定表中已含
(2)符号表的基本操作
① 对给定名字,查询此名是否已在表中(查表)
② 填入新名(填表) ③ 对给定名字,访问它的信息(访表信息) ④ 对给定名字,往表中填写或更新它的某些信息(更新) ⑤ 删除一个或一组无用的项(删除)
返回
7.2 符号表的组织与管理
1 符号表的组织结构
2 符号表的构造与查找
1、 符号表的组织结构
7.3 名字的作用范围
(1)名字的作用域分析
程序语言中,名字往往有一个确定的作用范围,一般是和它所处的
那个过程(它在这个过程中被说明了的)相联系的。这意味着,在一个 程序里,同一个标识符在不同的地方可能被说明为标识不同的对象,也 就是说,同一个标识符,具有不同的性质,要求分配不同的存储空间。 于是便产生了这样的问题,如何组织符号表,使得同一个标识符在不同 的作用域中能得到正确地引用,而不会产生混乱?这就是名字的作用域
将它们统称为符号表或名字表。
语义分析时,符号表中的信息可用于语义检查;代码优化时,编译 程序利用符号表提供的信息选出恰当的代码进行优化;目标代码生成时,
编译程序将依据符号表中的符号名来分配目标地址。可见,几乎在编译
程序工作的全过程中,都需要对符号表进行频繁地访问(查表或填表),其 耗费的时间在整个编译过程中占有很大的比例。因此,合理地组织符号
pointer
· ·
x NULL
令第一个碰到的名字作为“根“结点, 它的左,右指示器均置为null.当要加入新结 点时,首先把它和根结点值作比较,小者放 在右枝上,大者放在左枝上,如果根结点的 左(右)枝已成子树,则让新结点和子树的 根再作比较,重复直至把新结点插入使它成 为二叉树的一个端末结点(叶子)为止。
B5
7.3 名字的作用范围
(3)实现最近嵌套作用域规则的办法
以散列组织符号表:
①处理完过程f的声明之后、进入复合语句A之前
桶 i
同义词表 (char) size (int) i j (int) (int)
temp f
(char)
(function)
7.3 名字的作用范围
(3)实现最近嵌套作用域规则的办法
中表示局部名字用一个二元组:(名字,过程编号)。这种办法意味着
我们把整个符号表按不同的过程逻辑地划分为相应的不同段落。在查找 每个名字时,先查对过程编号,确定所属的表区段落,然后,再从此段
落中查对标识符。也就是说,对一个名字查找符号表是指:只有当表项
中的名字其字符逐个匹配,并且该记录相关的编号和当前所处理的过程 的编号匹配时,才能确定查找成功。