第六章 语义分析和符号表

合集下载

第6章语法制导

第6章语法制导
• 方法
–编写说明语句的文法 编写说明语句的文法 –将类型信息作为类型描述 T 的属性 type 将类型信息作为类型描述 in。 和变量表 L 的属性 in。
• 目的
–分析说明语句 D,为变量指定类型 分析说明语句
13
addtype
addtype
addtype
例:real id1,id2,id3 的分析树和 属性计算 14
2
语义分析的任务
• 语义检查
–例:类型、运算、维数、越界 例 类型、运算、维数、
• 语义处理
–例:变量的存储分配 例 –例:表达式的求值 例 –例:语句的翻译(中间代码的生成) 例 语句的翻译(中间代码的生成)
• 总目标:生成等价的中间代码 总目标:
3
处理方法
• 对应每一个产生式编制一个语义子程序, 对应每一个产生式编制一个语义子程序, 当一个产生式获得匹配时, 当一个产生式获得匹配时,调用相应的语 义子程序实现语义检查与翻译。 义子程序实现语义检查与翻译。 • 在产生式的右部的适当位置,插入相应的 在产生式的右部的适当位置, 语义动作,按照分析的进程, 语义动作,按照分析的进程,执行遇到的 语义动作。 语义动作。
第六章
• • • • •
属性文法和语法制导翻译
语法制导翻译概述 属性文法 翻译模式 自顶向下翻译方法 自底向上翻译方法
1
6.1 语法制导翻译概述
• 语法制导翻译以属性文法为基础 • 语法结构具有规定的语义 • 在进行语法分析的同时,完成相应的语 在进行语法分析的同时, 义处理 • ???如何根据被识别出的语法成分进 ???如何根据被识别出的语法成分进 行语义处理
消除左递归后的翻译模式: 消除左递归后的翻译模式: E → T {R.i := T.val} R{E.val:=R.s} R → + T {R1 .i:=R.i+T.val} } R → - T {R1 .i:=R.i+T.val} } R → ε {R.s:=R.i} R T → num T → ( E )

编译原理课件(刘铭)第6章

编译原理课件(刘铭)第6章

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

ch06--语义分析

ch06--语义分析
7
6.2

符号表
符号表在翻译过程中起两方面的重要作用:
–检查语义(即上下文有关)的正确性 –辅助正确地生成代码

通过在符号表中插入和检索变量的属性来实现的 符号表是一张动态表
–在编译期间符号表的入口不断地增加 –在某些情况下又在不断地删除

Wensheng Li BUPT
编译程序需要频繁地与符号表进行交互,符号表的 效率直接影响编译程序的效率。
变量名 able_n b_loop count flag form mlist x_total 类型 1 1 2 1 3 6 1 维数 0 0 1 0 2 0 0 声明行 5 5 2 7 4 6 3 引用行 11,23,25 10,11,13 9,14,15 28,29 36,37,38 17,21 12,14
优化 目标代码
其他遍
符号表

Wensheng Li BUPT
两方面的优点:
– 对语法分析程序来讲降低了文法的复杂性 – 允许用更系统的方法对上下文有关的错误进行检测和校正。
11
二、符号表内容


符号表中记录的是和标识符相关的属性 出现在符号表中的属性种类,在一定程度上取决 于程序设计语言的性质。 符号表的典型形式:
–实参的个数与形参的个数一致 –实参的类型与相应形参的类型一致

Wensheng Li BUPT
在符号表组织中:
–把参数的个数看作它的维数是很方便的,因此,可将这 两个属性合并成一个。 –这种方法也是协调的,因为对这两种属性所做的类型检 查是类似的。
17
交叉引用表


编译程序可以提供的一个十分重要的程序设计辅 助工具:交叉引用表 编译程序一般设一个选项,用户可以选择是否生 成交叉引用表

第六章 语义分析和符号表

第六章 语义分析和符号表

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-(二)

语义分析和语法制导翻译-编译原理-06-(二)
E.p
是语法结构树指针 是名字的表项入口 是数值
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 *

符号表组织符号表组织语义分析之一

符号表组织符号表组织语义分析之一
• CLEN(成分类型的长度)– 成分类型的数据所占值单 元的个数;
※ 这里假定:值单元个数依字长为单位计算。
路漫漫其修远兮, 吾将上下而求索
6.3.4 结构表(RINFL)
※ 结构:
每个域占表中一个纪录
ID
OFF TP
• ID(结构的域名)—
• OFF(区距)—是idk的值单元首址相对于所在记录值 区区头位置;

名字 类型 种类 地址
PFINFL(函数表)
TYPEL(类型表) TVAL TPOINT· AINFL(数组表 )
RINFL(结构表)

CONSL(常量表)
LENL(长度表 ) VALL(活动纪录 )
路漫漫其修远兮, 吾将上下而求索
6.3.1 符号表总表(SYNBL)
※ 结构: NAME TYP CAT ADDR
约定:off1=0, off2= off1+LEN(tp1), …… offn= offn-1+LEN(tpn-1)。 idn-1的长度
• TP(域成分类型指针) – 指针,指向idk域成分类型 路漫漫其修远兮, (在类型表中的信息);
吾将上下而求索
6.3.5 函数表(PFINFL)
---- 过程或函数语义信息 ※ 结构:
※ 结构:

路漫漫其修远兮, 吾将上下而求索
6.4 符号表的构造过程示例:
SYNBL
PFINFL
exp rtp f
?
2 ENT
线性表、顺序表、索引表和散列表,皆可以采用。
路漫漫其修远兮, 吾将上下而求索
6.2.3 符号表的维护、管理方式
※一个源文件有若干个函数组成,通常,每个函数对 应一个符号表,此外,还是有一个公用符号表;

第6章 语义分析(2)

第6章 语义分析(2)
类型声明
– 一般形式 id = type; 一般形式: – 内部表示 内部表示:
建立 type的内部表示; 建立 id的内部表示;
TypePtr
Kind typeKind
6.4 声明的语义分析
变量声明
– 一般形式: type id; 一般形式 – 内部表示 : 建立 type的内部表示;
获取<CurrentLevel, CurrentOffset> 获取 确定存取方式: 确定存取方式 dir/indir 建立 id的内部表示; CurrentOffset += sizeof(type)
语句
… FunNode1
6.4 声明的语义分析
常量声明
– 一般形式 id = number; 一般形式: – 内部表示 内部表示:
建立 number值的内部表示; 建立 number类型的内部表示; 建立 id的内部表示;
TypePtr
Kind constKind
Value
6.4 声明的语义分析
第六章 语义分析
6.1 语义分析概述 6.2 符号表 6.3 类型的语义分析 6.4 声明的语义分析 6.5 程序体的语义分析 6.6 属性文法和动作文法
内容回顾
什么是语义分析? 什么是语义分析
– 建立符号表 建立符号表; – 检查语义错误 检查语义错误;
在何处进行分析? 在何处进行分析
– 声明部分 --- 建立符号表;检查“重复声明”错误 建立符号表;检查“重复声明”错误; – 体部分 --- 查找符号表,检查“有使用无声明”错误和 查找符号表,检查“有使用无声明”
Size
Kind structTy
Body
6.3 类型的语义分析

编译原理_第6章__语义分析和中间代码生成

编译原理_第6章__语义分析和中间代码生成

非终结符T有一个综合属性type,其值为 int或float。语义规则L.in=T.type表示L.in的属性 值由相应说明语句指定的类型T.type决定;属 性L.in被确定后将随语法树的逐步生成而传递 到下边的有关结点使用,这种结点属性称为继 承属性。由此可见,标识符的类型可以通过继 承属性的复写规则来传递。 例如,对输入串int a,b,根据上述的语义 规则,可在其生成的语法树中看到用“→”表 示的属性传递情况,如图6–3所示。
直接生成目标代码 直接生成机器语言或汇编语言形式的目标 代码的优点是编译时间短且无需中间代码到目 标代码的翻译。 生成中间代码 生成中间代码的优点是使编译结构在逻辑 上更为简单明确,特别是使目标代码的优化比 较容易实现。
语义分析时语义检查的分类:
动态语义检查
需要生成相应的目标代码,它是在运行时进行的;
例如,简单算术表达式求值的属性文法如下: 规则 语义规则 (1) S→E print (E.val) (2) E→E(1)+T E.val=E(1).val+T.val (3) E→T E.val=T.val (4) T→T(1)*F T.val=T(1).val*F.val (5) T→T(1) T.val=T(1).val (6) F→(E) F.val=E.val (7) F→i F.val=i.lexval
6.1 概

6.1.1 语义分析的概念 一个源程序经过词法分析、语法分析之后,表 明该源程序在书写上是正确的,并且符合程序语言 所规定的语法。但是语法分析并未对程序内部的逻 辑含义加以分析,因此编译程序接下来的工作是语 义分析,即审查每个语法成分的静态语义。如果静 态语义正确,则生成与该语言成分等效的中间代码, 或者直接生成目标代码。

语义分析与符号表

语义分析与符号表

第五章语义分析5.1语义分析基础5.1.1 语义分析内容程序设计语言的语义可分为静态语义和动态语义。

所谓静态语义是指在编译阶段能检查的语义,而动态语义则指只有在目标码的运行阶段才能检查的语义。

如果所有类型均能在编译阶段检查,则称这种语言为强类型语言。

Pascal是强类型语言的一个例子。

在某些语言里变量的类型是可变的,这时类型的语义成为动态语义,因为类型相容问题只能在代码运行时才能检查出来。

语言的静态语义成分越多编译器和解释器的区别会越大,如果都属于动态语义,那么编译器和好的解释器的差别将会变小。

类型在大多数语言里都属于静态语义,而且它是最重要的静态语义,可以说,静态语义问题主要是类型相容的问题。

类型检查主要有以下几种:∙各种条件表达式的类型是不是boolean型?∙运算符的分量的类型是否相容?∙赋值语句的左右部的类型是否相容?∙形参和实参的类型是否相容?∙下标表达式的类型是否为所允许的类型?∙变体记录中表示情形的常量是否为合法类型?∙函数说明中的函数类型和返回值的类型是否一致?等除了上述类型检查外,还要进行如下一些语义检查:∙V[E]中的V是不是变量,而且是数组类型?∙V.i中的V是不是变量,而且是记录类型? i是不是该记录类型中的域名?∙V↑中的V是不是指针或文件变量?∙y+f(....)中的f是不是函数名?形参个数和实参个数是否一致?∙p(....)语句中的p是不是过程名?形参个数和实参个数是否一致?∙每个使用性标识符是否都有相应的声明?在同层内有无标识符被声明多次?∙标号是否有声明?有无重复声明和重复定位错误?有无非法转入错误?∙子界类型中的下界和上界类型是否相容?下界是否小于等于上界?∙ ..........................................一遍扫描的编译器是从源程序的ASC码序列即源语言的字符串序列直接生成目标代码,因此不会有独立的语义分析器。

多遍扫描的编译器,也未必有独立的语义分析器,如果没有,则意味着把语义检查工作分散到编译过程的几个阶段中顺便完成。

第六章(2)符号表的管理

第六章(2)符号表的管理

}
} a = 1, b = 1 printf(“a = %d, b = %d\n”, a, b);
}
33
2.在语言程序的局部化单位中,标识符的出现分为定 义性出现和使用性出现。
⑴定义性出现的标识符:局部化单位的声明部分出现 的标识符,其作用是确定该标识符的属性信息,如 名字,类型,存储位置等。一个标识符在一个局部 化单位只能被声明一次。
28
❖对于散列表,新符号的登录是通号表的目的:
判断该符号的存在性; 获取该符号的语义属性. ❖符号表的查找算法:顺序查找、折半查找、杂凑查 找.
30
6.3.3 符号表的局部化处理
一、问题的引出
1.源语言程序的局部化单位 程序中允许有声明的 部分称为一个局部化单位,通常是一个子程序(函数、 过程)或分程序:
19
6.3.1 符号表的建立和查找
一.符号表的初始化 在编译过程中某个时刻,符号表的状态反
映了该时刻被编译的语言程序正被编译的位置 的状态.具体来说主要是反映了在该时刻被编译 的语言程序中可视标识符的状态. 符号表的初始化,在对语言程序开始编译的时刻, 定义建立符号表的初始状态.
20
1.符号表的表长是渐增变化的情况: ❖线性组织和二分法组织的符号表,其表的长度在编译开始时 通常为0,而随着符号的逐步登录,表长增长. ❖按这类方法组织的符号表,其初始化方法只需将表尾推向表
一、符号表的总体组织
符号表的每一项包含两部分:标识符的名字;该名字的信 息。
不同类别的标识符所包含的信息是不同的。 符号表的总体组织既可以采用多表结构,也可以采用单表
结构,也可以二者折中。究竟采用哪种结构并没有统一的规 定,编译程序可根据实际处理语言的需要进行选择。

10+8--语义分析与符号表

10+8--语义分析与符号表
c hfwang - 8/22 -
基本概念
符号表
类型检查
VSL语言的符号表 1/3
符号表元素的数据类型 typedef struct symb { struct symb *next; int type; union { int val; char *text;
/* /* /* /* /*
} val1; union { /* 变量的第一个值 */ int val; /* 对变量取偏移量等 */ struct tac *label; /* 对标号取三地址码 指针 */ } val2 ; } SYMB ; /* 整数常量, 字符串常量和语句标号等也使用 本数据类型, 但是由于没有对其查找的要求, 这些数据将不保存在Hash表中 */ SYMB *symbtab[HASHSIZE] ; /* 符号表 */
静态性质(static):在编译阶段就可以确定的性质, 如:C语言的全 局变量, 类型, 变量和类型的关系,运算和转移指令和函数的入口 地址; 动态性质(dynamic):程序在运行阶段才能确定的性质— 程序在运 行时才能确定的性质,如:C语言的被调用函数的运行环境 (参数、 返回地址、 局部变量和返回值) ;面向对象语言的Virtual Function的动态绑定(binding); 动态性质有相对不变性, 栈式运行环境中, 如: 局部变量和栈顶的 位置关系是不变的; 动态性质必须用其相对不变性实现, 如:函数的调用和被调用转 化为相对不变的调用序列和被调用序列; 语义分析(Semantic Analysis)是编译器前端(front-end)的最后一个 环节, 主要是符号表的建立和类型检查(type checking), 为下一 步中间表示提供必要的上下文相关的信息。
下一个节点 */ 符号的数据类型 */ 变量的第一个值 */ 对整数常数取其值 */ 对变量取其形, 为字符指针 */

第六章(1)语义分析(Semantic Analysis)

第六章(1)语义分析(Semantic Analysis)
码生成时进行 ② 一般的语义检查:与语法分析相结合
17
方式二 独立一遍的语义分析的功能图示
语法分析树 TokenList
语义分析
语义定义
自然语言描述的规定
符号表 判定
18
类C语言的抽象语法树
程序Root
节点 Node1
节点 Node2 ……
节点 Noden
节点 Node
常量声明 类型声明 变量声明 函数声明
标识符的属性(续2)
存取方式 因为变量标识符代表的是一个内存单元或一段 连续的内存单元,根据这些内存单元中存放信息的类别 又可以把变量分为间接存取变量和直接存取变量。
如果变量标识符p所代表的内存单元中存放的是另一 个变量q对应的内存地址,则称变量p为间接存取变量; 如果变量标识符p所代表的内存单元中存放的是一个 值,则称变量p为直接存取变量。
形式语义描述技术没有形式语法描述技术成熟 硕士研究生的课程-《形式语义学》
11
语义分析的主要任务
根据声明部分建立符号表
符号表(symbol table):是一种供编译器用于保 存有关源程序的各种信息的数据结构。符号表的每 个条目中包含与一个标识符相关的信息,这些信息 全面地反映该名字的属性及它们在编译过程中的特 征。
① 自动(auto) ② 寄存器(register) ③ 静态(static) ④ 外部(extern)
自动变量(本函数内有效) 寄存器变量(本函数内有效) 形式参数(本函数内有效) 静态局部变量(函数内有效) 静态外部变量(本文件内有效)
30
作用域和可视性
通常,标识符的作用域都是通过它在程序中的位置隐 式说明的。
26
标识符的属性(续3) 程序区 静态存储区 动态存储区

编译原理符号表的作用

编译原理符号表的作用

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

6-第六章_语义分析-1-2-3节

6-第六章_语义分析-1-2-3节

2.语义分析程序 2.语义分析程序
为每个产生式,构造一个语义子程序Subi , 为每个产生式,构造一个语义子程序Sub 语义程序包括: 针对每一条产生式) 语义程序包括:⑴ Subi (针对每一条产生式) 公共子程序) ⑵ Comj (公共子程序)
语法分析程序 Par1,Par2…Park 语义 分析 程序 Sub1 Sub2 Ret1,Ret2…Reth
L.in= real L.in= real , , id2 id3
L.in= real id1
语 义 规 则 L.in:=T.type T.type=integer T.type:=real L1.in:=L.in;addtype(id.entry,L.in) ; addtype(id.entry,L.in)

Subn 中间代码Leabharlann Com1… Com m
例:E→E1 + E2 入口参数(Par) (Par): .PLACE, 入口参数(Par): E1.PLACE, E2.PLACE (存放E1 、E2 的值的单元地址) 存放E 的值的单元地址) 返回参数(Ret): E.PLACE (存放E值的单元地址) 返回参数(Ret): (存放E值的单元地址) (Ret) 存放 生成中间代码 ( +, E1.PLACE, E2.PLACE, E.PLACE)
例: E → E1 + E2 E .code —— E的中间代码序列 E .val —— E的值 存放E E .PLACE —— 存放E的值的单元地址
说明: 不同的中间代码形式、不同的语言成份, 说明: 不同的中间代码形式、不同的语言成份, 使用的属性不同。 使用的属性不同。
属性 • 综合属性(synthesized attribute) 综合属性(synthesized

编译原理课件-符号表

编译原理课件-符号表

關鍵字域的組織
符號表的關鍵字域(段)就是符號名稱 等長關鍵字域(段)符號表 不等長關鍵字段符號表---採用關鍵字池的 索引結構。
作用域檢查 作用域和可見性
基本作用域規則(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 符號表
.符號表的作用和地位 .符號的主要屬性及作用 .符號表的組織
符號表的作用和地位-----語義檢查的依據
目標代碼生成階段地址分配的依據
在編譯程式中符號表用來存放語言程式中出現的有 關識別字的屬性資訊,符號表中所登記的資訊在 編譯的不同階段都要用到。
在語義分析中,符號表所登記的內容將用於語義檢 查(如檢查一個名字的使用和原先的說明是否一 致)和產生中間代碼。

计算机编译chapt6

计算机编译chapt6

V→Elist]
{ V.place:=getc(Elist.array); V.offset:=Elist.place } 数组元素的宽度W1时, V.offset:=newtemp; emit(*,Elist.place,W,V.offset);
E→V
{ if V.offset=null then E.place:=V.place else begin E.place:=newtemp; emit(=[],V.place[V.offset],-,E.place); end }
2. 语法制导翻译
为每个产生式配上一个语义子程序,在语
法分析过程中,当用一个产生式进行匹配 或归约时,就调用相应的语义程序。
上述语义子程序既可能包含了语义检查,
也可能包含了语义处理,其核心是为了生 成相应的中间代码。
例:语法分析采用自底向上的LR分析法 XAB B的语义值 B A的语义值 YCD A ZXY
(2)两条新的四元式 变址取数 (=[],T1[T],_,X) 相当于X:=T1[T] 变址存数 ([]=,_,X,T1[T]) 相当于T1[T]:=X
(3)语义子程序 V→i { P:=lookup(); if P<>nil then begin V.place:=P; V.offset:=null end else error }
E4.place=d E5.place=t4
(*,t1,4,t2)
(=[], X0[t2],_,t3)
(+,t3,d,t4) (:=,t4,_,a)
Elist.array:记录数组名
Elist.place:记录归约过程中VARPART
的中间结果 Elist.dim:记录当前处理这一维的序号 getc(Elist.array):从内情向量中取数组的 CONSPART limit(Elist.array,k):从内情向量中取数组 第k维的维长
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

符号表的实现
用局部符号表实现 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
若有,则检查其Flag位,若是1,则有重复定位错误; 若Flag=0,令其Flag位为1,并将ℓ 填入LDEF表中; 查看LUSE表,若其中有ℓ则将其删除掉。
4)进入一个结构语句时,将本语句的LDEF和LUSE表位置填 入SL表。 5)遇到一个“goto ℓ” 时: 查看LDEF表,看其中是否有ℓ; 若无,将填入LUSE表。 6)退出一个结构化语句时: 清查本层LUSE表(若有定位则删除该项):用本层的 LUSE中标号查本层定位表,若查到,则把该项从LUSE 中删除; 作废本层的LDEF。 7)退出一个过/函时: 清查本层LUSE表; 作废本层的LDEC和LDEF。 8)程序结束时,清查LUSE表,若非空,则说明有标号为定 位的错误。
标准类型: 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
值的内部表示

非结构类型值的内部表示:
实型 指针 有序类型:整数形式
有序类型的常量表示:



整型常量: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,则值空间 为[ord(C1)...ord(C2)]
符号表
符号表的作用:为语义检查和代码生成提供 标识符的语义信息。 标识符的处理思想: 遇到定义性标识符时,在符号表中填写 被定义标识符的符号项; 当遇到使用性标识符时,用该标识符查 符号表求得其属性。
标识符的特点
标识符的作用域:标识符有效的最大程序段 嵌套作用域规则:当存在标识符的嵌套声明 时,最近定义的属性为标识符的当前属性 局部化单位:允许有声明的程序段
标号部分语义分析原理
设置五种表:LDEC,LDEF,LUSE,SL,PL
LDEC表:(Flag, Label,<Label>); LDEF、LUSE表:(Label); SL表:(kind,LDEFaddr,LUSEaddr); PL表:(LDECaddr,LDEFaddr);
标号的语义分析原理
FixBody: VariBody:
CaseUnit VariUnits
FixBody
VariBody Next
id CaseType Off
set:
Size Size Size
Kind Kind Kind
BaseType CompType TypeName
file:
pointer:
例有如下的类型定义:
语义分析例子
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(使用性出现) end
类型的内部表示
类型的种类:标准、子界、枚举、数组、记录、 集合、文件、指针类型等等。 TypeKind=(intTy,boolTy,charTy,realTy,enumTy, subTy,arrayTy,recordTy,setTy,f表示:(TypeIR)
标号的语义分析
标号出现的位置: 标号声明:label 1, 2, …, n; 标号定位(语句前):i:Statement; 标号使用(Goto后):goto i; 标号部分的语义错误: 标号重复声明; 标号重复定位; 标号有定位而无声明; 标号有使用而无定位; Goto语句有非法转入。
1)进入一个过/函时,将本层LDEC和LDEF的地址填入PL表。 2)遇到一个标号声明“label 1, 2,…,n”时,建立本层LDEC表(检查 重复声明错误),其中的Flag标志均设置为0。 3)遇到定位性标号“:Statement”时:

检查在LDEC表中有无ℓ ,若无则表示无标号声明错误;
语义定义 自然语言描述规定
判定
三种内部表示
标识符的内部表示 类型的内部表示 值的内部表示
标识符的内部表示
标识符种类:
常量名、类型名、变量名、函数名、过程名、域名。 TYPE idkind=( consKind, typeKind, varKind, fieldKind, procKind,funcKind )
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 构造类型的内部表示。
例有声明如下:
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 的属性表示。
语义分析和符号表
主要内容:

语义分析概述(必要性、功能、描述方法)


符号表
类型表达式 声明和程序体的语义分析
语义分析的必要性
语法和语义的区别: 语法:关于什么样的字符串才是该语言 在组成结构上合法的程序的法则。 语义:关于结构上合法的程序的意义的 法则。
语义分析的功能
语义种类
静态语义:在编译阶段(从程序文本上)可 以检查的语义。 动态语义:通过程序的执行才能检查的语 义。
语义的描述
语义形式化方法: 1. 操作语义 2. 指称语义 3. 公理语义 4. 代数语义
语义分析的内容:
类型分析 标识符相关信息
语义分析的功能:
检查语义错误 构造标识符属性表(符号表)
语义分析的实现:
与语法分析相结合
语义分析的功能图示
语法分析树 语义分析 符号表
TokenList
内部表示(AttributeIR):
常量: 类型: 变量: 域名*: 过函:
TypePtr TypePtr Kind Kind Value Forward
TypePtr Kind
TypePtr Kind
Access
Off
Level
Off
Off
HostType
TypePtr Kind
Level Parm Class Code Size Forward
符号表
标识符的作用: 声明部分:定义了各种对象及对应的属性和 使用规则。 程序体:对所定义的对象进行各种操作。 必要性
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…

标识符处理的原则
符号表的种类:全局符号表、局部符号表 原则: 进入一个局部化区时,记录本层符号表的 位置 遇到定义性标识符时,构造其语义信息, 查本层符号表,若存在,则有重复声明错 误,否则将语义信息填入表中 遇到一个使用性标识符时,查表(从里层 到外层),查不到则有未定义标识符错 误,否则构造新的TOKEN 退出一个局部化区时,作废本层符号表
相关文档
最新文档