- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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 中间代码
例如 X= a*b+c/d 的 四元式序列: (1) ( *, a, b, T1 ) (2) ( /, c, d, T2 ) (3) ( +, T1, T2, T3 ) (4) ( =, T3, -, X ) 四元式的第四个分量result是编译程序 为存放中间运算结果而临时引进的变量, 常称为临时变量,如Ti,也可以是用户 自定义变量,如X.
5.4 中间代码
例如 X= a*b+c/d 的 四元式序列:
(1) (2) (3) (4) ( *, ( /, ( +, ( =, a, c, b, d, T1 ) T2 ) T3 ) X )
T1 , T2 , T3 , - ,
相应的三地址语句序列为: (1)T1=a*b (3)T3=T1+T2 (2)T2=c/d (4)X=T3
{7+8*5,3+8,6*5,…} 5.3 语法制导翻译概述
例如,设有简单算术表达式的文法: E→E+E | E*E | (E) | digit 为文法每一产生式设计相应的求值的语义 描述(语义动作): 1.E → E(1)+E(2) {E.val =E(1).val +E(2).val} 2.E → E(1)*E(2) {E.val =E(1).val*E(2).val} {E.val =E(1).val} 3.E → (E(1)) {E.val =Lex.digit} 4.E → digit
E E.val = 47 E E.val = 7 7 + E E.val = 40 * E E.val = 5 5
E E.val = 8 8
5.4 中间代码
3. 编译中常用的中间代码: 逆波兰式 三元式 四元式 树形表示
5.4 中间代码
逆波兰式 逆波兰式除去了原表达式中的括号, 并将运算对象写在前面,运算符写在后 面,因而又称为后缀式 后缀式. 后缀式 例如: 中缀表达式 a*b (a+b)*(c+d) 逆波兰式 ab* ab+cd+*
5.4 中间代码
例如 a+b*c 的 三元式序列: (1) ( * , b , c) (2) ( + , a , (1) ) 运算对象是指向符号表的某一项或指向 三元式表的某一项.
5.4 中间代码
三元式的特点: 1. 三元式出现的顺序和语法成份的 计值顺序相一致. 2. 三元式之间的联系是通过指示器 实现的.
5.2 属性文法
1. 属性文法 (1) 属性 对文法的每一个符号, 引进一些属 性, 这些属性代表与文法符号相关的信 息, 如类型,值,存储位置等.与属性 相关的信息, 即属性值,可以在语法分析 过程中计算和传递.
5.2 属性文法
属性加工的过程即是语义的处理过程. 属性加工的过程即是语义的处理过程. 属性分为两类: 综合属性和继承属性. 综合属性其计算规则按"自下而上"方 式进行, 即规则左部符号的某些属性根 据其右部符号的属性和(或)自己的其他 属性计算而得.
1.E → E(1)+E(2) 2.E → E(1)*E(2) 3.E → (E(1)) 4.E → digit
{E.val =E(1).val +E(2).val} {E.val =E(1).val*E(2).val} {E.val =E(1).val} {E.val =Lex.digit} 句子 7+8*5
5.4 中间代码
间接三元式 (1) 间接三元式表: 用来存放各三元式本身. (2) 间接码表: 按执行各三元式的顺序,依次 列出各三元式在三元式表中的位置. 注意 : 间接三元式表中不存放重复的 三元式. 三元式.
5.4 中间代码
例如 语句 X= (A+B)*C Y= D↑(A+B)
三元式序列 (1) ( + , A , B ) (2) ( * , (1) , C ) (3) ( = , X , (2) ) (4) ( + , A , B ) (5) (↑ , D , (4) ) (6) ( = , Y, (5) ) 间接三元式 间接码表 三元式表 (1) (1) ( + , A , B ) (2) (2) ( * , (1) , C ) (3) (3) ( = , X , (2) ) (1) (4) (↑ , D , (1) ) (4) (5) ( = , Y, (4) ) (5)
5.3 语法制导翻译概述
S→…… {… … } … …… A→xy {… … } …… … 语义处理的 加工动作 a1 a2 a3 …ai ai+1 …an
语法制导翻译法使用属性文法为工具 来说明程序设计语言的语义.
5.3 语法制导翻译概述
(2) 语法制导翻译法 在语法分析过程中,依随分析的过程, 根据每个产生式所对应的语义子程序(或 语义规则描述的语义处理的加工动作)进 行翻译的方法.
5.4 中间代码
逆波兰式表示法同中缀表示法相比其 优点是: 1. 不再有括号,且运算符出现的顺序体 现了中缀表达式 的运算顺序 2. 易于计算机处理
5.4 中间代码
一般表达式计值时,要处理两类符 号,一类是运算对象,另一类是运算符, 通常用两个工作栈分别处理.但处理用 逆波兰式表示的表达式却只用一个工作 栈.
c R S
5.5 自下而上的语法制导翻译
{ print "1"} { print "2"} { print "3"} { print "4"} { print "5"} R 翻译结果为: R / 1 4 5 314 24 31
b
S→bTc S→a T→R R→R/S R→S
S
b R / S T b
第5章
语法制导翻译技术和中间 代码生成
5.1 概述 5.2 属性文法 5.3 语法制导翻译概述 5.4 中间语言 5.5 自下而上语法制导翻译 5.6 递归下降语法制导的翻译 本章小结
5.1 概述
语义分析的任务: 静态语义审查 审查每个语法结构的静态语义, 审查每个语法结构的静态语义 即验证语法结构合法的程序,是否 即验证语法结构合法的程序 是否 真正有意义. 真正有意义
5.5 自下而上的语法制导翻译
S b R R / b / S T b T R / S T c S a c
c R S
5.5 自下而上的语法制导翻译
例2 简单算术表达式求值的语义描述 例如,设有简单算术表达式的文法: E→E+E | E*E | (E) | digit 1.E → E(1)+E(2) {E.val =E(1).val +E(2).val} 2.E → E(1)*E(2) {E.val =E(1).val*E(2).val} {E.val =E(1).val} 3.E → (E(1)) {E.val =Lex.digit} 4.E → digit
5.4 中间代码
例1. –a + b * ( –c + d )的逆波兰式 a@ bc @ d + * +
5.4 中间代码
–a + b * ( –c + d )的四元式表示 t1= @ a t2= @ c t3= t2 + d t4= b* t3 t5= t1+ t4
5.4 中间代码
例2. i↑( i /( i – i ) )的逆波兰式 i i i i – /↑ i↑( i /( i – i ) )的四元式 t1= i – i t2= i / t1 t3= i ↑ t2
c
T1
T1
T2
5.4 中间代码
逆波兰形式可以推广到其他语法结构: 赋值语句 V=E 条件语句 if E S1 ; else S2 逆波兰式 VE= 逆波兰式 ES1S2¥
第5章 语法制导翻译技术和中间代 码生成
三元式和树形表示
三元式主要由三部分组成: 三元式 (OP,arg1, arg2) 其中OP是运算符, arg1,arg2分别是第一和第二两个运算对象. 当OP是一目运算时,常常将运算对象定 义为arg1.