第八章 语法制导翻译和中间代码生成

合集下载

第8章 语法制导翻译和中间代码生成

第8章 语法制导翻译和中间代码生成

例8.2 描述说明语句中各种变量的类型信息的语义规则
产生式
DTL
语义规则
Lin:=T type
T int
T real
T type :=integer
T type :=real
L L1,id
L id
L1 in :=L in
addtype(id entry,L in) addtype(id entry,L in)
1) 2) 3) 4) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 15)
r6 r4 r2 r6 r4
r6 r3 r1 接受
016975 01697(10) 169 01
—2—3— — —2—3—5 —2—(15) -17
#E+T*5 #E+T*F #E+T #E
2+3*5# +3*5# +3*5# +3*5# +3*5# 3*5# *5# *5# *5# 5# # # # #
自下而上的。在用某一产生式进行归约的同时就
执行相应的语义动作,在分析出一个句子时,这
个句子的“值”也就同时产生了,例如输入串是 3*5+4。
L
E.val=19 E.val=15
+
T.val=4 F.val=4 F.val=5 digit.lexval=4 digit.lexval=5
T.val=15
8.3 中间代码形式
所谓“中间代码”是一种结构简单、含义明 确的记号系统,这种记号系统可以设计为多种多 样的形式,重要的设计原则为两点:一是容易生 成;二是容易将它翻译成目标代码。编译程序所 使用的中间代码有多种形式。 常见的有逆波兰记号、三元式、四元式和树 形表示。

第8章语法制导翻译与中间代码生成ppt课件

第8章语法制导翻译与中间代码生成ppt课件
E.val=2 + E.val=4 n.lex=2 ( E.val=4 )
E.val=3 + E.val=1 n.lex=3 n.lex=1
例8.1 一个简单台式计算器的定义 综合属性val
产生 式
LE
E E1+T
ET T T1 * F TF
F (E) F digit
语 义 规 那么 Print(E.val)
r1 = [fp - 4] r2 = [r1 + 2] r3 = [fp - 8] r4 = r3 * 20 r5 = r4 + r2 r6 = 4 * r5 r7 = fp – 216 f1 = [r7 + r6]
8.3.1 逆波兰式
运算符跟在一切运算对象的后面的表 示法写出的式子称为后缀法或逆波兰 法。
#
.
a.
(b+c/d)#
* #
.
a.
b+c/d)#
( * #
.
ab.
+c/d)#
( * #
.
ab.
c/d)#
+ ( * #
.
abc.
/d)#
+ ( * #
.
abc.
d)#
/ + ( * / + ( * #
.
abcd/.
)#
+ ( * #
.
abcd/+.
)#
( * #
〔3〕一致性检查。在很多场所要求对象只能被 定义一次。例如Pascal言语规定同一标识符在一 个分程序中只能被阐明一次,同一case语句的标 号不能一样,枚举类型的元素不能反复出现等等。
〔4〕上下文相关性检查。比如,变量名字必 需先声明后援用;

语法制导翻译和中间代码生成

语法制导翻译和中间代码生成

A ∨ B→if A then true else B A ∧B→if A then B else false ┐ A →if A then false else true
这种翻译法涉及到如何翻译if-thenelse的问题,将在下面具体讨论。
33
控制语ห้องสมุดไป่ตู้中布尔表达式的翻译
if E then S1 else S2,其中E为布尔式
第8章 语法制导翻译和中间代码生成
经过词法分析、语法分析后,源程序 在静态结构上的正确性得到了保证,编译 程序接着要对源程序进行静态语义检查和 翻译。 语义检查:类型检查、控制流检查、 一致性检查等。 翻译:源程序→中间代码
1
本章主要内容
1. 属性文法 2. 语法制导翻译概念 3. 中间代码的几种形式 4. 几个语句的翻译:如赋值语句、条件语 句等。
26
翻译 a:= -b+c*d

t1:=uminus b t2:=c*d t3:=t1+t2
a
:=
E1

+ E2 E 21 c *
a:=t3

E 11 b
E 22 d
27
类型转换
如:X := Y + I * J,X,Y为实型,I,J为整型, 则相应的四元式序列应为: – (*i , I , J , T1 ) – ( itr , T1 , _ , T2 ) – ( +r , Y , T2 , T3 ) – ( := , T3 , _ , X )
23
四元式
1. 四元式对中间结果的引用必须通过 给定的名字,而三元式是通过产生中间结 果的三元式编号。四元式之间的联系是通 过临时变量实现的。 2. 四元式出现顺序与原表达式计算顺 序一致。(同三元式)

6hh第8章 语法制导翻译和中间代码生成

6hh第8章 语法制导翻译和中间代码生成

例 简单算术表达式求值的语义描述: 产生式 语义规则 (0) S→E print (E.val) (1) E→E(1)+T E.val = E(1).val+T.val (2) E→T E.val = T.val (3) T→T(1)*F T.val = T(1).val*F.val (4) T→F(1) T.val = T(1).val (5) F→(E) F.val = E.val (6) F→i F.val = i.lexval
T有一个综合属性T.type, 值为int或float; L有一个继承属性L.in, 值由T.type决定; 属性L.in被确定后将随语法树的逐步生成 而传递到下边有关结点。 例如, 输入串int a, b的属性传递情况:
D
T
L
L(1) id1 , id2
int
8.2 中间代码的形式
8.2.1 抽象语法树
1. 表达式E的逆波兰表示 (1)若E是变量或常数, 则E的后缀表示为E; (2) 若 E 为 E1opE2, 则后缀表示为 E1E2op, 其中E1,E2分别为E1,E2的后缀表示。 若op为一元运算, 则视E1和E1为空。 (3)若E为(E1)形式, 则后缀表示即为E1, 其 中E1为E1的后缀表示。
上述普通语法树的结点为14个, 而抽象语 法树的结点为7个且每个内部结点最多只 有两个分支。 因此, 赋值语句或表达式可表示为一棵二 叉树。对于含多元运算的语法成分, 其抽 象语法树为一棵多叉树, 但可转为二叉树。
抽象语法树的优点: 结构紧凑、容易构造、结点数较少。
8.2.2 逆波兰表示法 逆波兰表示法是由波兰科学家提出的一 种表达式表示方法, 这种方法把运算量写 在前、把运算符写在后, 又称后缀表示法。

第八章 语法制导翻译和中间代码生成

第八章 语法制导翻译和中间代码生成

目标代码
5
语义分析
语义分析的任务:在词法分析和语法分析的基础上,
盛 威 网 : 专 业 的 计 算 机 学 习 网 站
分析所写源程序的含义,在理解含义的基础上为生成 相应的目标代码作好准备或直接生成目标代码。 1)静态语义检查 例:类型检查、运算、维数、越界 2)语义翻译(具体的动作) 例:语句的翻译(中间代码或目标代码生成)
16
简化定义
对每个产生式,设属性定义性出现的集合为
盛 威 网 : 专 业 的 计 算 机 学 习 网 站
若Xi是产生式左部非终结符(即i=0),则称属性 Xi.a是综合属性(Synthesized Attributes) 若Xi出现在产生式的右部(即i≠0 ),则称Xi.a是 继承属性(Inherited Attributes)
2
教学内容
第一节
盛 威 网 : 专 业 的 计 算 机 学 习 网 站
属性文法 语法制导翻译概论 中间代码的形式 简单赋值语句的翻译 布尔表达式的翻译 控制语句的翻译 说明语句的翻译 数组和结构的翻译
3
第二节 第三节 第四节 第五节 第六节 第七节 第八节
盛 威 网 : 专 业 的 计 算 机 学 习 网 站
2.组成
语法树上的每个节点的所有属性在依赖图上各有 一个节点,如果属性y依赖于属性x,那么从x的节点 到y的节点有一条有向边。 【注】如果语法树一节点的属性y依赖某个节点的属 性x,那么属性y的语义产生式的计算必须在属性x的 语义产生式的计算之后进行。 24
盛 威 网 : 专 业 的 计 算 机 学 习 网 站
13
盛 威 网 : 专 业 的 计 算 机 学 习 网 站
3、文法规则number→number digit ,表明文法的个 数不止一个。我们必须表示出这个文法规则左边符 号的值和右边符号的值之间的关系。通过使用下标 进行区分,将文法写成如下形式: number1→number2 digit

编译原理-语法制导翻译和中间代码生成

编译原理-语法制导翻译和中间代码生成

例:类型、运算、维数、越界
–语义处理:
执行真正的翻译,生成程序的中间代码目标代码。
–例:变量的存储分配
–例:表达式的求值
–例:语句的翻译(中间代码的生成)
3
8.1 属性文法
• 语义分析的描述 –描述语法规则的同时,编写相应的语义 动作和计算顺序
• 语义的形式化描述 –操作语义学、公理语义学、指称语义学
例8-3 3*5+4 的 语法树与属性计算
T.val=3 F.val=3 digit.lexval=3
E.val=15 T.val=15

L Print(19)
E.val=19 +
T.val=4
F.val=4
F.val=5
digit.lexval=4
dgit.lexval=5
19
T.type=real
• 继承属性 – 从其兄弟结点和父结点的属性值计算出来的 – 如:L.in
• 固有属性(单词属性)
17
属性的计算
• 语法制导翻译:作语法分析,构造语法树,然 后在树的每个结点上添加相应的语义规则
• 综合属性 – 自底向上按照语义规则来计算各结点的综合 属性值
• 继承属性 –需要探讨计算次序
18
文法
E→ -E1 E.p:= mknode('-', 0, E1.p)
E→ (E1) E.p:= E1.p E→ id E.p:= mkleaf(id, id.entry) E→ num E.p:=mkleaf(num,num.val)
37
生成后缀式的属性文法
产生式
语义规则
S→id:=E Print( || E.code || “:=”)

讲稿第8章 语法制导翻译和中间代码生成

讲稿第8章 语法制导翻译和中间代码生成

第8章语法制导翻译和中间代码生成(3学时,15分钟)编译程序的任务是把源程序翻译成目标程序,这个目标程序必须和源程序的语义等同,也就是说,它们的语法结构可以不同,但表达的结果应完全相同。

通常,在语法分析过程中,每当一个产生式获得匹配(自上而下分析)或用于归约(自下而上分析)时,就执行相应于该产生式的语义子程序进行语义处理,这个过程就是语法制导翻译。

编译中的语义处理是指两个功能:第一,审查每个语法结构的静态语义,即验证语法结构合法的程序是否真正有意义,也称为静态语义检查或静态审查。

动态语义检查需要生成相应的目标代码,在运行时进行。

静态语义检查主要涉及以下几个方面:(1)类型检查,如参与运算的操作数及类型应相容。

(2)控制流检查,用以保证控制语句有合法的转向点。

如C语言中不允许goto转入case语句流;break语句需要寻找包含它的最小switch、while或for语句方可找到转向点,否则出错。

(3)一致性检查,如在相同作用域中标识符只能说明一次、case 语句的标号不能相同等。

第二,如果静态语义正确,语义处理的工作是要执行真正的翻译,即生成程序的一种中间表示形式(中间代码),或者直接生成实际的目标代码。

虽然源程序可以直接翻译为目标语言代码,但是通常编译程序还是采用了独立于机器的、复杂性介于源语言与机器语言之间的中间语言。

这样做的好处是:(1)便于进行与机器无关的代码优化;(2)使编译程序改变目标机更容易;(3)使编译程序的结构在逻辑上更为简单明确,以中间语言为界面,编译前端和后端的接口更清晰。

静态语义检查和中间代码产生在编译程序中的位置如图所示:需要指出的是:从单词符号序列的源程序到某种形式的中间代码,不像词法分析和语法分析那样有一套形式化的理论和算法(如自动机等),尽管已经有了一些形式语义系统,但大都没有得到公认。

这就是说,语义的形式化描述要远比语法的形式化困难得多。

目前较为常见的是用属性文法作为描述程序语言语义的工具,并采用语法制导翻译的方法完成对语法成分的翻译工作。

第八章语法制导翻译和中间代码生成

第八章语法制导翻译和中间代码生成
但文法开始符号没有继承属性。 终结符只有综合属性。
继承的和综合的属性
属性文法中,对应每一个产生式 A 都有 一套与之相关联的语义规则,每条规则的形 式为:b:=f(c1,c2,……,ck) 其中:f是一个函数,b和c1,c2,……,ck是该 产生式文法符号的属性。
(1)如果b是A的一个属性, c1,c2,……,ck是产 生式右部文法符号的属性或A的其它属性, 则称b是A的综合属性。
To relate each applied occurrence of an identifier in the source program to the corresponding declaration.
语义学
语义形式化、语义建模 文法模型—属性文法 命令式或操作式模型—操作语义学 公理式模型—公理语义学 应用式模型—指称语义学 目前在实际应用中比较流行的语义描述和语
语义规则
D TL T int T real L L1,id
L.in:=T.type T.type=integer T.type:=real L1.in:=L.in addtype(id.entry,L.in)
L id
addtype(id.entry,L.in)
继承属性
一个结点的继承
Real id1,id2,id3
属性文法
使用 N.t 的形式表示与非终结符N相连的属 性t。
T.t的值为int或bool。 与非终结符E的产生式相连的断言表明:两
个T的属性必须相同。
继承的和综合的属性
属性通常分为两类:综合属性和继承属性 综合属性用于“自下而上”传递信息, 继承属性用于“自上而下”传递信息。 非终结符既可有综合属性也可有继承属性,
语义规则 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

ch8-语法制导翻译和中间代码生成(1)

ch8-语法制导翻译和中间代码生成(1)
常用属性文法描述程序语言语义;采用语法制导翻译方 法对语法成分进行翻译。 语法制导翻译法就是为每个产生式配上一个语义子程 序,在语法分析过程中,在选用某个产生式的同时,执行
该产生式所对应的语义子程序来进行翻译的一种办法。
6
8.1 属性文法
1、文法的属性
属性是常用于描述事物或人的特征、性质或品质等。 在上下文无关文法中,为每个文法符号(终结符或非终结符) 例如:物体可以用颜色属性描述。 引入若干“值”(称为属性)。属性代表与文法符号相关 的信息,属性可以是类型、值、代码序列、符号表内容 (入口)等。属性可计算或传递。属性的加工过程即是语 义处理的过程。 对于文法的每个产生式都加入了一组属性的计算规则-语 义规则。
25
依赖图举例
假设A.a=f(X.x,Y.y)是对应于产生式A->XY的一个语 义规则,它确定了依赖于属性X.x和Y.y的综合属性A.a。 若在语法树中应用这个产生式,则在依赖图中会有三个结 点A.a、 X.x和Y.y。由于A.a依赖于X.x,所以有一条有向 边从X.x连到A.a;由于A.a依赖于Y.y ,所以有一条有向 边从Y.y连到A.a。 若 与 产 生 式 A - >XY 对 应 的 语 义 规 则 还 有 X.i=g(A.a,Y.y),则图中还有两条有向边,一条从A.a连到 X.i,另一条从Y.y连到X.i。
2
静态语义分析包括的主要内容-2
3)一致性检查。在很多场合要求对象只能被定义一次。例 如 Pascal语言规定同一标识符在一个分程序中只能被说 明一次,同一case语句的标号不能相同,枚举类型的元素 不能重复出现等等。 4)相关名字检查。有时,同一名字必须出现两次或多次。 例如,在Ada 语言程序中,循环或程序块可以有一个名字 出现在这些结构的开头和结尾,编译程序必须检查这两个 位臵用的名字是否相同。 5)名字的作用域分析

第八章_3语法制导翻译和中间代码生成-中间代码生成

第八章_3语法制导翻译和中间代码生成-中间代码生成

8.5
控制语句中布尔表达式的翻译
1
控制语句 S→ if E then S E 的代码 E.true: S 1 的代码 goto out S 2 的代码 out:
else S 2 E.true E.false
E.false:
. 把条件转移的布尔表达式翻译成仅含 把条件转移的布尔表达式翻译成仅含 和无条件转 条件真转 (jrop,B,C,L) 和无条件 转 (jump,_,_,L)的四元式 E =a rop b ⇒ if a rop b goto E.true goto E.false 如 :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
• 高级:最接近高级语言,保留了大部分源语言 的结构。 • 中级:介于二者之间,与源语言和机器语言都 有一定差异。 • 低级:最接近机器语言,能够反映目标机的系 统结构,因而经常依赖于目标机。
不同层次的中间代码
源语言 高级语言) (高级语言)
float a[10][20]; a[i][j+2];
中间代码 高级) (高级)
逆波兰 : 四元式 : ABCD-*+ECD–N^/+ (1) ( C D T1 D N T5 T1 ) T2) T4) T5) T6) T7)
(2) ( * B (3) ( + A (4) ( (6) ( / C E (5) ( ^ T4
T2 T3)

第08章语法制导翻译和中间代码生成

第08章语法制导翻译和中间代码生成
• 如:说明语句的属性文法
17
翻译模式
◆定义
翻译模式是语法制导定义的一种便于翻译的书写 形式。其中属性与文法符号相对应,语义规则或 语义动作用花括号{ }括起来,可被插入到产生 式右部的任何合适的位置上。
这是一种语法分析和语义动作交错的表示法,他 表达在按深度优先遍历分析树的过程中何时执行 语义动作。
–将值 val 作为表达式 E、项 T 和因子 F 的属性
• 用语义规则描述表达式的求值
7
属性文法(语法制导定义)
•L → E
print( E.val )
• E → E1 + T E.val := E1.val + T.val
•E → T
E.val := T.val
• T → T1 * F T.val := T1.val * F.val
33
四元式(三地址代码)
一般形式 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
条件转移
34
a∶=b*c+b*d的四元式表示
a Print(A.in) a Print(A.in)
24
如果计算A1.in和A2.in的值的动作分别被嵌入在产
生式SA1A2 的右部A1和A2之前,而不是后面,
那么A.in在执行Print(A.in)时已有定义。
S {A1in:=1 }A1{A2 in:=2} A2
A a
{ print(A in) }

编译第8章

编译第8章
–是一种接近形式化的语义描述方法 –长于描述静态语义、短于描述动态语义 –每个语法符号有相应的属性符号 –每个产生式有相应的计算属性的规则:
• 属性变量=属性表达式
1、属性文法定义
属性文法(attribute grammar)是一个三元 组:A=(G,V,F),其中 G:是一个上下文无关文法 V:有穷的属性集,每个属性与文法的一个终结符或非 终结符相连,这些属性代表与文法符号相关信息, 如它的类型、值、代码序列、符号表内容等等 .属 性与变量一样,可以进行计算和传递。属性加工 的过程即是语义处理的过程。 F:关于属性的属性断言或一组属性的计算规则(称为 语义规则) . 断言或语义规则与一个产生式相联,只 引用该产生式左端或右端的终结符或非终结符相 联的属性.
addtype
id3
addtype
例5-4:real id1,id2,id3 的分析树和属性计算
8.3 中间代码的形式
何谓中间代码: 源程序的一种内部表示,不依赖目标机的 结构,易于机械生成目标代码的中间表示。 为什麽要此阶段 逻辑结构清楚; 利于不同目标机上实现同一种语言; 利于进行与机器无关的优化; 这些内部形式也能用于解释;
• 语义处理
–例:变量的存储分配 –例:表达式的求值 –例:语句的翻译(中间代码的生成)
• 总目标:生成等价的中间代码
语义处理方法
• 对应每一个产生式编制一个语义子程序, 当一个产生式获得匹配时,调用相应的 语义子程序实现语义检查与翻译。 • 在产生式的右部的适当位置,插入相应 的语义动作,按照分析的进程,执行遇 到的语义动作。
8)若把语义子程序改成产生某种中间代 码的动作,就能在语法分析制导下,随 着分析的进展逐步生成中间代码。 9)若把语义子程序改成产生某种机器的 汇编语言指令,就能随着分析的进展逐 步生成某机器的汇编语言代码。

语法制导翻译和中间代码生成

语法制导翻译和中间代码生成
6
例3:变量的类型说明
规则
D TL T int Treal L L1,id
语义规则
L.in:=T.type T //将L.in属性值设置为T.type T.type=integer T.type:=real int L1.in:=L.in addtype(id.entry, L. in)
(后缀)逆波兰: ab*cd+ef-/-
-/* + Nhomakorabeaa b c d e -
f
14
(二)逆波兰表示
1、赋值语句的逆波兰表示 赋值语句 <变量>:=<表达式> 逆波兰表达式 <变量><表达式的逆波兰式>:= 例1: y:=(a+b)*c; yab+c*:= 2、转向语句的逆波兰表示 转向语句:goto <标号> 逆波兰式:<标号> LJ 例2:100:write(’晚上好’); …... goto 100; 逆波兰表示:100LJ
(1)若b是产生式左部A的一个属性,c1, c2, …, ck 是产生式右部符号或A的属性,则b是A的综合属 性。在分析树中,一个结点的综合属性值是从其 子结点的属性值计算出来的。 (2)若b是产生式右部符号X的一个属性, c1, c2, …, ck是A或右部符号的属性,则b 是X的继承属性。在分析树中,一个结点的 继承属性值是由该结点兄弟结点和父结点的 属性值计算出来的
D in 5 L 6 entry 3 , id3 real in 7 L 8 entry , in 9 L 10 id2 2 entry id1 1
9
4 T type
2、简单算术表达式求值: 用一个产生式进行归约时就执行相应的语义动作,在分 析一个句子时,句子的值同时产生。(自下而上分析)

编译原理 第八章 语法制导翻译与中间代码生成

编译原理 第八章  语法制导翻译与中间代码生成
语义子程序的设计:以属性文法为基础,将属性等式转化为 计算规则(属性等式本身指示了属性计算时的顺序约束)。
对产生式 X0→X1 X2 . . . Xn 的属性等式
Xi.aj=fij(X0.a1,…,X0.ak,X1.a1,…,X1.ak,…,Xn.a1,…,Xn.ak)
等式右边出现的所有属性值必须已经存在。但在属性文法的说 明中,这个要求可能被忽略,可以将等式写成任意顺序而不 会影响正确性。
类型检查应验证一种结构的类型是否匹配其上下文的要求。 如何把源程序改造成某种形式的中间语言程序?
在语法分析中,有相当成熟的理论和算法:使用 BNF中的上 下文无关文法描述语言的语法结构,并用自顶向下或自底向 上的分析算法实现语法分析。 语义分析目前还没有给出一种公认的形式化描述系统,只能 说有一些成功的系统和方法,其中比较接近形式化的一种方 法是语法制导翻译法。
如果语义分析可以推迟到所有的语法分析完成之后进行,那 么实现语义分析的任务就相当容易,其本质上是对语法树的 一序列的遍历过程,同时在遍历中每次遇到结点时进行计算 ,但也这就意味着编译程序必须是多遍的。
另一方面,如果要求编译程序在一遍中完成所有的操作(包 括代码生成),那么语义分析的实现就会变成寻找计算语义 信息的正确顺序和方法的特别的过程。
term(1)→term(2)*factor term(1).tree=mkOpNode(*,term(2).tree,factor.tree)
t属erm性→文fa法ctor
term.tree=factor.tree
f…act…or→(exp)
factor.tree=exp.tree
factor→number
1.decl→var-list id 2.var-list(1)→var-list(2) id,

第8章语法制导翻译和中间代码生成

第8章语法制导翻译和中间代码生成
属性一般分为两类:综合属性和继承属性。简 单的说,综合属性用于“自下而上”传递信息, 而继承属性用于“自上而下”传递信息。
属性加工的过程即是语义处理的过程,对于文 法的每一个产生式都配备了一组属性的计算规 则,则称为语义规则。
在一个属性文法中,对应于每个产生式A都 有一套与之相关联的语义规则,每条语义规则 的形式为:b:=f(c1,c2,…,ck)
第8章 语法制导翻译 和中间代码生成
语法分析的作用是判断一个输入是否为一个句子, 并且同时获得该句子的语法结构,即语法树。
例如在算术表达式的翻译中,不仅要知道表达式中 各个运算的先后次序,即语法结构,而且还要知道 该表达式中的各个变量和常量的内存地址或值,要 知道计算过程的中间结果所存放的内存地址或值, 甚至还要知道其数据类型。这些信息都被称为语义 信息,而对语义信息进行相应的分析处理就叫做语 义分析。因此,翻译是一个语法分析和语义分析综 合在一起进行的过程。
Im
Xm
Xm .VAL



I1
X1
X1 .VAL
I0
#
-
语义栈
ACTION
GOTO
状态 digit + * ( ) # E T F
0 s5
s4
123
1
s6
acc
2
r2 s7
r2 r2
3
r4 r4
r4 r4
4 s5
s4
823
5
r6 r6
r6 r6
6 s5
s4
93
7 s5
s4
10
8
s6
s11
9
r1 s7
F(E)
{F.val = E.val}

第8章 语法制导翻译和中间代码生成

第8章 语法制导翻译和中间代码生成

EE1+E2 {E.val := E1.val +E2.val} E(E1) {E.val := E1.val } En {E.val := n.lex} 属性文法的主要思想有两点: 首先对于每个文法符号引进相关的属性符号; 其次对于每个产生式写出属性值计算的规则。
2、属性分类
综合属性:一个结点的属性值是从其子结点的属性值计算 出来的。 继承属性:一个结点的属性值是由该结点兄弟结点和父结 点的属性值计算出来的。
val[top] := val[top]*val[top+2]; val[top] := val[top+1]; val[top] := lexval;
8.3
中间代码的形式
中间代码:源程序的一种内部表示,不依赖目标 机的结构,易于机械生成目标代码的中间表示。
意义:逻辑结构清楚;利于不同目标机上实现同一种语 言;利于进行与机器无关的优化。
例1:定义表达式的文法如下: EE+E E(E) En 给出定义表达式值的属性文法。
为文法符号E引进属性符号val,用E.val表示E的值,属性 计算规则以赋值语句的形式给出,附在每个产生式后,并用大 括号括起来。为了明确E的不同出现位置,用上角标区别。终 结符n的值是词法分析程序提供的,这里用n.lex表示。下面给 出属性文法:
L
Eval:=19 Eval:=15
Tval:=15 +
Tval:=4
Fval:=4
Tval:=3 Fval:=3 digitlexval:=3
*
Fval:=5 digitlexval:=5
例 5 .2
digitlexval:=4
输入:3*5+4
例2:说明语句语法制导定义(属性文法)

第8章语法制导翻译与中间代码生成-PPT精选

第8章语法制导翻译与中间代码生成-PPT精选

3*5+4的带注释的分析树
只使用综合属性.
T.val=3 F.val=3
E.val=15 T.val=15
*
L
E.val=19
+
F.val=5
T.val=4 F.val=4 digit.lexval=4
digit.lexval=5
digit.lexval=3
3*5+4的带注释的分析树
继承属性
一个结点的继承属性值是由此结点的父结点和/或兄弟结 点的某些属性来决定的。
(Intermediate representation)
(Intermediate language)
是源程序的一种内部表示 复杂性介于源语言和目标机语言之间
中间代码的作用:
使编译程序的逻辑结构更加简单明确 利于进行与目标机无关的优化 利于在不同目标机上实现同一种语言
中间代码的形式:
逆波兰式、四元式、三元式、间接三元式、树
属性分为两种:继承属性和综合属性. inherited and synthesized(derived)attribute 继承属性的计算规则由顶向下, 综合属性的计算规则由底向上.
例如定义表达式值的属性文法, E.val是一个综合属性 的例子:
EE1+E2 {E.val := E1.val +E2.val} E(E1) {E.val := E1.val }
8.2.2 S-属性文法和自下而上翻译 一般的属性文法的翻译器很难建立,然 而L-属性文法的翻译器很容易建立。
L-属性文法的一个特例叫S-属性文法。 S-属性文法是只含有综合属性的属性文法。
8.2.3 L-属性文法在自下而上分析中实现 L-属性文法允许一次遍历就计算出所以的 属性值。

编译原理 之 语法制导翻译和中间代码生成

编译原理 之 语法制导翻译和中间代码生成

非终结符 有一个综合属性type,其值有 非终结符T有一个综合属性 有一个综合属性 其值有 关键字决定(int或real). 关键字决定 或 L.in=T.type, L.in是继承属性 它将沿着 是继承属性,它将沿着 是继承属性 语法树传递到下边的结点. 语法树传递到下边的结点 与L相联的语义规则中有一个过程调 相联的语义规则中有一个过程调 用—addtype把标识符的类型信息登录 把标识符的类型信息登录 在符号表中. 在符号表中 一个结点的继承属性值是由此结点的 父结点和/或兄弟结点的某些属性来决 父结点和 或兄弟结点的某些属性来决 定的. 定的
2+3*5的分析和计值过程 语义栈(值栈 值栈) 步骤 动作 状态栈 语义栈 值栈 符号栈 余留输入串
1) 2) 3) r6 4) r4 5) r2 6) 7) 8) r6 9)r4 10) 10) 11) 11) 12) 12)r6 13) 13)r3 14) 14)r1 15) 15)接受 0 - 05 -- 03 -2 02 -2 01 -2 016 -2- 0165 -2-- 0163 -2-3 0169 -2-3 01697 -2-3- 016975 -2-3-- 01697(10) -2-3-5 0169 -(15 15) -2-(15) 01 17) - (17) # 2+3*5# 5 #2 +3 *5# 5 #F +3*5# 5 #T +3*5# 5 #E +3*5# 5 #E+ 3*5# 5 #E+3 *5# #E+3 5 #E+F *5# #E+F 5 #E+T *5# #E+T 5 #E+T* 5# #E+T #E+T*5 #E+T 5 # #E+T*F # #E+T F #E+T # #E #
属性有两种— 属性有两种 继承属性和综合属性 综合属性用于“自下而上”传递 综合属性用于“自下而上” 信息. 信息 继承属性用于“自上而下”传递 继承属性用于“自上而下” 信息. 信息
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第八章语法制导翻译和中间代码生成1、教学目的及要求:本章介绍编译程序的第三个阶段语义分析及中间代码生成的设计原理和实现方法,要求理解语法制导翻译、语义动作的基本概念;掌握算数表达式和赋值语句到中间代码的翻译、布尔表达式的目标代码结构分析和到四元式的语法制导翻译。

◇明确语义分析在编译过程所处的阶段和作用。

◇掌握属性文法的基本概念。

◇使用属性文法和语法制导翻译方法描述具体的语义分析和产生中间代码。

2、教学内容:语法制导翻译的基本概念、中间代码的形式,可执行语句的语法制导翻译方法。

3、教学重点:语法制导翻译基本思想,语法制导翻译概述,基于属性文法的处理方法,自下而上分析制导翻译概述。

4、教学难点:属性文法的处理方法,语法制导翻译实现的方法。

5、课前思考◇ 回顾第一章介绍的编译过程,理解语义分析在编译过程中的位置和作用。

◇什么是中间表示(中间代码),为什么要中间表示?◇"语法制导翻译"是什么含义?◇ 高级语言语句的结构和低级语言结构的不同。

6、章节内容第一节语法制导翻译概述第二节中间代码的形式第三节简单算术表达式和赋值语句的翻译第四节布尔表达式的翻译8.1语法制导翻译概述编译程序的第三个阶段是语义分析。

语义分析的任务是:在词法分析和语法分析的基础上,分析所写源程序的含义,在理解含义的基础上生成中间代码或直接生成目标代码。

语义分析包括语义检查和语义处理。

语义检查,例:类型、运算、维数、越界。

语义处理,例:变量的存储分配、表达式的求值、语句的翻译(中间代码的生成)。

中间代码或称中间语言,是复杂性介于源程序语言和机器语言之间的一种表示形式,在中间代码一级可进行代码优化工作。

一、属性文法目前许多编译程序的语义分析均采用语法制导翻译方法,它比较接近形式化。

语法制导翻译法采用属性文法为工具来说明程序设计语言的含义。

属性是文法符号的语义性质的表示。

对于文法中的某个终结符或非终结符,其属性可以有“类型”、“值”或“存储位置”等。

一个属性文法包含一个上下文无关文法和一系列语义规则,这些语义规则附在文法的每一个产生式上。

形式上讲,一个属性文法是一个三元组 A=(G,V,F)G:一个上下文无关文法V:一个属性的有穷集F:关于属性的断言或谓词的有穷集其中:每个属性与文法的某个非终结符或终结符相联,每个断言与文法的某个产生式相联,如果对G中的某一输入串而言(句子),A中的所有断言对该输入串的语法树结点的属性全为真,则该串也是A语言中的句子。

例1、有文法G为E→T1+T2|T1 or T2 T→num|true|false若属性文法中用N.t表示与非终结符N相联的属性,则对上述表达式的类型检查的属性文法可表示如下:E→T1+T2 {T1.t=int AND T2.t=int}E→T1 or T2 {T1.t=bool AND T2.t=bool}T→num {T.t=int }T→true {T.t=bool }T→ false {T.t=bool }即与每个非终结符T相联的有属性t(即“类型”),t要么是int,要么是bool。

与非终结符E的产生式相联的断言是:两个T的属性必须相同。

例2、简单算术表达式求值的语义描述产生式语义规则(0)L→E print(E.val)(1)E→E1+T E.val:=E1.val+T.val(2)E→T E.val:=T.val(3)T→T1*F T.val:=T1.val*F.val(4)T→F T.val:=F.val(5)F→(E) F.val:=E.val(6)F→digit F.val:=digit.lexval(lexval指综合属性)每个非终结符都有一个属性val(即“数值”)。

单词digit的值是由词法分析程序提供的。

与产生式L→E相联的语义规则是一个过程,该过程实现的功能是打印由E产生的表达式的值。

我们可以理解为L的属性是空的或是虚的。

例3.说明语句中变量的类型信息的语义规则产生式语义规则(1)D→TL L.in:=T.type(2)T→int T.type:=integer(3)T→real T.type :=real(4)L→L1,id L1.in:=L.in addtype(id.entry,L.in)(5)L→id addtype(id.entry,L.in)该语义规则中的addtype为一过程调用,其功能是把每个标识符的类型信息登录在符号表的相关项中。

type表示类型,综合属性;in起到类型传递的作用,继承属性;entry是单词 id 的属性。

属性文法最早出自克努特笔下,它将属性分为两类:综合属性和继承属性。

综合属性:从语法分析树的角度来看,如果一个节点的某一属性,其值由子节点的属性值来计算则称该属性为综合属性。

有时把内在属性也看作是综合属性。

继承属性:在语法树分析中,若一个节点的某个属性值由该节点的兄弟结点或父节点的属性值来计算,则此节点的该属性称为继承属性。

二、语法制导翻译(产生中间代码)产生中间代码的一种简单办法是让每个产生式对应一个语义子程序。

在自上而下语法分析中,若一个产生式匹配输入串成功,或者在自下而上分析中,当一个产生式被用于归约时,此产生式相应的语义子程序就进入工作。

一个语义子程序描述了一个产生式所对应的翻译工作,这些翻译工作在很大程度上取决于要产生什么形式的中间代码。

包括:改变编译程序某些变量的值,查填各种符号表,诊察与报告源程序错误,产生中间代码等。

在语法分析过程中,随着分析的步步进展,根据每个产生式所对应的语义子程序(语义动作)进行翻译(产生中间代码)的方法叫做语法制导翻译法。

语法制导翻译方法既可用来产生各种中间代码,也可用来产生目标指令,甚至可用来对输入串进行解释执行。

三、语法制导翻译的具体实现途径假定有一个自底向上分析器LR(1),可将LR(1)分析器的能力加以扩大,使之能在用某个产生式进行归约的同时调用相应的语义子程序进行有关的翻译工作,每个产生式的语义子程序执行之后,某些结果(语义信息)必须作为此产生式的左部符号的语义值暂时保存下来,以便以后语义子程序引用这些信息。

假定有一个LR语法分析器,现在把它的分析栈扩充,使得每个文法符号都跟有语义值,如左图。

状态栈语义值符号栈假定我们现在要分析的语法成分是简单算术表达式,所完成的语义处理不是将它翻译成中间代码或目标代码,而是计算表达式的值。

假设语法分析方法是自下而上的。

在用某一产生式进行归约的同时就执行相应的语义动作,在分析出一个句子时,这个句子的“值”也就同时产生了。

以上是对输入串2+3*5的分析处理过程。

按照上述实现方法,若把语义子程序改为产生某种中间代码的动作,那么则可在语法分析的制导下,随着分析的进展逐步生成中间代码。

8.2中间代码的形式不同的编译程序使用了不同的中间代码,有些快速编译程序甚至几乎没有中间代码阶段,但为编译程序的结构在逻辑上更为简单、明确,尤其为使目标代码的优化比较容易实现,许多编译程序都采用了复杂性介于源程序语言和机器语言之间的中间语言,并将源程序翻译成这种中间语言程序(中间代码)。

常见的中间语言有逆波兰记号、三元式、四元式和树形表示等。

源程序的中间代码是在编译程序将高级语言程序翻译成汇编语言或机器代码的过程中产生的,使用中间代码形式的优点:可以不考虑机器特性;可移植性;便于优化处理。

一、逆波兰表示法1、定义逆波兰表示,也称后缀式,即运算量在前,算符写在后面,该方法可在不使用括号的情况下,无二义性地说明算术表达式。

逆波兰表示不仅能用来作为算术表达式的中间代码形式,而且也能作为其它语言结构的中间代码形式。

一般而言,若θ是一个K(K>=1)目运算符,对后缀式e1,e2,..ek作用的结果将被表示为e1e2..ek θ,不必使用括号,如:▪abc+* a*(b+c)▪ab+cd+* (a+b)*(c+d)▪abc*bd*+:= a:=b*c+b*d根据运算量和运算符出现的先后位置,就完全决定了一个表达式的分解。

2、后缀式的计算逆波兰表示法表示表达式,其最大的优点是最易于计算机处理表达式,可用一个栈计算表达式的值。

计算过程为:自左至右扫描后缀式,每碰到运算量就将其推入栈,每碰到一个k目算符时,就将其作用于栈顶的k个项,并用运算结果来代替这k个项。

例:考虑后缀式ab+c@*的计值过程 (@表示一目减)3、后缀式的推广遵守运算量在前,算符在后的规则,可将后缀表示法扩大到比通常表达式更大的范围,如条件语句if E then S1 else S2 可表示为E S1 S2 ¥又如:数组元素A[<下标表达式1>, <下标表达式2>,…, <下标表达式n>]可表示为<下标表达式1><下标表达式2>…<下标表达式n>A subs4、语法制导生成后缀式①E→E1 OP E2 {E.CODE:=E1.CODE‖E2.CODE‖OP}②E→(E1) {E.CODE:= E1.CODE}③E→i {E.CODE:=i}E.CODE表示构成后缀式的符号串。

‖表示两串的“连接”。

第①个产生式语义动作的意思是:E的后缀式等于E1和E2两个后缀式的连接,而后再接上算符OP。

第②个产生式的语义动作指出,把括号无条件地去掉。

第③个产生式的语义动作告诉我们,标识符的语义值是那个标识符本身。

二、三元式和树形表示1、三元式表达式及各种语句都可表示成一组三元式:(算符OP 运算对象1 运算对象2)。

例:a:=b*c+b*d的三元式表示为(1) ( * b c)(2) ( * b d)(3) ( + (1) (2))(4) ( := a (3))三元式中含有对中间计算结果的显示引用,如三元式(1)表示的是b*c的结果。

对于一目算符op,通常用一个运算对象,如规定arg1,而多目运算符,可用若干个连续的三元式表示。

2、间接三元式为便于代码优化处理,作为中间代码,常不使用三元式,而另设一张指示器表(间接码表),按运算的先后顺序列出有关三元式在三元式表中的位置,即利用一张间接码表辅以三元式表的方法来表示中间代码,这种方法即为间接三元式。

+ * a b d c 如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)当在代码优化过程中需要调整运算顺序时,只需重新安排间接码表,无须改动三元式表。

另外由于另设了间接码表,相同的三元式就无须重复填进三元式表中,这样可以节省三元式表的存储空间。

3、树形表示如a*b+c*d 用树形结构表示为:树形表示是三元式表示的翻版。

相关文档
最新文档