编译原理 第七章

合集下载

编译原理chapter7

编译原理chapter7

Return sequence
被调用者将返回值放到和参数相邻的位置 恢复top_sp和寄存器,跳转到返回地址。 和寄存器, 恢复 和寄存器 跳转到返回地址。
版权所有 计算机学院 闫健恩
25
调用代码序列的例子
版权所有 计算机学院 闫健恩
26
7.3.4栈中的 栈中的 变长数据
如果数据对象 的生命期局限 于过程活动的 生命期, 生命期,就可 以分配在运行 时刻栈中。 时刻栈中。 top指向实际的 指向实际的 栈顶 top_sp用于寻 用于寻 找顶层记录的 定长字段
18
运行时刻栈的例子
运行栈: 运行栈:把控制栈中的信息拓广到包括过程 活动所需的所有局部信息(即活动记录) 活动所需的所有局部信息(即活动记录) s a : array s
版权所有 计算机学院 闫健恩
19
运行时刻栈的例子
运行栈: 运行栈:把控制栈中的信息拓广到包括过程 活动所需的所有局部信息(即活动记录) 活动所需的所有局部信息(即活动记录) s a : array r i: integer s r
版权所有 计算机学院 闫健恩
11
7.3 栈式分配
内容: 内容: 活动树 活动记录 调用代码序列 栈中的变长数据
版权所有 计算机学院 闫健恩
12
7.3.1 活动树
过程调用(过程活动)在时间上总是嵌套的: 过程调用(过程活动)在时间上总是嵌套的:
后调用的先返回 因此可以用栈式分配来处理过程活动所需要的 内存空间。 内存空间。
22
k: integer
7.3.3 调用代码序列
调用代码序列(calling sequence)为活动记录 调用代码序列 为活动记录 分配空间,填写记录中的信息; 分配空间,填写记录中的信息; 返回代码序列(return sequence)恢复及其状 返回代码序列 恢复及其状 是调用者继续运行。 态,是调用者继续运行。 调用代码序列会分割到调用者和被调用者 中。

编译原理第七章

编译原理第七章

4
LR 分析器工作示意图
5
步骤 符号栈 输入符号串
1) 2) 3) 4) 5) 6) 7) 8) 9) 10) 11) # #a #ab #aA #aAb #aA #aAc # aAcd #aAcB #aAcBe #S abbcde# bbcde# bcde# bcde# cde# cde# de# e# e# # #
13、 T • int 14、 T int • 15、 T •(E) 16、 T (• E) 17、 T (E •) 18、 T (E) • 注意: ① 初态 ② 句柄识别态 ③ 句子识别态
注意:拓广文法引入的意义。(确保初态唯一)
23
NFA for Viable Prefixes of the Example
求解方程组可得: [S’] = [S] = [A] = a+[A] [B] = aAc
推论:若文法G中有产生 式B→A,则有 LC(A) LC(B)· {}
[A] = a|[A]
[A] = a*=a
这样求出了每个非终结符在规范推导中用该非终结符的右部 替换该非终结符之前,它的左部可能出现的所有前缀,也就 是在规范归约过程中用句柄归约成该非终结符之前不包括句 柄的活前缀。 15
归约(如何找当前句柄归约)?
3
3) 4) 5) 6)
#ab #aA #aAb #aA
bcde# bcde# cde# cde#
归约(A→b) 移进 归约(A→Ab) 移进
分析:已分析过的部分在栈中的前缀不同,而且移进和归 约后栈中的状态会发生变化
我们引入一个新的状态栈来表示符号栈中的符号目前状态
用LR分析表来表示不同状态下对于各输入符号应采取的动 作

编译原理_第7章

编译原理_第7章

29
§7.3 赋值语句的翻译
3.例题:写出下列代码段中表达式的翻译制导过 程及其所产生的四元式 begin Integer:B、C、D、X;
X:=-B*(C+D);
end
符号表 <B> B <C> C <D> D <X> X Int Int Int Int (1) (2) (3) (4) 四元式 Op - + * := arg1 <B> <C> T1 T3 arg2 <D> T2 - result T1 T2 T3 X
语义处理分两步:
1.静态语义分析,即验证语法结构合法的程序是否真正有意义。
2.若静态语义正确,语义处理则要执行真正的翻译。 即要么生成程序的一种中间表示形式(中间代码),
要么生成实际的目标代码。
静态语义检查包括:
(1)类型检查; (2)控制流检查; (3)一致性检查; (4)相关名字检查。
2
第七章
8
§7.1 中间语言
例子:如图所示,为a+a*(b-c)+(b-c)*d的DAG
+
+
* a b c
*
d
9
§7.1 中间语言
2.抽象语法树
例子:(1)a:=b*-c+b*-c的图表示法
assign a * b uminus c b + * uminus c DAG
10
assign
a + * b uminus c
数据区中的相对地址offset.
(3)综合属性: T.type-名字的类型; T.width-名字的域宽(即该类型名字所占用 的存储单元个数)
22
§7.2 二、保留作用域信息

编译原理 - 陈火旺版 - 第七章

编译原理 - 陈火旺版 - 第七章

3
后缀式
后缀式(逆波兰式)
表达式E的后缀形式E’的写法:
• 若E是变量或常量,则E’ = E • 若E=E1 op E2,则E’ =E1’ E2’ op • 若E=(E1),则E’ = E1 表达式变为后缀形式的语义规则
E→E1 op E2 E→(E1) E→i {E.CODE := E1.CODE||E2.CODE||op } {E.CODE := E1.CODE} {E.CODE := i}
推广到表达式外的范围
• 例如 a:=b*c+b*d 后缀形式:abc*bd*+:=
5

抽象语法树
内部结点表示运算符,后代表示运算对象
无循环有向图(DAG)
与抽象语法树
• 相同之处:内部结点表示运算符,后代表示运算对象 • 不同之处:考虑到公共子表达式(不只一个父结点),更加紧 凑高效
四元组表示 (1) (-,C, D , T1) (2) (*, B, T1, T2) (3) (+, A, T2 , T3) (4) (↑, F, G , T4) (5) ( /, E, T4, T5) (6) (-, T3, T5 , T6)
13
说明语句的翻译
说明语句
定义局部于该过程的数据对象(以标识符标识) 为数据对象分配空间,在符号表中登记数据对象的名 字,类型,分配的存储地址 有过程嵌套的,表示出嵌套关系
编译方法
中国人民大学信息学院 陈文萍
1
第7章 语义分析和中间代码生成
中间语言 一些语法成分的翻译
说明语句 赋值语句 布尔表达式 控制语句 过程调用
类型检查
2
语义分析概述

编译原理第七章

编译原理第七章

例题

设有文法G(L)

LE,L LE Ea Eb
文法G(L)的LR分析表如下
ACTION表
状态 0 1 2 3 4 5 S3 S4 S5 r3 r4 a S3 b S4 acc r2 r3 r4 2 6 , # E 2
GOTO表
L 1
6
r1
以输入串“a,b,a”为例,给出LR分析 器的分析过程如下表示:
步骤 1 2 3 4 5 0 03 02 025 0254 状态栈 # #a #E #E, #E,b 符号栈 输入符号串 分析动作 a,b,a# S3(移进) ,b,a# r3(规约) ,b,a# S5(移进) b,a# S4(移进) ,a# r4(规约)
6
7 8 9
0252
02525 025253 025252
S4
S6 r2 r2 S8 r3 r3 r3 r2
3
7
r4 r1
r4 r1
r4 r1
以输入串“abbcde”为例,给出LR分析器的分析过程如下表示:
步骤 1 2 3 4 5 6 7 8 9 0 02 024 023 0236 023 0235 02358 02357 状态栈 # #a #ab #aA #aAb #aA #aAc #aAcd #aAcdB 符号栈 输入符号串 分析动作
7.1.2 分析表或分析函数

LR分析表是LR分析器的核心。 分析表由两个子表构成,即动作表(ACTION表)和状 态转换表(GOTO表)。它们都是二维数组形式(数组 名称分别是GOTO和ACTION)。


对于GOTO表。它的一个数组元素GOTO(Sm,Xi)代表一 个状态。表示当状态Sm面临输入符号Xi时转移到的下一个状态 (通常Xi是非终结符)。 对于ACTION表。它的一个数组元素ACTION(Sm, ai)代表一 个动作,表示当状态Sm面临输入符号ai时完成的分析动作(通 常ai是终结符)。动作可以有四种可能,分别是移进、规约、 接受和出错。

编译原理第七章

编译原理第七章

2014年6月15日12时14分
非终结符号T有两个综合属性 T.type 和T.width,分别表示 名字的类型和名字的域宽 (即该类型名字所占用的存储单 元个数)。 假定整数类型域宽为4;实数域宽为8;一个数组的域宽可 以通过把数组元素数目与一个元素的域宽相乘获得;每个 指针类型的域宽假定为4。 计算说明语句中名字的类型和相对地址的翻译模式如下:
子表达式 (base-((low1*n2)+low2)*w的值是可以在编译时 确定的。
2014年6月15日12时14分
例 1 设A为一个10*20的数组,即n1=10,n2=20。并设w=4。 赋值语句x:=A[y, z] 被翻译成如下三地址语句序列: T1:=y*20 T1:=T1+z T2:=A-84 T3:=4*T1 T4:=T2[T3] x:=T4
2014年6月15日12时14分
7.4 布尔表达式的翻译 在程序设计中,布尔表达式有两个基本作用:一个是用作 计算逻辑值;另一个用作控制流语句之中的条件表达式。 计算布尔表达式的值通常有两种办法。一种办法是,如同 计算算术表达式一样,一步不差地从表达式各部分的值计 算出整个表达式的值。例如,按通常的习惯,用数值1代 表true,用0代表false,那么,布尔式1 or (not 0 and 0) or 0的计算过程是: 1 or (not 0 and 0) or 0 =1 or (1 and 0) or 0 =1 or 0 or 0 =1 or 0 =1
S→id:=E {p:=lookup(); if p≠nil then emit(p’:=’E.place) else error} {E.place:=newtemp; emit(E.place’:=’E1.place’+’E2.place)}

编译原理7

编译原理7
… (p) goto (q) (p+1) (关于S2的四元式)
… (q)
// E.true
// E.false // E.true // E.false
回填 : (1)和(5)的转移地 址为(7), 它是在整个 布尔表达式的四元式 序列生成之后才回填 的地址。
if A<B goto 102 goto 106 …
108: if e<f goto 111 109: T3 =0 110: goto 112 111: T3 =1 112: T4 = T2 and T3 113: T5 = T1 or T4
7.4.2 作为条件控制的布尔式翻译
出现在条件语句
if E then S1 else S2
中的布尔表达式
E,
○ = 1 or (1 and 0) or 0 ○ = 1 or 0 or 0 ○ = 1 or 0 ○= 1
2.采取某种优化措施, 只计算部分表达式
把A or B解释成 if A then true else B
把A and B解释成 if A then B else false
第七章 语义分析和中间代码生成
0 1 中间语言 0 2 说明语句 0 3 赋值语句的翻译 0 4 布尔表达式的翻译 0 5 控制语句的翻译 0 6 过程调用的处理 0 7 类型检查
7.4 布尔表达式的翻译
布尔表达式文法G
○ E E1 or E2 | E1 and E2 | not E1 | ( E1 ) ○ | id1 relop id2 | true | false | id3
它的作
用仅在于控制对
S1和S2的选择。
无须保留E的值。
E.true: E.false:

编译原理作业集-第七章(精选.)

编译原理作业集-第七章(精选.)

编译原理作业集-第七章(精选.)第七章语义分析和中间代码产⽣本章要点1. 中间语⾔,各种常见中间语⾔形式;2. 说明语句、赋值语句、布尔表达式、控制语句等的翻译;3. 过程调⽤的处理;4. 类型检查;本章⽬标掌握和理解中间语⾔,各种常见中间语⾔形式;各种语句到中间语⾔的翻译;以及类型检查等内容。

本章重点1.中间代码的⼏种形式,它们之间的相互转换:四元式、三元式、逆波兰表⽰;3.赋值语句、算术表达式、布尔表达式的翻译及其中间代码格式;4.各种控制流语句的翻译及其中间代码格式;5.过程调⽤的中间代码格式;6.类型检查;本章难点1. 各种语句的翻译;2. 类型系统和类型检查;作业题⼀、单项选择题:1. 布尔表达式计算时可以采⽤某种优化措施,⽐如A and B⽤if-then-else可解释为_______。

a. if A then true else B;b. if A then B else false;c. if A then false else true;d. if A then true else false;2. 为了便于优化处理,三地址代码可以表⽰成________。

a. 三元式b. 四元式c. 后缀式d. 间接三元式3. 使⽤三元式是为了________:a. 便于代码优化处理b. 避免把临时变量填⼊符号表c. 节省存储代码的空间d. 提⾼访问代码的速度4. 表达式-a+b*(-c+d)的逆波兰式是________。

a. ab+-cd+-*;b. a-b+c-d+*;c. a-b+c-d+*;d. a-bc-d+*+;5. 赋值语句x:=-(a+b)/(c-d)-(a+b*c)的逆波兰式表⽰是_______。

a. xab+cd-/-bc*a+-:=;a. xab+/cd-bc*a+--:=;a. xab+-cd-/abc*+-:=;a. xab+cd-/abc*+--:=;6. 在⼀棵语法树中结点的继承属性和综合属性之间的相互依赖关系可以由________来描述。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

图 7.1 LR分析器工作过程示意图
其中SP为栈指针,S[i]为状态栈,X[i]为文法符号栈。状态转换表用 GOTO[Si,X]=Sj 表示,规定当栈顶状态为Si遇到当前文法符号为X时应转向 状态Sj。X为终结符或非终结符,状态的含义将在后面介绍。
ACTION[Si,a]规定了栈顶状态为Si时遇到输入符号a应执行的动 作。动作有4种可能:
7.2 LR(0)分析
LR(0)分析表构造的思想和方法是构造其它LR分析表的基础。 例6.1文法G[S]为: (1) S→aAcBe (3) A→Ab
(2) A→b (4) B→d
对输入串abbcde#用自底向上归约的方法进行分析,当归约到第5步时栈中 符号串为#aAb,我们采用了产生式(3)进行归约而不是用产生式(2)归约,而在第 3步归约时栈中符号串为#ab时却用产生式(2)归约,虽然在第2步和第5步归约前 栈顶符号都为b,但归约所用产生式却不同,其原因在于已分析过的部分在栈中 的前缀不同,也就是我们在LR分析中引进的状态栈的栈顶状态不同,为了说明这 个问题我们先在表7.1中给出例6.1文法G[S]的LR(0)分析表,在表7.2给出对输入 串abbcde#的分析过程,并引进一些概念和术语。 表 7.1符号说明: Si:移进,将状态i和输入符进栈 ri:归约,用第i个产生式归约,同时状态栈与符号栈退出相应个符号,并 把GOTO表相应状态和第i个产生式的左部非终结符入栈。
规定:LR(0)CONTEXT(A→β)=LC(A).β(加上产生式右部,得到包含 句柄的活前缀)。 例6.1 文法包含句柄的活前缀。 包含句柄的活前缀也就是可归约前缀,将它们展开就得到所有 的活前缀。
P129页 例: 1、求不包含句柄在内的有关非终结符A的活前缀LC(A) (方程组)。 观察产生式右部的非终结符。 2、应用LR(0)CONTEXT(A→β)=LC(A).β求得包含句柄 的活前缀。 3、由此可构造以文法符号为字母表的识别(包括句柄) 活前缀的不确定有限自动机。 4、应用子集法对上述的不确定有限自动机进行确定化 得到识别可归前缀的确定有限自动机。 结论:对任何一个上下文无关文法只要能构造出识别 可归前缀的有限自动机,就可以构造其相应的分析表。
7.2.1 可归前缀和子前缀
为了在以后的LR分析中不致引起混淆,现对原文法进行拓广。 若原文法G的开始符号为S,在G中加产生式S′→S后得新的文法G′, 则称G′为原文法G的拓广文法,而S′为拓广后文法G′的开始符号。 对文法进行拓广的目的是为了对某些右部含有开始符号的文法,在 归约过程中能分清是否已归约到文法的最初开始符,还是在文法右 部出现的开始符号,拓广文法的开始符号S′只在左部出现,这样 确保了不会混淆。
S
定义7.1 若S′
R
αAω
R
αβω是文法G′中的一个规范推导,G′
是G的拓广文法,符号串γ是αβ的前缀,则称γ是G的,也是G′ 的一个活前缀。 实际上γ是规范句型αβω的前缀,但它的右端不超过该句型句 柄的末端(其中A→β是一产生式,ω∈VT*; α、β、γ∈V*)。 由以上分析我们很容易理解,在LR分析过程中,实际上是把αβ的 前缀列出放在符号栈中,一旦在栈中出现αβ,即句柄已经形成, 则用产生式A→β进行归约。 7.2.2 识别活前缀的有限自动机 在LR方法实际分析过程中并不是去直接分析文法符号栈中的符号 是否形成句柄,但它给我们一个启示,我们可以把终结符和非终结 符都看成一个有限自动机的输入符号,每把一个符号进栈时看成已 识别过了该符号,而状态进行转换,当识别到可归前缀时,相当在 栈中形成句柄,则认为到达了识别句柄的终态。
若对例6.1文法G[S]的每条产生式编上序号用[i]表示加在产生式的 尾部,使产生式变为: S→aAcBe[1] A→b[2] A→Ab[3] B→d[4] 但[i]不属产生式的文法符号,对输入串abbcde进行推导时把 序号也带入,则最右推导过程为:
aAcBe[1] aAcd[4]e[1] aAb[3]cd[4]e[1] ab[2]b[3]cd[4]e[1] 所以输入串abbcde为该文法的句子。 它的逆过程,即最左归约(规范归约)则为: ab[2]b[3]cd[4]e[1] 用产生式(2)归约 aAb[3]cd[4]e[1] 用产生式(3)归约 aAcd[4]e[1] 用产生式(4)归约 aAcBe[1] 用产生式(1)归约 S 其中“ ”表示归约,从这里可以看到每次归约时,归约前和归约后的 已归约部分和剩余部分合起来只是构成文法的规范句型,而用哪个产生式归约 仅取决于当前句型的前部分,例中每次归约前句型的前部分依次为: ab[2] aAb[3] aAcd[4] aAcBe[1] 这正是我们在表7.2的分析过程中每次采取归约动作前符号栈中的内容,即分 别对应步骤3、5、8、10时符号栈中的符号串,我们把规范句型的这种前部分 串称可归前缀。
LR分析法正是给出一种能根据当前分析栈中的符号串(通常以 状态表示)和向右顺序查看输入串的K个(K≥0)符号就可唯一地确 定分析器的动作是移进还是归约和用哪个产生式归约,因而也就 能唯一地确定句柄。LR分析法的归约过程是规范推导的逆过程, 所以LR分析过程是一种规范归约过程。 LR(K)分析方法是1965年Knuth提出的,括号中的K表示向右查 看输入串符号的个数。这种方法比起自顶向下的LL(K)分析方法和 算符优先分析方法对文法的限制要少得多,也就是说对于大多数 用无二义性上下文无关文法描述的语言都可以用相应的LR分析器 进行识别,而且这种方法还具有分析速度快,能准确、即时地指 出出错位置。它的主要缺点是对于一个实用语言文法的分析器的 构造工作量相当大,K愈大构造愈复杂,实现相当困难。目前对于 真正实用的编译程序,所采用的LR分析器都是借助于美国Bell实 验室1974年推出的“一个编译器的编译器-YACC”来实现的。它能 接受一个用BNF描述的满足LALR(1)的上下文无关文法并将自动构 造
7.2.3 活前缀及其可归约前缀的一计算方法
对一个任给的上下文无关文法需要有确定的办法来求出它的所有活前缀和可归前 缀才能构造其识别该文法活前缀的有限自动机。
定义 7.2 设G是一个上下无关文法,对A∈VN有: LC(A)={α|S’ αAω,α∈V*, ω∈VT*},其中S’是G的拓广文法G’
第7章 LR分析
【学习目标】
本章将介绍自底向上分析的另一种方法,即LR分析法。 ◇ 理解LR分析法的基本思想 ◇ 理解可归前缀和子前缀概念 ◇ 理解识别活前缀的有限自动机概念 ◇ 掌握LR分析器的构造思想和方法 ◇ 对给定的文法能构造LR(0)、SLR(1)、LALR(1)、LR(1)四 种分析器,并能判断所给文法是四种分析器的哪几类。 ◇ 对给定的输入符号串能用构造的分析器判断该输入串是否 是所给文法的句子 ◇ 了解某些二义性文法在LR分析中的应用。
7.2.4 LR(0)项目集规范族的构造
【本章难重点】
◇ 可归前缀和子前缀概念
◇ 识别活前缀的有限自动机概念 ◇ 对可归前缀为规范归约的句柄的理解 ◇ 构造LR(1)项目集族时搜索符的计算 ◇ LR分析器的关键部分是分析表的构造 ◇ 对给定的文法能构造LR(0)、SLR(1)、LALR(1)、LR(1)四种分析器 ◇ 当一个文法能构造出不含移进-归约或归约-归约冲突时的LR(0)/ SLR(1)/ LALR(1)/ LR(1)分析表时,称这个文法为LR(0) / SLR(1)/ LALR(1)/ LR(1)文 法。 ◇ 对给定的文法能判断是四种LR类文法的哪几类 ◇ 了解某些二义性文法在LR分析中的应用
① 移进: 把Sj=GOTO[Si,a]移入到状态栈,把a移入到文法符号栈。其中i,j表示状态 号。 ② 归约: 当在栈顶形成句柄为β时,则用β归约为相应的非终结符A,即文法中有A→β 的产生式,若β的长度为r(即|β|=r),则从状态栈和文法符号栈中自栈顶向下 去掉r个符号,即栈指针SP减去r。并把A移入文法符号栈内,Sj=GOTO[Si,A]移进 状态栈,其中Si为修改指针后的栈顶状态。 ③ 接受acc: 当归约到文法符号栈中只剩文法的开始符号S时,并且输入符号串已结束即 当前输入符是‘#’,则为分析成功。 ④ 报错: 当遇到状态栈顶为某一状态下出现不该遇到的文法符号时,则报错,说明输 入串不是该文法能接受的句子。 LR分析器的关键部分是分析表的构造,后边将针对每种不同的LR分析器详细 介绍其构造思想及方法。
7.1 LR 分析概述
一个LR分析器由3个部分组成: (1) 总控程序,也可以称为驱动程序。对所有的LR分析器 总控程序都是相同的。 (2) 分析表或分析函数,不同的文法分析表将不同,同一 个文法采用的LR分析器不同时,分析表将也不同,分析 表又可分为动作表(ACTION)和状态转换(GOTO)表两个部 分,它们都可用二维数组表示。 (3) 分析栈,包括文法符号栈和相应的状态栈,它们均是 先进后出栈。 分析器的动作就是由栈顶状态和当前输入符号所决定(LR(0) 分析器不需向前查看输入符号)。LR分析器工作过程示 意图如图7.1所示。
如果加一个开始状态X并用ε弧和每个识别可归前缀的有限自动机 连接,则可变为图7.3。
将图7.3确定化并重新编号后变为图7.4。
由例6.1文法对输入串abibcde#可以有如下推导: S′ S aAcBe aAcde aAbcde abibcde 其中i为任意正整数。 由此可见该文法所描述的语言可用正规式ab+cde表示。 用有限自动机识别时每当识别完句柄,则状态应退回到去掉句 柄所构成的串,例如在图7.4中若已识别到终态 ⑤ ,这时句柄已 形成,而且句柄是Ab,则应用A→Ab归约,状态应退回到②,又因 左部为A,所以,相当在状态②时又遇到A,这时应转向状态④。在 状态④再遇输入串的一个b,又转到终态 ⑤ ,重复上述过程。以 上我们仅由对某些句子规范推导的逆过程直观地看出它的活前缀和 可归前缀,然后构造其有限自动机。 为加深理解LR分析是用识别活前缀的有限自动机对输入串进行 分析,下面给出例中动态分析过程。
相关文档
最新文档