编译原理 第18讲(第八章)
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
8.3.4 布尔表达式的翻译
程序设计语言中的布尔表达式有两个 作用。一是计算逻辑值,更多的情况是二, 用做改变控制流语句中的条件表达式,如 在if-then,if-then-else,或是while-do 语句中那样。
属性nextstat: 属性nextstat:表示下一个四元式序号 nextstat
过程中的说明语句的属性文法
P→D D→…. {offset:=0}
D→real id{enter(id,real,offset); D.att:=real;
D.width:=8; offset:=offset+D.width} …
用全程变量offset表示变量在本过程的数据区的相对位置 增加的量为 表示变量在本过程的数据区的相对位置,增加的量为 用全程变量 表示变量在本过程的数据区的相对位置 数据对象的宽度,用属性 用属性width表示. 数据对象的宽度 用属性
最简单的说明句的语法: 最简单的说明句的语法: D→integer〈namelist〉|real〈namelist〉 〈namelist〉→〈namelist〉,id|id 用自下而上翻译,文法改写: D→D1,id |integer id |real id 主要语义动作是在符号表中登录名字及其性质。 主要语义动作是在符号表中登录名字及其性质。 函数enter(id,A)表示: 将id的属性 填入符号表 表示: 的属性A填入符号表 函数 表示 的属性
布尔表达式的翻译举例
例:a or b and not c 翻译成四元式序列 (1) t1:= not c (2) t2:= b and t1 (3) t3:= a or t2
例:a < b 翻译成四元式序列, 可看成等价的条件语句 if a < b then 1 else 0 (1) if a<b goto (4) (2) t:=0 (3) goto(5) (4) t:=1 (5) ……
简单说明语句的属性文法
(1)D→integer id{enter(id,int); D.att:=int} (2)D→real id {enter(id,real); D.att:=real} (3)D→D1, id {enter(id,D1.att) ; D.att:=D1.att}
注意:一般, 注意:一般,变量的说明语句并不生成相应的目 标代码(四元式) 标代码(四元式)
例:语句if a<b or c<d and e>f then S1 else S2 语句 < < >
我们把该表达式放在条件语句中考虑, 我们把该表达式放在条件语句中考虑,可翻译成如下的四元式序列 (1) if a<b goto (7) //(7)是整个布尔表达式的真出口 ) < ) ( ) (2) goto (3) ) ) (3) if c<d goto (5) ) < ) //(p+1)是整个布尔表达式的假出口 (4) goto (p+1) ) ( ) (5) if e>f goto (7) ) > ) (6) goto (p+1) ) ) 的四元式…) // (E.true ) 入口 (7) (关于 的四元式 ) ) 关于S1的四元式 (p) goto (q) ) ) )(关于 的四元式…) (p+1)(关于 的四元式 ) // (E.false)入口 )(关于S2的四元式 入口 (q) )
8.3.2 简单赋值语句的翻译(四元式) 简单赋值语句的翻译(四元式)
四元式形式: (op , arg1, arg2, result) 或 result := arg1 op arg2 语义属性: 语义属性: id.name, E.place //E内容所在的地址,指针 内容所在的地址, 内容所在的地址 函数: 函数: lookup(id.name) ;
简单赋值语句的翻译举例
例:x = y * z 翻译为四元式 (*, z, y, t1) (=, t1, _, x)
例:a=b*c+b*d 翻译为四元式 (*, b, c, t1) (*, b, d, t2) (+, t1, t2, t3) (+, t3, _, a)
8.3.3 简单说明语句的翻译
控制语句 S→ if E then S
E的代码
1
else S 2 E.true E.false
E.true:
S1的代码 goto S.next
E.false: S2的代码 S.next:
控制语句的结构(3) 控制语句的结构
→ while E do S 1 控制语句 S S.begin:
E的代码
E.true E.false
//创建一个新的临时变量,并返回该临时 创建一个新的临时变量, 创建一个新的临时变量 变量的地址
简单赋值语句的属性文法 产生式和语义描述: 产生式和语义描述:
(1) S→id:= E → { P:=lookup(id.name); if P ≠ nil then emit(P“:=” E.place) //引号中的部分按原样输出 引号中的部分按原样输出 else error } (2) E→E1+E2 → { E.place:= newtemp; emit(E.place“:=” E1.place“+”E2.place)} (3) E→ - E1 → { E.place:=newtemp; emit(E.place“:=”“uminus” E1.place)} (4) E→( E1) → { E.place:= E1.place} } //无须分配新空间,相当于改写指针,E.place看成一个指针 无须分配新空间, 无须分配新空间 相当于改写指针, 看成一个指针 (5) E→id → { E.place:=newtemp; P:=lookup(id.name); if P≠nil then E.place:=P ≠ else error}
8.3.5.1 控制语句的代码结构
注:此处的代码都是中间代码(比如四元式) 此处的代码都是中间代码(比如四元式)
控制语句的结构(1) 控制语句的结构
控制语句 S→ if E then S 1
E的代码
E.true wenku.baidu.com.false
E.true:
S1的代码
E.false:
控制语句的结构(2) 控制语句的结构
第八章 语义分析
8.1 语义处理概述 8.2 属性文法和语法制导翻译 8.3 中间代码的形式 8.4 中间代码的生成 典型语句的翻译 中间代码的生成(典型语句的翻译 典型语句的翻译) 8.5 符号表
8.3 中间代码生成
•简单赋值语句(四元式)的翻译 简单赋值语句(四元式) 简单赋值语句 •简单说明语句的翻译 简单说明语句的翻译 •布尔表达式的翻译 布尔表达式的翻译 •控制语句的翻译 控制语句的翻译 •过程调用的翻译(四元式产生) 过程调用的翻译(四元式产生) 过程调用的翻译 •数组的翻译 数组的翻译
E.true: S1的代码
goto S.begin
E.false:
…
8.3.5.2 控制语句结构的属性文法 控制语句结构的属性文法
S→if E then S1 → { E.true:=nemlable; E.false:=S.next; S1 .next:=S.next; S.code:=E.code || gen(E.true’:’) || S1.code } S→if E then S1 else S2 → { E.true:=nemlable; E.false:= nemlable; S1 .next:=S.next; S2 .next:=S.next S.code:=E.code || gen(E.true’:’) || S1.code || gen(‘goto’ S.next) || gen(E.false’:’) || S2.code } S→while E do S1 → { ….. }
例:布尔表达式 a<b or c<d and e>f
可翻译成如下四元式: 可翻译成如下四元式: (1) if a<b goto E.true ) (2) goto (3) ) ) (3) if c<d goto (5) ) ) (4) goto E.false ) (5) if e>f goto E.true ) (6) goto E.false ) (翻译不是最优,( )四元式不需要) 翻译不是最优,(2)四元式不需要) ,(
控制语句中布尔表达式的翻译
作为条件表达式的E 仅把E翻译成代码是一串条件 作为条件表达式的E,仅把E翻译成代码是一串条件 条件表达式的 (jrop,B,C,L)和无条件转(jump,_,_,L)四元式。 (jump,_,_,L)四元式 转(jrop,B,C,L)和无条件转(jump,_,_,L)四元式。 翻译的基本思路是: 翻译的基本思路是: 对于E b的形式生成代码为 的形式生成代码为: (1)对于E为a rop b的形式生成代码为:if a rop E.false。 b goto E.true 和goto E.false。 对于E E2的形式 的形式, E1是真 是真, (2)对于E为E1 or E2的形式,若E1是真,则可知 为真即E1的真出口和E的真出口一样。如果E1是假, E1的真出口和 E1是假 道E为真即E1的真出口和E的真出口一样。如果E1是假, 那么必须计算E2 E1的假出口就是E2代码 E2, 的假出口就是E2 那么必须计算E2,E1的假出口就是E2代码 的第一个四元 式标号, 这时E2的真出口和假出口分别与E E2的真出口和假出口分别与 式标号, 这时E2的真出口和假出口分别与E的真出口和 假出口一样。 假出口一样。 类似的考虑适于E E2等情形 等情形。 (3)类似的考虑适于E为E1 and E2等情形。
8.3.5 控制语句的翻译
现在讨论出现在if-then;if-then-else和while-do 现在讨论出现在if-then;if-then-else和whileif 等语句中的布尔表达式E的翻译。 等语句中的布尔表达式E的翻译。 这三种语句的语法为: 这三种语句的语法为: S→if E then S1 if E then S1 else S2 while E do S1 这些语句的代码结构示意图如下图所示,其中使用. 这些语句的代码结构示意图如下图所示,其中使用. 两个出口分别表示E为真和假时控制流向的转移。 和。两个出口分别表示E为真和假时控制流向的转移。分 别叫做真出口 假出口。 真出口和 别叫做真出口和假出口。
//在符号表中查找指定名字的标识符,如果存在则返 在符号表中查找指定名字的标识符, 在符号表中查找指定名字的标识符 回该项指针,否则返回nil 回该项指针,否则返回
过程: 过程: emit(t := arg1 op arg2);
//生成一个四元式(文本) 生成一个四元式(文本) 生成一个四元式
newtemp;
布尔表达式的属性文法
E→E1 or E2 {E.place∶=newtemp; . ∶ ; emit(E.place′∶=′E1.place ′or′E2.place)} ( . ∶ . . )} E→E1 and E2 {E.place∶ =newtemp; . ∶ ; emit(E.place′∶=′E1.place ′and′E2.place)} ( . ∶ . . )} E→not E1 {E.place∶ =newtemp:; . ∶ :; emit(E.place′∶=′not′E1.place)} ( . ∶ . )} E→(E1) ( ) {E.place∶=E1.place} . ∶ . } E→id1 relop id2 {E.place∶=newtemp; . ∶ ; emit(′if′ id1.place relop id2.place ′goto′nextstat+3); ( ); emit(E.place′∶=′′0′); ( . ∶ ); emit(′goto′nextstat+2); ( ); emit(E.place′∶=′′1′)} ( . ∶ )} E→true {E.place∶=newtemp; . ∶ ; emit(E.place′∶=′′1′)} ( . ∶ )} E→false {E.place∶=newtemp; . ∶ ; emit(E.place′∶=′′0′)} ( . ∶ )}