编译原理作业集-第七章
编译原理 第7章习题解答
![编译原理 第7章习题解答](https://img.taocdn.com/s3/m/e81bf18d6529647d27285212.png)
第七章习题解答7.1 给定文法:S→(A)A→ABBA→BB→bB→c①构造它的基本LR(0)项目集;②构造它的LR(0)项目集规范族;③构造识别该文法活前缀的DFA;④该文法是SLR文法吗?若是,构造它的SLR分析表。
7.2 给定文法:E→EE+E→EE*E→a①构造它的LR(0)项目集规范族;②它是SLR(1)文法吗?若是,构造它的SLR(1)分析表;③它是LR(1)文法吗?若是,构造它的LR(1)分析表;④它是LALR(1)文法吗?若是,构造它的LALR分析表。
7.3 给出一个非LR(0)文法。
7.4 给出一个SLR(1)文法,但它不是LR(0)文法,构造它的SLR分析表。
7.5 给出一个LR(1)文法,但它不是LALR(1)文法,构造它的规范LR(1)分析表。
7.6 给定二义性文法:① E→E+E② E→E*E③ E→(E)④ E→id用所述的无二义性规则和(或)另加一些无二义性规则,例如,给算符*、+施加某种结合规则。
①构造它的LR(0)项目集规范族及识别活前缀的DFA;②构造它的LR分析表。
习题参考答案7.1 解:文法的基本LR(0)项目集为S→.(A) S→(.A) S→(A.) S→(A).A→.ABB A→A.BB A→AB.B A→ABB.A→.B A→B. B→.b B→b.B→.c B→c.构造该文法的识别活前缀的DFSA如下图所示:I文法的识别活前缀的DFSA该文法的LR(0)项目集规范族={I0,I1,I2,I3,I4,I5,I6,I7,I8}因为在构造出来的识别活前缀的DFA中,每一个状态对应的项目集都不含有移进-归约、归约-归约冲突,所以该文法是LR(0)文法,当然也是SLR文法。
因为 FOLLOW(S)={#}FOLLOW(A)=FIRST{)}∪FIRST(BB)={),b,c}FOLLOW(B)=FIRST(B)∪FOLLOW(A)={b,c,)}其对应的SLR(1)分析表如下表所示。
编译原理chapter7
![编译原理chapter7](https://img.taocdn.com/s3/m/090e28d376eeaeaad1f330f1.png)
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)恢复及其状 返回代码序列 恢复及其状 是调用者继续运行。 态,是调用者继续运行。 调用代码序列会分割到调用者和被调用者 中。
编译原理第七章
![编译原理第七章](https://img.taocdn.com/s3/m/5d9345e2aeaad1f346933f49.png)
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分析表来表示不同状态下对于各输入符号应采取的动 作
编译原理 - 陈火旺版 - 第七章
![编译原理 - 陈火旺版 - 第七章](https://img.taocdn.com/s3/m/920a9adead51f01dc281f171.png)
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
语义分析概述
编译原理Chapter 7
![编译原理Chapter 7](https://img.taocdn.com/s3/m/47cb493beefdc8d376ee32f9.png)
prev
next 40
LR(0)分析表的构造※
dir
LR(0)分析表相当于识别活前缀的有限自动
机DAF的状态转换矩阵
prev
next 41
LR(0)分析表的构造算法
dir
令包含S’→•S 的项目集Ik的下标k为分析器的初态
LR(0)分析表的ACTION和GOTO表的构造步骤如下:
若项目 A→•a 属于Ik,且转换函数GO(Ik,a)= Ij ,当a为终结符时,则置ACTION[k,a]为Sj 若项目 A→• 属于Ik ,则对a为任何终结符或‘#’, 置ACTION[k,a] = rj ,j为产生式在文法G’中的编 号 若项目 X→•A 属于Ik ,且GO(Ik,A)= Ij ,则置 GOTO[k,A]=j,其中A为非终结符,j为某一状态号 若项目 S’→S• 属于Ik ,则置ACTION[k,#] = acc 其它填上“报错标志”,可用空白表示
Step2 对初态集或其它所构造的项目集应用转
换函数 GO(I,X)= CLOSURE(J)求出新状态 J的项目集
Step3 重复Step2直到不出现新的项目集为止
prev next 36
dir
S’ E A B
E aA | bB cA | d cB | d
c
c a
I4:Ac•A A•cA A•d I2:Ea•A A•cA A•d
prev
next 46
S’E[0] EaA[1]|bB[2] AcA[3]|d[4] BcB[5]|d[6]
dir
对输入串bccd#的分析
符号栈 输入串 bccd# ACTION S3
up
步骤 状态栈 0 1 03 2 035 3 0355 4 5 6 7
编译原理 第七章习题-推荐下载
![编译原理 第七章习题-推荐下载](https://img.taocdn.com/s3/m/0f4e5d5e7e21af45b307a845.png)
E:=A+D
G:=A
H:=G*G
F:=H*G
L:=F
M:=L
n6
1
n2/
1
C
n4
41+
n7
1
*
n5
1
D
G
E
(1) G:=B*C H:=G*G L:=G*H M:=L
n1
B
对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术通关,1系电过,力管根保线据护敷生高设产中技工资术艺料0不高试仅中卷可资配以料置解试技决卷术吊要是顶求指层,机配对组置电在不气进规设行范备继高进电中行保资空护料载高试与中卷带资问负料题荷试2下卷2,高总而中体且资配可料置保试时障卷,各调需类控要管试在路验最习;大题对限到设度位备内。进来在行确管调保路整机敷使组设其高过在中程正资1常料中工试,况卷要下安加与全强过,看度并22工且22作尽22下可22都能22可地护以缩1关正小于常故管工障路作高高;中中对资资于料料继试试电卷卷保破连护坏接进范管行围口整,处核或理对者高定对中值某资,些料审异试核常卷与高弯校中扁对资度图料固纸试定,卷盒编工位写况置复进.杂行保设自护备动层与处防装理腐置,跨高尤接中其地资要线料避弯试免曲卷错半调误径试高标方中高案资等,料,编试要5写、卷求重电保技要气护术设设装交备备置底4高调、动。中试电作管资高气,线料中课并敷3试资件且、设卷料中拒管技试试调绝路术验卷试动敷中方技作设包案术,技含以来术线及避槽系免、统不管启必架动要等方高多案中项;资方对料式整试,套卷为启突解动然决过停高程机中中。语高因文中此电资,气料电课试力件卷高中电中管气资壁设料薄备试、进卷接行保口调护不试装严工置等作调问并试题且技,进术合行,理过要利关求用运电管行力线高保敷中护设资装技料置术试做。卷到线技准缆术确敷指灵设导活原。。则对对:于于在调差分试动线过保盒程护处中装,高置当中高不资中同料资电试料压卷试回技卷路术调交问试叉题技时,术,作是应为指采调发用试电金人机属员一隔,变板需压进要器行在组隔事在开前发处掌生理握内;图部同纸故一资障线料时槽、,内设需,备要强制进电造行回厂外路家部须出电同具源时高高切中中断资资习料料题试试电卷卷源试切,验除线报从缆告而敷与采设相用完关高毕技中,术资要资料进料试行,卷检并主查且要和了保检解护测现装处场置理设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。
编译原理第7章答案
![编译原理第7章答案](https://img.taocdn.com/s3/m/2a9e5b345727a5e9856a61d8.png)
第七章LR分析法1.已知文法A→aAd|aAb|ε判断该文法是否是SLR(1)文法,若是构造相应分析表,并对输入串ab#给出分析过程。
解:增加一个非终结符S/后,产生原文法的增广文法有:S/→AA→aAd|aAb|ε下面构造它的LR(0)项目集规范族为:02对于I0来说有FOLLOW(A)∩{a}={b,d,#}∩{a}=Φ所以在I0状态下面临输入符号为a时移进,为b,d,#时归约,为其他时报错。
对于I2来说有也有与I0完全相同的结论。
这就是说,以上的移进-归约冲突是可以解决的,因此该文法是SLR(1)文法。
其他SLR(1)分析表为:下面构造它的SLR(1)项目集规范族为:15S→a|^|(T)T→T,S|S(1)构造它的LR(0),LALR(1),LR(1)分析表。
(2)给出对输入符号串(a#和(a,a#的分析过程。
(3)说明(1)中三种分析表发现错误的时刻和输入串的出错位置有何区别。
解:(1)加入非终结符S/,方法的增广文法为:S/→SS→aS→^S→(T)T→T,ST→S下面构造它的LR(0)项目集规范族为:表7.15.1 文法的LR(0)分析表17.若包含条件语句的语句文法可缩写为:S→iSeS|iS|S;S|a其中:i代表if,e代表else,a代表某一语句。
若规定:(1)else与其左边最近的if结合(2);服从左结合试给出文法中i,e,; 的优先关系,然后构造出无二义性的LR分析表,并对输入串iiaea#给出分析过程。
解:加入S/→S产生式构造出增广文法如下:[0] S/→S[1] S→iSeS[2] S→iS[3] S→S;S[4] S→a由习惯可知,定义文法中i,e,;,a4个算符的优先关系为:a>e>i>;。
并且i与;的结合方向均为自左至右。
由上述状态项目集可见:a.状态I1存在移进-归约冲突,由于FOLLOW(S/)∩{;}={#}∩{;}=Φ,所以面临#号时应acc,面临;号时应移进。
编译原理作业集-第七章(精选.)
![编译原理作业集-第七章(精选.)](https://img.taocdn.com/s3/m/0bb4724d814d2b160b4e767f5acfa1c7aa0082fe.png)
编译原理作业集-第七章(精选.)第七章语义分析和中间代码产⽣本章要点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. 在⼀棵语法树中结点的继承属性和综合属性之间的相互依赖关系可以由________来描述。
编译原理第7章
![编译原理第7章](https://img.taocdn.com/s3/m/a894ff1fad02de80d5d84028.png)
b.若NODE(B)和NODE(C)都是以常数叶结点,则转步骤②d,否则转步 骤③b。
c.执行OP B(即合并已知量),令得到的新常数为P。若NODE(B)是处理当 前四元式时新建立的结点,则应予以删除;若NODE(P)=null,则建立以常 数P为标记的结点n,置 NODE(P)=n,转步骤④。
(a)构造前
(1) (=, 3.14, _, T1) (2) (=, 6.28, _, T2) (3) (=, 6.28, _, T4) (4) (+, R, r, T3) (5) (=, T3, _, T5) (6) (*, 6.28, T3, A) (7) (=, A, _, T6) (8) (_, R, r, T7) (9) (=, T5, T7, B)
(1) (:=, 3.14, _, T1) (2) (*, 2, T1, T2) (3) (+, R, r, T3) (4) (*, T2, T3, A) (5) (:=, A, _, B) (6) (*, 2, T1, T4) (7) (+, R, r, T5) (8) (*, T4, T5, T6) (9) (-, R, r, T7) (10) (*, T5, T7, B)
k=1;
if(k<5)
(×)
s=s+k;
else s=s-k;
基本块的划分算法
①确定各基本块的入口,其原则是 a.程序的第一条语句。 b.控制语句所转向的语句。 c.紧跟在条件转移语句之后的语句。
②对每一个入口语句,确定其所属的基本块。它是由该入 口语句到下一个入口语句(不包括下一个入口语句),或到一个 转移语句(包括该转移语句),或到一个停语句(包括该停语句) 之间的语句序列组成的。
编译原理课后答案——第七章_目标代码生成
![编译原理课后答案——第七章_目标代码生成](https://img.taocdn.com/s3/m/8ff4f90a16fc700abb68fcd2.png)
第七章 目标代码生成
7.1 对下列四元式序列生成目标代码: T=A-B S=C+D
W=E-F
U=W/T V=U*S 其中,V是基本块出口的活跃变量,R0和R1是可用寄存 器。
第七章 目标代码生成 【解答】 简单代码生成算法依次对四元式进行翻译。
我们以四元式T=a+b为例来说明其翻译过程。 汇编语言的加法指令代码形式为 ADD R, X 其中,ADD为加法指令;R为第一操作数,第一操作数必 须为寄存器类型;X为第二操作数,它可以是寄存器类型,也 可以是内存型的变量。ADD R,X指令的含意是:将第一操作数 R与第二操作数相加后,再将累加结果存放到第一操作数所在 的寄存器中。要完整地翻译出四元式T=a+b,则可能需要下面 三条汇编指令:
第七章 目标代码生成 此外,如果必须使用第一条指令,即第一操作数 不在寄存器而是在内存中,且此时所有可用寄存器都 已分配完毕,这时就要根据寄存器中所有变量的待用 信息(也即引用点)来决定淘汰哪一个寄存器留给当前 的四元式使用。寄存器的淘汰策略如下: (1) 如果某寄存器中的变量已无后续引用点且该 变量是非活跃的,则可直接将该寄存器作为空闲寄存 器使用。 (2) 如果所有寄存器中的变量在基本块内仍有引 用点且都是活跃的,则将引用点最远的变量所占用寄 存器中的值存放到内存与该变量对应的单元中,然后 再将此寄存器分配给当前的指令使用。
第七章 目标代码生成 因此,本题所给四元式序列生成的目标代码如下: MOV R0, A SUB R0, C MOV R1, C ADD R1, D /*R1=S*/ /*R0=T*/
MOV S, R1 的值送内存单元S*/
MOV R1, E SUB R1, F SUB R1, R0 MUL R1, S
编译原理-第七章解析资料
![编译原理-第七章解析资料](https://img.taocdn.com/s3/m/0bc68f59168884868662d605.png)
中间代码 中间 中间代码 生成器 代码 优化器
静态语义检查和中间代码生成器的位置
2018/10/26
TJNU-COCIE-WJW
5
第七章 语义分析和中间代码产生
中间语言 7.2 说明语句 7.3 赋值语句的翻译 7.4 分情况语句 7.5 回填技术 7.6 类型检查
7.1
2018/10/26 TJNU-COCIE-WJW 6
TJNU-COCIE-WJW 28
2018/10/26
例子:语句a:=b*-c+b*-c 的三元式表示
op arg1 arg2
(0) (1) (2) (3) (4) (5)
uminus * uminus * + Assign
c b c b
(1)
(0) (2) (3) (4)
a
2018/10/26
TJNU-COCIE-WJW
例:x
+ y * z翻译成 t1 := y * z t2 := x + t1
TJNU-COCIE-WJW 16
2018/10/26
1.一般形式(续)
三地址代码是AST或DAG的线性化表示
DAG图对应的三地址代码可能比相应的AST
对应的三地址代码要优化,因为可以复用中 间结果
2018/10/26
29
注意: 有些三地址语句要多个三元式表示 例子: x[i] := y op arg1 arg2 (0) [ ]= x i (1) := (0) y
y := x[i] op arg1 (0) =[ ] x (1) := y arg2 i (0)
2018/10/26
TJNU-COCIE-WJW
编译原理_第7章(清华大学)
![编译原理_第7章(清华大学)](https://img.taocdn.com/s3/m/6931d4dcb14e852458fb57e9.png)
+ + > - > * > / > > ( < ) > i > # <
> > > > > < > > <
* < < > > > < > > <
/ < < > > > < > > <
< < < < < < > > <
( < < < < < <
) > > > > > = > >
<
i # < > < > < > < > < > < > > < =
规定 若 S a…或 S Ca… 则 # < a 若 S …a 或 S …aC 则 a > #
在 OG文法 G 中,若任意两个终结符间至多有 一种算符优先关系存在,则称G 为算符优先文 法(OPG)。 注意:允许b>c, c>b; 不允许 b>c, b<c, b=c中任两个 同时存在。 b=c 不一定 c = b。 例7.1中:“(” = “)”,“)”<>“(”。
最左素短语为:T*F
T
E + T
句型T+T+i的素短语为: i
句型T+T+F的素短语为:T+T
分析程序模型
输入串#
总控程序 # 算符优先关系表
编译原理王生原课后习题第七章
![编译原理王生原课后习题第七章](https://img.taocdn.com/s3/m/89bff54015791711cc7931b765ce050877327552.png)
编译原理模拟试卷一、选择题(每题1分,共5分)1.在编译过程中,词法分析的主要任务是什么?A.构建语法树B.将源程序分解为单词序列C.语义分析D.代码2.下列哪个不属于编译器的组成部分?A.词法分析器B.语法分析器C.代码器D.数据库管理系统3.在编译器中,中间代码的作用是什么?A.提高编译速度B.方便目标代码C.提高程序的可读性4.下列哪种语言通常被用作编译器的实现语言?A.PythonB.JavaC.C++5.在编译原理中,形式语言的主要作用是什么?A.描述程序设计语言的语法B.描述程序的语义C.描述程序的数据结构D.描述程序的算法二、判断题(每题1分,共5分)1.编译器的主要任务是将源程序转换为目标代码。
(正确/错误)2.语法分析器负责检查源程序中的语法错误。
(正确/错误)3.语义分析是在语法分析之后进行的。
(正确/错误)4.中间代码是一种与机器无关的代码。
(正确/错误)5.代码优化不会影响程序的正确性。
(正确/错误)三、填空题(每题1分,共5分)1.编译器包括____、____、____、____等组成部分。
2.在编译过程中,____负责将源程序分解为单词序列。
3.语法分析器的主要任务是构建____。
4.语义分析器负责检查____。
5.代码器负责____。
四、简答题(每题2分,共10分)1.简述编译器的工作流程。
2.解释什么是词法分析。
3.什么是语法分析?它的主要任务是什么?4.什么是语义分析?它的主要作用是什么?5.简述中间代码的作用。
五、应用题(每题2分,共10分)1.给出一个简单的C语言程序,请描述它通过编译器的过程。
2.什么是编译器的优化?请给出一个例子。
3.解释什么是编译器的错误处理。
4.什么是编译器的调试信息?它的作用是什么?5.请解释编译器的前端和后端。
六、分析题(每题5分,共10分)1.分析并解释编译器中的词法分析、语法分析和语义分析之间的关系。
2.分析并解释编译器中的中间代码和目标代码之间的关系。
编译原理第七章_自下而上的LR(K)分析方法
![编译原理第七章_自下而上的LR(K)分析方法](https://img.taocdn.com/s3/m/33874c6a8f9951e79b89680203d8ce2f01666541.png)
二、求出文法的所有项目,按一定规则构造识别 活前缀的NFA再确定化为DFA(了解)
三、使用闭包函数(CLOSURE)和转向函数 (GOTO(I,X))构造文法G’的LR(0)的项目集规范 族,再由转换函数建立状态之间的连接关系得 到识别活前缀的DFA(掌握)
编译原理 Compilers Principles 第7章9
移进-归约中的问题分析
3) #ab 4) #aA 5) #aAb 6) #aA
bcde# bcde# cde# cde#
归约(A→b) 移进
归约(A→Ab) 移进
分析:已分析过的部分在栈中的前缀不同,而且移 进和归约后栈中的状态会发生变化
S aA cBe
Ab d b
0 S 1*
1 * 句子识别态
2a 3b 4
i
5a 6 A 7 b 8
9 a 10 A 11 c 12 d 13
14 a 15 A 16 c 17 B 18 e 10
构造识别活前缀的有限自动机 例子
句柄识别态
X
0S 2a 5a 9a
14 a
*
1
3b 4 6 A7b 10 A 11 c 15 A 16 c
1) # 2) #a 3) #ab
abbcde# bbcde# bcde#
动作
移进 移进 归约(A→b)
状态栈
0 02 024
ACTION
S2 S4 r2
GOTO
3
对输入串abbcde#的LR分析过程
S
1*
b
4
0 a 2 A 3 b 6
编译原理第7章 语法制导翻译和中间代码生成
![编译原理第7章 语法制导翻译和中间代码生成](https://img.taocdn.com/s3/m/b8e32e1faeaad1f347933f24.png)
• 检查静态语义 • 生成中间代码/目标代码
语义处理
语义处理的环境:符号表 • 为语义分析提供类型、作用域等信息。 • 为代码生成提供类型、作用域、存储类别、
存储(相对)位置等信息。
语义处理
PL/0编译程序的语义处理(一)call语句的处理
if sym = callsym
then
源语言程序
词法分析
前
语法分析
端
处理Biblioteka 语义分析语 义 处 理
后 端
代码生成
处
理
汇编代码
语义处理
语义处理的任务: • 静态语义检查
• 静态语义:语法规则的良形式条件 • 静态语义检查:审查静态语义
• 动态语义处理
• 动态语义:程序单元执行的操作 • 动态语义处理:生成(中间/目标)代码
语义处理
语义处理的实现: • 属性文法:描述语义规则。 • 语法制导翻译:在语法分析的同时,执行
类型的基本概念
声明和定义,使用: • 声明:
• 程序通过声明语句把标识符的名称、类型和 作用域等信息传递给编译器。
• 声明语句本身传递名字和类型信息,声明语 句的位置传递作用域信息。
• 定义:
• 变量、类的声明就是定义。 • 函数可以先声明一个原型,在定义中再给出
实现的代码。
类型的基本概念
强类型语言和弱类型语言: • 强类型语言
第七章语法制导翻译和中间代码生成
7.1语义处理概述 7.2属性文法和语法制导翻译 7.3 中间代码生成(一些语句的翻译) 7.4符号表
7.1 语义处理(语义分析和中间代码生成)
在编译中的逻辑阶段
源语言程序
词法分析
编译原理第7章 习题与答案
![编译原理第7章 习题与答案](https://img.taocdn.com/s3/m/9dcae46d561252d380eb6e2f.png)
第7章习题7-1 设有如下的三地址码(四元式)序列:read NI:=NJ:=2L1 : if I≤J goto L3L2 : I:=I-Jif I>J goto L2if I=0 goto L4J:=J+1I:=Ngoto L1L3 : Print ′YES′haltL4 : Print ′NO′halt试将它划分为基本块,并作控制流程图。
7-2 考虑如下的基本块:D:=B*CE:=A+BB:= B*CA:=E+D(1) 构造相应的DAG;(2) 对于所得的DAG,重建基本块,以得到更有效的四元式序列。
7-3 对于如下的两个基本块:(1) A:=B*CD:=B/CE:=A+DF:=2*EG:=B*CH:=G*GF:=H*GL:=FM:=L(2) B:=3D:=A+CE:=A*CF:=E+DG:=B*FH:=A+CI:=A*CJ:=H+IK:=B*5L:=K+JM:=L分别构造相应的DAG,并根据所得的DAG,重建经优化后的四元式序列。
在进行优化时,须分别考虑如下两种情况:(ⅰ)变量G、L、M在基本块出口之后被引用;(ⅱ)仅变量L在基本块出口之后被引用。
7-4 对于题图7-4所示的控制流程图:(1) 分别求出它们各个结点的必经结点集;(2) 分别求出它们的各个回边;(3) 找出各流程图的全部循环。
7-5 对于如下的程序:I:=1read J,KL: A:=K*IB:=J*IC:=A*Bwrite CI:=I+1if A<100 goto Lhalt试对其中的循环进行可能的优化。
第8章习题答案7-1 解:划分情况及控制流程如答案图7-1所示:答案图7-1 将四元式序列划分为基本块7-2 解:(1) 相应的DAG如答案图7-2所示。
答案图7-2 DAG(2) 优化后的代码为:D:=B*CE:=A+BB:=DA:=E+D7-3 解:(1) 相应的DAG如答案图7-3-(1)所示。
若只有G、L、M在出口之后被引用,则优化后的代码为:G:=B*CH:=G*GL:=H*GM:=L若只有L在出口之后被引用,则代码为:G:=B*CH:=G*GL:=H*G(2) 相应的DAG如答案图7-3-(2)所示。
编译原理 第七章 习题解答
![编译原理 第七章 习题解答](https://img.taocdn.com/s3/m/0891f04ea8956bec0975e370.png)
第七章习题答案1.拓广该文法:(0) S→A (1)A→aAd (2)A→aAb (3)A→ε构造LR(0)项目集规范族如下:由图可知,在项目集I0、I2中存在移进-归约冲突,该文法不是LR(0)文法。
在I0中,移进符号为a,而归约符号为Follow(A)={b,d,#},交集为空,可以解决冲突;在I2中,移进符号为a,而归约符号为Follow(A)={b,d,#},交集为空,可以解决冲突。
因此,该文法是SLR(1)文法。
输入串ab#的分析过程7.拓广该文法:(0) S’→S (1) S→A (2)A→Ab (3)A→bBa(4)B→aAc (5)B→a (6)B→aAb构造LR(0)项目集规范族如下:由图可知,在项目集I2、I6中存在移进-归约冲突,该文法不是LR(0)文法。
Follow(S’)={#}Follow(S)=Follow(S’)={#}Follow(A)=Follow(S)∪{b,c}={b,c,#}Follow(B)={a}在I2中,移进符号为b,归约符号为Follow(S)={#},交集为空,可以解决冲突;在I6中,移进符号为b,归约符号为Follow(B)={a},交集为空,可以解决冲突。
因此,该文法为SLR(1)文法。
8.拓广该文法:(0) S’→S (1) S→A$ (2)A→BaBb(3)A→DbDa (4)B→ε(5)D→ε构造LR(0)项目集规范族如下:由图可知,在项目集I0中存在归约-归约冲突,该文法不是LR(0)文法。
Follow(S’)={#}Follow(S)=Follow(S’)={#}Follow(A)= {$}Follow(B)={a,b}Follow(D)={a,b}在I 0中,归约项目B→·的归约符号集为Follow(B)={a,b},归约项目D→·的归约符号集为{a,b},交集不为空,因此,该文法不是SLR(1)文法。
构造LR(1)项目集规范族如下:由图可知,不存在任何冲突,该文法是LR(1)文法。
编译原理第七章
![编译原理第七章](https://img.taocdn.com/s3/m/fa41e46b443610661ed9ad51f01dc281e53a56f8.png)
对例6.1的文法用拓广文法表示成: S′→S[0] S→aAcBe[1] A→b[2] A→Ab[3] B→d[4] 现对句子abbcde的可归前缀列出: S[0] ab[2] aAb[3] aAcd[4] aAcBe[1]
构造识别其活前缀及可归前缀的有限自动机如图7.2。 每一个终态都是句柄识别态,用双圈表示。带"*"号的状态既为句柄识
观察产生式右部的非终结符。 2、应用LR(0)CONTEXT(A→β)=LC(A).β求得包含句柄 的活前缀。 3、由此可构造以文法符号为字母表的识别(包括句柄) 活前缀的不确定有限自动机。 4、应用子集法对上述的不确定有限自动机进行确定化 得到识别可归前缀的确定有限自动机。
结论:对任何一个上下文无关文法只要能构造出识别 可归前缀的有限自动机,就可以构造其相应的分析表。
if ACTION[Si,a]=Sj then begin PUSH j,a (进栈)
ip 前进(指向下一输入符号)
end
else
if ACTION[Si,a]=rj(若第j条产生式 为A→β) then begin
pop |β| 项
对于上面的分析过程我们可以知道:
若当前栈顶状态为Sk push GOTO[Sk,A] 和A(进栈) end
在文法G中每个产生式的右部适当位置添加一个圆点构成项目。
例如,产生式S→aAcBe对应有6个项目:
[0] S→·aAcBe [2] S→aA·cBe [4] S→aAcB·e
7.2.1 可归前缀和子前缀
为了在以后的LR分析中不致引起混淆,现对原文法进行拓广。 若原文法G的开始符号为S,在G中加产生式S′→S后得新的文法G′, 则称G′为原文法G的拓广文法,而S′为拓广后文法G′的开始符号。 对文法进行拓广的目的是为了对某些右部含有开始符号的文法,在 归约过程中能分清是否已归约到文法的最初开始符,还是在文法右 部出现的开始符号,拓广文法的开始符号S′只在左部出现,这样 确保了不会混淆。
编译原理chapter7
![编译原理chapter7](https://img.taocdn.com/s3/m/f0d6b47bf01dc281e53af03f.png)
举例:Tiger表达式 a>b | c<d
可以将它转换为:
MEN
BINOP(PLUS, e1, e2) 简写为 +(e1, e2)
• 对于在当前过程中声明的存放在栈帧中的简单变量v,
MEN + TEMP fp CONST k
BINOP
PLUS TEMP fp CONST k
MEM (BINOP (PLUS, TEMP fp, CONST k))
Translation to Intermediate Code
计算机科学与技术学院 刘 慧
• Translate:转换为某人的母语或另一种语言。 • 编译器的语义分析阶段必须将抽象语法转换成抽象 机器代码(abstract machine code)。它可以在类 型检查之后或在类型检查的同时做这项工作。 • 直接将抽象语法转换成真实 的机器代码,尽管可以实现 但不利于可移植性和模块化
• MEM(e):开始于存储地址e的wordSize个字节的内容。
–当MEM作为MOVE操作的左子式时,它表示对存储地址e 的 “存储”; –在其他位置用:以参数表l 调用函数f ,子表达式f 的计算先于参数的计算,参数的计算则从左到右。 • ESEQ(s,e):先计算语句s 以形成其副作用,然后计算e 作为此表达式的结果。
typedef struct patchList_ *patchList; struct patchList_ {Temp_label *head; patchList tail;}; static patchList PatchList (Temp_label *head, patchList tail);
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第七章语义分析和中间代码产生本章要点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. 在一棵语法树中结点的继承属性和综合属性之间的相互依赖关系可以由________来描述。
a. 抽象语法树;b. 语法规则;c. 依赖图;d. 三地址代码;7. 按照教材中的约定,三地址语句if x relop y then L表示成四元式为。
a. (relop,x,y,L);b. (relop,L,x,y);c. (relop,x,L,y);d. (L,x,y,relop);8. 在编译程序中,不是常见的中间语言形式。
a.波兰式;b. 三元式;c. 四元式;d. 抽象语法树;9. 在编译程序中安排中间代码生成的目的是________。
a. 便于提高编译效率;b. 便于提高分析的正确性;c. 便于代码优化和目标程序的移植;d.便于提高编译速度;10. 按照教材中的约定,下面不是类型表达式:a. boolean;b. type-error;c. real;d. DAG;11. 一个Pascal函数function f ( a, b:char ) :↑integer;……其作用域类型是:a. char×integer;b. char×char;c. char×pointer(integer);d. integer×integer;12. 因为标识符可用于多种情况,比如常量标识符、变量标识符、过程标识符等等。
因此,在符号表中为了给出各个符号的标志,常给标识符引入一个属性kind,然后在相应产生式的语义动作中添加给kind属性赋值的语句。
比如,在在产生式D id:T的语义动作中添加赋值语句id.kind= 。
a. V AR;b. CONSTANT;c. PROC;d. FUNC;13. 下面情况下,编译器需要创建一张新的符号表。
a. 过程调用语句;b. 标号说明语句;c. 数组说明语句;d.记录说明语句;14. 函数function f(a,b:char):↑integer;…所以f函数的类型表达式为:a. char×char→pointer(integer);b. char×char→pointer;c. char×char→integer;d. char×char→integer (pointer)15. 如果一个语言的编译器能保证编译通过的程序,在运行时不会出现类型错误,则称该语言是。
a. 静态的;b. 强类型的;c. 动态的;d. 良类型的;一.答案:1. b;2. d;3. b;4. d;5. c;6. c.;7. a;8. a;9. c;10. d;11. b;12. a;13. d;14. a;15. b;二、填空题:1. 语法分析是依据语言的语法规则进行的,中间代码产生是依据语言的________规则进行的。
2. 多目运算x:=y[i]的三元式表示为两部分:________________和________________。
3.生成三地址代码时,临时变量的名字对应抽象语法树的____________。
4. 一个类型表达式或者是基本类型,或者由____________施加于其它类型表达式组成。
5. 在程序设计语言中,布尔表达式有两个基本的作用:一个是;另一个是。
6. 允许嵌套过程的语言,其过程说明语句的翻译用两个栈tblptr和offset分别保存尚未处理完的过程的和它们的offset,这两个栈顶的元素分别是正在处理的过程的的符号表指针和。
7. 在一些pascal的实现中,如果说明中出现了没有名字的类型表达式,编译器这样处理:建立一个来和每个声明的变量标识符相联系。
8. 赋值语句a:=b*-c+b*-c的后缀式为。
9. 多目运算X[i]:=y的三元式表示为两部分:________________和________________。
10. 编译器遇到常量说明时,要把常量值登录入并回送序号;在中为等号左边的标识符建立新条目,在该条目中填入常量标志、相应类型和常量表序号。
11. 典型的转移条件语句:if E then S1 else S2中,作为转移条件的布尔表达式E,赋予它两种“出口”:一是;二是。
12. 类型表达式或者是,或者是作用在其它类型表达式上得到的新的类型表达式。
13. pascal变量说明:var A:array[1..10] of integer与A相关的类型表达式为:。
14. 若T是类型表达式,则pointer(T)是类型表达式,它表示类型。
15. 通过一遍扫描来产生布尔表达式和控制流语句的代码存在一个问题,就是当生成某些转移语句时可能还不知道该语句将要转移到的语句的地址是什么。
采用的办法来解决这个问题。
二.1. 语义;2. (0): ( [ ]=, y, i ),(1): ( assign, x, (0) );3. 内部结点;4. 类型构造符;5. 计算逻辑值;作控制流语句中的条件表达式;6. 符号表指针,相对地址;7. 隐含的类型名;8. a b c uminus * b c uminus * + assign;9. (0):(=[ ],x,i);(1):(assign,(0),y);10. 常量表;符号表;11. “真”出口,转向S1;“假”出口,转向S2;12. 基本类型;类型构造符;13. array(1..10, integer) ;14. “指向T类型对象的指针”;15. “拉链-回填”三、判断题:1. 中间代码是独立于机器的,复杂性介于源语言和机器语言之间,便于进行与机器无关调换代码优化工作。
()2. 在程序设计语言中,一般来说,布尔表达式仅仅用于条件、循环等控制流语句中的条件表达式计算。
()3. “回填”技术用于对过程中的说明语句进行处理时把计算出的有关符号的属性填入符号表。
( )4. 如果E是一个常量或变量,则E的逆波兰式是E自身。
( )5. 对于任何一个编译程序来说,中间代码的产生是不一定必要的。
()6. 由于三元式中的三个域中,仅有两个域与地址有关,所以,三元式不是严格意义上的三地址代码。
()7. 两个类型表达式要么是同样的基本类型,要么是同样的类型构造符作用于结构等价的类型,我们就说,这两个类型系统等价。
()8. 对于Pascal这样允许嵌套过程的语言,每当遇到过程说明D→proc id ; D1; S时,便创建一张新的符号表,也就是说,让每个过程说明都有自己一张独立的符号表。
()9. 记录类型的各个域变量分配存储区域的地址的确定是相对于为记录类型变量所分配存储区域的首地址的,所以记录类型不应该建立自己的符号表。
()10. 类型表达式中不可出现类型变量,即类型变量值不是类型表达式。
()11. 所谓类型系统就是把类型表达式赋给语言各相关结构成分的规则的集合。
同一种语言(比如C++语言)的编译程序,在不同的实现系统里(比如微软的Visual C++和Linux下的开源编译器TCC),可能使用不同的类型系统。
12. 四元式表示的是四地址代码,三元式表示的是三地址代码。
()13. 生成三地址代码时,临时变量的名字对应抽象语法树的内部结点。
()14. 后缀式是抽象语法树的线性表示形式,后缀式是树结点的一个序列,其中每个结点都是在所有子结点之后立即出现的。
()15. 后缀表示形式只是用于表达式的,其他的语法结构比如条件语句、循环语句等不能使用后缀式。
()三.答案:1. √;2. ×;3. ×;4. √;5. √;6. ×;7. √;8. √;9. ×;10. ×;11. √;12. ×;13. √;14. √;15. ×;四、名词解释:1. 三地址代码;2. 回填;3. 类型表达式;4. 类型系统;5. 静态语义检查四.答案:1. 三地址代码是由下面一般形式的语句构成的序列:x:= y op z。
其中x、y、z为名字、常数或编译时产生的临时变量;op代表运算符号如定点运算符、浮点运算符、逻辑运算符等等,每个语句的右边只能有一个运算符。
2. 通过一遍扫描来产生布尔表达式和控制流语句的代码的主要问题在于,当生成某些转移语句时我们可能还不知道该语句将要转移到的标号是什么。
为了解决这个问题,可以在生成形成分支的跳转指令时,暂时不确定跳转目标,而建立一个链表,把转向这个目标的跳转指令的标号键入这个链表,一旦目标确定之后再把它填入有关的跳转指令中。
这种技术称为回填。
3. 一个类型表达式或者是基本类型,或者由类型构造符施于其他类型表达式组成。
基本类型和类型构造符都因具体语言的不同而不同。
Ⅰ. 一个基本类型是一个类型表达式。
Ⅱ. 类型名是一个类型表达式Ⅲ. 类型构造符作用于类型表达式,其结果仍然是类型表达式Ⅳ. 类型表达式中可出现类型变量,即变量值是类型表达式。