中间语言与语法制导翻译
编译原理课件05语法制导翻译技术和中间代码生成
5.4 中间代码
四元式的特点: 1. 四元式出现的顺序和语法成份的计值 顺序相一致. 2. 四元式之间的联系是通过临时变量实 现的,这样易于调整和变动四元式. 3. 便于优化处理.
5.4 中间代码
编译系统中,有时将四元式表示成另一 种更直观,更易理解的形式——三地址代 码或三地址语句. 三地址代码形式定义为: result := arg1 OP arg2 三地址语句:语句中是三个量的赋值语句, 三地址语句 每个量占一个地址.
5.5 自下而上的语法制导翻译
例3 简单算术表达式翻译到四元式的 语义描述 例如,设有简单算术表达式的文法: E→E+E | E*E | (E) | i
T R / S T
c S a c
c R S
输入是bR / bTc / bSc /ac 输出为: 1 4 5 314 24 31 给出相应语义动作(翻 译方案) S→bTc { print "1"} { print "2"} S→a R T→R { print "3"} R→R/S { print "4"} R→S { print "5"}
5.1 概述
例如: 表达式 A+B*C 对运算对象进行类型检查, 对变 量进行先定义后使用检查 执行真正的翻译 如果静态语义正确, 语义处理则要执 行真正的翻译, 即生成程序的某种中间 代码的形式或直接生成目标代码.
5.1 概述
目前多数编译程序进行语义分析的方 法是采用语法制导翻译法 .它不是一种 采用语法制导翻译法 形式系统, 但它比较接近形式化. 语法制导翻译法使用属性文法为工具 来描述程序设计语言的语义.
5.4 中间代码
第8章语法制导翻译与中间代码生成ppt课件
E.val=3 + E.val=1 n.lex=3 n.lex=1
例8.1 一个简单台式计算器的定义 综合属性val
产生 式
LE
E E1+T
ET T T1 * F TF
F (E) F digit
语 义 规 那么 Print(E.val)
r1 = [fp - 4] r2 = [r1 + 2] r3 = [fp - 8] r4 = r3 * 20 r5 = r4 + r2 r6 = 4 * r5 r7 = fp – 216 f1 = [r7 + r6]
8.3.1 逆波兰式
运算符跟在一切运算对象的后面的表 示法写出的式子称为后缀法或逆波兰 法。
#
.
a.
(b+c/d)#
* #
.
a.
b+c/d)#
( * #
.
ab.
+c/d)#
( * #
.
ab.
c/d)#
+ ( * #
.
abc.
/d)#
+ ( * #
.
abc.
d)#
/ + ( * / + ( * #
.
abcd/.
)#
+ ( * #
.
abcd/+.
)#
( * #
〔3〕一致性检查。在很多场所要求对象只能被 定义一次。例如Pascal言语规定同一标识符在一 个分程序中只能被阐明一次,同一case语句的标 号不能一样,枚举类型的元素不能反复出现等等。
〔4〕上下文相关性检查。比如,变量名字必 需先声明后援用;
语法制导翻译和中间代码生成
产生式
语义子程序
(1)A i=E
{GEN(=, E•PLACE ,_,ENTRY(i)}
(2)E -E (1)
{T=NEWTEMP;
GEN(@, E(1)•PLACE ,_,T);
E•PLACE =T }
(3)E E (1)*E(2) {T=NEWTEMP;
GEN(*, E(1)•PLACE , E(2)•PLACE ,T);
予不同的语义值:类型、地址、代码值等。
2021/4/9
9
4、语义栈 各个符号的语义值放在语义栈中 当产生式进行归约时,需对产生式右部符号 的语义值进行综合,其结果作为左部符号的语义 值保存到语义栈中。
下推栈包含3部分: 状态栈、符号栈和语义栈
注:语义栈与状态栈和符号栈是同步变化的。
2021/4/9
10
注:
1)若把语义子程序改成产生某种中间代码的动 作,就能在语法分析制导下,随着分析的进展逐 步生成中间代码。
2)若把语义子程序改成产生某种机器的汇编语 言指令,就能随着分析的进展逐步生成某机器的 汇编语言代码。
2021/4/9
11
例如:
产生式
语义子程序
(0)S` E
{PRINT E•VAL}
注:这些翻译工作很大程度上决定了要产生什么形 式的中间代码。
2021/4/9
8
2、写法 语义子程序写在该产生式后面的花括号内。
Eg: X α {语义子程序1}
注:在一个产生式中同一个文法符号可能出现多次, 但他们代表的是不同的语义值,要区分可以加上 角标。如:E E(1)+E (2)
3、语义值 为了描述语义动作,需要为每个文法符号赋
E•PLACE =T }
第5章语法制导翻译技术和中间代码生成
编译原理
2024年8月7日
25
逆波兰表示法(后缀式)
特点:运算符直接写在其运算对象之后。 • 不再有括号 • 运算对象出现的次序未变 • 求值过程简单,宜于用栈实现
后缀式的计算 用一个栈实现。 一般的计算过程是:自左至右扫描后缀式,每碰 到运算量就把它推进栈。每碰到k目运算符就把 它作用于栈顶的k个项,并用运算结果代替这k 个项。
④相关名字检查。有的语言中有时规定,同一名字 必须出现两次或多次。例如,Ada语言中,循环或程 序块可以有一个名字,它出现在这些结构的开头和结 尾,如同语句括号一般,编译程序必须检查它们的配 对情况。
编译原理
2024年8月7日
6
5.2 属性文法
附加了一组语属义性信和息运算(语义)规则的文法
1. 属性的表示
3
语义分析的任务
根据语义规则对识别出的各种语法成分析其含义, 进行初步翻译,生成相应的中间代码或直接生成目 标代码。
第一,审查每个语法结构的静态语义,即检查语法结构合法 的程序是否真正有意义。也称静态语义检查。(类型检查、 控制流的检查、一致性检查、相关名字的检查) 第二,如果静态语义正确,语义处理则要执行真正的翻译, 要么生成中间代码,要么生成实际的目标代码。(说明性语 句:填符号表;可执行性语句:生成中间代码)
编译原理
2024年8月7日
12
翻译步骤
(1)分析输入符号串,建立分析语法树 (2)从分析树得到描述结点属性间依赖关系的依赖图,由 依赖图得到语义规则的计算次序 (3)进行语义规则的计算,得到翻译结果
输入符号串 分析树 执行语义规则
翻译结果
编译原理
2024年8月7日
13
语法制导定义
第08章语法制导翻译和中间代码生成
常用的中间语言
• 三地址代码(四元式) 三地址代码(四元式) • 语法结构树(三元式) 语法结构树(三元式) • 后缀式
特点
• 形式简单、语义明确、便于翻译 形式简单、语义明确、 • 独立于目标语言
29
三元式和树形表示
• 每个三元式由三个部分组成,分别是:算符op, 每个三元式由三个部分组成,分别是:算符op, op 第一运算对象ARG1和第二运算对象ARG2 ARG1和第二运算对象ARG2。 第一运算对象ARG1和第二运算对象ARG2。运算 对象可能是源程序中的变量, 对象可能是源程序中的变量,也可能是某个三 元式的结果,用三元式的编号表示。 元式的结果,用三元式的编号表示。 • 表达式的树形表示很容易实现:简单变量或常 表达式的树形表示很容易实现: 数的树就是该变量或常数自身,如果表达式e1 数的树就是该变量或常数自身,如果表达式e1 e2的树分别为T1和T2,那么e1+e2 e1*e2, 的树分别为T1 e1+e2, 和e2的树分别为T1和T2,那么e1+e2,e1*e2, e1的树分别为 的树分别为: -e1的树分别为:
9
–lexval 是单词 digit 的属性 lexval
例8-3 3*5+4 的
语法树与属性计算
L Print(19) E.val=19
E.val=15 T.val=15 T.val=3 F.val=3 digit.lexval=3 *
+
T.val=4 F.ቤተ መጻሕፍቲ ባይዱal=4
F.val=5 dgit.lexval=5
• 用中间语言过渡的好处: 用中间语言过渡的好处:
–便于编译系统的实现、移植、代码优化 便于编译系统的实现、移植、 便于编译系统的实现
语法制导翻译和中间代码生成
继承属性L.in
语 义 规 则
语句: real id1, id2, id3 的分析树,采用自上而下的分析方法
产 生 式
D TL
T int
T real
L L1,id
L id
L.in:=T.type
T.type=integer
F.val=3
F.val=5
digit.lexval=4
digit.lexval=5
digit.lexval=3
+
*
3*5+4的带注释的分析树
如果一个语法制导定义仅仅使用综合属性,则称这种语法制导定义为S属性定义。通常采用自底向上的方法对其分析树加注释,即从树叶到树根,按照语义规则计算每个节点的属性值。
表达式文法 E→T+T| T or T T → n | true | false
E → T1 + T2 { T1.type = int AND T2.type = T1. type E.type :=int } E → T1 or T2 { T1.type = bool AND T2.type= T1.type E.type :=bool } T → n { T.type := int } T → true { T.type := bool } T → false { T.type := bool }
T.type:=real
L1.in:=L.in
addtype(id.entry,L.in)
addtype(id.entry,L.in)
D
L.in= real
L.in= real
L.in= real
T.type=real
语法制导翻译和中间代码生成【共50张PPT】
例 完成类型检查的属性文法
1) E→T1+T2{T1.t=int AND T2.t=int}
2) E→T1 or T2 {T1.t=bool AND T2.t=bool}
3) T→num
{T.t :=int}
4) T→true {T.t :=bool}
5) T→false
{T.t :=bool}
6.1 属性文法(续)
四元式(续)
四元式的优点:
四元式比三元式更便于优化 优化要求改变运算顺序或删除某些运算,引起编号的变化。 三元式通过编号引用中间结果,编号的变化引起麻烦;四元 式通过临时变量引用中间结果,编号变化无影响。
四元式对生成目标代码有利
四元式表示很类似于三地址指令,很容易转换成机器代 码。
四元式(续)
3) E→T
{ E.val :=T.val }
4) T→T1*F { T.val :=T1.val * F.val }
5) T→F
{ T.val :=F.val }
6) F→(E) { F.val :=E.val }
7) F→digit { F.val :=digit.lexval }
E.val、T.val、F.val都是综合属性
每个使用性标识符是否都有声明? 运算符的分量类型是否相容? 赋值语句的左右部的类型是否相容?
➢ 赋值语句的翻译目标:
在赋值语句右部表达式产生的四元式序列后加一 条赋值四元式
简单赋值语句到四元式的翻译
考虑如下文法描述的简单赋值句的翻译: A→i:=E E→E+E|E*E|-E|(E)|i (6.1)
:=
a
+
叶子结点代表运算量, 非叶子结点代表运算符
语法制导翻译及中间代码生成.最全优质PPT
3.对一动作符号而言,其综合属性之值是以该动作符号的继承属性或产生式右部符号的任意属性为变元的函数。
根据DT(我T)所们构造可的关将系图这称为些依赖语关系义图(以或简“称为属依赖性图)”。 的形式附加到各个文法 符号上,再根据产生式所蕴含的语义,给出每个文法 符号的属性的求值规则,从而形成一种附带有语义属 性的前后文无关文法,即属性文法。
终结符至少有一种属性,即词文。当然,它还可能具 有其它属性,例如无符号数123,单词“123”就是它 的词文,而其数值以及它的类型(整型)是它的其它 两个属性。终结符的属性是其内在性质.
非终结符的属性是从其它符号的属性经计算而得的, 即由其它符号的属性定义的。
属性依赖关系
各个文法符号的属性之间,可能存在某种依赖关系,这 种依赖关系可用属性规则(语义规则)定义。
综合属性与继承属性
定义 5.3 对每个产生式p:X0→X1X2…Xn ,设属性 定义性出现的集合为
AF(p)={Xi.a|Xi.a=f(Xk1.ak1,…,Xkm.akm)∈ R(p),0≤kj≤n}
若Xi是产生式左部的非终结符(即i=0),则称属性 Xi.a是综合属性(Synthesized Attributes);若 Xi出现在产生式的右部(即1≤i≤n),则称Xi.a是 继承属性(Inherited Attributes)。
我们用形如X.ATTR的记号来表示文法符号X的相关 语义属性。
如果一个文法符号X在一产生式中多次出现,为了在 语义上能够对其进行区分,可添加不同的上标。
文法符号及其语义属性
例如,文法G[E]:
产生式
语义子程序
E→E(1)+T {E.Val=E(1).val+T.val;}
编译原理试题
中间语言与语法制导翻译重点与难点重点:语法制导翻译的基本思想,属性文法,翻译模式,说明语句的翻译方案。
三地址码,各种语句的目标代码结构、属性文法与翻译模式。
难点:属性的意义,对综合属性,继承属性,固有属性的理解,属性计算,怎么通过属性来表达翻译。
布尔表达式的翻译,对各种语句的目标代码结构、属性文法与翻译模式的理解。
基本要求掌握语法制导翻译的基本思想,属性文法,综合属性,继承属性,固有属性,属性计算,S_属性文法,L_属性文法,说明语句的翻译方案,翻译模式、属性文法的实现掌握中间语言与语义分析的基本概念;熟练掌握语法(结构)树、三地址代码、赋值与控制语句的翻译、说明语句的翻译;掌握组合数据说明的翻译、过程调用翻译。
例题解析例1 给定文法 E --> T { R.i := T.p }R { E.p := R.s }R --> addopT { R1.i := mknode( addop.val, R.i, T.p ) }R { R.s := R1.s }R --> { R.s := R1.s }T --> ( E ) { T.p := E.p }T --> id { T.p := mkleaf( id, id.entry ) }T --> num { T.p := mkleaf( num, num.val ) }(1) 指出文法中的各非终结符具有哪些综合属性和哪些继承属性⑵画出按本翻译模式处理表达式 a + 20 + ( b - 10 ) 时所生成的语法树【解】(1)E的综合属性 p,R的继承属性i,综合属性s;T的综合属性p(2) 处理表达式 a + 20 + ( b - 10 ) 时所生成的语法树如下+(ID, a) +(NUM, 20) -( ID, b) (NUM, 10)例2 定义一个计算器的属性文法,完成一个输入表达式值的计算和显示,【解】计算器的文法L → EE → E1 + T | TT → T1 * F | FF → ( E ) | digit引进属性val,计算器的属性文法:L → E print( E.val )(L的虚属性)E → E1 + T E.val := E1.val + T.valE → T E.val := T.valT → T1 * F T.val := T1.val * F.valT → F T.val := F.valF → ( E ) F.val := E.valF → digit F.val := digit.lexvallexval 是单词 digit 的属性例3给出对输入串6-3 3*5+4 的分析树与属性计算【解】3*5+4 的分析树与属性计算例4定义一个说明语句的属性文法【解】说明语句的文法D → T LT → intT → realL → L1,idL → id要解决的问题:记录标识符的类型和类型信息传递方法:引进属性type,和in,用T.type记录类型信息,并传给L.in, 说明语句的属性文法如下:D → T L L.in := T.typeT → int T.type := ‘integer’T → real T.type := ‘real’L → L1,id L1.in := L.inaddtype( id.entry, L.in ) L → id addtype( id.entry, L.in )entry 单词 id 的属性addtype 在符号表中为变量填加类型信息例5 给出输入串real id1,id2,id3 的分析树和属性计算例6 设下列文法生成变量的类型说明D → id LL → , id L | : TT → integer | real试构造一个翻译模式,把每个标识符的类型存入符号表。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
L → id addtype( id.entry, L.in )
entry 单词 id 的属性
addtype 在符号表中为变量填加类型信息
例5 给出输入串real id1,id2,id3 的分析树和属性计算
解答
为S、L引入属性h,代表配对括号个数。语法制导定义如下:
产生式 语义规则 S → (L) S.h:=L.h+1 S → a S.h:=0 L → L1 , S L.h:=L1.h+S.h L → S L.h:=S.h S'→S print(S.h) (2)为S、L引入d,代表a的嵌套深度。翻译方案如下:
翻译为三地址代码。
【解】解题思路
把表达式或赋值语句翻译为三地址代码是容易理解的,如x:=y*z+1翻译为:
T1:=y*z
T2:=T1+1
x:=T2
while语句和if语句的翻译涉及到布尔表达式,我们一并讨论。产生布尔表达式三地址代码的语义规则如表7.1所示。按表1的定义,每个形如A relop B的表达式(其中relop为任一关系运算符)将被翻译为如下形式的两条转移指令:
例题解析
例1 给定文法 E --> T { R.i := T.p }
R { E.p := R.s }
R --> addop
T { R1.i := mknode( addop.val, R.i, T.p ) }
R { R.s := R1.s }
产生式 语义规则 E→E1+T if E1.type=real and T.type=int then
begin
E.type:=real;
print(T.lexeme);
print('inttoreal');
end
else if E1.type=int and T.type=real then
begin
E.type:=real;
print('inttoreal');
print(T.lexeme);
end
else begin
E.type:=E1.type;
print(T.lexeme);
end
print('+'); E→T E.type:=T.type;print(T.lexeme); T→num.num T.type:=real;T.lexeme:=num1.lexeme||"."||num2.lexeme T→num T.type:=int;T.lexeme:=num.lexeme;
lexval 是单词 digit 的属性
例3给出对输入串6-3 3*5+4 的分析树与属性计算
【解】3*5+4 的分析树与属性计算
例4定义一个说明语句的属性文法
【解】说明语句的文法
D → T L
T → int
T → real
L → L1,id
L → id
要解决的问题:记录标识符的类型和类型信息传递
L → : T {L.type:=T.type}
T → integer {T.type:=interger}
T → real {T.type:=real}
例7文法G的产生式如下:
S → (L) | a
L → L , S | S
(1)试写出一个语法制导定义,它输出配对括号个数;
R --> ? { R.s := R1.s }
T --> ( E ) { T.p := E.p }
T --> id { T.p := mkleaf( id, id.entry ) }
T --> num { T.p := mkleaf( num, num.val ) }
【解】解题思路
确定每个子表达式结果类型的属性文法是比较容易定义的。关键是如何扩充此属性文法,使之把表达式翻译成后缀形式。我们将不在name或num.num向T归约的时候输出该运算对象,而是把运算对象的输出放在T或E+T向E归约的时候。这是因为考虑输出类型转换算符inttoreal的动作可能在E+T归约的时候进行,如果这时两个运算对象都在前面name或num.num向T归约的时候已输出,需要为第1个运算对象输出类型转换算符时就已经为时太晚。
(1) 指出文法中的各非终结符具有哪些综合属性和哪些继承属性
⑵ 画出按本翻译模式处理表达式 a + 20 + ( b - 10 ) 时所生成的语法树
【解】
(1)E的综合属性 p,R的继承属性i,综合属性s;T的综合属性p
(2) 处理表达式 a + 20 + ( b - 10 ) 时所生成的语法树如下
例6 设下列文法生成变量的类型说明
D → id L
L → , id L | : T
T → integer | real
试构造一个翻译模式,把每个标识符的类型存入符号表。
【解】解题思路
这是一个对说明语句进行语义分析的题目,不需要产生代码,但要求把每个标识符的类型填入符号表中。
解答
逆波兰表示为:bc+e*bc+f/+:=
三元式序列为:
(1)(+,b,c)
(2)(* ,(1) ,e)
(3)(+ ,b,c)
(4)(/ ,(3) ,f)
(5)(+ ,(2) ,(4))
(6)(:= ,a,(5))
四元式序列为:
(1)(+ ,b,c,T1)
还要注意的是,在E+T向E归约时,该加法运算的第1个运算对象已经输出。所以E→E+T的语义规则不需要有输出E运算对象的动作。
解答
(1)为文法符号E和T配以综合属性type,用来表示它们的类型。类型值分别用int和real来表示。确定每个子表达式结果类型的属性文法如下:
产生式 语义规则 E→E1+T {T.type:=if E1.type=int and T.type=int then int else real E→T {E.type:=T.type} T→num.num T.type:=real T→num T.type:=int (2)下面属性文法将表达式的后缀表示打印输出,其中lexeme属性表示单词的拼写。
S'→{S.d:=0;}S
S →'('{L.d:=S.d+1;}
L
')'
S →a{print(S.d);}
L → {L1.d:=L.d;}
L1
{S.d:=L.d;}
S
L → {S.d:=L.d}
S
解答
对D,L,T设置综合属性type。过程addtype(id,type)用来把标识符id及其类型type填入到符号表中。
翻译模式如下:
D → id L {addtype(id.entry,L.type)}
L → ,id L1 {addtype(iБайду номын сангаас.entry,L1.type);L.type:=L1.type;}
方法:引进属性type,和in,用T.type记录类型信息,并传给L.in,
说明语句的属性文法如下:
D → T L L.in := T.type
T → int T.type := 'integer'
T → real T.type := 'real'
L → L1,id L1.in := L.in
四元式由4个部分组成:算符op、第1和第2运算量arg1和arg2,以及运算结果result。运算量和运算结果有时指用户自定义的变量,有时指编译程序引进的临时变量。如果op是一个算术或逻辑算符,则result总是一个新引进的临时变量,用于存放运算结果。
三元式只需3个域:op、arg1和arg2。与四元式相比,三元式避免了临时变量的填入,而是通过计算这个临时变量的语句的位置来引用这个临时变量。我们很容易把一个算术表达式或一个赋值句表示为四元式序列或三元式序列。
+
(ID, a) +
(NUM, 20) -
( ID, b) (NUM, 10)
例2 定义一个计算器的属性文法,完成一个输入表达式值的计算和显示,
【解】计算器的文法
L → E
E → E1 + T | T
T → T1 * F | F
F → ( E ) | digit
引进属性val,计算器的属性文法:
L → E print( E.val )(L的虚属性)
E → E1 + T E.val := E1.val + T.val
基本要求
掌握语法制导翻译的基本思想,属性文法,综合属性,继承属性,固有属性,属性计算,S_属性文法,L_属性文法,说明语句的翻译方案,翻译模式、属性文法的实现
掌握中间语言与语义分析的基本概念;熟练掌握语法(结构)树、三地址代码、赋值与控制语句的翻译、说明语句的翻译;掌握组合数据说明的翻译、过程调用翻译。
中间语言与语法制导翻译
重点与难点
重点:语法制导翻译的基本思想,属性文法,翻译模式,说明语句的翻译方案。
三地址码,各种语句的目标代码结构、属性文法与翻译模式。
难点:属性的意义,对综合属性,继承属性,固有属性的理解,属性计算,怎么通过属性来表达翻译。布尔表达式的翻译,对各种语句的目标代码结构、属性文法与翻译模式的理解。