第七章语义分析和中间代码产生

合集下载

程序设计语言编译原理第三版第7章

程序设计语言编译原理第三版第7章

N→ Є
D →id: T { enter(top(tblptr), , T.type, top(offset)); top(offset):= top(offset) +T.width } 24
§7.2
说明语句
2.含嵌套说明的翻译模式:
(1)语义规则中的操作: Mktable (previous): 创建一张新符号表,并返回指向新表的一个指针; Enter (table, name, type, offset):
(2)置相对地址为当前offset之值, (3)使offset加上该名字所表示的数据对象的域宽。
20
§7.2 说明语句
3. 相应的翻译模式:
PD { offset:=0 } { enter (, T.type,offset);
DD;D
Did:T
offset:=offset+t.width } Tinteger
(0) (1) (2) (3) (4) (5)
(2) (3) (4)
16
§7.1 中间语言
4.间接三元式:便于代码优化处理
方法:间接码表+三元式表
按运算的先后顺序列出有关三元式在三元表中的位置 例: 语句X:=(A+B)*C;Y:=D↑(A+B)的间接三元式表示如下所示: 间接代码 三元式表 (1) (2) (3) (1) (4) (5)
30
已归约串
PLACE
输入串
语义动作
# #X # X:= # X:= # X:= # X:= # X:=
X:= -B*(C+D)# X := -B*(C+D)# X_ -B*(C+D)# X__ B*(C+D)# -B X__B *(C+D)# -E X__B *(C+D)# { E.place:=p=<B>} E1 X_T1 *(C+D)# {E1.place:=newtemp=T1; 生成四元式(1) } … … … … # X:=E*(C X_T1__C +D)# # X:=E*(E1 X_T1__C +D)# { E1.place:=p=<C> } … … … …

编译原理语义分析与中间代码生成

编译原理语义分析与中间代码生成

编译原理语义分析与中间代码生成在编译原理中,语义分析是编译器的重要组成部分之一,它负责验证和处理源代码中的语义信息,为后续的中间代码生成做准备。

本文将介绍语义分析的基本概念和流程,并探讨中间代码生成的相关技术。

一、语义分析的基本概念和流程语义分析是指对源代码进行语义检查和语义信息提取的过程。

其主要目标是确保源代码在语义上是正确的,并从中提取出各种语义信息,以便后续阶段使用。

语义分析的基本流程如下:1. 词法分析和语法分析:在进行语义分析之前,需要先对源代码进行词法分析和语法分析,以便将代码转化为具有结构的中间表示形式(如抽象语法树)。

2. 符号表的构建:符号表是语义分析的重要数据结构,用于存储程序中出现的各种标识符及其相关信息,如类型、作用域等。

在语义分析阶段,需要构建符号表并实时更新。

3. 类型检查:类型检查是语义分析的核心任务之一。

它通过对表达式、赋值语句、函数调用等进行类型推导和匹配,来验证程序是否存在类型错误。

4. 语义规则检查:除了类型检查外,语义分析还需要检查程序是否符合语言规范中的其他语义规则,如变量是否已声明、函数调用是否正确等。

5. 语义信息提取:语义分析还负责提取源代码中的各种语义信息,如函数调用关系、变量的定义和引用关系、控制流信息等。

这些信息将为后续的代码优化和代码生成提供依据。

二、中间代码生成的相关技术中间代码是指某种形式的中间表示形式,通常与源代码和目标代码之间存在一定的映射关系。

它在编译过程中起到连接前后两个阶段的桥梁作用,并且可以进行一些优化。

常见的中间代码形式之一是三地址码。

三地址码是一种低级的代码表示形式,每条指令最多包含三个操作数。

它具有简洁明了的特点,适合进行后续的优化工作。

在进行中间代码生成时,需要考虑以下几个方面的技术:1. 表达式的翻译:在将源代码转化为中间代码时,需要将源代码中的表达式进行翻译。

这包括对表达式的计算顺序、运算符优先级等方面的处理。

2. 控制流的处理:在编译过程中,需要将源代码中的控制流转化为中间代码中的条件分支和循环结构。

语义分析和中间代码产生

语义分析和中间代码产生
源程序 语法分析 中间代码 优化 优化后中间代码
2、关于语法制导翻译法 、
目标代码
代码生成
中间语言有多种形式,常见的有逆波兰表示、四元式、 中间语言有多种形式,常见的有逆波兰表示、四元式、三 元式和树表示等,对中间语言要有两方面的要求: 元式和树表示等,对中间语言要有两方面的要求: •与具体目标机无关; 与具体目标机无关; 与具体目标机无关 •要有利于代码生成。 不同的参考书不一样! 要有利于代码生成。 不同的参考书不一样! 要有利于代码生成 为了描述的方便,我们约定如下几个符号: 为了描述的方便,我们约定如下几个符号: 转向某个标号处; (1) LJ : 转向某个标号处; (2) TJ : 按真转移; 按真转移; (3) FJ : 按假转移; 按假转移; (4) RJ : 无条件转移。 无条件转移。
写成一行: 写成一行: i1:=i100<=21FJssi+:=ii1+:=4RJ
7.2 四元式表示
一、四元式的格式: 四元式的格式: 二、举例说明: 举例说明: 1.表达式的四元式: 表达式的四元式: 表达式的四元式 例1.a*b+c/d
<分量 、<分量 为 分量1>、 分量 分量2>为 分量 <结果 参加运算的两个分量 结果>即为运算结果 结果 即为运算结果
x:=a*b+c/d *
在进行具体处理时,可以采用与表达式相似的方法, 在进行具体处理时,可以采用与表达式相似的方法,不 同之处是进行运算时,栈中保存的是<左部 变量的地址, 左部>变量的地址 同之处是进行运算时,栈中保存的是 左部 变量的地址,而 不是它的直,最后的处理不是得到一个结果, 不是它的直,最后的处理不是得到一个结果,而是进行赋值 (将表达式的值送到指定的内存单元 ,所以,赋值工作完成 将表达式的值送到指定的内存单元), 将表达式的值送到指定的内存单元 所以, 应将栈顶两项(变量地址和表达式的值 退栈。 变量地址和表达式的值)退栈 后,应将栈顶两项 变量地址和表达式的值 退栈。

编译原理 语义分析和中间代码的产生

编译原理 语义分析和中间代码的产生

n 语义分析的概念:源程序经过词法分析、语法分析后,表明该源程序书写正确、符合程序语言所规定的语法,但语法分析并未对程序内部的逻辑含义加以分析,因此编译程序接着进行语义分析,即审查每个语法成分的静态语义。

如果静态语义正确,则生成与该语言成分等效的中间代码,或直接生成目标代码。

直接生成机器语言或汇编语言形式的目标代码的优点是编译时间短且无需中间代码到目标代码的翻译,而生成中间代码的优点是使编译结构在逻辑上更为简单明确,特别是使目标代码的优化较易实现。

语义分析进行的语义检查有两类:动态语义检查和静态语义检查。

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

教学要求n 掌握:n 1. 逆波兰式, DAG图, 抽象语法树, 三地址代码, 三元式, 四元式等中间代码表示;n 2. 简单赋值语句的翻译, 带数组元素引用的赋值句的翻译;n 3. 布尔表达式的翻译, 控制语句中布尔表达式的翻译;n 4. 控制语句的翻译。

n 了解理解:说明语句的翻译,过程调用和参数的处理。

教学内容n 7.1 中间语言n 后缀式,DAG,三地址码(四元式,三元式,间接三元式)n *7.2 说明语句的翻译n 7.3 赋值语句的翻译,数组元素引用的翻译n 7.4 布尔表达式的翻译n 求布尔式值的翻译,作为控制条件的翻译n 7.5 控制语句的翻译n if , while , goto , casen 7.6 过程调用的处理, 参数传递的处理n *7.7 类型检查(不作要求,不讲)7.1 中间语言n 要掌握几种中间语言的基本结构:n 逆波兰表示即后缀式n 抽象语法树n DAG图n 三地址代码(四元式、三元式、间接三元式)7.1.1 后缀式n 波兰逻辑学家卢卡西维奇(Lukasiewicz)发明的一种表示法,又称逆波兰式表示法。

n 后缀式这种方法是,把运算量(操作数)写在算符的前面,把算符写在运算量的后面(后缀)。

第7章 语义分析和中间代码生成

第7章 语义分析和中间代码生成

规约过程

15
图 x:=(a+b)*(a+b)图形表示的中间代码 (a) 树表示;(b) DAG表示
16
(1)E E(1) OP E(2) (2)E(E(1))
函数过程,建立一个以OP为 结点,E(1).optr和 E(2).optr为左右枝的子树, 回送新子树根的指针
{ E.nptr:= makenode (OP,E(1).optr,E(2).optr)} { E.optr:= E(1).optr } (3)E-E(1) { E.nptr := makenode (‘uminus’,E(1).optr)}
E→E1+E2 E. nptr:= mknode('+', E1. nptr, E2. nptr)
E. nptr:= mknode('*', E1. nptr, E2. nptr)
E. nptr:= mknode('-', 0, E1. nptr) E. nptr:= E1. nptr E. nptr:= mkleaf(id, id. place) E. nptr:=mkleaf(num,num.val)

30
(3)
x=y形式的赋值语句,将y的值赋给
χ。 (4) 无条件转移语句goto L,即下一个将 被执行的语句是标号为L的语句。 (5) 条件转移语句if x rop y goto L,其 中rop为关系运算符,如<、<=、==、!=、 >、>=等。若x和y满足关系rop就转去执 行标号为L的语句,否则继续按顺序执行 本语句的下一条语句。
47作用说明语句declarations用于对程序中规定范围内使用的各类变量常数过程进行说明编译要完成的工作在符号表中记录被说明对象的属性为执行做准备计算要占的存储空间计算相对地址48简单声明句的翻译程序中的每个名字如变量名都必须在使用之前进行说明而说明语句的功能就是为编译程序说明源程序中的每一个名字及其性质

编译原理作业集-第七章(精选.)

编译原理作业集-第七章(精选.)

编译原理作业集-第七章(精选.)第七章语义分析和中间代码产⽣本章要点1. 中间语⾔,各种常见中间语⾔形式;2. 说明语句、赋值语句、布尔表达式、控制语句等的翻译;3. 过程调⽤的处理;4. 类型检查;本章⽬标掌握和理解中间语⾔,各种常见中间语⾔形式;各种语句到中间语⾔的翻译;以及类型检查等内容。

本章重点1.中间代码的⼏种形式,它们之间的相互转换:四元式、三元式、逆波兰表⽰;3.赋值语句、算术表达式、布尔表达式的翻译及其中间代码格式;4.各种控制流语句的翻译及其中间代码格式;5.过程调⽤的中间代码格式;6.类型检查;本章难点1. 各种语句的翻译;2. 类型系统和类型检查;作业题⼀、单项选择题:1. 布尔表达式计算时可以采⽤某种优化措施,⽐如A and B⽤if-then-else可解释为_______。

a. if A then true else B;b. if A then B else false;c. if A then false else true;d. if A then true else false;2. 为了便于优化处理,三地址代码可以表⽰成________。

a. 三元式b. 四元式c. 后缀式d. 间接三元式3. 使⽤三元式是为了________:a. 便于代码优化处理b. 避免把临时变量填⼊符号表c. 节省存储代码的空间d. 提⾼访问代码的速度4. 表达式-a+b*(-c+d)的逆波兰式是________。

a. ab+-cd+-*;b. a-b+c-d+*;c. a-b+c-d+*;d. a-bc-d+*+;5. 赋值语句x:=-(a+b)/(c-d)-(a+b*c)的逆波兰式表⽰是_______。

a. xab+cd-/-bc*a+-:=;a. xab+/cd-bc*a+--:=;a. xab+-cd-/abc*+-:=;a. xab+cd-/abc*+--:=;6. 在⼀棵语法树中结点的继承属性和综合属性之间的相互依赖关系可以由________来描述。

第7章 语义分析与中间代码生成

第7章 语义分析与中间代码生成
2013-7-25 2

第6章小结
• 注释分析树和相应的依赖图是属性值的关联 关系和计算顺序的表达形式,语义关系可以 使用抽象语法树表示。 依据语法分析方法有自底向上的和自顶向下 的,语法制导翻译既可以按照自底向上的策 略进行,也可以按照自顶向下的策略进行。

2013-7-25
3
第7章 语义分析与中间代码生成
第6章小结
• • 语法分析中进行静态语义检查和中间代码生 成的技术称为语法制导翻译技术。 为了通过将语义属性关联到文法符号、将语 义规则关联到产生式,有效地将语法和语义 关联起来,人们引入了语法制导定义。没有 副作用的语法制导定义又称为属性文法。
2013-7-25
1
第6章小结
• 为相应的语法成分设置表示语义的属性,属 性的值是可以计算的,根据属性值计算的关 联关系,将其分成综合属性和继承属性,根 据属性文法中所含的属性将属性文法分成S属性文法和L-属性文法。 如果不仅将语义属性关联到文法符号、将语 义规则关联到产生式,而且还通过将语义动 作嵌入到产生式的适当位置来表达该语义动 作的执行时机,这就是翻译模式。翻译模式 给语义分析的实现提供了更好的支持。
2013-7-25
arg2 result t1 d t2 d t4 t2 t3 t4 t5 a
5 assign
图7.2(a) 图7.1中三地址码的四元式表示
11
三元式
• 为了节省临时变量的开销,有时也可以使用只有三个域的三 元式来表示三地址码。三元式的三个域分别称为op,arg1和 arg2,op,arg1和arg2的含义与四元式类似,区别只是arg1和 arg2可以是某个三元式的编号(图7.2(b)中用圆括号括起来的数 字),表示用该三元式的运算结果作为运算对象。

编译原理chapter7 语义分析及中间代码生成

编译原理chapter7 语义分析及中间代码生成

编译原理
chapter7
语义分三元式 三元式顾名思义就是带有三个域的记录结构。 三元式顾名思义就是带有三个域的记录结构。 一般形式为: (i)( ,arg1,arg2) 一般形式为: )(op, )( , ) 其中,( )为三元式的编号, 其中,(i)为三元式的编号,也代表了该式的运算 ,( 结果, , 的含义与四元式类似, 结果,op,arg1,arg2的含义与四元式类似,区别在 , 的含义与四元式类似 于arg可以是某三元式的序号,表示用该三元式的结果 可以是某三元式的序号, 可以是某三元式的序号 作为运算对象。 作为运算对象。
编译原理
chapter7
语义分析和中间代码生成
对于文法G[E]: E →E+T | T 例:对于文法 T→ digit 产生式 ) E→ E(1)+T E→ T T→ digit 语 法 分 析 栈 T + E … # 语义子程序 ) {E.Val=E(1).Val+T.Val} {E.Val=T.Val} {T.Val=digit} T.Val 语 义 ‘+’ ) E(1).Val 分 析 … 栈 #
编译原理
chapter7
语义分析和中间代码生成
三地址代码可以看成是抽象语法树一种线性表示。 三地址代码可以看成是抽象语法树一种线性表示。 线性表示 例: a=b*-c+b*-c = a + T1=-c T2=b*T1 T3=-c
*
b
* - b
c
c
T4=b*T3 T5=T2+T4 a=T5
编译原理
语义分析和中间代码生成
图表示法—抽象语法树 图表示法 抽象语法树 在语法树中去掉一些对翻译不必要的信息后 在语法树中去掉一些对翻译不必要的信息后,获得 去掉一些对翻译不必要的信息 的更有效的源程序的中间表示, 的更有效的源程序的中间表示,这种经过变换后的语法 树称为抽象语法树。 树称为抽象语法树。 内部结点代表操作符,它的孩子代表对应的操作数。 内部结点代表操作符,它的孩子代表对应的操作数。 例:a+a*(b-c)+(b-c)*d ( ) ( ) + + a a b
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
3. 如果E是(E1)形式的表达式,则E1 的后缀式就 是E的后缀式。
国防科技大学计算机系602教研室
逆波兰表示法不用括号。只要知道每个 算符的目数,对于后缀式,不论从哪一 端进行扫描,都能对它进行唯一分解。
后缀式的计算
用一个栈实现。 一般的计算过程是:自左至右扫描后缀式,
每碰到运算量就把它推进栈。每碰到k目运 算符就把它作用于栈顶的k个项,并用运算
国防科技大学计算机系602教研室
7.1.2 图表示法
无循环有向图(Directed Acyclic Graph, 简称DAG)
对表达式中的每个子表达式,DAG中都有一个 结点
一个内部结点代表一个操作符,它的孩子代表 操作数
在一个DAG中代表公共子表达式的结点具有多 个父结点
国防科技大学计算机系602教研室
国防科技大学计算机系602教研室
国防科技大学计算机系602教研室
assign
a
+
抽象语法树对应的代码:
T1:=-c T2:=b*T1 T3:=-c T4:=b*T3 T5:=T2+T4 a:=T5
*
b
uminus
c DAG
DAG对应的代码:
T1:=-c T2:=b*T1 T5:=T2+T2 a:=T5
第七章 语义分析和中间代码产生
静态语义检查
类型检查 控制流检查 一致性检查 相关名字检查 名字的作用域分析
语法分 析器
静态检 查器
中间代码 产生器
中间代码
优化器
国防科技大学计算机系602教研室
中间语言(复杂性界于源语言和目标语言 之间)的好处:
便于进行与机器无关的代码优化工作 易于移植 使编译程序的结构在逻辑上更为简单明确
结果代替这k个项。
国防科技大学计算机系602教研室
•把表达式翻译成后缀式的语义规则描述
产生式 E→E(1)op E(2) E→ (E(1)) E→id
语义动作 E.code:= E(1).code || E(2).code ||op E.code:= E(1).code E.code:=id
• E.code表示E后缀形式 • op表示任意二元操作符 • “||”表示后缀形式的连接。
E→E(1)op E(2) (E(1))
{POST[k]:=op;k:=k+1} {}
E→i
{POST[k]:=i;k:=k+1}
例:输入串a+b+c的分析和翻译 POST: 1 2 3 4 5
a b + c +…
国防科技大学计算机系602教研室
7.1.2 图表示法
图表示法
DAG 抽象语法树
7.1.1 后缀式
后缀式表示法:Lukasiewicz发明的一种表示 表达式的方法,又称逆波兰表示法。
一个表达式E的后缀形式可以如下定义:
1. 如果E是一个变量或常量,则E的后缀式是E 自身。
2. 如果E是E1 op E2形式的表达式,其中op是任 何二元操作符,则E的后缀式为E1 E2 op,其 中E1 和E2 分别为E1 和E2的后缀式。
x:=y op z x:=op y x:=y goto L if x relop y goto L或if a goto L param x和call p,n,以及返回语句return
y x:=y[i]及x[i]:=y的索引赋值 x:=&y, x:=*y和*x:=y的地址和指针赋值
国防科技大学计算机系602教研室
生成三地址代码时,临时变量的名字对应 抽象语法树的内部结点
id:=E
对表达式E求值并置于变量T中值 id.place:=T
国防科技大学计算机系602教研室
从赋值语句生成三地址代码的S-属性文法
非终结符号S有综合属性S.code,它代表 赋值语句S的三地址代码。
非终结符号E有如下两个属性:
E→-E1 E.nptr:=mknode(‘uminus’,E1.nptr)
E→ (E1) E.nptr:=E1.nptr
E→id
E.nptr:=mkleaf(id,id.place)
国防科技大学计算机系602教研室
7.1.3 三地址代码
三地址代码
x:=y op z
三地址代码可以看成是抽象语法树或DAG 的一种线性表示
Compiler
Compiler
源语言 Front End 中间语 Back End 目标语
程序
言程序
言程序
国防科技大学计算机系602教研室
7.1 中间语言
常用的中间语言:
后缀式,逆波兰表示 图表示: DAG、抽象语法树 三地址代码
三元式 四元式 间接三元式
国防科技大学计算机系602教研室
国防科技大学计算机系602教研室
产生赋值语句抽象语法树的属性文法
产生式
语义规则
S→id:=E S.nptr:=mknode(‘assign’,
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)
国防科技大学计算机系602教研室
国防科技大学计算机系602教研室
T1:=-c T2:=b*T1 T3:=-c T4:=b*T3 T5:=T2+T4 a:=T5 对于抽象语法树的代码
T1:=-c T2:=b*T1 T5:=T2+T2 a:=T5
对于DAG的代码
国防科技大学计算机系602教研室
三地址语句的种类
E.place表示存放E值的名字。 E.code表示对E求值的三地址语句序列。 函数newtemp的功能是,每次调用它时,将返
回一个不同临时变量名字,如T1,T2,…。
国防科技大学计算机系602教研室
为赋值语句生成三地址代码的S-属性文法定义
产生式 S→id:=E E→E1+E2
E→E1*E2
国防科技大学计算机系602教研室
E→E(1)op E(2) E→ (E(1)) E→id
E.code:= E(1).code || E(2).code ||op E.code:= E(1).code E.code:=id
数组POST存放后缀式:k为下标,初值为1
上述语义动作可实现为:
产生式
程序段
E→-E1
E→ (E1) E→id
语义规则
S.code:=E.code || gen(id.place ‘:=’ E.place)
相关文档
最新文档