第九章符号表与错误处理

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

符号名:若干非空字符组成 符号类型:整形、实型、字符型、逻辑型等 符号的存储类别 符号的作用域 符号变量的存储分配信息 符号的其它属性
第9章 符号表与错误处理
符号名即名字本身,即构成名字的字符串,原则上可以 由任意长的字符组成。当前的大部分编译器的编辑器或 文字处理器允许行的最大值超过256个字符。也就是说, 标识符长度原理上可以超过256个字符,而一般我们习 惯用的标识符长度在10个字符上下。如果把名字的字符 串信息本身直接存放在符号表中,则会造成很大浪费, 同时也无法解决极端情况。
(3)所分配的数据区地址(一般为相对地址);
(4)若为数组,应填写其内情向量并给出内情向量的首址;
(5)若为记录结构,则应把该登记项与其各分量按某种方式 连接起来;
(6)是否为形式参数,若是,则应记录其类型:
第9章 符号表与错误处理
(7)定义性出现或引用性出现标志; (8)是否对该变量进行过赋值的标志,等等。 过程名: (1)是否为程序的外部过程; (2)若为函数,应指出它的类型; (3)是否处理过相应的过程或函数定义; (4)是否递归定义;
括弧界定,而花括弧内可以再嵌套花括弧。
第9章 符号表与错误处理
一个名字在哪个范围内起作用,被称为名字的作用域。分 别在并列的两个范围内的名字作用域互不相干,但是分别
在嵌套的两个范围内的名字,其作用域的问题就需要制定
规则来限定,以使得任何一个名字在任何范围内涵义都是 无二义的。 规定一个名字在什么样的范围内应该表示什么意义的原 则,被称为名字的作用域规则,通用的程序设计语言,如 Pascal、C/C++、Ada等均遵守下述两条原则。第一条原则实 际上是一个总的方针,第二条是在总方针下的具体规则。 (1) 静态作用域原则(static-scope rule):编译时就可以确定
符号表的间接组织方式。
第9章 符号表与错误处理
Nam e 7 5 3
In fo rm a t ro n … … …


S
T
U
D
E
N
T
G
R
A
N
D
A
G
E

图9.2 间接组织方式的符号表
第9章 符号表与错误处理
另一种组织方式是按标识符的种属,如简单变量、
数组、过程等分别建立不同的符号表,如简单变量名 表、数组名表、过程名表等。例如,下面的函数:
在名字引用处从内向外看,它处在所遇到的第一个该名字
声明的作用域。
第9章 符号表与错误处理
例 下述源程序说明了C的程序块符合上述作用域规则。
main( )
{ int a=0; int b=0;
{ int b=1; { int a=2; int c=4; int d=5; printf("%d %d\n",a,b); } { int b=3;
由于程序设计语言对源程序大小一般不做任何限制,符 号表中存放的名字的个数原则上也是无限的,符号表的存储 空间无论开设多大,都会有溢出的可能。因此,符号表的空 间存储,应该是可以动态扩充的。
第9章 符号表与错误处理
9.1 符号表的作用
在编译程序工作的过程中,需要不断收集、记录、 查证和使用源程序中的一些语法符号(简称为符号)的类
图9.3 按标识符种属组织的各种符号表 (a) 简单变量名表;(b) 常数表;(c) 函数入口名表
第9章 符号表与错误处理
根据符号表名字栏的组织特点,符号表信息栏的
组织方式也分为两类:固定信息内容和仅记录信息存 放地址。
如果名字栏中的标识符按种属分类,则因同类标
识符其基本特征一致,故可将这些信息一一记录在信 息栏中。 如果符号表的名字不分种属,则由于不同种属的 标识符其特征不一致,也即它们所需存储的信息不一
第9章 符号表与错误处理
第九章 符号表与 错误处理
基本知识点:符号表的作用及内容,符号表的数据结构 与符号表的组织。错误的种类、对错误的的处理方法。 重点:符号表的数据结构与符号表的组织。对错误的处 理方法。 难点:符号表的结构与符号表的操作,遏止重复错误的 方法。
第9章 符号表与错误处理
符号表的基本知识结构图
printf("%d %d\n",a,b);
}
/* 结果为:0,0 */
第9章 符号表与错误处理
在不同程序块中声明的a和b,它们的作用域分别为:
声 明
int a=0 int b=0 int b=1 int a=2 int b=3
作用域
B0-B2 B0-B1 B1-B3 B2 B3
图9.5 作用域表
名字的作用域,也可以说,仅从静态读程序就可确定名字的
作用域。
第9章 符号表与错误处理
(2) 最近嵌套原则(most closely nested)(下边的作用域规 则以程序块为例,但也适用于过程): ① 程序块B中声明的作用域包括B; ② 如果名字x不在B中声明,那么B中x的出现是在外围 程序块B'的x声明的作用域中,使得B'有x的声明,并且B'比 其它任何含x声明的程序块更接近被嵌套的B。 通俗地讲,名字的声明在离其最近的内层起作用,即
型和特征等相关信息。为方便起见,一般的做法是让
编译程序在其工作过程中建立并保存一批表格,如常 数表、变量名表、数组内情向量表、过程或子程序名 表及标号表等,将它们统称为符号表或名字表。
第9章 符号表与错误处理
符号表中的每一项包括两个部分:
名字(标识符) 名字有关的信息 这些信息将全面地反映各个语法符号的属性以及它们 在编译过程中的特征,诸如名字的种属(常数、变量、
第9章 符号表与错误处理
9.3
符号表的组织
由于处理对象的作用和作用域可以有多种,所以符
号表也有多种组织方式。按照处理对象的特点,符号表
的组织方式一般可分为直接方式和间接方式。 直接方式是指在符号表中直接填入源程序中定义的
标识符及相关信息(如图9.1)。在图中,Name(名字)栏的
长度是固定的,这种栏目长度固定的表格易于组织、填 写或查找,因而是最简单的一种符号表组织方式, 它
形式 符号表的组织与使用 组织方式
符 号 表
线性表 整理与查找
对折查找与二叉树
杂凑技术 名字的作用范围 符号表的内容 Fortran的符号表 Algol的符号表
第9章 符号表与错误处理
一、符号表
符号表是连接声明与引用的桥梁。一个名字在声明时,
相关信息被填写进符号表,而在引用时,根据符号表中的
信息生成相应的可执行语句。如何有效记录各类符号的信
适合于规定标识符长度的程序语言。
第9章 符号表与错误处理
Nam e W an ch e xue

In fo rm a t ro n … … …

图9.1 符号表的形式
第9章 符号表与错误处理
然而,并不是所有高级语言都规定标识符的长度,如
果对标识符长度不加限制,则上述定长方式必须按最 大长度来定长,这显然浪费存储空间。因此,对不定 长标识符一般采用间接方式来组织符号表。 间接方式是指单独设置一个字符串数组来存放所 有的标识符,并在符号表的名字栏中设置两项内容: 一是指针,用来指向标识符在数组中的起始位置;二 是一整数值,用来表示该标识符的长度。图9.2给出了
致,因而不容易确定一个固定长度的空间来统一安排。
这时,可在符号表外另设一组存储空间,并在符号表 信息栏中放一指针来指向这个存储空间始址。
第9章 符号表与错误处理
例如,对数组标识符需要存储有关数组维数,每
维上、下界值,数组类型及数组存放的起始地址等信 息。如果将信息与名字一起全部放在符号表中,则因
维数不同而使记录该信息的空间大小不易确定,因此,
数组、标号等)、名字的类型(整型、实型、逻辑型、字
符型等)、特征(当前是定义性出现还是使用性出现等)、 给此名字分配的存储单元地址及与此名语义有关的其
它信息等。
第9章 符号表与错误处理
根据编译程序工作阶段的不同划分,名字表中的
各种信息将在编译程序工作过程中的适当时候填入。
对于在词法分析阶段就建立符号表的编译程序,当扫 描源程序识别出一个单词(名字)时,就以此名字查找符 号表;若表中无此名的登记项,就将此名字填入符号 表中;至于与此名相关的其它信息,可视工作方便分 别在语法分析、语义分析及中间代码生成等阶段陆续 填入。在语义分析时,符号表中的信息可以用于语义 检查;在代码优化时,编译程序则利用符号表提供的 信息选出恰当的代码进行优化;

a 数组



图9.4 记录数组内情向量的符号表

第9章 符号表与错误处理
名字的作用域:
程序设计语言中一个名字可以出现在不同的范围内,
并且可以具有不同的意义。程序设计语言范围的划分可以 有两种不同的方式——并列的和嵌套的。不同的程序设计 语言,根据其提供的抽象方法不同,采用不同的范围划分 方式。例如,Pascal语言的过程定义,可以是嵌套的,即一 个过程内部可以再定义另一个过程;而C/C++语言的过程 只能是并列的,也就是说C/C++的过程中不能再定义过程, 但是C/C++允许程序块(block)嵌套,每个程序块的范围以花
/* 最外层,不妨定为B0层 */
/* B1层,被B0嵌套 */ /* B2层,被B1嵌套 */ /* 结果为:2,1 */
/* B3层,与B2并列,并列的名字作用域不交叉 */ /* 结果为:0,3 */ /* 结果为:0,1 */
printf("%d %d\n",a,b);
}
printf("%d %d\n",a,b); }
通常给它们另外安排一个内情向量表来记录数组的全 部信息,同时在符号表的信息栏设置一指针指向内情 向量的入口地址(见图9.4)。此外,对像函数名、过程 名等含有较多信息且不容易规范信息长度的名字都可 以采取这种办法。
第9章 符号表与错误处理
符号表 Nam e In fo rm a t i o n
内情向量表 维数 下 界 i1 首地址 上 界 u1
息, 以便于在编译的各个阶段对符号表进行快速、有效的
查找、插入、修改、删除等操作,是符号表设计的基本目
标之一。
第9章 符号表与错误处理
符号表的内容:
对常见的程序设计语言而言,其变量名及过程名登记项的 信息栏通常包含如下信息。 变量名: (1)种属(简单变量、数组、记录结构等);
(2)类型(整型、实型、双精度实型、逻辑型、字符串型、复 数型、标号或指示器等);
(5)指出过程的形式参数,并按形参排列的顺序将它们的种 属、类型等信息与过程名相联系,以便其后检查实参在顺 序、种属及类型上是否与形参一致。
第9章 符号表与错误处理
符号表的管理贯穿整个编译过程,既涉及前端, 也涉及后 端, 尤其与后端的存贮空间分配有密切联系。符号表的内容一 般仅在编译时使用,如果名字的具体信息需要在运行时确定 或者使用,则符号表的部分内容还要保留到运行时,例如动 态数组和跟踪调试信息等。符号表的信息组织与符号表数据 结构的安排对于编译的效率有重大影响。合理组织符号表的 内容,以适应不同阶段的需要,也是符号表设计需要考虑的 问题。
int f(int a,int b)
{ int c; if(a>b) c=1; else c=0; return c; }
第9章 符号表与错误处理
v alu e Nam e a b c In fo rm a t i o n 整型,变量,形参 整型,变量,形参 整型,变量 Nam e (a) f 二目子程序,入口地址 (c) In fo rm a t i o n 1 0 (b)
第9章 符号表与错误处理
而目标代码生成时,编译程序将依据符号表中的符号
名来分配目标地址。几乎在编译程序工作的全过程中, 都需要对符号表进行频繁地访问(查表或填表),其耗费 的时间在整个编译过程中占有很大的比例。因此,合 理地组织符号表并相应选择好的查、填表方法是提高 编译程序工作效率的有效办法。 对于编译程序所用的符号表来说,它所涉及的基 本操作大致可以归纳为五类:
第9章 符号表与错误处理
常用符号表结构:
由于在整个编译过程中需要不断地访问符号表, 因而如何构造符号表以及如何查填符号表就成为编译 程序设计的重要问题之一。除了上述我们介绍的用于 嵌套结构程序语言的栈式符号表外,还有其它几种常 用符号表结构。
第9章 符号表与错误处理
符号表的操作分为五类:
(1) 判断一个给定的名字是否在表中;
(2) 在表中填入新的名字; (3) 对Βιβλιοθήκη Baidu定的名字访问它在表中的有关信息; (4) 对给定的名字填入或更新它在表中的某些信息; (5) 从表中删去一个或一组无用的项。
第9章 符号表与错误处理
9.2
符号的主要属性和作用
相关文档
最新文档