第7章+语法制导翻译和中间代码生成
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
25
间接三元式的优点
1. 间接码表是一张指示器表,它将按运算 的先后顺序列出有关三元式在三元式表 中的位置。所以,当有相同三元式出现 时,无需反复填进三元式表中。 2. 当调整运算顺序时,只需重新安排间接 码表即可。无需改动三元式表。 如 Y:=D↑(A+B) X:=(A+B)*C 间接码表:(1)(4)(5)(1)(2)(3)
第7章
语法制导翻译 和中间代码 生成
❤❤
1
经过词法分析、语法分析后,源程序 在静态结构上的正确性得到了保证,编译 程序接着要对源程序进行静态语义检查和 翻译。 语义检查:类型检查、控制流检查、 一致性检查等。 翻译:源程序→中间代码
2
本章主要内容
1. 属性文法 2. 语法制导翻译概念 3. 中间代码的几种形式 4. 几个语句的翻译:如赋值语句、条件语句等。
9
Hale Waihona Puke Baidu
如何实现这种翻译
至此不难明白,语法制导翻译的关键 是为每个产生式写相应的语义子程序。 例子中的print产生式序号这种语义子 程序是为了输出数字串而写的语义子程序。 所以一个语义子程序描述了一个产生式对 应的翻译工作。 这些工作有:改变编译程序某些变量 的值、查填各种符号表、发现并报告源程 序错误、产生中间代码。 10
21
上述三种方法的比较
三种方法的共同点:
1. 运算量个数不变,顺序也不变。 2. 运算符个数不变。
逆波兰式的优点:
1. 是一个无括号表达式。 2. 逆波兰式的运算符出现的顺序就是原表达 式的运算顺序,因而计算方便。
22
举例
1. (a+b)*(c+d) ab+cd+* 2. 赋值语句的后缀式 A:=B+C ABC+:=
44
if a<b or c<d and e>f then S1 else S2
(1) if a<b goto (7) 转移至E.true,即S1的四元式 (2) goto (3) (3) if c<d goto (5) (4) goto (p+1) 转移至E.false,即S2的四元式 (5) if e>f goto (7) 转移至E.true (6) goto (p+1) 转移至E.false (7) (关于S1的四元式) E.true ………… (p) goto (q) (p+1) (关于S2的四元式) E.false ………… (q)
13
属性文法
属性文法是一个三元组:A=(G,V,F),其中 G:是一个上下文无关文法。 V:属性的有穷集,每个属性与文法的一个终 结符或非终结符相连,这些属性代表与文 法符号相关信息,如它的类型、值、代码 序列、符号表内容等等 .属性与变量一样, 可以进行计算和传递。
14
F:关于属性的属性断言或一组属性的计 算规则(称为语义规则) 。 断言或语义 规则与一个产生式相联,只引用该产生 式左端或右端的终结符或非终结符相 联的属性。
3
语法制导翻译的引例
E→E+T E→T T→T*F T→F F→(E) F→i {print ”1”} {print ”2”} {print ”3”} {print ”4”} {print ”5”} {print ”6”}
在文法的每个 产生式后配了 一个有{ }括起 来的语义子程 序。
4
对(i+i)*i的翻译
16
§ 7.2
自底向上语 法制导翻译 概述
17
表达式为3*5+4,则语义动作打印数值19
L
E.val=19
E.val=15 + T.val=15 F.val=4 F.val=5 * digit.lexval=5 digit.lexval=4 T.val=4
T.val=3
F.val=3
digit.lexval=3
28
四元式
1. 四元式对中间结果的引用必须通过 给定的名字,而三元式是通过产生中间结 果的三元式编号。四元式之间的联系是通 过临时变量实现的。 2. 四元式出现顺序与原表达式计算顺 序一致。(同三元式)
29
§ 7.6
简单赋值 语句的翻译
30
文法:S→i:=E
E→E+E|E*E|-E|(E)|id
33
§ 7.6
布尔表达式 的翻译
34
布尔表达式在程序语言中有两个基本 作用。 1. 逻辑运算,计算逻辑值。 2. 控制语句(如if-then或while-do语句)的 条件式。
35
布尔表达式
布尔表达式是由布尔算符(and,or,not)施于布 尔变量或关系表达式而成。其中关系表达式的形 式为E1 rop E2,E1和E2都是算术表达式,rop是 关系符,如≤、<、=、≥、>、≠等。 布尔表达式的运算顺序:算术运算→关系运 算→布尔运算(┐、∧、∨; ∧、∨服从左结合)
15
属性文法的例子
简单算术表达式求值的语义描述
产生式 L E E T T F F E E1+T T T1 * F F (E) digit 语 义 规 则
Print(E.val) E.val:=E1.val+T.val
E.val:=T.val T.val:=T1.val F.val T.val:=F.val F.val:=E.val F.val:=digit.lexval
8
什么时候实现这种变换(翻译)
直观来说,就是为每个产生式配上一个翻 译子程序(语义子程序),并且在语法分析的 同时执行这些子程序。 具体来说,就是一边分析,一边翻译,语 法分析完成,翻译也就完成了。 语法制导翻译法对自上而下分析或自下而 上分析都适用。 语法制导翻译方法是比较接近于形式化的 翻译方法。
(op ,arg1,arg2,result) 或 result:= arg1 op arg2
四元式形式:
31
翻译 a:= -b+c*d
t1:=uminus b
S a := E
t2:=c*d t3:=t1+t2 a:=t3
E1 - E 11
b
+ E 21
c
E2 * E 22
d
32
类型转换
如:X := Y + I * J,X,Y为实型,I,J为整型, 则相应的四元式序列应为: (*i , I , J , T1 ) ( itr , T1 , _ , T2 ) ( +r , Y , T2 , T3 ) ( := , T3 , _ , X )
语义子程序的一般形式
语义子程序写在该产生式后面的花括号内: (1) X… { 语义子程序1 } (2) Y… { 语义子程序2 } (3) AXY { 语义子程序3 }
11
§ 7.1 属性文法
12
属性文法与语法制导翻译的关系
对于某个压缩了的文法,当把每个文法符 号和一组属性相关联,并把产生式附加以 语义规则的时候,就得到属性文法。 语法制导的翻译过程:由于属性文法的规 则和产生式是一一对应的关系。所以,由 属性文法确定的语义分析可以在语法分析 的过程中进行。这个过程成为语法制导的 翻译。
不难证明该符号串是文法的合法句子。 按照这个句子向文法开始符号E的归约次 序,且每当归约时调用该句柄的产生式所 对应的语义子程序,便可得到相应的数字 串:64264154632。
5
这个例子表明: (i+i)*i
64264154632
这是一种变换,而变换的规则是每当 归约时调用相应的语义子程序。无疑这个 例子是翻译的一个十分简单的模型。
A ∨ B→if A then true else B A ∧B→if A then B else false ┐ A →if A then false else true
这种翻译法涉及到如何翻译if-then-else 的问题,将在下面具体讨论。
39
作为条件转移的E的翻译
仅把E翻译成仅含条件真转和无条件转的 四元式。 (jnz , A , _ , p): 若A为真,转向第p个四元式 (jθ,A ,B , p): 若AθB为真,转向第p个四元式 (j , _ , _ , p): 无条件转向第p个四元式 40
37
例子
1. a or b and not c (1) t1:=not c (2) t2:=b and t1 (3) t3:=a or t2 2. A∨B∧C=D (=, C, D, T1) (∧, B, T1, T2) (∨, A, T2, T3)
38
2. 采取优化措施,只计算部分表达式。 如A or B,如果A为1,B就无需计算; 如A and B,如果A为0,则B就无需计算。
间接三元式
用一张间接码表辅以三元式表的办法 来表示中间代码。 例:X:=(A+B)*C Y:=D↑(A+B) 三元式表 间接码表 (1) ( + , A , B ) (1) (2) ( * , (1) , C ) (2) (3) (:= , X , (2) ) (3) (4) ( ↑ , D , (1) ) (1) (5) (:= , Y , (4) ) (4) (5)
23
三元式
组成: 算符OP,第一运算量ARG1,第二运算量ARG2 如:a:=b*c+b*d的三元式为: (1) ( * , b , c ) (2) ( * , b , d ) (3) ( + , (1) , (2) ) (4) ( := , a , (3) ) 注意:三元式出现的顺序与原表达式计算顺 序一致。 24
45
控制语句中的回填技术
上例中的一些转移地址并不能不产生 这些四元式的同时得知。 也就是说,一个布尔式的真假出口往 往不能在产生四元式的同时就确定。 因此,要回填这些地址。
3*5+4的带注释的分析树
18
§ 7.3
中间代码 的形式
19
中间代码的形式
1. 逆波兰式 2. 三元式、间接三元式和树形表示 3. 四元式
20
表达式的表示方法
1. 中缀表达式(一般表达式):运算符放在运 算量之间。A+B A*B 2. 前缀表达式(波兰表达式):运算符放在运 算量前面。+AB *AB 3. 后缀表达式(逆波兰表达式):运算符放在 运算量后面。AB+ AB*
26
树形表示
表达式的树形表示: 1. 简单变量或常数的树就是该变量或常数自身。 2. 如果表达式e1和e2的树分别为T1和T2,那 么e1+e2,e1*e2,-e1的树分别为: + * T1 T2 T1 T2 T1 树形表示是三元式的翻版。
27
四元式
组成: OP ,ARG1 ,ARG2 ,RESULT 如:a:=b*c+b*d的四元式为: (1) ( * , b , c , t1 ) (2) ( * , b , d , t2 ) (3) ( + , t1 , t2 , t3 ) (4) ( := , t3 , _ , a ) 更易理解的形式 t1 := b * c t2 := b * d t3 := t1 + t2 a : = t3
布尔表达式文法: E→E∧E | E∨E | ┒E | (E) | id rop id |id
36
布尔表达式的逻辑计算
1. 按布尔式的运算顺序(用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
§ 7.7
控制流语句 的翻译
41
if语句的翻译
if E then S1 else S2,其中E为布尔式
E的代码序列
真出口 假出口
S1的代码序列
S2的代码序列
42
E 的代码
E.true: E.false: S1的代码
E.true E.false
goto out
S2的代码 out:
43
例子
if A∨ B < D then S1 else S2 (1) ( jnz , A , _ , 5 ) 真出口 (2) ( j , _ , _ , 3 ) 不是最优翻译 (3) ( j< , B , D , 5 ) (4) ( j , _ , _ , p+1 ) 假出口 (5) ( 关于S1的四元式序列 ) ………… (p) ( j , _ , _ , q ) (p+1) ( 关于S2的四元式序列 ) ………… (q)
6
翻译要解决的问题
1. 翻译成什么样的代码? 2. 什么时候实现这种变换(翻译)? 3. 如何实现这种翻译?
7
翻译成什么样的代码
按照相应语义规则产生一种介于源语 言与目标代码之间的一种代码(中间代码), 它不依赖于机器但又便于产生依赖于机器 的目标代码。 中间代码可用多种方式表示,常见的 有:逆波兰表示法、树形表示法、三元式、 四元式等。