编译原理 第八章符号表

合集下载

编译原理:第八章 符号表

编译原理:第八章 符号表
规定主程序的层次为1主程序中定义的层次为2依次类推名字的类型类型有整型ints字符型chars布尔型bool数组arrays对于无类型的名字填入notype一个布尔量用于标明名字是否为变量形参名当名字是否为变量形参名时填入false其他情况填入true或不填当名字为数组类型或数组变量名时ref指向该数组在数组信息表中的位置
合肥工业大学 计算机与信息学院软件所
表 0.1 符号名表 SNT NAME INFORMATION M 形式参数,整 型,值参数 N 形式参数,整 型,值参数 K 整型,变量
表 0.2 常数表 CT 值 (VALUE) (1) 1 (2) 4
表 0.3 入口名表 ENT NAME INFORMATION (1) INCWAP 二目子程序, 入口四元式:1

ax→
数组下限 数组上限 数组元素的体积 数组本身的体积 当元素为数组时,它指向 数组元素类型 数组的下标类型 该元素数组信息在atab表 中的位置,其他情况为0
合肥工业大学 计算机与信息学院软件所
type a=array[1..10, 1..10] of integer;
name kind typ ref
合肥工业大学 计算机与信息学院软件所
PL 语言编译程序的符号表
1. 表格的定义 名字表(nametab) 程序体表(btab) 层次显示表(display) 数组信息表(atab) 中间代码表(code)
合肥工业大学 计算机与信息学院软件所
1) 名字表(nametab) 名字表nametab:登记程序中出现的各种名 字及其属性
lastpar last psize vsize 0 1

bx→
指向本程序体中最后一个形式参在 本程序体所有局部数据所 指向本程序体中最后一个名字在 本程序体所有形参所需体积、包 nametab 中的位置 需空间大小 nametab 中的位置 括连接数据所占空间

编译原理chapter8符号表(2016)分析

编译原理chapter8符号表(2016)分析

...
...
...
n1
available
SYM1
...
n2 SYM2
available
...
n3 SYM3
...
NULL
...
...
n1
...
...
...
n...2
编译原理
8.3 名字的作用范围
chapter8 符号表
最近嵌套作用域规则:即对每个过程指定一个唯一的 编号,以便跟踪过程里的局部名字。
(1)对给定名字,查询此名是否已在表中; (2)往表中填入一个新名字; (3)对给定名字,访问它的相关信息; (4)对给定名字,往表中填写或更新它的某些信息; (5)从表中删除一个或一组名字。
编译原理
chapter8 符号表
符号表的组织方式NAME
INFORMATION
1、各项各栏所占•存储单元的长度固定 2、间接方式安排•名字栏
(2)若要查找的项小于中项,则继续在1〜[n/2]的各项 中去查找。
(3)若要查找的项大于中项,则就到[n/2]+2〜n的各项 中去查找。
平均查找次数 1+log2n
编译原理
chapter8 符号表
二叉树的形成过程如下:
令第一个碰到的名字作为“根”结点,它的左、右 指示器均置为空,当要加入新结点时,首先把它和根 结点的值作比较,小者放在右枝上,大者放在左枝上。 如果根结点的左(右) 枝已成子树,则让新结点和子 树的根再作比较。重复上述步 骤,直至把新结点插入 使它成为二叉树的一个端末结点(叶)为止。
让链头指向最新项,含有这种链条的线性表叫做自适应线性表。
编译原理
二、对折查找与二叉树
chapter8 符号表

编译原理符号表的应用

编译原理符号表的应用

编译原理符号表的应用1. 什么是编译原理符号表编译原理中的符号表是一种数据结构,用于记录程序中各个符号的相关信息,包括变量名、函数名、常量等。

在编译过程中,符号表起着重要的作用,可以进行词法分析、语法分析和语义分析等过程中的变量和函数的命名检查、重名检查以及类型检查等功能。

2. 符号表的组织结构符号表可以采用不同的组织结构,最常见的有线性表、散列表和树等。

下面列举了几种常见的符号表组织结构:•线性表:符号表可以通过数组或链表等数据结构来表示。

•散列表:采用散列函数对符号进行映射,能够快速地查找符号。

•树:符号表可以用二叉搜索树、AVL树或红黑树等数据结构来表示,支持快速的查找、插入和删除操作。

3. 符号表在编译过程中的应用符号表在编译过程中扮演着重要的角色,下面介绍了符号表在不同阶段的应用:3.1 词法分析阶段在词法分析阶段,编译器通过符号表来记录程序中出现的各个标识符的信息,包括变量名、函数名和常量等。

符号表可以用来进行标识符的重名检查,以及维护标识符的属性信息,比如变量的类型、作用域和内存地址等。

3.2 语法分析阶段在语法分析阶段,编译器需要判断语法是否正确,并生成语法树。

符号表在此阶段可以用来进行各种类型的语法检查,比如检查函数参数的类型、检查类型转换的合法性等。

符号表还可以用来维护函数的参数表和局部变量表等信息。

3.3 语义分析阶段在语义分析阶段,编译器需要对代码进行语义检查,包括类型检查、作用域检查等。

符号表是进行这些检查的重要依据,通过符号表可以判断变量是否被定义、变量的作用域和类型是否匹配等。

3.4 中间代码生成阶段在中间代码生成阶段,编译器需要将源代码转换成中间代码,符号表可以用来生成中间表示时的参考依据。

符号表可以用来维护中间变量的属性信息,并生成中间代码时进行类型转换的判断。

3.5 代码优化和目标代码生成阶段在代码优化和目标代码生成阶段,符号表可以用来进行变量的寄存器分配和内存分配等操作。

编译原理 第八章符号表

编译原理 第八章符号表

第八章符号表编译过程中编译程序需要不断汇集和反复查证出现在源程序中各种名字的属性和特征等有关信息。

这些信息通常记录在一张或几张符号表中。

符号表的每一项包含两部分,一部分是名字(标识符),另一部分是此名字的有关信息。

每个名字的有关信息一般指种属(如简单变量、数组、过程等)、类型(如整、实、布尔等)等等。

这些信息将使用于语义检查、产生中间代码以及最终生成目标代码等不同阶段。

编译过程中,每当扫描器识别出一个单词后,编译程序就查阅符号表,看它是否已在其中。

如果它是一个新名就将它填进表里。

它的有关信息将在词法分析和语法-语义分析过程中陆续填入。

符号表中所登记的信息在编译的不同阶段都要用到。

在语义分析中,符号表所登记的内容将用于语义检查(如检查一个名字的使用和原先的说明是否相一致)和产生中间代码。

在目标代码生成阶段,当对符号名进行地址分配时,符号表是地址分配的依据。

对于一个多遍扫描的编译程序,不同遍所用的符号表也往往各有不同。

因为每遍所关心的信息各有差异。

本章重点:符号表的一般组织和使用方法。

第一节符号表的组织和使用信息栏通常包含许多子栏和标志位,用来记录相应名字的种种不同属性。

由于查填符号表一般都是通过匹配名字来实现的,因此,名字栏也称主栏。

主栏的内容称为关键字(key word)。

虽然原则上说,使用一张统一的符号表也就够了,但是,许多编译程序按名字的不同种属分别使用许多符号表,如常数表、变量名表、过程名表等等。

这是因为,不同种属名字的相应信息往往不同,并且信息栏的长度也各有差异的缘故。

因而,按不同种属建立不同的符号表在处理上常常是比较方便的。

对于编译程序的符号表来说,它所涉及的基本操作大致可归纳为五类:1、对给定名字,确定此名是否在有中;2、填入新名;3、对给定名字,访问它的有关信息;4、对给字名字,填写或更新它的某些信息;5、删除一个或一组无用的项。

不同种类的表格所涉及的操作往往也是不同的。

上述五方面只是一些基本的共同操作。

编译原理符号表的作用

编译原理符号表的作用

编译原理符号表的作用介绍编译原理中的符号表是一个重要的数据结构,用于存储程序中的标识符及其相关信息。

标识符可以是变量、常量、函数名等,在编译过程中需要进行词法和语义分析,符号表提供了一个地方来管理这些标识符,并为编译器的其他模块提供必要的信息。

作用符号表在编译过程中起着关键作用,它具有以下几个主要作用。

1. 标识符的声明符号表记录了程序中所有标识符的声明情况,包括标识符的类型、作用域等信息。

对于变量,符号表可以记录其数据类型和内存地址;对于函数,符号表可以记录其参数列表、返回值类型等。

编译器可以通过符号表查找标识符的声明信息,并根据需要进行语义检查和代码优化。

2. 标识符的引用和解析编译过程中,标识符可能会被多次引用,符号表用于解析标识符的引用。

编译器可以根据符号表中的信息确定标识符的类型、作用域等,从而进行语义检查和类型推导。

如果编译器在符号表中找不到对应的标识符,就会报错或警告,提示可能存在的错误。

3. 作用域管理符号表还可以用于管理标识符的作用域。

在程序中,不同的代码块可能定义了相同名称的标识符,符号表可以通过作用域信息来区分这些标识符。

当编译器遇到一个标识符时,它可以在符号表中查找该标识符的作用域,并根据作用域规则来解析标识符的含义。

4. 错误检测和提示符号表还可以用于错误检测和提示。

编译器可以通过符号表判断标识符是否已经定义或声明,以及是否满足相应的语义规则。

如果标识符在符号表中已经存在多个定义,编译器可以发现这种错误,并给出相应的错误提示信息。

符号表的组织结构为了高效地实现符号表的作用,通常采用哈希表或树形结构来组织符号表。

下面是一些常见的符号表组织结构。

1. 线性表符号表可以使用线性表结构进行组织,例如数组、链表等。

线性表结构简单直观,适用于较小规模的符号表。

但对于大规模的符号表,线性表的查找效率较低。

2. 哈希表哈希表是一种基于键值对存储的数据结构,可以快速地查找和插入数据。

符号表中的标识符可以作为哈希表的键,对应的信息可以作为值进行存储。

编译原理第8章

编译原理第8章
第八章 符号表
6、翻译模式
P:说明语句,D:类型说明语句,id:标识符(变量名),T:类型 T T T T integer {T.type:=integer;T.width:=4} 变量名及 real {T.type:=real;T.width:=8} 其性质填 T1 {T.type:=pointer(T1.type);T.width:=4} 入符号表 array[num] of T1 {T.type:=array(num.val,T1.type); offset T.width:=num.val*T1.width} D id:T {Enter(,T.type,offset); offset:=offset+T.width} offset D D;D P D {offset:=0} 内存用户区 语义子程序(语义动作) 产生式
* a * b * @b * @ b * @
c c c c b d a+a*(b-c)+(b-c)*d的DAG a:=b*-c+b*-c的语法树 a:=b*-c+b*-c的DAG
第八章 符号表
3、与后缀式的关系:表达式的抽象语法树形式的中间代码与后 缀式等价,后缀式是抽象语法树的线性表现形式,是树的结点 序列(每个结点都在其所有子结点之后立即出现 )。
第八章 符号表
符号表的作用和地位 符号的主要属性及作用 符号表的组织
第八章 符号表
一、符号表的作用和地位
一、本章主要内容: 静态语义检查和翻译中间代码; 二、静态语义检查的内容: 类型检查、控制流检查、一致性检查、相关名字检查、 名字的作用域分析等; 三、翻译产生中间代码的优点: 便于进行与机器无关的代码优化工作、使编译程序改变目标 机更容易、使编译程序的结构在逻辑上更为简单明确; 四、静态语义检查和中间代码产生在编译程序中的地位:

编译原理符号表

编译原理符号表

编译原理符号表符号表是编译器中一个非常重要的数据结构,用于存储程序中的标识符(如变量、函数名等)和对应的属性信息(如数据类型、作用域等)。

在编译器的各个阶段,都需要使用符号表来进行词法分析、语法分析、语义分析等操作,因此符号表设计的好坏直接影响到编译器的质量和效率。

一般来讲,符号表可以被看作是一个以标识符为键、以属性信息为值的映射表。

在编译器的词法分析阶段,源代码中的每个标识符都会被扫描并加入符号表中,同时为每个标识符生成一个唯一的“id”(也称为“符号表条目”)作为在后续处理中访问符号表的索引。

在编译器的语法分析和语义分析阶段,编译器会利用符号表进行语法分析和语义检查。

例如,在语法分析阶段,编译器需要判断变量是否被正确声明和使用,因此需要在符号表中查找变量的属性信息;而在语义分析阶段,编译器需要对表达式进行类型检查或者函数调用进行参数匹配,因此也需要在符号表中查找相关的属性信息。

需要注意的是,符号表的实现需要考虑到标识符的作用域、重复定义、名称空间等问题。

一般来说,编译器需要支持不同作用域之间的变量共存和访问,因此需要为不同的作用域维护不同的符号表。

当在一个新作用域中遇到相同的标识符时,编译器应该创建新的符号表条目;而在同一作用域中出现重复定义时,编译器应该抛出错误信息。

同样需要注意的是,符号表的实现也需要考虑到数据结构的效率和空间占用。

一些常用的实现方式包括基于哈希表的实现、基于树的实现(如平衡树、二叉查找树等)等。

在编译器优化阶段,符号表的实现也会影响编译器生成的目标代码的质量和效率。

例如,在常量表达式优化中,编译器使用符号表来维护常量的值和类型信息,从而可以直接进行常量表达式的求值,而不必在运行时才计算。

总的来说,在编译器中,符号表是一个极其重要的数据结构,对于编译器的性能和代码质量有着重要的影响。

因此,在设计和实现编译器时,需要认真考虑符号表的性能和可扩展性,并且根据具体的编程语言特性进行相应的优化。

第8章符号表

第8章符号表

第八章符号表
知识结构:
符号表的组织与作用
符号表符号表的组织
符号表的管理
第一节符号表的组织与作用
一、符号表的作用
1、符号表是编译程序保存(记录)源程序中各种名字的属性和特征信息的各种表格(数据结构);
2、符号表中信息在编译各阶段都要使用,编译结束生成目标代码后,符号表中信息也随之删除。

3、编译结束时,符号表中的信息体现在目标代码的存储单元的地址。

二、符号表的组织方式
符号表最简单的组织方式是各项各栏所占用的存储单元的长度都是固定的。

易于组织、填写和查找。

例:符号表
中间代码:
(+, A, B,T1)
(+ , 15, 16 ,T1)
目标代码:
LD R0 A—地址(a+4)
ADD R0 B—地址地址中体现了存储单元的大小。

第二节整理与查找
一、线性表
构造符号表的最简单办法是按关键字出现的顺序填写各个项。

可以用一个一维数组来存放名字及有关信息。

二、符号表的操作
⑴查找
⑵填入
⑶访问信息
⑷填入或更新信息
⑸删除
三、符号表的查找
编译工作的大部分时间花费在查、填符号表,对编译的效率有直接的影响。

⑴对折查找
⑵二叉树
⑶杂凑技术
第三节符号表的内容
一、符号表的类型
⑴变量
类型,种属,长度,相对数,数组内情向量
⑵过程
过程名,外过程,形参
⑶常数表
⑷标号表
二、符号表各项的设计
表项内容:
⑴名字和信息定长
符号表
⑵名字和信息不定长。

编译原理符号表的原理及典型实例

编译原理符号表的原理及典型实例

05
符号表的设计与实现
符号表的数据结构设计
符号表的数据结构应满足高效、 易扩展和易维护的要求,通常 采用哈希表、二叉树等数据结
构实现。
符号表应包含符号名称、符 号类型、符号属性等信息, 以便在编译过程中快速查找
和识别符号。
符号表还应支持动态添加、删 除和修改等操作,以适应源代
码中符号的变化。
符号表的实现算法
常量名的符号表实例
总结词
常量名符号表实例展示了如何使用符号表来管理程序中的常量。
详细描述
常量名符号表记录了常量的名称、类型和值等信息。通过符号表,编译器能够方 便地查找常量的定义和使用,并进行相应的语义分析和代码生成。在处理常量时 ,符号表有助于编译器优化程序的性能,例如常量折叠和常量传播等。
04
编译原理符号表的原 理及典型实例
目录
• 编译原理符号表概述 • 符号表的原理 • 符号表的典型实例 • 符号表在编译过程中的应用 • 符号表的设计与实现
01
编译原理符号表概述
符号表的概念
符号表是一种用于存储程序中标识符 信息的数据结构,主要用于编译过程 中对标识符进行跟踪和管理。
符号表中的每个条目都包含有关标识 符的信息,如名称、类型、作用域等。
如果符号表中存在该标识符的信息,编译器就可以 使用这些信息来生成相应的代码。
符号表的更新
01
在编译过程中,符号表可能会被更新以反映源代码的变化。
02
当源代码中添加、删除或修改标识符时,符号表中的相关信息
也需要相应地更新。
更新符号表的过程通常涉及到在哈希表中插入、删除或修改相
03
应的条目。
03
符号表的典型实例
典型实例

编译原理符号表

编译原理符号表

确定符号表的组织方式,一般应包括名字栏和信息栏,其中名字栏作为关键字。

要考虑能够存储有关名字的信息,并可以高效地完成如下操作:1.查找:根据给定的名字,在符号表中查找其信息。

如果该名字在符号表中不测试范例:procedure test; var b,c,i:integer;begin b:=1; if a>b thenc:=a+b elsec:=a-b;for i:=0 to 3dobeginc:=i;end;end;符号表的结构#include<stdio.h>#include<string.h>#include<ctype.h>#include<stdlib.h>struct{ int m;char name[20]; char inf[20];}co[999]; int num;include 称为文件包含命令,其意义是把尖括号""或引号<>内指定的文件包含到本程序中,成为本程序的一部分。

被包含的文件通常是由系统提供的,其扩展名为.h 而stdio为standard input output的缩写,意为“标准输入输出” .。

#include<string,h>这是C语言/C++中的字符串处理函数的头文件。

#include <ctype.h>是用作字符处理的,#include <stdlib.h>是用于定义杂项函数及内存分配函数,最后是一个结构函数,分别定义了符号名,信息,个数等变量。

符号显示在C-Free中用了void display(),将已经输入进系统的符号全部都显示出来 3. 符号查找本符号表系统中用void find() ,并通过for循环将所要查找的符号及其信息全都显示出来。

如果查找的字符存在,则在显示之前,运用system(“cls”)进行了清屏,把之前屏幕上所显示的内容全部清除,同时,在显示完成以后,又用了if 语句判断是否要删除此符号及其信息。

编译原理第八章 符号表

编译原理第八章  符号表
• 需要做作用域分析!
8.3 名字的作用范围(Fortran)
• Fortran 局部、全局
• 执行时过程(函数)不
Name
Information
嵌套,局部区域只有一
···

个现行段;
···
部 • 编译时,尽管查填符号
表过程只限于局部,但
考虑到地址分配的全局
性,需将每个程序段符
号表保存在外存中,采
• 定长方式 • 间接方式 (1)名字的间接存储 (2)信息的间接存储
Name ● ●
Information
如何组织
方式
6 S A MP L E 3 S U M
Name
Information ● ●
数组信息表 维数 首地址 维1
内情向量表
··· ···
以数组为例 维n
如何组织
• 对于名称:把所有标识符都存放在一个 独立的字符串数组,主栏只放一个指示 器和一个整数(名字的长度)
var f, g: real; procedure B3(y:real) const b=5; procedure B4 … end B4 end B3
end B2 end B1
8.3 名字的作用范围 (Pascal)
top
(14)…
B4 (13)…
0
h (12)… 13
sp b (11)…
12
y (10)…
最近使用优先查找 (链头)
较难
中 排序整理 折半查找
二叉树
较难
中 构造排序树,查找时 依子树次序逼近。
杂凑(哈希

表)
高 杂凑函数: 名称于位置的映射 基于计算的查找。
数据结构的知识

编译原理符号表的原理及典型实例

编译原理符号表的原理及典型实例

第二种组织法:单一组织 优点:管理一致,集中单一 缺点:管理复杂
三、符号表的组织
假设有下列三类符号及其所需属性
第一类符号 第二类符号 第三类符号 属性1 属性1 属性2 属性2 属性2 属性5 属性3 属性4 属性6
第三种组织法:折中方法
四、符号表的数据结构
线性表——符号表项按照符号被扫描到的先 后顺序登录
………………… …a…………… …………b…… …a…………… …………d…… …c…………… …………b…… ……
四、符号表的数据结构
有序表——符号表项按照符号的字符代码串 的值的大小排列
………………… …a…………… …………b…… …a…………… …………d…… …c…………… …………b…… ……
三、符号表的组织
假设有下列三类符号及其所需属性
第一类符号 第二类符号 第三类符号 属性1 属性1 属性2 属性2 属性2 属性5 属性3 属性4 属性6
第一种组织法:按属性分类 优点:管理一致,空间效率高 缺点:管理复杂
三、符号表的组织
假设有下列三类符号及其所需属性
第一类符号 第二类符号 第三类符号 属性1 属性1 属性2 属性2 属性2 属性5 属性3 属性4 属性6
B1的符号表
B2的符号表
b
aB3的Biblioteka 号表b二、符号表的内容
标识符的名字 与标识符有关的信息 类型信息(包括种类和属性) 地址码 层次信息 行号信息 ……
二、符号表的内容 例:Pascal语言的名字信息表nametab
name kind lev typ normal ref adr/val/size link
0 1 tx→
指向同一程序体中定义的上一个名字 名字所在的程序体的静态层次。规 adr, 当名字为变量名时(包括形参,存入该变量(或形参)在相应活动记录 一个布尔量,用于标明名字是否为变量形参 当名字为数组类型或数组变量名时,ref指向该数组在数 名字的类型,类型有整型(ints)、字符型 名字种类,可以是常量 名字标识符 在nametab中的位置,每个程序体在 中分类的存贮单元的相对地址;对于过程名,填入他们相应代码的入口地 定主程序的层次为1,主程序中定 名,当名字是否为变量形参名时填入false, 组信息表中的位置;当名字为过程名时,ref指向该过程 (chars)、布尔型(bool)、数组(arrays),对 址(constant)、变量(variable)、 nametab中登记的第一个名字的link 义的层次为2,依次类推 val, 当名字为变量名时,填入他们的相应值 其他情况填入true或不填 在程序体表(btab)中的位置;其他情况ref为0 于无类型的名字填入notype 为0 类型(type)、过程(procedure) size, 当名字为类型名时,填入该类型数据所需存贮单元的数目

编译原理08符号表

编译原理08符号表
线性符号表 项 数 1 2 3 4 AVAILABLE→ NAME BC I J1 XYZ INFORMATION … … … …
对这种顺序化的表格可采用对折法查找
15
对一遍扫描的编译程序来说,对折法用处不大。 对一遍扫描的编译程序来说,对折法用处不大。因 符号表是边填边引用的, 为,符号表是边填边引用的,每填进一个新项都得 顺序化符号表, 顺序化符号表,极费时间 可采用二叉树来组织符号表,令每项为一结点, 可采用二叉树来组织符号表,令每项为一结点,每 个结点附设两个指示器栏,一栏为LEFT,另一栏 个结点附设两个指示器栏,一栏为 , 为RIGHT,主栏内码值作为该结点的值 , 任何结点p右枝的所有结点值均小于 的值, 右枝的所有结点值均小于p的值 任何结点 右枝的所有结点值均小于 的值,而左枝 的任何结点值均大于p的值 的任何结点值均大于 的值
14
NAME J1 XYZ I BC
INFORMATION … … … …
3.2 对折查找与二叉树
为提高查表速度,在造表同时把表格中的项按名字的“大小” 为提高查表速度,在造表同时把表格中的项按名字的“大小” 顺序整理排列 名字的“大小”指名字的内码二进制,如规定值小者在前, 名字的“大小”指名字的内码二进制,如规定值小者在前, 值大者在后
11
四元式表QT 四元式表 OPR (1) ) LINK INCWAP INCWAP M N K INCWAP INCWAP 1 2 1 2 1 4 M N K M N M N (2) actpar ) (3) actpar ) (4) ) (5) ) (6) ) + + := AGR1 AGR2 RESULT //保护返回地址及有关寄存器 保护返回地址及有关寄存器 //把第一个实参值传给 把第一个实参值传给M 把第一个实参值传给 //把第二个实参值传给 把第二个实参值传给N 把第二个实参值传给 //K:=M+1 //M:=N+4 //N:=K //把M的值回送给第一个实参 把 的值回送给第一个实参 //把N的值回送给第二个实参 把 的值回送给第二个实参 //恢复寄存器,控制返回调用段 恢复寄存器, 恢复寄存器

编译原理符号表的作用

编译原理符号表的作用

编译原理符号表的作用一、引言编译器是将高级语言翻译成机器语言的程序,其主要功能是将源代码转换为可执行的目标代码。

在编译过程中,符号表是一个非常重要的数据结构,用于存储程序中出现的各种符号信息。

本文将介绍符号表的作用及其实现原理。

二、符号表的定义符号表是编译器中用于存储程序中出现的各种符号信息的数据结构,包括变量名、函数名、类型名等标识符及其属性信息。

它通常由一个哈希表和多个链表组成。

三、符号表的作用1. 语法分析阶段:在语法分析阶段,编译器会扫描源代码并生成相应的语法树。

同时,在扫描过程中,编译器会将每个标识符添加到符号表中,并记录其类型、作用域等属性信息。

这些信息可以在后续阶段中被使用。

2. 语义分析阶段:在语义分析阶段,编译器会对程序进行类型检查、作用域检查等操作。

这些操作需要使用到之前保存在符号表中的属性信息。

3. 代码生成阶段:在代码生成阶段,编译器会将源代码转换为目标代码。

在此过程中,编译器需要根据符号表中的信息生成目标代码中的符号表。

四、符号表的实现1. 哈希表:符号表通常由一个哈希表和多个链表组成。

哈希表用于快速查找标识符,并将其插入到相应的链表中。

2. 链表:每个链表对应一个作用域,用于存储该作用域中出现的所有标识符及其属性信息。

当进入一个新的作用域时,编译器会创建一个新的链表,并将其添加到符号表中。

当离开该作用域时,编译器会删除该链表。

3. 属性信息:在符号表中,每个标识符都有相应的属性信息,包括类型、作用域、地址等。

这些信息可以在后续阶段中被使用。

五、总结在编译过程中,符号表是一个非常重要的数据结构。

它可以存储程序中出现的各种标识符及其属性信息,并在后续阶段中被使用。

符号表通常由一个哈希表和多个链表组成,其中哈希表用于快速查找标识符,链表用于存储每个作用域中出现的所有标识符及其属性信息。

通过对符号表的实现和使用,编译器可以更加准确地将源代码转换为目标代码。

编译原理符号表和词法分析

编译原理符号表和词法分析

扫描源程序
识别单词
转换成属性字
六、词法分析(续一)
词法分析的两种处理结构
字符
单词
源程序
词法分析
L1程序
源程序
字符
符号表
单词
词法分析
语法分析
回送单词
符号表
七、取单词
1、单词的种类
单词由字符组成。 <字符>::=<字母>|<数字>|<特定符号>|<无效字符> <字母>::=a|b|c|..z|A| B|C|...|Z <数字>::=0|1|2|3|...|9 <特定符号>::=+|-|*|/|:=|<>|<|…. <无效字符>::=<回车符>|<换行符>|<制表符> symbol=(ident,constsy,notop,mul,div,add,sub….) 单词的机内表示采用长度统一的二元形式(token字) (单词种别码,单词的自身值)
七、取单词 流程图
开始
跳过空格符和回车符
N 字母
Y 读标识符
数字 N Y
查保留字表
取数
查到 N
Y identsy
保留字sy
constsysy
特殊符号 N Y
特殊符号sy
error
结束
八、读标识符
1、标识符的文法规则 <标识符>::=<字母>{<字母>| <数字> } <字母>::=a|b|c|..z|A| B|C|...|Z <数字>::=0|1|2|3|...|9

编译原理课件-符号表

编译原理课件-符号表

關鍵字域的組織
符號表的關鍵字域(段)就是符號名稱 等長關鍵字域(段)符號表 不等長關鍵字段符號表---採用關鍵字池的 索引結構。
作用域檢查 作用域和可見性
基本作用域規則(lexical rule) int a;
void Binky(int a) { int a; a = 2; ...
} 作用域檢查實現: 1每個作用域一個獨立的符號表,這些符號表組織成作用域
name:alfa; case kind: object of
constant: (val: integer); variable,procedur: (level, adr, size: integer) end;
例程式說明部分為:
CONST A=35,B=49;
Const(常量)無層次
VAR C,D,E;
VAL:35 VAL:49 LEVEL:LEV LEVEL:LEV LEVEL:LEV LEVEL:LEV LEVEL:LEV+1
ADR:DX ADR:DX+1 ADR:DX+2 ADR: ADR:DX
SIZE:4
…… ……
……
……
名字
類型
層次/值
地址 存儲空間
某編譯器的符號表實例
編譯程序分析第13行時符號表的內容
7.4 符號表
.符號表的作用和地位 .符號的主要屬性及作用 .符號表的組織
符號表的作用和地位-----語義檢查的依據
目標代碼生成階段地址分配的依據
在編譯程式中符號表用來存放語言程式中出現的有 關識別字的屬性資訊,符號表中所登記的資訊在 編譯的不同階段都要用到。
在語義分析中,符號表所登記的內容將用於語義檢 查(如檢查一個名字的使用和原先的說明是否一 致)和產生中間代碼。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第八章符号表编译过程中编译程序需要不断汇集和反复查证出现在源程序中各种名字的属性和特征等有关信息。

这些信息通常记录在一张或几张符号表中。

符号表的每一项包含两部分,一部分是名字(标识符),另一部分是此名字的有关信息。

每个名字的有关信息一般指种属(如简单变量、数组、过程等)、类型(如整、实、布尔等)等等。

这些信息将使用于语义检查、产生中间代码以及最终生成目标代码等不同阶段。

编译过程中,每当扫描器识别出一个单词后,编译程序就查阅符号表,看它是否已在其中。

如果它是一个新名就将它填进表里。

它的有关信息将在词法分析和语法-语义分析过程中陆续填入。

符号表中所登记的信息在编译的不同阶段都要用到。

在语义分析中,符号表所登记的内容将用于语义检查(如检查一个名字的使用和原先的说明是否相一致)和产生中间代码。

在目标代码生成阶段,当对符号名进行地址分配时,符号表是地址分配的依据。

对于一个多遍扫描的编译程序,不同遍所用的符号表也往往各有不同。

因为每遍所关心的信息各有差异。

本章重点:符号表的一般组织和使用方法。

第一节符号表的组织和使用信息栏通常包含许多子栏和标志位,用来记录相应名字的种种不同属性。

由于查填符号表一般都是通过匹配名字来实现的,因此,名字栏也称主栏。

主栏的内容称为关键字(key word)。

虽然原则上说,使用一张统一的符号表也就够了,但是,许多编译程序按名字的不同种属分别使用许多符号表,如常数表、变量名表、过程名表等等。

这是因为,不同种属名字的相应信息往往不同,并且信息栏的长度也各有差异的缘故。

因而,按不同种属建立不同的符号表在处理上常常是比较方便的。

对于编译程序的符号表来说,它所涉及的基本操作大致可归纳为五类:1、对给定名字,确定此名是否在有中;2、填入新名;3、对给定名字,访问它的有关信息;4、对给字名字,填写或更新它的某些信息;5、删除一个或一组无用的项。

不同种类的表格所涉及的操作往往也是不同的。

上述五方面只是一些基本的共同操作。

符号表最简单的组织方式是让各项各栏所占的存储单元的长度都是固定的。

这种项栏长度固定的表格易于组织、填写和查找。

对于这种表格,每一栏的内容可直接填写在有关的区段里。

例如,有些语言规定标识符的长度不得超过8个字符,于是,我们就可以用两个机器字作为主栏(假定每个机器字可容四个字符)每个名字直接填写在主栏中。

若标识长度不到8个字符,则用空白符补足。

这种直接填写式的表格形式如下:但是,有许多语言对标识符的长度几乎不加限制,或者说,标识符的长度范围甚宽。

譬如说,最长可容许由100个字符组成的名字。

在这种情况下,如果每项都用25个字作主栏,则势必会大量浪费存储空间。

因此,最好用一个独立的字符串数组,把所有标识符都存放在其中。

在符号表的主栏放一个指示器和一个整数。

指示器指出标识符在字符串数组中的位置;整数代表此标识符的长度。

这样,符号表的结构就如下图所示:这是一种用间接方式安排名字栏的办法。

类似地,如果各种名字所需的信息(INF-ORMA TION )空间长短不一,那么,我们可把一些共同属性直接登记在符号表的信息栏中,而把某些特殊属性登记在别的地方,并在信息栏中附设一指示器。

指向存放特殊属性的地方。

编译开始时,符号表或者是空的,或者预先存放了一些保留字和标准函数名的有关项。

在整个编译过程中,符号表的查填频率是非常高的。

编译工作的相当一大部分时间是花费在查填符号表上。

所以,研究表格结构和查填方法是一件非常重要的事情。

下面,我们简略地介绍几种一般的表格构造法和查填法。

第二节 符号表项的排列与查找符号表作为一个多元组,表中元组之间的排列组织是构造符号表的重要成分。

在编译程序的整个工作过程中,符号表被频繁也用来建立表项,找查表项,填充和引用表项的属性。

因此表项的排列组织对该系统运行的效率起着十分重要的作用。

在“数据结构”技巧的讨论中提供了很多有关多元组表格的组织方法和它们有关的操作算法。

而在编译程序中,符号表项的组织传统上采用三种构造方法。

即线性法,二分法及散列法。

1、线性组织 这种方法规定符号表项中按它的符号被扫描到的先后顺序建立。

例如有一程序中出现符号的情况如下:…………………a …………………b ………a …………………d ………c …………………b …… ……则符号表中表项排列将如图8-2-1其中h 表示该符号表之表头,是表的开始位置,p 表示该符号表的表项是符号表当前的结束位置,在编译程序工作过程中,扫描得到之新符号总是登入到p 的位置,而p 又取下一新位置,编译程序开始工作时p 处于h 表头位置。

这种组织方式在“数据结构”的讨论中可知它的管理简单但运行效率低,特别当表项数目较大后效率就非常低。

因为它没有空白项,因此存储空间效率高,但对于符号个数不确定的情况下,无法事先确定该符号表的总长度。

对于事先能确定符号个数且符号个数不大(公认为小20)时采用线性表组织是非常合适的。

2、排序组织及二分法 语言中任何符号都是由一个或几个字符拼写而成的,在机器中是用字符代码(通常是ASCII 或EBCDIC 代码)表达。

因每一个符号在机器内都是由这种字符代码串来表示。

排序组织的符号表,就是在符号表中的表项按其符号的字符代码串(可以看成一个整数值)的值的大小从大到小(或从小到大)排列的。

对上述例2中的符号出现情况按排序组织得到的符号表将如图8-2-2。

编译扫描的次序是a,b,d,c 。

由于c 代码小于d 代码,因此c 应在d 表项之前。

关于排序表的表项建立及符号查找,通常采用“二分法”。

详细的组织和算法在有关“数据结构”的书中可找到。

排序表的空间组织和存储开销与线性表基本相同,但排序表的运行效率要比线性表高,算法复杂性也高于线性表。

排序表有很多变形结构方式,如二叉树结构等,也在编译程序中可根据空间开销和运行效率等要求作适当的选取,这儿不去详细讨论,因为它不属编译范畴。

3、散列组织 对于表格处理来说,根本问题在于如何保证查表与填表两方面的工作都能高效地进行。

对于线性表来说,填表快,查表慢。

而对于二分法而言,则填表慢,查表快。

杂凑法是一种争取查表、填表两方面都能高速进行的统一技术。

这种办法是:假定有一个足够大的区域,这个区域是以填写一张含N 项的符号表。

我们希望构造一个地址函数H ,对任何名字SYM ,H (SYM )取值于0至N —1之间。

这就是说,不论对SYM 查表或填表,我们都希望能从H (SYM )获得它的表中的位置。

例如,我们用无符号整数作为项名,令N=17,把H (SYM )定义为SYM ÷N 的余数。

那么,名字ˋ09ˊ将被置于表中的第9项,ˋ34ˊ 将被置于表中的第0项,ˋ171ˊ将被置于表中的第1项,如此等等。

对于地址函数H 有两点要求:第一,函数的计算要简单、高效;第二,函数值能比较均匀地分布在0至N —1之间。

例如,若取N 为质数,把H (SYM )定义为SYM ÷N 的余数就是一个相当理想的函数。

构造函数H 的办法很多,通常是将符号名的编码杂凑成0~N~1间的某一个值。

因此,地址函数H 也常常称为杂凑函数。

注意,杂凑函数的选择往往和具体计算机系统的字符编码有关。

如果是对数目确定的已知符号名,我们可以通过试验,精挑细选,构造出一个一一对应函数。

如果杂凑函数是用来产生用户的标识符表的,由于用户使用标识是随机的,而且标识符的个数也是无限的(虽然在一个源程序中所有的标识符的全体是有限的),因此,企图构造一一对应的函数当然是徒劳的。

在这种情况下,除了希望函数值的分布比较均匀之外,我们还应没法解决“地址冲突”的问题。

以N=17,H (SYM )为SYM÷N 的余数为例,由于H (ˋ05ˊ)= H (ˋ22ˊ)=5,若表格的第5项已为ˋ05ˊ所占,那么,后来的ˋ22ˊ应放在哪里呢?解决地址冲突的办法很多。

我们这里只介绍一种最简单的线性查填解决法。

这种办法的填表过程是:对任何名字SYM ,令H (SYM )=h ,若第h 项为空,则直接把SYM 填入。

若h 项不空,则看第h+1(mod N )项,为空则填入,否则继续考察第h+2(mod N )项,如此反复,直至或者把SYM 填为第h+i (mod N )项;或者到达h+N=h (mod N )(说明表区已满),无法再填入。

查表过程与此相仿:令H (SYM )=h ,若第h 项为空,则说明SYM 不在表中,若SYM 等于第h 项的名字,则宣布查找成功,且SYM 的项数为h 。

否则,继续考察第h+1(mod N )项。

如此反复,直至或者在第h+i (mod N )项中找到SYM ;或者h+i (mod N )项为空,说明SYM 不在表中;或者到达h+N= h (mod N ),同样说明SYM 不在表中。

详细的组织和算法在有关“数据结构”的书中可找到。

第三节 习题一、单项选择题1、编译程序使用 区别标识符的作用域。

a. 说明标识符的过程或函数名b. 说明标识符的过程或函数的静态层次c. 说明标识符的过程或函数的动态层次d. 标识符的行号2、在目标代码生成阶段,符号表用于 。

a. 目标代码生成b. 语义检查c. 语法检查d. 地址分配3、过程信息表不包含 。

a. 过程入口地址b. 过程的静态层次c. 过程名d. 过程参数信息4、下列关于标识符和名字叙述中,正确的是。

a. 标识符有一定的含义b. 名字是一个没有意义的字符序列c. 名字有确切的属性d. a~c都不正确解答:1、b 2、d 3、b 4、c二、多项选择题1、符号表的每一项均包含。

a. 名字栏b. 类型栏c. 信息栏d. 值栏e. a~d均包含2、对编译程序所用到的符号表,涉及的操作有。

a. 填写或更新信息栏内容b. 填入新名c.给定名字,访问它的有关信息d. 杂凑技术e.线性表和排序二叉树3、源程序中的错误一般有。

a. 词法错误b. 语法错误c. 语义错误d. 编译错误e. 违反环境限制的错误解答:1、a 、c 2、a、b、c 3、a、b、c、e三、填空题1、符号表中名字栏内容有两种填写方式,它们是填写和填写。

2、词法分析阶段的错误主要是,可通过的办法纠正错误。

3、符号表中名字的有关信息在和过程中陆续填入。

4、在目标代码生成阶段,符号表是的依据。

解答:1、标识符标识符地址及长度2、拼写错误最小距离匹配3、词法分析语法语义分析4、地址分配四、问答题:1、在编译过程中为什么要建立符号表?解答:在编译过程中始终要涉及到对一些语法符号的处理,这就需要用到语法符号的相关属性。

为了在需要时能找到这些语法成分及其相关属性,就必须使用一些表格来保存这些语法成分及其属性,这些表格就是符号表。

相关文档
最新文档