第8章 语法制导翻译和中间代码生成
第8章语法制导翻译与中间代码生成ppt课件
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〕上下文相关性检查。比如,变量名字必 需先声明后援用;
第8章 语法制导翻译和中间代码生成2013
图1 3*5+4的注释分析树
14
第8章
语法制导翻译和中间代码生成
D
继承属性
例2. 类型定义的语法制导定义(L.in为继承属性)。
产生式
(1)DTL (2)Tint
语义规则
L.in:=T.type T.type:=integer
Type
T L1 id1
L
(3)Treal T.type:=real
9
第8章 语法制导翻译和中间代码生成
3 语法制导定义
一个结点的综合属性值是从其子结点的综合属性值计算得来的,综 合属性用于自下而上传递信息;而继承属性则是由语法树中该结点 的父结点和位于其左边的兄弟结点的属性值计算出来的,继承属性 用于自上而下传递信息。 (1)非终结符既可有综合属性也可有继承属性,但文法开始符号 没有继承属性。 (2)终结符只有综合属性,它们由词法分析程序提供。 我们将每个结点都带有属性值的语法分析树称为注释分析树。计算 结点属性值的相关活动称为注释或装饰语法树。
21
8.2.1 翻译文法
如何构造翻译文法? 翻译文法的构造方法可通过对输入文法修改得到。对输入文法 的产生式,在其右部的适当位置插入动作符号就形成翻译文法。因 此,翻译文法产生的动作序列实际上是受输入语言的文法控制的。 按语法制导翻译的方法来实现语言的翻译,就要根据输入语言 的文法,分析各条产生式的语义,即分析他们要求计算机所完成的 操作,分别编出完成这些操作的子程序或程序段(称为语义子程序 或语义动作),并把这些子程序或程序段的名字作为动作符号插入 到输入文法各产生式右部的适当位置上,从而实现翻译文法。
10
第8章 语法制导翻译和中间代码生成
3 语法制导定义
定义1 语法制导定义
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章语法制导翻译和中间代码生成(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)
该产生式所对应的语义子程序来进行翻译的一种办法。
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语法制导翻译和中间代码生成-中间代码生成
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章语法制导翻译和中间代码生成
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章
• 属性变量=属性表达式
1、属性文法定义
属性文法(attribute grammar)是一个三元 组:A=(G,V,F),其中 G:是一个上下文无关文法 V:有穷的属性集,每个属性与文法的一个终结符或非 终结符相连,这些属性代表与文法符号相关信息, 如它的类型、值、代码序列、符号表内容等等 .属 性与变量一样,可以进行计算和传递。属性加工 的过程即是语义处理的过程。 F:关于属性的属性断言或一组属性的计算规则(称为 语义规则) . 断言或语义规则与一个产生式相联,只 引用该产生式左端或右端的终结符或非终结符相 联的属性.
addtype
id3
addtype
例5-4:real id1,id2,id3 的分析树和属性计算
8.3 中间代码的形式
何谓中间代码: 源程序的一种内部表示,不依赖目标机的 结构,易于机械生成目标代码的中间表示。 为什麽要此阶段 逻辑结构清楚; 利于不同目标机上实现同一种语言; 利于进行与机器无关的优化; 这些内部形式也能用于解释;
• 语义处理
–例:变量的存储分配 –例:表达式的求值 –例:语句的翻译(中间代码的生成)
• 总目标:生成等价的中间代码
语义处理方法
• 对应每一个产生式编制一个语义子程序, 当一个产生式获得匹配时,调用相应的 语义子程序实现语义检查与翻译。 • 在产生式的右部的适当位置,插入相应 的语义动作,按照分析的进程,执行遇 到的语义动作。
8)若把语义子程序改成产生某种中间代 码的动作,就能在语法分析制导下,随 着分析的进展逐步生成中间代码。 9)若把语义子程序改成产生某种机器的 汇编语言指令,就能随着分析的进展逐 步生成某机器的汇编语言代码。
语法制导翻译和中间代码生成
例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、简单算术表达式求值: 用一个产生式进行归约时就执行相应的语义动作,在分 析一个句子时,句子的值同时产生。(自下而上分析)
第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章 语法制导翻译和中间代码生成
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精选
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 #
属性有两种— 属性有两种 继承属性和综合属性 综合属性用于“自下而上”传递 综合属性用于“自下而上” 信息. 信息 继承属性用于“自上而下”传递 继承属性用于“自上而下” 信息. 信息
编译原理 第八章 语法制导翻译与中间代码生成
对产生式 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,
语法制导翻译和中间代码生成
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
S
t1:=uminus b t2:=c*d t3:=t1+t2
a
:=
E1
E
+ 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. 四元式出现顺序与原表达式计算顺 序一致。(同三元式)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
例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 中间代码形式
所谓“中间代码”是一种结构简单、含义明 确的记号系统,这种记号系统可以设计为多种多 样的形式,重要的设计原则为两点:一是容易生 成;二是容易将它翻译成目标代码。编译程序所 使用的中间代码有多种形式。 常见的有逆波兰记号、三元式、四元式和树 形表示。
逆波兰记号 逆波兰记号是最简单的一种中间代码表示形 式,早在编译程序出现之前,它就用于表示算术 表达式,是波兰逻辑学家卢卡西维奇发明的。 这种表示法将运算对象写在前面,把运算符 号写在后面,比如把a+b写成ab+,把a*b写成ab*, 用这种表示法表示的表达式也称做后缀式。
:= a * b c b + * d
表达式的树形表示很容易实现:简单变量或 常数的树就是该变量或常数自身,如果表达式e1 和e2的树分别为T1和T2,那么e1+ e2,e1* e2,-e1 的树分别为:
静态语义)E→E1+E2{E.val:=E1.val+E2.val} 2)E→1 {E.val:=1} 3)E→0 {E.val:=0 }
属性文法最早出自克努特笔下。他把属性分 成两类:继承属性和综合属性,我们不对属性文 法进行理论上的研究而仅仅将它做为工具描述语 义分析。在编译的许多实际应用中,属性和断言 以多种形式出现,也就是说,与每个文法符号相 联的可以是各种属性、断言、以及语义规则,或 者某种程序设计语言的程序段等等。
属性,常用以描述事物或人的特征、性质、 品质等等。比如,谈到一个物体,可以用“颜色” 描述它,谈起某人,可以使用“有幽默感”来形 容他。对编译程序使用的语法树的结点, 可以 用“类型”、“值”或“存储位置”来描述它。
属性文法是一个三元组:A=(G,V,F),其中
G:是一个上下文无关文法。 V:有穷的属性集,每个属性与文法的一个终 结符或非终结符相连。 F:关于属性的属性断言或谓词集。每个断 言与一个产生式相联.而此断言只引用该产生式 左端或右端的终结符或非终结符相联的属性。
简单算术表达式求值的语义描述。 产生式 (0)L→E (1)E→E1+T (2)E→T (3)T→T1*F (4)T→F (5)F→(E) (6)F→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
T.val=3
F.val=3
*
digit.lexval=3
3*5+4的带注释的分析树
语法制导翻译的具体实现途径不困难。假定 有一个LR语法分析器,现在把它的分析栈扩充, 使得每个文法符号都跟有语义值同时把LR分析器 的能力扩大,使它不仅执行语法分析任务,且能 在用某个产生式进行归约的同时调用相应的语义 子程序,完成在属性文法中描述的语义动作。每 步工作后的语义值保存在扩充的分析栈里“语义 值”栏中。采用LR分析,其中使用d代替digit。 分析和计值2+3*5的过程。
s11 r1 r3 r5 r1 r3 r5
2+3*5的分析和计值过程
步骤 归约动作 状态栈 0 05 03 02 01 016 0165 0163 0169 01697 语义栈 — — — —2 —2 —2 —2— —2— — —2—3 —2—3 —2—3— 符号栈 # #2 #F #T #E #E+ #E+3 #E+F #E+T #E+T* 留余输入串
B@CD*+(它的中缀表示为-B+C*D,使用@表 示一目减)的计值过程为: 1、B进栈; 2、对栈顶元素施行一目减运算,并将结果 代替栈顶,即-B置于栈顶; 3、C进栈; 4、D进栈;
5、栈顶两元素相乘,两元素退栈,相乘结 果置栈顶; 由于后缀式表示上的简洁和计值的方便 , 特别适用于解释执行的程序设计语言的中间表 示 ,也方便具有堆栈体系的计算机的目标代码 生成。 6、栈顶两元素相加,两元素退栈,相加结 果进栈,现在栈顶存放的是整个表达式的值。
第8章 语法制导翻译和中间代码生成
编译程序的任务是把源程序翻译成目标程序, 这个目标程序必须和源程序的语义等同,也就是 说,尽管它们的语法结构完全不同,但它们所表 达的结果应完全相同。通常,在词法分析程序和 语法分析程序对源程序的语法结构进行分析之后, 要么由语法分析程序直接调用相应的语义子程序 进行语义处理,要么首先生成语法树或该结构的 某种表示,再进行语义处理。
三元式表示
把表达式及各种语句表示成一组三元式。每
个三元式三个组成部分是:算符op,第一运算对
象ARG1,和第二运算对象ARG2。
a:=b*c+b*d的三元式表示为:
(1)(*, (2)(*, (3)(+, (4)(:=, b, b, (1), (3), c) d) (2)) a)
树形表示是三元式表示的翻版。上述三元式 可表示成下面的树表示:
要特别强调的是: (1)终结符只有综合属性,它由词法分析器提供; (2)非终结符既可以有综合属性也可以有继承属性,文 法开始符号的所有继承属性作为属性计算前的初始值。 一般来讲,对出现在产生式右边的继承属性和出现在产 生式左边的综合属性都必须提供一个计算规则,属性计算 规则中只能使用相应产生式的文法符号的属性,这有利于 产生式范围内“封装”属性的依赖性。然而,出现在产生 式左边的继承属性和出现在产生式右边的综合属性不由所 给的产生式的属性计算规则进行计算,它们由其它产生式 的属性规则计算,由属性计算器的参数提供。
• 语义规则所描述的工作可以包括属性计算、静态语义检查、 符号表操作、代码生成等。语义规则可能产生副作用(如 产生代码),也可能不是变元的严格函数(如某个规则给 出可用的下一个数据单元的地址)。这样的语义规则通常 写成过程调用,或过程段。 • 综合属性: • 在语法树中,一个结点的综合属性的值由其子结点 的属性值确定。因此,通常使用自底向上的方法在每一个 结点处使用语义规则计算综合属性的值。仅仅使用综合属 性的属性文法称S—属性文法。 • 继承属性: • 在语法树中,一个结点的继承属性由此结点的父结 点和/或兄弟结点的某些属性确定。用继承属性来表示程 序语言结构中的上下文依赖关系很方便。
本章主要内容
属性文法 语法制导翻译思想 中间代码 一些语句的翻译
8.1属性文法 现在很多编译程序采用语法制导翻译方法。 这仍不是一种形式系统,但它是比较接近形式化 的。这种方法使用属性文法为工具来说明程序设 计语言的语义。 一个属性文法包含一个上下文无关文法和一 系列语义规则,这些语义规则附在文法的每个产 生式上,在语法分析过程中,完成附加在所使用 的产生式上的语义规则描述的动作,从而实现语 义处理。
如,有文法G为: E→T1+T2|T1orT2 T→num|true|false 因为T在同一个产生式里出现了两次,使用 上角标将它们区分开。
属性文法记号中常使用N.t的形式表示与非 终结符N相联的属性t。比如可把完成对上面表达 式的类型检查的属性文法写成形式:
类型检查的属性文法 E→T1+T2{T1.t=int AND T2.t=int} E→T1orT2{T1.t=bool AND T2.t=bool} T→false{T.t:=bool} T→num{T.t:=int} T→true{T.t:=bool}
• 一个属性文法它包含一个上下文无关文法和一系 列语义规则,这些语法规则附在文法的每个产生 式上。 • 在一个语法制导定义中,A→P都有与之相关 联的一套语义规则,规则形式为 • b:= f(c1,c2,…,ck), • f是一个函数,而且 • 1.b是A的一个综合属性并且c1,c2,…, ck是中的符号的属性,或者 • 2.b是中的符号的一个继承属性并且c1, c2,…,ck是A或中的任何文法符号的属性。 • 在两种情况下,都说 • 属性b依赖于属性c1,c2,…,ck。
8.2 语法制导翻译
在语法分析过程中,随着分析的步步进展, 根据每个产生式所对应的语义子程序(或语义规 则描述的语义动作)进行翻译的办法称作语法制 导翻译。
假定我们现在要分析的语法成分是简单算术 表达式,所完成的语义的处理不是将它翻译成中 间代码或目标代码,而是计算表达式的值。采用
的描述系统是上节的例1。 假如语法分析方法是
在该描述中,每个非终结符都有一个属性: 一个整数值的称作val的属性。 按照语义规则对 每个产生式来说, 它的左部E,T,F的属性值的 计算来自它右部的非终结符,这种属性称作综合 属性。单词digit仅有综合属性, 它的值是由词 法分析程序提供的。和产生式L→E相联的语义规 则是一个过程,打印由E产生的表达式的值。 我 们可以理解为L的属性是空的或是虚的。