当前位置:
文档之家› 第六章 语义分析和语法制导翻译
第六章 语义分析和语法制导翻译
addtype( id.entry, L.in )
将语义动作中的计算向前移,使继承属性的计 算出现在其文法符号之前
翻译模式的设计
D → T { L.in := T.type } L T → int { T.type := integer } T → real { T.type := real } L → { L1.in := L.in } L1 , id { addtype(id.entry, L.in) } L → id { addtype(id.entry, L.in) }
/* newtemp => t3 => E2.place */
|| gen( „t1:=t2+t3‟ ) || gen( „a:=t1‟ ) => gen( „t2:= 0 - c‟ ) || gen( „t3:=b*34‟ ) /* „c‟ => E11.place */ /* „b‟ => E21.place */
指针运算
6.3 赋值语句的翻译
翻译的需求
充分了解各种语言现象的语义
包括:控制结构、数据结构、单词 充分了解它们的实现方法
目标语言的语义
了解中间代码的语义 了解运行环境
实现赋值语句的翻译
语义过程
产生一条中间代码 产生新的临时变量
gen(code) newtemp
属性设置
中间代码序列 存储位置
A→X1 X2 … Xn
属性计算仅使用A X1 X2 … Xi-1 的属性
如:说明语句的属性文法
翻译模式 (Translation Schemes)
特征
规定在语法分析中使用语义规则进行计算
的次序
保证当动作使用某属性时,该属性必须是
可用的
实现方法
将语义动作插入到产生式中的某个位置
addtype
id3
addtype
例6-4:real id1,id2,id3 的
分析树和属性计算
S-属性定义:
仅包括综合属性
对于所有A
→ X1 X2 …Xn, 的属性
A的属性计算仅用X1…Xn
如:算术表达式求值的属性文法
L-属性定义:
其属性可用深度优先的顺序从左
至右计算
对于所有 Xi
断言和谓词
例6-1: 计算器的算法设计
需求:算术表达式的求值 设计:
编制算术表达式的文法 引入属性表示语义信息
将值
val 作为表达式 E、项 T 和因子 F 的属性
用语义规则描述表达式的求值
属性文法(语法制导定义)
产生式
L → E E → E1 + T E → T
T → T1 * F T → F F → ( E ) F → digit
code
place
赋值语句的四元式翻译
S → id := E S.code := E.code || gen( id.place':='E.place ) E → E1 + E2 E.place := newtemp;
E.code := E1.code || E2.code ||
gen(E.place':='E1.place'+'E2.place)
例6-2:说明语句的类型信息统计
说明语句的作用
支持语义分析,提供语义检查的依据
设计
编写说明语句的文法
将类型信息作为类型描述
T 的属性 type
和变量表 L 的属性 in。
目的
分析说明语句
D,获取变量的类型信息
描述类型信息提取的属性文法
产生式 D → T L 语义规则 L.in := T.type
变量名、过程名
建立运行环境
6.1Βιβλιοθήκη 属性文法语义分析与语法制导翻译的描述方法
属性文法的定义:
G
A=(G,V,F)
是上下文无关文法
V
F
属性的有穷集
关于属性的断言和谓词
用法
针对语义,为文法符号设置属性
终结符使用单词的属性
为每个产生式设置语义规则
通过描述各属性的关系 将语义分析和翻译步骤定义为产生式的
E.val=15 T.val=15 T.val=3 F.val=3 digit.attr=3 *
+
T.val=4 F.val=4
F.val=5 digit.attr=5
digit.attr=4
D T.type=real real L.in=real id1
addtype
L.in=real L.in=real , , id2
1 2
5 6 7 8
三地址代码
一般形式
其中
x := y op z
x, y, z 为变量名、常数或编译 产生的临时变量
四元式(op,
x, y, z)
双目运算
种类:x := y op z
x := op y
x := y
单目运算
赋值
if x relop y goto l
条件转移
其他三地址代码
goto l param x call p, n (n是参数个数) return x x := y[i] x[i] := y x := &y x := *y *x = y 无条件转移 实在参数 过程调用 过程返回 数组运算
从其兄弟结点和父结点的属性值计算出来的 如:L.in
固有属性(单词属性)
属性的计算
构造语法分析树,填加响应的语义规则 综合属性
自底向上按照语义规则来计算各结点的综
合属性值
继承属性
需要探讨计算次序
例6-3:3*5+4 的
语法树与属性计算
L Print(19) E.val=19
6.2
中间语言
用于编译程序
源程序经过语义分析被译成中间代
码序列
(中间语言的语句)
用中间语言过渡的好处:
便于编译系统的实现、移植、代码
优化
常用的中间语言
三地址代码(四元式) 语法结构树(三元式)
后缀式
特点 形式简单、语义明确、便于翻译 独立于目标语言
语法制导编译
描述方法
T → int T → real
L → L1,id L → id
entry addtype
T.type := „integer‟ T.type := „real‟
L1.in := L.in
addtype( id.entry, L.in )
addtype( id.entry, L.in ) 单词 id 的属性(符号表入口) 在符号表中为变量填加类型信息
习题
1. 下列文法是一个二进制数的文法。试根据 该文法,编写一个语法制导定义,描述由 S 生成的二进制数的数值计算。 S -> L . L L -> L B | B B -> 0 | 1 2. 参照下列表达式文法编写语法制导定义, 描述表达式的类型计算。要求在不同精度的 数的计算中,结果取精度高的类型。 E -> E + T | T T -> n.n | n
S
id := E1 - E 11 E + E 21
例 6-7:
翻译 a:= -c+b*34
E2 * E 22
id
id
num
结果:开始符号的属性 S.code
1)
找出分析树中使用的产生式规则
2) 根据产生式的语义规则,代换公式中的 各属性 3) 反复使用 1) 和 2) 改写公式,最后得 到代码生成语句组成的公式
是语法结构树指针
id.entry
num.val
是名字的表项入口
是数值 建中间结点
树构造函数
mknode mkleaf
建叶结点
生成语法树的属性文法
产生式 S→id:=E 语义规则 S.p:= mknode(':=', mkleaf(id, id.entry), E.p)
E→E1+E2 E.p:= mknode('+', E1.p, E2.p) E→E1*E2 E.p:= mknode('*', E1.p, E2.p) E→ -E1 E→ (E1) E→ id E→ num E.p:= mknode('-', 0, E1.p) E.p:= E1.p E.p:= mkleaf(id, id.entry) E.p:=mkleaf(num,num.val)
/* „34‟ => E22.place */
|| gen( „t1:=t2+t3‟ ) || gen( „a:=t1‟ ) /* „ ‟ => E21.code => E22.code */
表达式翻译中的其他问题
运算类型检查
利用符号表保存的名字类型
类型自动转换
填加专用指令
临时变量空间的统计
例6-6:a := b * (- c) + b *
(- 34) 的语法结构树
root
:= id a +
* id b * id b
- 0 id c - 0 num 34
地址
0 1
算符
操作数
操作数
2
语法结构树的 三元式表示
3 4
5
6 7
8
9 10
id id * id num * + id :=
b c 0 0 b 34 0 4 3 a 9
attr print(
语义规则 print( E.val )