第七章语义分析和中间代码产生
程序设计语言编译原理第三版第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章 语义分析和中间代码生成
规约过程
树
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章 语义分析与中间代码生成
•
第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
语义分三元式 三元式顾名思义就是带有三个域的记录结构。 三元式顾名思义就是带有三个域的记录结构。 一般形式为: (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
语义分析和中间代码产生.ppt
定义:在语法树中去掉那些对翻译不必要的信息,从而获
得更有效的源程序中间表示,经过这种变换的语法树就是 抽象语法树。在抽象语法树中,操作数和关键字都不作为 叶子结点出现,而是作为内部结点,即这些节点的父结点。
产生式:S → if B then S1 else S2的抽象语法树
If_then_else
属性和变量一样,可以进行计算和传递。 属性分类:综合属性和继承属性。简单的说,综合属性用
于“自下而上”传递信息,而继承属性用于“自上而下” 传递信息。
语义规则——属性加工加工的过程即是语义处理的过程,
对于文法的每一个产生式都配备了一组属性的计算规则,
则称为语义规则。主要包括:属性计算、静态语义检查、 符号表操作、代码生成等。在一个属性文法中,对应于每
表7.1给出了把表达式翻译为后缀式的语义规则描述,
其中||表示后缀式的连接。
第七章 语义分析和中间代码产生
7.1.2 图表示法
图表示法包括: 。
第七章 语义分析和中间代码产生
抽象语法树的每个结点上都可带上一定的属性。语法制导
翻译可以基于语法树分析,也可以基于抽象语法树进行。
b
cb
d
第七章 语义分析和中间代码产生
(2) 无循环有向图:
无循环有向图(Directed Acyclic Graph , 简称
DAG ).与抽象语法树一样,对于表达式中的每个子表达式,
DAG图中都有一个结点。一个内部结点代表一个操作符,
它的孩子代表操作数。两者不同的是,在DAG图中代表公共
子表达式的结点具有多个父结点,而在一棵抽象语法树中
第七章 语义分析和 中间代码的产生
第七章 语义分析和中间代码产生
07-第7章-中间代码生成-编译原理PDF精讲课件-中国科技大学(共13讲)
7.2 声 明 语 句
sort readarray exchange quicksort partition readarray 表头 i 空 sort 表头 指向readarray 指向exchange quicksort 表头 k v partition partition a x readarray exchange quicksort exchange 表头
7.2 声 明 语 句
7.2.2 作用域信息的保存 • 所讨论语言的文法
P D; S D D ; D | id : T | proc id ; D ; S sort var a:…; x:…; readarray var i:…; exchange quicksort var k, v:…; partition var i, j:…; 图6.14的程序 参数被略去
E E1 E2 E.nptr = mkNode( ‘’, E1.nptr, E2.nptr) E.nptr = mkUNode( ‘uminus’, E1.nptr) E E1 E (E1) F id E.nptr = E1.nptr E.nptr = mkLeaf (id, id.entry)
7.2 声 明 语 句
本节介绍 • 为局部名字建立符号表条目 • 为它分配存储单元 • 符号表中包含名字的类型和分配给它的存储 单元的相对地址等信息
7.2 声 明 语 句
7.2.1 过程中的声明
7.2 声 明 语 句
计算被声明名字的类型和相对地址 P {offset = 0} D; S DD;D D id : T {enter ( id.lexeme, T.type, offset); offset = offset + T.width } T integer {T.type = integer; T.width = 4 } T real {T.type = real; T.width = 8 } T array [ num ] of T1 {T.type = array (num.val, T1.type); T.width = num.val T1.width} T T1 {T.type = pointer (T1.type); T.width = 4 }
语义分析和中间代码产生
* id uminus id c b id
* b
6 7
uminus id c
7.1 §7.1 中间语言
三、三地址代码 1.三地址代码:下面一般形式的语句构成的序列: 1.三地址代码:下面一般形式的语句构成的序列: 三地址代码
x:=y op z T1:=y*z, T2:=x+T1
名字,常数, x,y,z: 名字,常数,编译时产生的临时变量 op: 运算符号(如定点运算符,浮点运算符,逻辑运算符等) 运算符号(如定点运算符,浮点运算符,逻辑运算符等) 称为三地址代码的原因: 称为三地址代码的原因: 每条语句通常包含三个地址,两个用来表示操作数, 每条语句通常包含三个地址,两个用来表示操作数,一 个用来存放结果。 个用来存放结果。 具体实现:用记录表示,其中包含运算符和操作数的域。 具体实现:用记录表示,其中包含运算符和操作数的域。 运算符 的域
(0) (1) (2) (3) (4) (5)
23
7.1 §7.1 中间语言
4.间接三元式: 4.间接三元式:便于代码优化处理 间接三元式
方法:间接码表+ 方法:间接码表+三元式表
按运算的先后顺序列出有关三元式在三元表中的位置 语句X:=(A+B)*C;Y:=D↑(A+B)的间接三元式表示如下所示: X:=(A+B)*C;Y:=D↑(A+B)的间接三元式表示如下所示 例: 语句X:=(A+B)*C;Y:=D↑(A+B)的间接三元式表示如下所示: 间接代码 三元式表 (1) (2) (3) (1) (4) (5)10来自7.1 §7.1 中间语言
例子:如图所示, a+a*(b-c)+(b-c)*d的 例子:如图所示,为a+a*(b-c)+(b-c)*d的DAG
编译程序原理与实现:第7章 中间代码生成(1)
--- 传值
• 结构语句
• (THEN, t ,_ ,_ )
--- THEN分支标记
• (ELSE, _ , _ ,_ )
--- ELSE分支标记
• (ENDIF, _ , _ , _ )
--- IF语句结束四元式
• (WHILE, _ , _ , _ )
---WHILE语句开始标记
• (DO,t,_ ,_ )
• 三地址中间代码
• 三地址:两个操作分量和一个结果的抽象地址;
• 为方便起见, 通常用变量名代替抽象地址;
• 三元式
• No. (op, operand1, operand2) • 编号 (操作符, 操作分量1, 操作分量2) • 其中操作分量可以是变量名(抽象地址)或者编号
• 四元式
• (op, operand1, operand2, result) • (操作符, 操作分量1, 操作分量2, 结果) • 其中操作分量可以是变量名(抽象地址)或者临时变量(抽象地址)
--- 函数出口
• (CALL, f, true/false, Result) --- 调用函数f,返回值给Result
• (RETURN, -,-, -)
• (RETURN, -,-, t)
• 传递参数
• (VARACT, id, offset, size )
--- 传地址
• (VALACT, id, offset, size )
•
{ op = pop(S1,1); (str1, str2)=pop(S2,2);
•
push(S2, str2+str1 + “op”);
•
}
•
push(S1,tk); goto (2);
编译原理课件07语义分析和中间代码产生
语义分析阶段中的关键问题和 挑战
语义分析阶段面临着许多关键问题和挑战,例如识别复杂的语义错误、处理 不完整的代码等。
在处理大型程序时,编译器需确保语义分析的效率和准确性,并能处理各种 语法结构。
中间代码的定义和作用
中间代码是一种介于高级语言和底层机器代码之间的形式,它是一种可读性 较强且易于生成和优化的表示。
语义分析的基本任务和目标
语义分析的主要任务是识别和验证程序中的语义错误,例如类型不匹配、变量未定义等。 它的目标是确保程序的语义是一致的,以便于理解和执行。语义语义分析使用了各种技术和方法,包括符号表、类型检查、控制流分析等。 符号表用于记录变量和函数的信息,类型检查用于比较表达式和操作数的类 型是否一致。 控制流分析用于检测条件语句、循环语句和函数调用等代码块的流程。
编译原理课件07语义分析 和中间代码产生
在这一节中,我们将学习关于语义分析和中间代码产生的定义、概述以及它 们在编译过程中的作用。我们将探讨语义分析的任务、方法和挑战,以及中 间代码产生的基本原理和实际应用。
语义分析和中间代码产生的定义和概述
语义分析是编译过程中的重要阶段,用于分析程序的意义和语法结构,并生成中间代码。中间代码产生是将高 级语言代码转换为更低级的可执行形式的过程。 在这一阶段,编译器将检查语法的正确性和静态语义的正确性,以确保程序在执行时没有语法错误。 语义分析和中间代码产生是编译器的核心部分,它们直接影响了程序的性能和可读性。
中间代码作为编译器和解释器的输入,是程序在执行前的一个中间阶段,并 可用于代码优化和跨平台编译。
中间代码产生的基本原理和方法
中间代码产生的基本原理是将程序的语义结构转换为一系列指令序列,这些指令不依赖于具体的计算机体系结 构。 中间代码生成的方法包括源代码到抽象语法树的转换、语法树到中间代码的转换等。
编译原理-语义分析和中间代码生成
编译器是一种将高级语言翻译成低级语言的程序。语义分析和中间代码生成 是编译器中非常重要的两个步骤。在本次演讲中,我们将深入探讨它们的内 容和作用。
定义和目的
1 语义分析
对代码的意义和上下文进行全面的分析。
2 目的
识别出语法正确但不符合语言规范的代码,以及提取中间代码。
检查和错误
1
步骤
类型检查、控制流检查、错误信息收集。
2
类型
变量未声明、数组维数不符、类型不匹配、函数参数个,中断代码生成流程。
中间代码生成
概述
表示形式
将源代码翻译为一种可读性和 可执行性都比较好的中间代码。
三元式、四元式、静态单赋值 形式。
算法
递归下降法、语法制导翻译、 继承型翻译。
实例和案例分析
实例
对表达式 "a = b + c * d" 进行语义分析和中 间代码生成。
案例
使用LLVM对C语言代码生成中间代码。
总结
语义分析
中间代码生成
全面分析代码以及上下文,发现不符合语言规 范的代码。
将源代码翻译为可读性和可执行性都比较好的 中间代码。
“Your code isn't wrong, it's just not right yet.” "If you can't run with the big dogs, stay on the porch."
编译原理第7章 语法制导翻译和中间代码生成
• 检查静态语义 • 生成中间代码/目标代码
语义处理
语义处理的环境:符号表 • 为语义分析提供类型、作用域等信息。 • 为代码生成提供类型、作用域、存储类别、
存储(相对)位置等信息。
语义处理
PL/0编译程序的语义处理(一)call语句的处理
if sym = callsym
then
源语言程序
词法分析
前
语法分析
端
处理Biblioteka 语义分析语 义 处 理
后 端
代码生成
处
理
汇编代码
语义处理
语义处理的任务: • 静态语义检查
• 静态语义:语法规则的良形式条件 • 静态语义检查:审查静态语义
• 动态语义处理
• 动态语义:程序单元执行的操作 • 动态语义处理:生成(中间/目标)代码
语义处理
语义处理的实现: • 属性文法:描述语义规则。 • 语法制导翻译:在语法分析的同时,执行
类型的基本概念
声明和定义,使用: • 声明:
• 程序通过声明语句把标识符的名称、类型和 作用域等信息传递给编译器。
• 声明语句本身传递名字和类型信息,声明语 句的位置传递作用域信息。
• 定义:
• 变量、类的声明就是定义。 • 函数可以先声明一个原型,在定义中再给出
实现的代码。
类型的基本概念
强类型语言和弱类型语言: • 强类型语言
第七章语法制导翻译和中间代码生成
7.1语义处理概述 7.2属性文法和语法制导翻译 7.3 中间代码生成(一些语句的翻译) 7.4符号表
7.1 语义处理(语义分析和中间代码生成)
在编译中的逻辑阶段
源语言程序
词法分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
国防科技大学计算机系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)