第六章语义和符号表
符号表原理介绍(详细)

§6.1 符号表的作用和地位
二、上下文语义的合法性检查的依据 上下文语义的合法性检查的依据 语义的合法性检查
同一个标识符可能在程序的不同地方出现,而有关该符号的属 性是在不同情况下收集的。通过符号表中属性记录可进行相应 上下文的语义检查。 例如: 例如 int i [3][5]; float i[4][2]; int i [3][5]; 1. 2. 首先在符号表中记录i的属性是3×5个整型元素的数组 在分析第二、第三个说明时,通过符号表检查出标识符i的二次 二次 重定义冲突错误 重定义
§6.2 符号的主要属性及作用
(2) 动态存储区 根据变量的局部定义和分程序结构,编译程序设置动态存储区来 适应这些局部变量 局部变量的生存和消亡。局部动态变量 局部动态变量的生存期是定义 局部变量 局部动态变量 该变量的局部范围,即在该定义范围之外此变量已经没存在的必 要。及时撤销时这些单元的分配可以回收,从而提高程序运行时 的空间效率。 对变量存储分配的属性除了存储类别之外还要确定其在所在存储 区的具体位置的属性信息。通常在符号表中存放具体位置的信息 是按该变量的存储区类分别依出现先后的次序(扫描源程序的次 序)排列下相对该存储区表头的相对位移量来表示的。
§6.2 符号的主要属性及作用
(2) 分程序(或复合语句)结构 // 第一层头,定义的局部整型变量a {int a; ; … // 第二层头,定义的局部字符型变量a {char a; ; … // 第三层头 { … {float a; // 第四层头,定义的局部实型变量a ; … // 第四层尾 } …a… // 引用第二层定义的局部字符型变量a // 第三层尾 } // 第二层尾 } // 第一层尾 }
§6.2 符号的主要属性及作用
编译原理课件(刘铭)第6章

本章小结
也就是说标识符是一个没有意义 的字符序列,而名字有确切的意义。 在程序语言中标识符可以是一个变量 的名字或一个函数的名字。
例如 area , 作为标识符,它没有 任何意思,但作为名字,可以表示 变量名或函数名等。
本章小结
3. 符号表的查找
符号表查找算法与该符号表的构造方法 密切相关即有顺序查找、折半查找和杂 凑查找算法。
6.3 符号表的组织
一个编译程序,从词法分析、语法 分析、语义分析到代码生成的整个过程 中,符号表是连贯上下文进行语义检查、 语义处理、生成代码和存储分配的主要 依据,因此符号表的组织直接关系到这 些语义功能的实现和语义处理的时空效 率。
6.3 符号表的组织
符号表的表格形式
名 字 栏 信 息 栏
符号表的作用
符号表的组织
符号表的建立和查找
6.1 符号表的作用与生成期
符号表的作用 符号表用来存放程序语言中出现 的有关标识符的属性和特征。 符号表在整个编译期间的作用归 纳为以下几个方面: 将标识符的名字及属性登录在符号 表中
6.1 符号表的作用与生成期
在分析说明语句时,编译程序根 据说明语句信息将标识符的相应属性 如标识符的类型:实型,整型,布尔 型等;标识符的种属:数组名,变量 名,过程名,函数名等; 标识符的作用 域:全局变量或局部变量等信息登录 到符号表中。
名字栏存放标识符的名字,信息栏存放 名字相关属性。
. . .
. . .
6.3 符号表的组织
符号表的总体组织 1. 编译程序按名字的不同属性构造出多 个符号表。如常量表、变量名表等。 符号表结构相同,表项等长。不便管理。
2. 编译程序把语言中的所有名字组织在 一张符号表中。 符号表便于管理,但表结构复杂且表项 不等长。
c语言 程序符号表

在C语言中,符号表(Symbol Table)是编译器在编译过程中用来存储变量、函数、宏等符号信息的数据结构。
符号表对于编译器的语义分析和代码生成阶段非常重要,它可以帮助编译器识别和解析标识符,并进行类型检查、函数链接等操作。
在C语言的编译器中,符号表通常是一个表格或哈希表结构,其中存储了以下类型的符号信息:
1.变量符号:包括变量的名称、类型、作用域等信息。
2.函数符号:包括函数的名称、参数类型、返回类型等信息。
3.宏定义符号:包括宏的名称、宏的参数和宏的替换文本等信息。
4.其他符号:例如结构体、联合体、枚举等类型的名称和成员信息。
在编译过程中,编译器会根据源代码中的标识符,将其添加到符号表中,并记录相关的符号信息。
同时,编译器还会对符号表中的信息进行验证和更新,以确保类型安全和正确的链接。
需要注意的是,具体的符号表实现方式可能会因编译器而异,但它们的基本原理和功能是相似的。
第六章 语义分析和符号表

FixBody: VariBody:
CaseUnit VariUnits
FixBody
VariBody Next
id CaseType Off
set:
Size Size Size
Kind Kind Kind
BaseType CompType TypeName
file:
pointer:
例有如下的类型定义:
标号部分语义分析原理
设置五种表:LDEC,LDEF,LUSE,SL,PL
LDEC表:(Flag, Label,<Label>); LDEF、LUSE表:(Label); SL表:(kind,LDEFaddr,LUSEaddr); PL表:(LDECaddr,LDEFaddr);
标号的语义分析原理
符号表
符号表的作用:为语义检查和代码生成提供 标识符的语义信息。 标识符的处理思想: 遇到定义性标识符时,在符号表中填写 被定义标识符的符号项; 当遇到使用性标识符时,用该标识符查 符号表求得其属性。
标识符的特点
标识符的作用域:标识符有效的最大程序段 嵌套作用域规则:当存在标识符的嵌套声明 时,最近定义的属性为标识符的当前属性 局部化单位:允许有声明的程序段
标准类型: Size sub: enum: array:
Size Size Size Kind HostType Elems Low Up Leng ElemType
Kind Kind Kind
IndexType
record:
Size Kind FixBody VariBody id FixUnitType Off Next
类型的内部表示
类型的种类:标准、子界、枚举、数组、记录、 集合、文件、指针类型等等。 TypeKind=(intTy,boolTy,charTy,realTy,enumTy, subTy,arrayTy,recordTy,setTy,fileTy,pointerTy)
语义分析和语法制导翻译-编译原理-06-(二)

是语法结构树指针 是名字的表项入口 是数值
id.entry num.val
树构造函数
mknode 建中间结点 mkleaf 建叶结点
生成语法树的属性文法
产生式 S→id:=E 语义规则 S.p:= mknode(':=', mkleaf(id, id.entry), E.p)
E→E1+E2 E.p:= mknode('+', E1.p, E2.p) E→E1*E2 E.p:= mknode('*', E1.p, E2.p) E→ -E1 E→ (E1) E→ id E→ num E.p:= mknode('-', 0, E1.p) E.p:= E1.p E.p:= mkleaf(id, id.entry) E.p:=mkleaf(num,num.val)
翻译模式的设计
D → T { L.in := T.type } L T → int { T.type := integer } T → real { T.type := real } L → { L1.in := L.in } L1 , id { addtype(id.entry, L.in) } L → id { addtype(id.entry, L.in) }
从其兄弟结点和父结点的属性值计算出来的 如:L.in
固有属性(单词属性)
属性的计算
构造语法分析树,填加响应的语义规则 综合属性
自底向上按照语义规则来计算各结点的综
合属性值
继承属性
需要探讨计算次序
例6-3:3*5+4 的
语法树与属性计算
E.val=15 T.val=15 T.val=3 F.val=3 digit.attr=3 *
c语言符号表

C 语言符号表C 语言符号表是一个重要的编译器数据结构,它用于存储和管理程序中的各种符号。
符号是指程序中的变量、函数、常量、类型等具有标识作用的名称。
符号表的作用是在编译过程中,为符号分配内存地址、类型、作用域等属性,并在需要时查找和修改符号的相关信息。
本文将从以下几个方面简述 C 语言符号表的概念、结构、功能和实现方法:符号表的概念和分类符号表的结构和组织方式符号表的功能和操作符号表的实现方法和技术符号表的概念和分类符号表的概念符号表是一种映射关系,它将程序中的符号名称映射到其对应的属性集合。
属性集合包括了符号的内存地址、数据类型、作用域、存储类别、初始化值等信息。
例如,下面的 C 语言代码片段中,定义了一个全局变量globalA,一个静态变量globalB,一个函数funcA和一个主函数main:/*** 全局变量*/int globalA =2022;/*** 静态变量*/static int globalB =2023;int funcA() {int localFuncAValue =13;return0;}int main(int argc, char*argv[]) {int localMainValue =14;return0;}对于这段代码,编译器会为每个符号创建一个符号表项,并填充其属性。
一个可能的符号表如下:符号名称内存地址数据类型作用域存储类别初始化值globalA1000int全局外部2022globalB1004int全局静态2023funcA2000int()全局外部-main3000int(int, char**)全局外部-localFuncAValue-4(%rbp)int局部(funcA)自动-localMainValue-4(%rbp)int局部(main)自动-可以看到,每个符号表项由一个符号名称和一个属性集合组成。
属性集合可以根据不同的编译器设计而有所差异,但一般都包含了上述几个基本属性。
第6章 语义分析(1)

类型的内部表示
为什么需要类型的内部表示?
– 类型是标识符的重要属性; – 类型检查是语义分析的重要部分; – 类型的结构对类型检查很重要;
程序语言的类型
– 基本类型 Integer (int ) Real (float) Bool Char – 构造类型 数组(Array) 结构体(Structure、record) 联合类型(Union、变体记录) – 枚举类型 – 指针类型
联合类型的内部表示
Kind Body unionT y Body: 指向联合体中域定义链表 Size: 所有域的类型的size中最大值;
Body
FieldName FieldType Next
Size
typedef union{ int i; char name[10]; real x; } test;
基本类型的内部表示
Size intPtr Kind
intSize
boolSize realSize
intTy
boolTy realTy
boolPtr realPtr
charPtr
charSize
charTy
数组类型的内部表示
Size
Kind arrayTy
Low
Up
ElemTy
size = sizeof(ElemTy) (Up-Low+1) ElemTy: 指向数组成分类型的指针; array [2..9] of integer; (8, arrayTy, 2, 9, intPtr)
第六章 语义分析
6.1 语义分析概述
6.2 符号表
6.3 类型的语义分析 6.4 声明的语义分析 6.5 程序体的语义分析 么是符号表(Symbol Table)?
编译原理符号表

编译原理符号表1. 引言编译原理是计算机科学领域中一个重要的研究方向,它研究的是将高级语言程序转化为机器语言的过程。
在编译器中,符号表是一种常用的数据结构,用于存储程序中的各种符号及其相关信息。
本文将深入探讨编译原理符号表的概念、作用、设计方法以及常见的符号表实现方式。
2. 符号表的概念和作用2.1 符号表的定义符号表是编译器中用于存储程序中各种符号信息的数据结构。
它一般由编译器自动生成和维护,用于支持语法分析、语义分析和代码生成等编译过程。
2.2 符号表的作用符号表在编译器的各个阶段都发挥着重要的作用:•语法分析阶段:符号表用于识别和存储各种变量、函数和类型的声明信息,以支持后续的语义分析过程。
•语义分析阶段:符号表用于检查变量和函数的引用是否合法,并记录其类型信息和作用域等属性,以支持类型检查和语义约束的验证。
•代码生成阶段:符号表用于存储中间代码和目标代码中的符号引用和符号定义的映射关系,以支持代码生成和目标代码优化等过程。
3. 符号表的设计方法3.1 符号表的数据结构符号表的数据结构通常由符号表项组成,每个符号表项用于存储一个符号及其相关信息。
常见的符号表项包括符号名称、符号类型、作用域、内存地址等。
3.2 符号表的组织方式符号表的组织方式可以有多种选择,常见的包括线性表、哈希表、树和图等。
选择合适的组织方式可以提高符号表的查询效率和插入删除的性能。
3.3 符号表的查询算法符号表的查询算法是指根据给定的符号名称,在符号表中进行查找并返回对应的符号表项。
常见的查询算法有线性搜索、二分搜索和哈希搜索等,选择合适的查询算法可以提高符号表的查询效率。
4. 常见的符号表实现方式4.1 线性表实现线性表实现是符号表最简单的一种实现方式,它可以使用数组或链表来存储符号表项。
线性表实现的优点是简单易懂,缺点是查询效率较低,随着符号表规模的增大,性能下降明显。
4.2 哈希表实现哈希表实现是一种常用的符号表实现方式,它通过哈希函数将符号名称映射到符号表项存储的位置。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
值的内部表示
非结构类型值的内部表示:
实型 指针 有序类型:整数形式
有序类型ห้องสมุดไป่ตู้常量表示:
整型常量:ord(N) = N 布尔常量:ord(false)=0, ord(true) = 1 字符常量:ord(C) = ASCⅡ (C) 枚举常量:设有枚举类型(D,A,B),则有
ord(D)=0,ord(A)=1,ord(B)=2 子界常量:设有子界类型C1..C2,则值空间
语义分析和符号表
主要内容: 语义分析概述(必要性、功能、描述方法) 符号表 类型表达式 声明和程序体的语义分析
语义分析的必要性
语法和语义的区别: 语法:关于什么样的字符串才是该语言 在组成结构上合法的程序的法则。 语义:关于结构上合法的程序的意义的 法则。
语义分析的功能
语义种类
静态语义:在编译阶段(从程序文本上)可 以检查的语义。
VariBody:
CaseUnit VariUnits
FixBody VariBody Next
id CaseType Off
set: Size
file: Size
pointer:
Size
Kind Kind
BaseType CompType
Kind TypeName
例有如下的类型定义: at = ARRAY [1..10] OF ARRAY[1..100] OF integer; rt = RECORD x : real ; a : at; CASE u: boolean OF false:(k : integer); true:(y: real; b: boolean) END 构造类型的内部表示。
符号表的实现
用局部符号表实现 proc p:x,y,z
proc p1:x,y1,z1 proc p2:y y,z x,y1,z1,y
proc p3:z,a x,y,a
x,z
符号表的实现
用全局符号表实现 proc p0:x,y proc p1:x,z y proc p2:x1,y1 y x,z
语义分析例子
例有声明如下: CONST pai= 3.14 ; TYPE vector=ARRAY[1..10] OF integer; VAR x, y : real ; r, s : vector ;
设当前层数和可用offset值分别为L和0, 构造标识符 pai, vector, x, y, r 和s 的属性表示。
program p() type at=array[1..100] of array[1..10] of inteter var x:real; a:at; i:integer; proc p1(var a1:at; a2:at) var x:integer; a:real; proc p2(n:integer) var m:1..50; x:real; m,n,x(使用性出现) end a1,a2,x,a,i(使用性出现) end x,a,i(使用性出现)
内部表示(AttributeIR):
常量: TypePtr Kind
Value
类型: TypePtr Kind
Forward
变量: TypePtr Kind Access Level Off
域名*: TypePtr Kind
Off
过函:
TypePtr Kind Level Parm Class
HostType Off Code Size Forward
处理符号表的模块: 定义符号表数据结构 定义符号表上的操作
符号表
符号表的作用:为语义检查和代码生成提供 标识符的语义信息。
标识符的处理思想: ▪ 遇到定义性标识符时,在符号表中填写 被定义标识符的符号项; ▪ 当遇到使用性标识符时,用该标识符查 符号表求得其属性。
标识符的特点
标识符的作用域:标识符有效的最大程序段 嵌套作用域规则:当存在标识符的嵌套声明
动态语义:通过程序的执行才能检查的语 义。
语义的描述
语义形式化方法: 1. 操作语义 2. 指称语义 3. 公理语义 4. 代数语义
语义分析的内容:
类型分析 标识符相关信息
语义分析的功能:
检查语义错误 构造标识符属性表(符号表)
语义分析的实现:
与语法分析相结合
语义分析的功能图示
语法分析树 TokenList
符号表的种类:全局符号表、局部符号表
原则:
▪ 进入一个局部化区时,记录本层符号表的 位置
▪ 遇到定义性标识符时,构造其语义信息, 查本层符号表,若存在,则有重复声明错 误,否则将语义信息填入表中
▪ 遇到一个使用性标识符时,查表(从里层 到外层),查不到则有未定义标识符错 误,否则构造新的TOKEN
▪ 退出一个局部化区时,作废本层符号表
sub: Size Kind HostType Low Up
enum: Size
Kind
Elems Leng
array: Size Kind IndexType ElemType
record: Size Kind FixBody VariBody
FixBody: id FixUnitType Off Next
语义分析
语义定义 自然语言描述规定
符号表 判定
三种内部表示
标识符的内部表示 类型的内部表示 值的内部表示
标识符的内部表示
标识符种类:
常量名、类型名、变量名、函数名、过程名、域名。
TYPE idkind=( consKind, typeKind, varKind,
fieldKind, procKind,funcKind )
为[ord(C1)...ord(C2)]
符号表
标识符的作用: 声明部分:定义了各种对象及对应的属性和 使用规则。 程序体:对所定义的对象进行各种操作。
必要性 Token: $id idname 新表-符号表(种类、类型等信息):
Idname AttributeIR
有关符号表的操作: 添加、作用域删除、查询
时,最近定义的属性为标识符的当前属性 局部化单位:允许有声明的程序段
P: Var x ,y,z x:=0;
Q: Var x,m,n
x:=1; m:=x+1;
y:=x+1;
局部化区入口
Proc p(… Func f(… 形式过/函 p( … f(… Record begin…
标识符处理的原则
类型的内部表示
类型的种类:标准、子界、枚举、数组、记录、
集合、文件、指针类型等等。 TypeKind=(intTy,boolTy,charTy,realTy,enumTy,
subTy,arrayTy,recordTy,setTy,fileTy,pointerTy)
内部表示:(TypeIR)
标准类型: Size Kind