编译原理(王晓斌)编译第三章

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
.发信号的过程被终止,而不再恢复。
2021/7/13
25
②过程内可以发信号的那些异常必须在过 程头加以说明
coca_cola=proc(a:int,s:string) returns(int)
signals (zero(int),overflow,had_format(string)) ③异常处理程序静态绑定于调用者
7 CONTINUE
2021/7/13
7
②Pascal的for 语句 计数重复的值可在任何有序集上 for . . . to for . . . downto 在循环外循环控制变量的值无定义
2021/7/13
8
2. 条件制导
①while 循环:描述0或任意多次的重复 ②repeat until循环:至少一次以上的重复 ③ALGOL 68循环的一般形式: for i from j by k to m while b do...od
2021/7/13
14
subprogram S(F1,F2,…,FN); ……
end
位置绑定: call S(A1,A2,…,AN) call S(A1,,A3,,,,,A8,,A10)
关键字绑定: call S(A1=>F1,A3=>F3,A8=>F8,A10=>F10)
2021/7/13
15
3. 副作用 对非局部环境的修改
2
二. 选择
1. if语句 ①ALGOL 60的选择结构引起二义性
if x>0 then if x<10 then x:=0 else x:=1000
②PL/1和Pascal的“最近匹配原则” ③ ALGOL 68中if语句的结束符号fi ④ ALGOL 68和Ada对else if 进行缩写
2021/7/13
第三章 控制结构
第一节 语句级控制结构
控制结构:程序员用来规定程序各个成分 的执行流程的控制部分。
语句级控制结构:语言用来构造各种语句 执行顺序的机制。
传统语言的三种语句级控制结构:顺序、 选择、重复。
2021/7/13
1
一. 顺序
顺序运算符; 语句括号begin . . . end 复合语句
2021/7/13
2021/7/13
31
3. 玩牌游戏
begin boolean gameover; integer winner; class player(n,hand); integer n; integer array hand(1:13); begin ref(player) next; detach; while not gameover do begin 出牌; if gameover then winner:=n else resume(next) end end
2021/7/13
12
第二节 单元级控制结构
单元级控制结构:规定程序单元之间控制 流程的机制 四种单元级控制结构:显式调用,异常处理, 协同程序,并发单元
2021/7/13
13
一. 显式调用从属单元
1.调用方式 由调用语句使用被调用单元的名字来
进行调用 2. 参数的两种绑定方式
位置绑定 关键字绑定
in:=0; {用于同步,可挂起consumer} spaces:=n; {用于同步,可挂起producer}
2021/7/13
41
process producer;
var i:integer;
repeat
produce (i); P(spaces); {等待自由空间} P(mutex); {等待缓冲区可用} 添加项目i到缓冲区; V(mutex); {终止访问缓冲区} V(in); {缓冲区项目数加1} forever
④异常名可多次说明,以最新一个为准 ON ZERODIVIDE BEGIN
…… END ⑤可用“NO <异常名>”限定异常的范围 (NO ZERODIVIDE): BEGIN
…… END
24
2. CLU的异常处理
①处理方法
.当过程P引发一个异常时,只能将其信号 传送给调用P的过程。这样做的目的使程 序有良好的结构,但在表达力方面要弱一 些。
2021/7/13
37
3. 信号灯
信号灯是一个数据对象,该数据对象采用一个 整数值,并可用原语P和V对它进行操作。信号 灯在说明时,以某个整数值对它初始化。
2021/7/13
38
①P、V操作的定义 P(s): if s>0 then s:=s-1
else 挂起当前进程 V(s): if 信号灯上有挂起的进程
B2 →S2
B3 →S3
…...
BN →SN
其中,Bi是布尔表达式,称为卫哨。若有 多个卫哨为真时执行任一Si。
2021/7/13
6
三. 重复
1. 计数器制导
当预先知道重复次数时,在循环计数器值的有 限集合上重复。
①FORTRAN的DO循环中,用标号控制循环体 DO 7 I=1,10 A(I)=0 B(I)=0
then 唤醒进程 else s:=s+1
2021/7/13
39
②原语P、V是不可再分的原子操作 ③信号灯满足的要求 记录挂起的进程(用队列) 唤醒策略(考虑优先级、时间等)
2021/7/13
40
④一个例子 “生产者-消费者”问题 const n=20 shared var 缓冲区长度n,缓冲区项目总数t; semaphare mutex:=1; {用于保证互斥}
②程序单元可以显式引发异常 raise <异常名>;
2021/7/13
27
③异常处理程序紧跟在子程序、程序包或 分程序之后
begin …;
exception when HELP=>…;
when DESPERATE=>…;
end;
④若引发异常的单元为异常提供处理程序, 控制将直接转移到那个处理程序, 一旦处理程 序执行完后, 引发异常的单元也终止
2021/7/13
30
2. SIMULA 67的协同程序是一个类实例
一般形式为:
class 类名(参数);
若设类x, 变量y1和y2
参数说明;
是对x的引用, 那么可
begin
写成:
说明;
y1:-new x(…);
语句表1; detach; 语句表2 end
y2:-new x(…); 当遇到一个new时, 建 立类的一个新实例, 并 执行类体
repeat 从缓冲区移出一项; 对该项执行某个运算;
forever
2021/7/13
34
2. 几个基本概念
①并发单元的特点:诸程序单元并行活动 ②同步问题 正确访问缓冲区:不会向已满的缓冲区写数据, 不会从空缓冲区读数据
2021/7/13
35
动作的”不可分”与”可分”
设t表示所存项目总数,append是生产者向缓 冲区存数的操作,remove是消费者从缓冲区取 数的操作,这两个操作都要修改t的值,相应执行 操作(1)t:=t+1和(2)t:=t-1来实现。假定(1)和 (2)是这样实现的:
①副作用降低了程序的可读性
②副作用限制了数学运算律的使用
如:w:=x+f(x,y)+z
x、y为变参 z为全局变量
③副作用影响目标代码的优化
如:u:=x+z+f(x,y)+f(x,y)+x+z
2021/7/13
16
4.别名
在单元激活期间,两个变量表示(共享)同一 数据对象
①FORTRAN的EQUIVALENCE语句 ②Pascal的变参使得形参和实参共享同一数
读t到一个专用寄存器;
更新专用寄存器的值;
将专用寄存器的值写到t;
2021/7/13
36
互斥:执行(1)时不能开始执行(2),反之亦然。 即,(1)和(2)必须以互斥的方式执行,(1)或(2)就 像不可分的操作。
③进程的并发性:诸进程的执行概念上是可重 叠的(即正在执行的进程尚未终止,另一个进 程可能开始执行)。
procedure swap(var x:integer); /*a是全局变量*/
begin
x:=x+a;
a:=x-a;
x:=x-a;
end; 调用
swap(a); 将产生不正确的结果
2021/7/13
19
④别名也影响编译器生成优化的代码
a:=(x-y*z)+w /* 若a与x、y或z中任一个
b:=(x-y*z)+u
p(i).next:-p(i+1); p(4).next:-p(1); resume (1); 打印胜利者(winner) end
2021/7/13
33
四.并发单元
1. 一个例子 “生产者-消费者”问题
单元producer
repeat 生产一个元素; 存放这个元素到缓冲区;
forever
单元consumer
……
case operator of
‘.’:result:=operand1 and operand2;
‘+’:result:=operand1 or operand2;
‘=’:result:=operand1 = operand2;
end
2021/7/13
5
③Dijkstra选择结构的非确定性
if B1→S1
(异常处理程序)?
(4)发生异常时,如何绑定相应的异常处理程 序?
(5)处理异常之后,控制流程转向何处?
2021/7/13
22
1. PL/1异常处理
①异常的说明 ON <条件> <异常处理程序> ②异常的引发 SIGNAL<条件>
2021/7/13
23
2021/7/13
③语言预定义了一些异常, 如 ZERODIVIDE
2021/7/13
9
④Ada 的循环结构
loop /*可以在loop前加重复说明*/
循环体(语句序列)
end loop;
ห้องสมุดไป่ตู้
重复说明可以是:
while <条件>
或 for <计数变量> in <离散范围>
或 for <计数变量> in reverse <离散范围>
可由exit或exit when<条件>终止循环
据对象
2021/7/13
17
procedure swap(var x,y:integer);
begin
x:=x+y;
y:=x-y;
x:=x-y;
end; 调用
swap(a,a); swap(b[i],b[j]); swap(p,q);
若i=j 若p、q指向同一数据对象
2021/7/13
18
③变参和全局变量表示同一数据对象时,也 会引起别名
2021/7/13
10
⑤Dijkstra的卫哨命令表示法 do B1→S1 B2→S2
...... BN→SN od
2021/7/13
11
四. 语句级控制结构讨论
顺序、选择、重复是一定意义的抽象 关于goto语句的讨论 控制结构的选择
五. 用户定义控制结构
如:Pascal的计数控制变量可以是枚举 类型
是别名 */
⑤别名的消除
.废除可能引起别名的结构

2021/7/13
.限制使用指针、变参、全局变量、数组
20
二. 隐式调用单元异常处理
异常是指导致程序正常执行中止的事件, 要靠发信号来引发,用异常条件来表示。
2021/7/13
21
有关异常处理的主要问题:
(1)异常如何说明,它的作用域是什么? (2)异常如何发生(或如何发信号)? (3)发出异常信号时,如何控制要执行的单元
2021/7/13
28
⑤若当前执行的单元U并未提供相应的异常 处理程序,异常将被传播: 若U是一个分程序, 那 么终止U的执行, 并在包围U的单元内隐式引发 这个异常; 若U是一个程序包体, 那么异常传播 给包含这个程序包说明的单元
2021/7/13
29
三. SIMULA 67协同程序
1. 两个或两个以上程序单元之间交错地 执行,这样的程序称为协同程序
3
2. 多重选择
①PL/1的select结构
SELECT:
WHEN(A)S1;
WHEN(B)S2;
WHEN(C)S3;
OTHERWISE S4;
END
2021/7/13
4
②多种语言的case语句
var operator:char;
operand1,operand2,result:boolean;
2021/7/13
32
ref(player) array p(1:4);integer i; integer array cards(1:13); for i:=1 step 1 until 4 do begin 第i家拿牌;
p(i):-new player(i, cards) end; for i:=1 step 1 until 3 do
<语句> except<处理程序表>end 其中,<处理程序表>的形式是
when <异常表1>: <语句1>
…… when<异常表n>: <语句n>
2021/7/13
26
3. Ada的异常处理
①异常的说明类似于变量的类型说明
PECULIAR,BUFFER_FULL,ERROR:exception;
相关文档
最新文档