南开大学编译原理第6章课件

合集下载

编译原理教案.ppt

编译原理教案.ppt
❖ 教学主线:类型检查
4
第七章:运行时环境
❖ 教学内容及进度:第七章运行时环境7.17.3&7.6-7.8
概述(5分钟) 源语言问题(15分钟) 存储组织(5分钟) 存储分配策略(15分钟) 符号表(20分钟) 支持动态存储分配的语言措施(10分钟) 动态存储分配技术(10分钟)
5
第七章:运行时环境
编译原理教案 第十六课
1
第六章:类型检查 ❖ 教学内容及进度:第六章类型检查6.1-6.2
概述(10分钟) 类型系统(10分钟) 一个简单的类型检查器的说明(20分钟)
2
第六章:类型检查 ❖ 教学目的和要求
掌握类型系统 掌握一个简单的类型检查器的说明
3第六章:类型ຫໍສະໝຸດ 查 ❖ 教学重点掌握类型系统 掌握一个简单的类型检查器的说明
❖ 教学目的和要求
掌握源语言问题 掌握存储组织 掌握存储分配策略 掌握符号表 了解支持动态存储分配的语言措施 了解动态存储分配技术
6
第七章:运行时环境
❖ 教学重点
源语言问题 存储组织 存储分配策略 符号表
❖ 教学主线:存储组织、分配策略和符号表
7

南开大学C++课件_第_6章b_指针、结构体及引用

南开大学C++课件_第_6章b_指针、结构体及引用

21
bool compword(char* a, char* b) //比较二字符串大小,按字典序a<b则返1即true(书p155为int型) { while(*a != '\0' && *b != '\0') //a串与b串都没结束时 if(*a != *b) return(*a < *b); //第一个不相等字符, 决定整个a,b串的大小 else {a++; b++;} return(*a=='\0'); //注意,此时至少有一个串已结束(短者优先) }
当要对a赋值123时,下述三个语句是等价的: a=123; *pa=123; ra=123;
4
引用类型变量与其他类型变量不同,它没有 自己的值和地址空间,只是作为另一变量的别 名,在它的生存期期间两个名字绑定在一起, 因此,引用类型的使用是有限制的: 引用类型变量不能被引用; 引用类型不能组成数组; 引用类型不能定义指针。 正是这些限制,保证了它的安全性,反而成 为人们选择它取代方便灵活的指针的原因。
22
6.5.2
构建一个人员档案链表
为了管理人员(职员,学生,居民等)或物资、文献的档案 资料,使用链表形式很方便。链表可长可短,其功能可通过使 用指针以及动态创建和撤消数据对象的运算符new和delete来 完成。
本示例性程序建立并管理人员链表,具体做以下4项工作: 1) 读入若干个人员的档案资料(读入'*'符号时结束输入), 动态生成链表项,并将输入的档案资料存放于链表项之中,而 后总将新链表项加入到原链表的末尾; 2) 遍历链表, 输出整个链表的各项内容; 3 ) 在 链 表 首 加 入 一 项 , 其 name="wang ping", age=20, sex='M' ; 4) 统计出当前链表中共有多少男士,并计算出他们的平均 年龄。

编译原理chapter6 语法分析

编译原理chapter6  语法分析

可能有几处说明,语言的作用域规则规定:
在语句序列中引用的一个名字是在何处说
明的名字。
3 . 编译时,处理说明把名字及其属性信息填
写进符号表(add(id.entry,id.vul)); 处理引用
名字时,查找这个名字的属性信息
(lookup(id)),符号表管理程序根据语 言的
作用域规则,使 lookup(id)返回id的作用域
中绑定的属性信息。 精品文档
14
6.1.5名字与存储的绑定 名字与存储单元的绑定是指把源程序中的数 据名字映射到目标机存储单元的过程。 引进两个函数,environment和state。 environment把名字映射到一个存储单元上; state把存储单元映射到那里所存放的值上。 可以说,函数environment把一个名字映射为 一个l-value(左-值),而函数state把一个lvalue(左-值)映射为一个r-value(右-值)。 如图6.5所示。
精品文档
11
例6.2 栈和活动树的变化
栈 s Sr S q(1.9) S q(1.9) p(1,9) S q(1.9) q(1,3)
S q(1.9) q(1,3) p(1,3) S q(1.9) q(1,3) q(1,0)
S q(1.9) q(1,3) q(2,3)
s r q(1,9)
p(1,9) q(1,3)
用活动树来讨论正在这个结点上的控 制。
ห้องสมุดไป่ตู้
精品文档
9
s
图6.3 一棵活动树
r q(1,9)
p(1,9) q(1,3)
q(5,9)
p(5,9) q(5,5) q(7,9) p(1,3) q(1,0) q(2,3)

编译原理 6章

编译原理 6章

布尔矩阵和关系
• 关系可用集合定义,也可用布尔矩阵表示 xRy 当且仅当M[x,y]=1 • • • • 定理6.1 M(RT)=M(R)T 定理6.2 M(R1+R2)=M(R1)+M(R2) 定理6.3 M(R1R2)=M(R1)M(R2) 定理6.4 M(R+)=M(R)+
传递闭包 的Warshall算法 算法
文法G(E): E→E+T | T T→T*F | F F→(E) | i
+ + * i ( ) > > > < > * < > > < > < < i < < ( < < ) > > > = >f+ Nhomakorabeaf*
fi
f(
f)
g+
g*
gi
g(
g)
+
f 4 f+, g+, f(, g) 3 g+,f(,g)
*
6.7.2 Bell 方法
• Bell方法:有向图构造法。 方法: 方法 有向图构造法。 ① 作两排结点:一排为f L ,另一排为g R; L>R, 从L到R连一有向弧; L<R, 从R到L连一有向弧; L=R, 从L到R和从R到L各连一有向弧; ② 计算各结点能到达的结点数(包括自己) 为该函数点的值。 ③ 按定义6.1的条件判断,若不满足则不存在 优先函数。
与文法有关的一些关系: 与文法有关的一些关系:
⑴ 关系和 x, y∈Σ,R1和R2是Σ上的两个关系,R1与 R2的两个关系和记为R1+R2。 x(R1+R2)y 当且仅当 xR1y或xR2y ⑵ 关系积 R1和R2是Σ上的两个关系,R1与R2的两个 关系积记为R1R2。 xR1R2y 当且仅当 存在w∈Σ,使得xR1w与wR2y ⑶ 传递闭包 关系R的传递闭包记为R+,x, y∈Σ, xR+y 当且仅当存在n>0,使得xRny ⑷ 自反传递闭包 关系R的传递闭包记为R*,x, y∈Σ, xR*y 当且仅当 存在n≥0,使得xRny ,其中R0为恒等

编译原理 第6章课件

编译原理 第6章课件

第6章LR分析法教学要求:1.掌握:活前缀的概念,2.理解:LR (0 ), SLR (1), LR(1)和LALR(1)分析过程,各类分析表的构造3.了解:二义性文法在LR 分析中的应用目录 6.1 LR 分析概述6.2 LR (0) 分析6.3 SLR(1) 分析6.4 LR (1)分析6.5 LALR(1)分析6.6 二义性文法在LR 分析中的应用强调算符之间的优先关系的唯一性,这使得它的适应面比较窄算法在发现最左素短语的尾时,需要回头寻找对应的头LR(k)分析法可分析LR(k)文法产生的语言– L :从左到右扫描输入符号,– R :最右推导对应的最左归约(反序完成最右推导)– k :向前读入k 个符号,以便确定归约用的产生式LR 分析法正是给出一种能根据当前分析栈中的符号串和向右顺序查看输入串的K 个( K ≥0)符号就可唯一地确定分析器的动作是移进还是归约和用哪个产生式归约,因而也就能唯一地确定句柄。

LR 分析法的归约过程是规范推导的逆过程,所以LR 分析过程是一种规范归约过程。

6.1 LR分析概述L:从左到右扫描输入串R : 最右推导的逆过程分析器模型和分析算法• LR分析特征讨论说明:S[i] 为状态栈, X[i]为文法符号栈。

状态转换表用GOTO[S i ,X]= S j 表示,规定当栈顶状态为S i ,遇到当前文法符号为X 时应转向状态S j ,X 为终结符号或非终结符号。

ACTION[S i ,a]规定了栈顶状态为S i ,遇到输入符号为a 应执行的动作。

动作有如下四种: 移进: S j = GOTO[S i ,a]移入状态栈,a 移入到文法符号栈。

归约: 栈顶形成句柄为β时,文法有产生式 A →β,若 β的长度为r ,则从两个栈顶去掉r 个符号,把A 移入符号栈,S j =GOTO[S i ,A] 移入状态栈。

接受acc 报错LR 分析算法 置ip 指向输入串w 的第一个符号 令S 为栈顶状态 a 是ip 指向的符号 重复 begin if ACTION[S,a]=S j then begin PUSH j,a(进栈)ip 前进(指向下一输入符号) end else if ACTION[S,a]=r j (第j 条产生式为A →β)then beginpop |β| 项令当前栈顶状态为S’push GOTO[S’,A]和A(进栈)end else if ACTION[s,a]=accthen return (成功)else errorend.重复LR 文法:对于一个上下文无关文法(Context Free Grammar)-cfg 文法, 如果能 够构造一张 LR 分析表, 使得它的每一个入口均是唯一的(Sj,rj,acc,空白), 则称该 cfg 是LR 文法.LR分析:特征:规范的符号栈中的符号是规范句型的前缀,且不含句柄以后的任何符号(活前缀)分析决策依据:栈顶状态和现行输入符号.• 四种技术 LR(0) SLR(1) LR(1) LALR(1)6.2 LR(0) 分析LR(0)文法--------能力最弱,理论上最重要:存在FA 识别活前缀识别活前缀的DFA 如何构造(LR(0)项目集规范族的构造)LR(0)分析表的构造一、可归约前缀和子前缀最右推导过程(每条产生式尾部加上编号)S ⇒aAcBe[1] ⇒aAcd[4]e[1] ⇒aAb[3]cd[4]e[1]⇒ab[2]b[3]cd[4]e[1]归约时在栈里的句型的前缀 归约前可在栈里的规范句型(不含句柄) 的前缀 ab[2] aaAb[3] a,aAaAcd[4] a,aA,aAcaAcBe[1] a,aA,aAc,aAcB可归约前 子前缀活前缀(viable prefixes )G=(Vn,Vt,P,S),若有S’ ⇒ αA ω ⇒ αβω,γ是αβ的前缀,则称是文法G 的活 前缀. 其中S’是对原文法扩充(S’→S)增加的非终结符.? 为使S’不出现在任何产生式的右部.活前缀是规范句型(右句型)的前缀,但不超过句柄移进归约分析的栈中出现的内容加上余留输入构成规范句型二、识别活前缀的FA启示:可以把非终结符号和终结符号都看成一个FA 的输入符号,每把一个符号 进栈时看成已识别过了该符号,而状态进行转换,当识别到可归约前缀 时,相当于在栈顶形成了句柄,则认为达到了识别句柄的终态。

编译原理第6章_1

编译原理第6章_1

STACK REMAINING INPUT
1
(int + int)#
2(
int + int)#
3 (int
+ int)#
4 (T
+ int)#
5 (E
+ int)#
6 (E +
int)#
7 (E + int
)#
8 (E + T
)#
9 (E
)#
10 (E)
#
11 T
#
12 E
#
13 S
#
PARSER ACTION Shift Shift Reduce: T –> int Reduce: E –> T Shift Shift Reduce: T –> int Reduce: E –> E + T Shift Reduce: T –> (E) Reduce: E –> T Reduce: S –> E
的左部而得到的
文法要求
shift-reduce or reduce-reduce 冲突(conflicts)
分析程序不能决定是shift 还是 reduce 或者分析程序归约时有多个产生式可选
例子 (dangling else) : S –> if E then S | if E then S else S
LR分析算法
then begin pop || 项 令当前栈顶状态为S’ push GOTO[S’, A]和A(进栈)
end else if ACTION[s,a]=acc
then return (成功) else error end

编译原理---第6章

编译原理---第6章
国家精品课程
——
1
《编译原理》
第6章 语法制导翻译 与属性文法
语法制导翻译概述 属性文法
综合属性与继承属性 S_属性文法 L_属性文法
翻译模式

国家精品课程
——
2
《编译原理》
6.1 语法制导翻译概述
语法制导翻译的概念描述
在进行语法分析的同时,完成相应的语义处理 E→E1 + E2 E.val:=E1.val+E2.val
T → int
T → real
L → L1,id
L → id
1. 纪录标识符的类型 2. 类型信息传递
方法:用T.type记录类
型信息,并传给L.in

国家精品课程
——
15
《编译原理》
例6-2 说明语句的属性文法
D→TL
T → int T → real L → L1,id L → id
digit.lexval=4

例6-4:real id1,id2,id3 的分析树和属性计算
D T .type=real L .in=real D → T { L.in := T.type } L T → int { T.type := integer } T → real { T.type := real }
这种属性叫做继承(Inherited)属性

国家精品课程
——
21
《编译原理》
3. 属性分类——固有属性
语言中的标识符、常数(数值的、符号的) 、常量,它们的属性是用户给定的、固有不 变的
T → int T.type := „integer‟
固有(Inherent)属性(单词属性) 归类于综合属性

编译原理精选版演示课件.ppt

编译原理精选版演示课件.ppt

预测分析表
3
表驱动的预测分析程序模型
khk
4
实现步骤:
(1) 判断文法是否为LL(1)文法。 如果文法中含有左递归,必须先消除 左递归
(2)构造预测分析表 : Select(A ) (3)列出预测分析过程
khk
5
第6章:自底向上分析方法
自底向上分析方法,也称移进归约分析法
实现思想(是推导的逆过程):
对输入符号串自左向右进行扫描,并将输入符逐个 移入一个后进先出栈中,边移入边分析,一旦栈顶 符号串形成某个句型的可归约串时,就用该产生式 的左部非终结符代替相应右部的文法符号串,称为 归约。重复这一过程,直到归约到栈中只剩下文法 的开始符号时,则分析成功。
关键问题
khk
6
移进—规约分析(Shift-reduce parsing)

A a
可得 b <. a
由A→( B 且B+ ( B… 可得 (<. (

B aa…
可得 (<. a

B Aa )
可得 (<. A
khk
18
A(B(Aa) …)
(3) 求> .关系:
A(B…B

Aa
由S→bAb,且A…) 可得 ) > . b
A+…B 可得 B > . b
khk
88
例1:文法
SaAcBe A b A Ab B d
输入串abbcde#分析
khk
9
归约分析过程(移进归约):
步骤 1 2 3 4 5 6 7 8 9 10 1kh1k
符号栈 # #a #ab #aA #aAb #aA #aAc #aAcd #aAcB #aAcBe #S
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

类型表达式的图表示不同——叶结点为
基本类型或类型名 递归定义类型会导致回路
6.3.1 类型表达式的结构等价

结构等价(structural equivalence)
1.
2.
相同的基本类型 对子表达式施加的类型构造符相同 两个类型表达式结构等价——dag中对应相 同结点 等价性检查算法稍做修改
第六章 类型检查
内容
类型系统
类型表达式的等价
类型转换
函数和运算符的重载
多态函数 一致化算法
静态检查(static checking)
1. 2.
类型检查(type check)

操作对象必须与操作符匹配:函数名相加×
break必须退出while、for、switch… 对象(变量、标号…)定义必须唯一 相同名字在不同位置
4.
可使用类型表达式变量
图表示类型表达式
(char×char)pointer(integer)
6.1.2 类型系统
type
system:规则的集合 规则——将类型表达式赋予程序的不同 部分 类型检查程序:实现一个类型系统 语法制导方式实现——嵌入语义规则
6.1.2静态/动态检查
5个变量类型是否都相同?——依赖实现 允许类型表达式命名,但不允许回路 名字等价:完全相同 结构等价:名字被替换后完全相同

例6.2
变量 next last p q r 类型表达式 link link pointer(cell) pointer(cell) pointer(cell)
名字等价:next,

例6.1(续)
构造符的编码 pointer array freturns 基本类型编码 boolean char integer real

01 10 11
0000 0001 0010 0011
例6.1(续)

编码方法
最右端四位二进制位表示基本类型 它前面两位表示第一个构造符 再前面两位表示第二个构造符 类型表达式 编码
静态——编译器进行
动态——运行时进行 可靠类型系统,强类型语言——编译器 无type_error运行时无类型错误 int a[10], i; b=a[i];——需动态检查 安全领域也涉及类型检查(缓冲溢出问 题)
6.1.4 错误恢中
…, Tn——T1×…×Tn 更复杂例子:root: (realreal)×realreal
function root(function f(real): real; x: real): real
6.3 类型表达式的等价
两个类型表达式等价的精确定义?
用类型表示方式可快速确定等价性
结构等价和名字等价
错误修正比描述正确程序更困难
根据错误的程序、处理缺失信息,来推测正
确类型在变量使用之前无需定义它 类型变量可用来处理这种问题
6.2 一个简单的类型检查器
6.2.1 一种简单语言

PD;E D D ; D | id : T T char | integer | array [ num ] of T | ^T E literal | num | id | E mod E | E [E] | E^

char freturns(char) pointer(freturns(char)) array(pointer(freturns(char)))
000000 0001 000011 0001 000111 0001 100111 0001
例6.1(续)
加速等价性检查
不同二进制串不可能表示相同类型
可添加其他类型和运算
6.2.3 语句的类型检查
赋值、条件、while 无错误,void;错误,type_error

S id := E
S if E then S1
S while E do S1
S S1 ; S2
{S.type = if (lookup(id.entry)==E.type) then void else type_error } {S.type = if (E.type == boolean) then S1.type else type_error } {S.type = if (E.type == boolean) then S1.type else type_error } {S.type = if (S1.type == void) and (S2.type == void) then void else type_error }
类型表达式(续)
d) 指针:T为类型表达式,则pointer(T)为类型表 达式,表示“指向类型为T的对象的指针”类 型 row *p;——pointer(row) e) 函数:数学上,一个集合“定义域”到另一个 集合“值域”的映射。程序语言,定义域类型 D到值域类型R的映射:DR。 %运算符——(int×int)int int *f(char a, char b);—— (char×char)pointer(integer) 不考虑函数返回数组、函数类型的情况 (integerinteger)(integerinteger)
6.2.4 函数的类型检查
函数定义
T T1„‟ T2
函数调用 E E1(E2) 多参数:T1,
{T.type = T1.typeT2.type }
{E.type = if (E2.type==s) and (E1.type==st) then t else type_error }

6.1.1 类型表达式

type expression——用以表示语言结构 的类型 基本类型或用类型构造符组合基本类型
1.
2.
基本类型:boolean, char, integer, real, type_error, void 类型名
类型表达式(续)
3.
类型构造符
a) 数组:T是类型表达式,I为索引集合(整数范 围),则array(I, T)是一个类型表达式,表示元 素为类型T的数组类型 int A[10];——array({0, …, 9}, integer) b) 笛卡儿积:T1、T2为类型表达式,则T1×T2为 类型表达式

有时要放松条件——数组参数忽略界限

等价性检查算法
bool sequiv(s, t) { if (s和t为相同基本类型) return true; else if (s == array(s1, s2) and t == array(t1, t2)) return sequiv(s1, t1) and sequiv(s2, t2); else if (s == s1×s2 and t = t1×t2) return sequiv(s1, t1) and sequiv(s2, t2); else if (s == pointer(s1) and t == pointer(t1)) return sequiv(s1, t1); else if (s == s1s2 and t == t1t2) return sequiv(s1, t1) and sequiv(s2, t2); else return false; }
控制流检查(flow-of-control check)

3.
4.
唯一性检查(uniqueness check)

名字关联检查(name-related check)

类型检查
检查语法结构的类型与上下文匹配
简单的类型检查 两个类型的匹配
代码生成要利用类型信息
重载,多态
6.1 类型系统

名字等价:next, last类型相同,q, r类型相同, p, next, q类型不同
例6.3(续)

实现方式——构造类型图


对基本类型和类型构造符——创建新结点 对新类型名——创建叶结点,保存与类型表达式的 链接

名字等价——相同结点
6.3.3 回路问题
链表、树:递归定义
实现:记录——数据、指向同一记录类

语法结构、类型、将类型赋予语法结构的规则


+, -, *的两个运算数均为整数,结果为整数 &的结果为指向操作对象的指针,若操作对象类型 为T,结果类型为“指向T的指针”
每个表达式都有一个相关联的类型 类型是有结构的!——指针 基本类型:语言内部支持类型 结构类型:组合基本类型构成新类型
翻译模式
PD;E {} DD;D {} D id : T { addtype(id.entry, T.type) } T char {T.type = char } T integer {T.type = integer } T array [ num ] of T {T.type=array(1..num.val,T.type)} T ^T {T.type = pointer(T.type) }
不同类型可能表示为相同二进制串——数组
界限、函数参数
记录的编码
在类型表达式中记录作为基本类型 用另一个二进制串编码它的域
6.3.2 名字等价
type link = ^cell; var next : link; last : link; p : ^cell; q, r : ^cell;
类型表达式(续)
c) 记录:与笛卡儿积的不同之处仅在于记录的域 有名字。<域名,域类型>元组 typedef struct { int address; char lexeme[15]; } row; row table[101]; 类型表达式为: record((address×integer)× (lexeme×array({0, …, 15}, char)))
相关文档
最新文档