编译原理-第七章解析资料
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
c
0 id b 1 id c 2 unimus 1 3 * 0 4 id b 5 id c 6 unimus 5 7 * 4 8 + 3 9 id a 10 assign 9 11 ...
2
6 7 8
15
TJNU-COCIE-WJW
三、三地址代码
1.一般形式 包含三个地址:两个操作数,一个结果 x := y op z 一系列的上述形式 x, y, z是名字、常数和编译器产生的临时变量 op是算符,定点、浮点、逻辑,只能有一个
8
1.表达式E的后缀表示递归定义 如果E是变量和常数,则E的后缀表示是E本身 如果E是形如E1 op E2的表达式,其中op是任 意的二元算符,则E的后缀表示是E1’ E2’ op, 其中E1’和E2’分别是E1和E2的后缀表示 如果E是形如op E1的表达式,其中op是一元 算符,则E的后缀表示是E1’ op,其中E1’ 是E1 的后缀表示 如果E是形如(E1)的表达式,则E1的后缀表示 也是E的后缀表示
TJNU-COCIE-WJW 23
其中: (1)E.place表示存放E值的名字。 (2)E.code表示对E求值的三地址语句序列。 (3)newtemp是个函数,对它的调用将产生一个新的 临时变量 注意: ◆ 三地址语句序列是语法树的线性表示,用临时变 量代替语法树中的结点 ◆实际实现中,三地址语句序列往往是被存放到一 个输出文件中,而不是将三地址语句序列置入code属 性之中
注意:后缀式不需要括号
2018/10/26 TJNU-COCIE-WJW 9
例:赋值语句 a := b *(- c)+ b *( - 34) 的后缀式: a b c- * b 34- * + :=
2018/10/26
TJNU-COCIE-WJW
10
二、图表示法
1.特点和形式 描述了源程序的自然层次结构
2018/10/26
TJNU-COCIE-WJW
27
(2)三元式
op, arg1, arg2
避免四元式引入临时变量,可以用三地址语句的
序号表示临时变量 有3个域的记录结构 op:算符的内部编码 arg1和arg2分别表示操作数 语句的结果通过语句的序号引用 arg1、arg2的内容通常是符号表条目指针或 三地址语句的序号(对于临时变量)
2018/10/26
TJNU-COCIE-WJW
3
静态语义检查 一致性检查:很多场合要求对象只能被定义一次 例如,Pascal语言规定同一标识符在一个分程序 中只能被说明一次,同一case语句的标号不能相 同,枚举类型的元素不能重复出现等等。 相关名字检查:有时,同一名字必须出现两次或 多次。 例如,Ada语言程序中,循环或程序块可以有一 个名字,它出现在这些结构的开头和结尾,编译 程序必须检查这两个地方用的名字是相同的。 其他:如名字的作用域分析等。
2018/10/26
TJNU-COCIE-WJW
14
例:赋值语句:a:=b*-c+b*-c 抽象语法树的表示方法
后缀式:a b c uminus * b c uminus * + assign
assign
id a * id b uminus
+
* id b uminus
id
2018/10/26
c
id
语法树(抽象语法树) 有向无环图(DAG)
2018/10/26
TJNU-COCIE-WJW
11
例:a := b * - c + b * - c 后缀式是抽象语法树的线性表示 assign 后根序遍历 a b c uminus * b c uminus * + :=
a +
*
b
*
uminus c
中间代码 中间 中间代码 生成器 代码 优化器
静态语义检查和中间代码生成器的位置
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
b
uminus
c
(a)抽象语法树
2018/10/26 TJNU-COCIE-WJW 12
例:a:=b * - c+b * -c
assign a
其中,b*-c是公共子表达式
+
*
b
uminus
c (b) DAG
2018/10/26 TJNU-COCIE-WJW 13
2.产生赋值语句抽象语法树的属性文法
TJNU-COCIE-WJW
17
例子:
相应于a:=b * - c+b * -c的AST和DAG的三地址代码 t1 := -c t2 := b* t1 t3 := -c t4 := b* t3 t5 := t2+t4 a := t5 (a)对于AST的代码 t1:=-c t2:=b*t1 t5:=t2+t2 a:= t5
2018/10/26
TJNU-COCIE-WJW
4
翻译(产生中间代码) 采用独立于机器的中间代码的好处:
便于进行与机器无关的代码优化工作 使编译程序改变目标机更容易 使编译程序的结构在逻辑上更为简单明确。以中间语 言为界面,编译前端和后端的接口更清晰
符号流
语法 分析器
静 态 检查器
TJNU-COCIE-WJW
2
静态语义检查 类型检查:如果操作符作用于不相容的操作数, 编译程序必须报告出错信息。 例如,在C语言中”.”因该作用与结构体变量, 若作用于指针变量应用“->” 控制流检查:控制流语句必须使控制转移到合 法的地方。 例如,在C语言中break语句使控制跳离包括语 句的最小while、for或switch语句。如果不存 在包括它的这样的语句应该报错。
2018/10/26 TJNU-COCIE-WJW 24
4. 三地址代码的具体实现
三地址代码是一种抽象形式,其具体实现可用结构 体来表示,有以下几种表示方法:
四元式 :op, arg1, arg2, result
三元式 :op, arg1, arg2 间接三元式:间接码表+三元式表
2018/10/26
TJNU-COCIE-WJW
25
(1)四元式 op, arg1, arg2, result op:算符的内部编码 arg1和arg2分别表示两个操作数 result表示计算结果 arg1、arg2和result的内容通常是符号表条目指针 注意: 一元运算不需要使用arg2的域 param不使用arg2和result域 条件和无条件转移把目标语句的标号放在result中
26
2018/10/26
TJNU-COCIE-WJW
例子:语句a:=b*-c+b*-c 的四元式表示
op arg1 arg2 result
(0) (1) (2) (3) (4) (5)
uminus * uminus * + Assign
c b c b t2 t5
t1
t3 t4
t1 t2 t3 t4 t5 a
(b)对于DAG的代码
18
2018/10/26
TJNU-COCIE-WJW
2.三地址代码的种类 (1)赋值语句: x := y op z,op是二元算术算符或逻辑算符 (2)赋值语句: x := op z,op是一元算符,如:负号,逻辑非 not等
(3)复写语句: x := y
2018/10/26
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
E→E1*E2
E→-E1
E→(E1) E→id
2018/10/26
E.place:=newtemp; E.code:=E1.code‖gen(E.place´:=´´uminus´E1.place)
E.place:=E1.place; E.code:=E1.code E.place:=id.place; E.code:=‘’
Baidu Nhomakorabea
TJNU-COCIE-WJW
19
2.三地址代码的种类(续1) (4)无条件转移: goto L,L是下一步要执行的三地址语句的标号
(5)条件转移语句: if x relop y goto L 根据逻辑运算的结果决定是否执行转移 if a goto L a为真跳到L执行,否则执行if后边的语句
2018/10/26
产生式 语义规则 S→ id := E S.nptr := mknode(‘:=’, mkleaf(id, id.place), E.nptr ) E→ E1 + E2 E.nptr := mknode(‘+’, E1.nptr, E2.nptr ) E→ E1 * E2 E.nptr := mknode(‘*’, E1.nptr, E2.nptr ) E→ -E1 E.nptr := mknode(‘uminus’, E1.nptr ) E→ ( E1 ) E.nptr := E1.nptr E→ id E.nptr := mkleaf(id , id.place )
TJNU-COCIE-WJW
20
2.三地址代码的种类(续2) (6)过程调用语句: param x和call p, n n表示实参个数 例如:call p(x1 , x2 , … , xn ),表示成三地址语句: param x1 param x2 …… param xn call p , n
过程返回:return y y表示返回值
编译原理
——第七章
语义分析和中间代码产生
王金伟 计算机与信息工程学院 天津师范大学
第七章 语义分析和中间代码产生
在词法分析和语法分析之后的阶段就是语义分析 和中间代码生成 本章把第六章介绍的有关语法制导翻译的相关方 法和技术用在中间代码生成和语义分析上 主要工作 静态语义检查 翻译
2018/10/26
7.1中间语言
中间语言 源程序的中间表示方法 中间语言的形式 后缀式 图表示法 三地址代码
2018/10/26
TJNU-COCIE-WJW
7
一、后缀式
把运算量(操作数)写在前面,把算符写在后面。
例如:
原式 a+b, a*b,
后缀式 ab+ ab*
2018/10/26
TJNU-COCIE-WJW
产生式
S→id:=E
E→E1+E2
语义规则
S.code:=E.code║gen(id.place':='E.place)
E.place:=newtemp; E.code:=E1.code║E2.code║ gen(E.place':='E1.place '+'E2.place) E.place:=newtemp; E.code:=E1.code║E2.code║ gen(E.place':='E1.place'*'E2.place)
2018/10/26 TJNU-COCIE-WJW 21
2.三地址代码的种类(续3) (7)数组引用赋值 x := y[ i ] x[ i ] := y (8)地址和指针的使用 x := &y x := *y *x := y
2018/10/26
TJNU-COCIE-WJW
22
3.对赋值语句产生三地址代码的属性文法
2018/10/26
TJNU-COCIE-WJW
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
30
(3)间接三元式 在三元式基础上,增加一个间接码表. 该表按运算的先后顺序列出有关三元式在三元表 中的位置。
例:x
+ y * z翻译成 t1 := y * z t2 := x + t1
TJNU-COCIE-WJW 16
2018/10/26
1.一般形式(续)
三地址代码是AST或DAG的线性化表示
DAG图对应的三地址代码可能比相应的AST
对应的三地址代码要优化,因为可以复用中 间结果
2018/10/26