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

合集下载

第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
  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 用树形结构表示为:树形表示是三元式表示的翻版。

相关文档
最新文档