编译原理-第八章

合集下载

编译原理第8章

编译原理第8章

8.3 动态存储分配
TOP 临时变量 内情向量 局部变量
1. 返回地址 保存该被调过程 返回后的地址。
2. 动态链 指向调用该过程 前的最新活动记录 地址(即前一个活动 记录的地址)。
形式单元 静态链
SP 动态链 返回地址
8.3 动态存储分配
TOP 临时变量 内情向量 局部变量 3. 静态链 指向静态直接外层 最新活动记录地址的 指针,用来访问非局 部数据。
形式单元 静态链
SP 动态链 返回地址
8.3 动态存储分配
TOP 临时变量 内情向量 局部变量
4. 形式单元 存放相应的实在 参数的地址或值。
5. 局部变量 一个子程序(过程) 的局部变量。
形式单元 静态链
SP 动态链 返回地址
8.3 动态存储分配
TOP 临时变量 内情向量 局部变量 6. 临时变量 比如计算表达式过 程中需存放中间结果 用的临时值单元。 连接数据
8.2 静态存储分配
CNSUME 的代码 PRDUCE 的代码 CHARACTER * 50 BUF INTEGER NEXT CHARACTER C CHARACTER * 80 BUFFER INTEGER NEXT
代码
静态数据
该图描 述了程 序中局 部变量 的静态 存储位 置。
8.2 静态存储分配
8.1 概述
程序设计语言关于名字的作用域和 生成期的定义规则决定了分配目标程序 数据空间的基本策略。
在大部分现有编译中目标程序数据 空间的分配策略有:
8.1 概述
静态存储分配策略 分配策略
栈式动态存储分配
动态存储分配策略
堆式动态存储分配
8.1 概述
静态存储分配策略

编译原理,清华大学,第2版_第8章 语法制导翻译和中间代码生成资料

编译原理,清华大学,第2版_第8章 语法制导翻译和中间代码生成资料

3、属性的计算
•综合属性计算 –自底向上按照语义规则来计算各结点的综合属性值 •继承属性计算 –根据依赖关系决定计算顺序
例1 台式计算器程序的语法制导定义
产生式 语义规则
L E {print(Eval)} EE1+T {Eval:=E1val+Tval} E T {Eval:=Tval} TT1*F {Tval:=T1val*Fval} T F {Tval:=Fval} F(E) {Fval:=Eval} Fdigit {Fval:=digitlexval} 1、与L→E相连的语义规则是一个过程,打印E的值,理 解为L的属性是虚的或空的。 2、E,T,F的属性val都为综合属性。 3、lexval 是单词 digit 的属性(由词法程序提供)。
按照语法制导翻译的方法,对每个产生式给出相应 的语义规则。(P203 5)
8.2
语法制导翻译
1、语法制导翻译基本思想:根据翻译的需要设置文 法符号的属性,以描述语法结构的语义。随着语法分 析的进行,执行属性值的计算,完成语义分析和翻译 的任务。
注:1)语法制导翻译的依据是语义子程序。
2)每个产生式均配置一个语义子程序,当语法分 析进行归约和推导时,就调用相应语义子程序,完成 一部分翻译任务,翻译的结果是生成相应中间代码。 3)语法分析完成,翻译工作也告结束。
L→L1,id L→id
entry 单词id的属性
L1.in:=L.in
addtype(id.entry,L.in)
addtype(id.entry,L.in)
addtype 在符号表中为变量填加标识符的类型信息
D→TL T→int T→real L→L1,id
L→id
D T.type=real real

编译原理蒋宗礼课件第8章

编译原理蒋宗礼课件第8章

22
8.4.2 程序块结构符号表的其他实现
对图8.10 中的程序
...
a0 ... b0 ...
NULL NULL
(a) 处理到语句(5)时的符号表
... a0 ... b1 ... b0 NULL NULL
(b) 处理到语句(7)时的符号表
23
8.4.2 程序块结构符号表的其他实现
对图8.10中的程序
名字 符号种类 符号表表项1 符号表表项2 符号表表项3 abc i myarray ... 变量 变量 数组 int int int ... 基本属性 类型 地址 扩展属性指针 0 4 8 NULL NULL 维数 2 各维维长 3 4 扩展属性
图8.3 多种符号共用符号表的一种实现结构
11
8.1.2 符号表中的属性
19
8.4.2 程序块结构符号表的其他实现
• 将所有块的符号表放在一个大数组中,然后再引入 一个程序块表来描述各程序块的符号表在大数组中 的位置及其相互关系
名字 外层块 符号个数 起始指针 0 1 2 3 -1 0 1 1 2 1 1 1 程序块表 1 2 3 4 5 a b b b a 符号表 属性
– 如栈式存储分配时,i的地址是以栈指针sp为基址 加上i相对于活动记录起始地址的偏移量offseti
• 符号表中各符号的地址属性就是该符号相对于 第一个符号的偏移地址
13
8.3 符号表的组织结构 8.3.1 符号表的线性表实现
• 用线性表实现符号表较为直观
– 数组实现:插入n个符号、执行e次查找操作的时 间复杂度为T(n, e) = O(n(n+e)) – 有序数组实现:插入n个符号、执行e次查找操作 的时间复杂度为T(n, e) = elog n+ (log i) + i ≤ (n+e)log n+O(n2)

编译原理第8章

编译原理第8章

2
在程序的执行过程中,程序中数据的存取是通过对 应的存贮单元进行的。
在早期的计算机上,这个存贮管理工作是由程 序员自己来完成的。在程序执行以前,首先要将用机 器语言或汇编语言编写的程序输送到内存的某个指定 区域中,并预先给变量和数据分配相应的内存地址。
在有了高级语言之后,程序员不必直接和内存 地址打交道,程序中使用的存贮单元都由逻辑变量(标 识符)来表示,他们对应的内存地址都是由编译程序在 编译时或由其生成的目标程序运行时进行分配。程序 执行时,源程序中同样的名字可以指示目标机器中不 同的数据对象,本章即考察名字与数据对象的对应关 系。所以,对编译程序来说,存贮的组织及管理是一 个复杂而又十分重要的问题。 编译程序根据如何组织运行环境而生成目标代码。
• 简单变量: (以字节为单位)
– char:1,可以分配在任何地址。 – integer,short:2,对齐到2(即从能被2或4整除的
地址开始分配) – long : 4,对齐到4 – float: 4至16,对齐到相应字节数 – double(双精度型):8,对齐到8 – booleans: 1位,但常设为1个字节 • 指针:unsigned integers • 一维数组:一块连续的存储区 • 多维数组:一块连续的存储区,按行存放 • 结构(记录):把所有域(field)存放在一块存储区 • 对象:类的实例变量象结构的域一样存放在一块连续 的存储区,但方法(成员函数)不存在该对象里
即使在一个程序中每一个名字只被说明一次,同一个名 字在运行时刻仍可能代表不同的数据目标。 一个名字的说明是静态的概念,名字的联编是名字的说 明的动态副本。
7
•引进两个函数,environment(环境) state (状态) – environment把名字映射到一个存储单元上(Lvalue左-值)。 – state把存储单元映射到那里所存放的值上,即把 一个L-value(左-值)映射为一个 R-value(右-值)。如 下图所示。

编译原理第8章

编译原理第8章
第八章 符号表
6、翻译模式
P:说明语句,D:类型说明语句,id:标识符(变量名),T:类型 T T T T integer {T.type:=integer;T.width:=4} 变量名及 real {T.type:=real;T.width:=8} 其性质填 T1 {T.type:=pointer(T1.type);T.width:=4} 入符号表 array[num] of T1 {T.type:=array(num.val,T1.type); offset T.width:=num.val*T1.width} D id:T {Enter(,T.type,offset); offset:=offset+T.width} offset D D;D P D {offset:=0} 内存用户区 语义子程序(语义动作) 产生式
* a * b * @b * @ b * @
c c c c b d a+a*(b-c)+(b-c)*d的DAG a:=b*-c+b*-c的语法树 a:=b*-c+b*-c的DAG
第八章 符号表
3、与后缀式的关系:表达式的抽象语法树形式的中间代码与后 缀式等价,后缀式是抽象语法树的线性表现形式,是树的结点 序列(每个结点都在其所有子结点之后立即出现 )。
第八章 符号表
符号表的作用和地位 符号的主要属性及作用 符号表的组织
第八章 符号表
一、符号表的作用和地位
一、本章主要内容: 静态语义检查和翻译中间代码; 二、静态语义检查的内容: 类型检查、控制流检查、一致性检查、相关名字检查、 名字的作用域分析等; 三、翻译产生中间代码的优点: 便于进行与机器无关的代码优化工作、使编译程序改变目标 机更容易、使编译程序的结构在逻辑上更为简单明确; 四、静态语义检查和中间代码产生在编译程序中的地位:

编译原理编译第八章

编译原理编译第八章

一. 状态转换图的定义
有限的有向图 有向边上标记字符
x
2
唯一初态
1
若干终态(至少一个)
y
3
精选ppt
二. 状态转换图识别的串
从初态出发到某一终态路径上字符的连 接。下图是识别标识符的状态转换图:
字母或数字
字母
0
1 其它字符
* 2
精选ppt
第四节 词法分析器的设计
一. 单词符号
第四章设计的语言允许下述单词: 标识符、数字串、begin、end、integer、if、 then、else、function、read、write、
精选ppt
(9)buildlist:将token中的标识符存入符号表,并 将其在符号表中的位置填入val (10)dtb:将token中的数字串转换成二进制,并 存入常数表,位置填入val (11)val:存放标识符在符号表中的位置,或常数 在常数表中的位置 (12)return(c,val):返回二元式 (13)error:出错处理
<=
<>
类别编码
9 10 11 12 13 14
15
16
精选ppt
助记符
$FUNCTION $READ $WRITE $SUB $MUL $LT
$LE
$NE
单词符号
= > >= := ; (

类别编码
17 18 19 20 21 22 23
精选ppt
助记符
$EQ $GT $GE $ASSIGN $SEM $LPAR $RPAR
‘ : ‘: begin getchar; if character = ‘ = ‘ then return($ASSIGN,—) else error

编译原理 第八章

编译原理 第八章

② for(i=6,j=0; j<i; ++j) fun(i); 在六次循环中,i的值保持为6,则可优化为: for(i=6,j=0;j<6; ++j) fun(6);
3. 综合使用常数传播和常数合并进行优化处理 为了对保持定值的所有变量之值进行跟踪,建立一个局部符号表,使 每一个活动的变量在该表中有一个登记项,每当对这些变量进行再定 值时,就相应的修改其登记项中的内容。 例: t1=1; t1+=5; 优化为: t1=6; t2=t1; t2=6;
一. 强度削弱
用一种(或一串)执行时间较短的操作去等价的代替一个操作。 1. x*2n 替换为 x<<n (乘法用左移运算替换) x/2n 替换为 x>>n x%2n 替换为 x&(2n-1) 2. 乘以一个较小的整数可以用多个加法代替 x*=3 替换为 x1=x; x+= x1; x+= x1; 3. 较大整数的乘法可以联合使用位移和加法进行强度削弱优化 x*=9 替换为 x1=x; x*=27 替换为 x1=x; x1<<=3; x1<<=1; x+= x1; x+= x1; x1<<=2; x+= x1; x1<<=1; 4. 对于非算术运算进行强度削弱的情形 x+= x1; 例如:许多机器有多种形式的转移指令, 优化程序可以从其中选择效率更高的指令。
三. 无用变量与无用代码的删除
1. 无用变量:变量的最后一次引用到对该变量再置初值期间,可视为无用 变量。在变量的无用期间,对该变量的所有定值(如赋值)指令均可删去。 例: t=a; t+=5; x=t; …… /*此后的一个时间间隔内,t成为无用变量*/ t=c; /*在t的无用期内,对t的定值可以删除*/ …… t=b; /*t被再次置初值,无用期结束*/ y=t+a;

编译原理第八章

编译原理第八章

2013年8月21日2时45分
(3) 在符号表的信息栏中引入一个指针域(previous)用以 链接它在同一过程内的前一域名字在表中的下标(相对位 置)。每一层的最后一个域名字,其previous之值为0。这 样,每当需要查找一个新名字时,就能通过DISPLAY找出 当前正在处理的最内层的过程及所有外层的子符号表在栈 符号表中的位置。然后,通过previous可以找到同一过程 内的所有被说明的名字。
2013年8月21日2时45分
8.4 符号表的内容
符号表的信息栏中登记了每个名字的有关的性质,如类型、 种属、大小以及相对数。 对于变量名、数组名和过程名,信息栏中一般有下列信息: (1)变量 类型(整数、实、双实、布尔、字符、复、标号 或指针); 种属(简单变量、数组或记录结构); 长度(所需的存储单元数); 相对数(存储单元数); 若为数组,则记录其内情况向量。
2013年8月21日2时45分
杂凑技术
对于表格处理来说,根本问题在于如何保证查表与填表两 方面的工作都能高效地进行。对于线性表来说,填表快, 查表慢。而对于对折法而言,则填表慢,查表快。杂凑法 正是一种争取查表、填表两方面都能高速进行的统一技术。 这种办法是:假定有一个足够大的区域,这个区域以填写 一张含N项的符号表。构造一个地址函数H。对于地址函 数H有两点要求:第一,函数的计算要简单、高效;第二, 函数值能比较均匀地分布。对于杂凑技术还应设法解决 “地址冲突”的问题。
2013年8月21日2时45分
8.2 整理与查找
符号表作为一个多元组,表中元组的排列组织是构造符号 表的重要成分。在编译程序的整个工作过程中,符号表被 频繁地用来建立表项,找查表项,填充和引用表项的属性 。因此表项的排列组织对该系统运行的效率起着十分重要 的作用。在编译程序中,符号表项的组织传统上采用三种 构造方法。即线性法,二分法及散列法。

编译原理 第18讲(第八章)

编译原理 第18讲(第八章)

布尔表达式的翻译举例
例:a or b and not c 翻译成四元 b and t1 (3) t3:= a or t2
例:a < b 翻译成四元式序列, 可看成等价的条件语句 if a < b then 1 else 0 (1) if a<b goto (4) (2) t:=0 (3) goto(5) (4) t:=1 (5) ……
布尔表达式gotoetruegotoefalsegotoetruegotoefalse翻译不是最优2四元式不需要我们把该表达式放在条件语句中考虑可翻译成如下的四元式序列gotop1p1是整个布尔表达式的假出口gotop1s1elses2拉链与回填技术转移地址并不能在产生这些四元式的同时得知
第八章 语义分析
例:布尔表达式 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 ) (翻译不是最优,( )四元式不需要) 翻译不是最优,(2)四元式不需要) ,(
//在符号表中查找指定名字的标识符,如果存在则返 在符号表中查找指定名字的标识符, 在符号表中查找指定名字的标识符 回该项指针,否则返回nil 回该项指针,否则返回
过程: 过程: emit(t := arg1 op arg2);
//生成一个四元式(文本) 生成一个四元式(文本) 生成一个四元式
newtemp;
8.1 语义处理概述 8.2 属性文法和语法制导翻译 8.3 中间代码的形式 8.4 中间代码的生成 典型语句的翻译 中间代码的生成(典型语句的翻译 典型语句的翻译) 8.5 符号表

编译原理第17讲(第八章)

编译原理第17讲(第八章)

01
02
数据结构优化
选择合适的数据结构来存储和操作数 据,以减少内存占用和提高数据访问 速度。
03
循环优化
通过对循环进行展开、合并、重排等 操作,减少循环次数和提高循环效率 。
05
04
函数优化
通过对函数进行内联、外联、合并等 操作,减少函数调用开销和提高函数 执行效率。
程序性能提升的策略
优化内存管理
全局优化
针对整个程序的优化,包括函数 内联、循环展开、公共子表达式 消除等。
机器相关优化
针对特定机器指令集和硬件特性 进行的优化,如指令调度、寄存 器分配等。
常用的优化技术
无用代码删除
删除程序中不会被执行到的代 码,以及不会对程序结果产生 影响的代码。
循环展开
将循环体中的代码复制多次, 从而减少循环次数和循环控制 的开销,提高程序执行效率。
语法分析
编译器首先对源程序进行语法分析,生成 语法树(Syntax Tree)。
目标代码生成
编译器将优化后的中间代码转换成目标代 码,生成与特定计算机体系结构相关的机 器指令序列。
语义分析
编译器对语法树进行语义分析,检查源程 序的语义正确性,并进行类型检查、符号 表管理等。
优化
编译器对中间代码进行优化,提高目标代 码的执行效率。
01
目标代码(Object Code)是指编译器将源程序翻译成机器语 言后生成的代码,它是计算机能够直接执行的指令序列。
02
目标代码通常与特定的计算机体系结构相关,不同的计算机体
系结构需要不同的目标代码。
目标代码通常以二进制格式存储,可以被链接器(Linker)链
03
接成可执行文件。

编译原理 第八章

编译原理 第八章
义子程序。
例 算术表达式求值的语义描述
(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
2
r
r44rr44
S4
8 23
r
r
6
6
r
r
6
6
S4
93
S
10
4
S
S
6
11
r1
S7
r1
r1
r
r
3
3
r
r
3
3
r
r
5
5
r
r
5
5
LR分析输入串2+3*5
步骤 状态栈 语义栈(值栈) 符号栈
1
0
-
#
剩余输入串 归约动作
2+3*5#
2
05
--
#2
+3*5#
3
03
-2
#F
+3*5#
r6
4
02
-2
#T
+3*5#
r4
E { T1.t =T2.t}
{ T1.= int} T + T { T2.= int}
3
4
A为属性文法
如果对G中的某一输入串而言,A中的所有断言 对该输入串的语法树的结点的属性全为真,则该串 也是A语言中的句子。

编译原理 8章

编译原理 8章

8.1 一般原理和树变换
• 语法制导翻译法(SDTS) 一个源语言 一个目标语言 一组翻译规则 • SDTS是一个CFG(Context Free源自Grammar) 上下文无关文法。
SDTS是一个上下文无关文法
• T=(VT, VN, Δ , R , S) VT: 有穷输入字母表 VN: 有穷非终结符号集合 Δ: 有穷输出字母表 R : 一组A→w,y 规则的有穷集合 A∈VN, w∈(VT∪VN)*, y∈(Δ∪VN)* S : 开始符号
T1的基础源文法是: E→E+T|E-T|-T|T T→[E]|A A→a|b|c T1的基础目标文法则是: E→T E ADD | E T SUB | T NEG | T T→E | A A→x|y|z
8.1一般原理和树变换 8.1一般原理和树变换
一般原理(5) 8.1.1 一般原理(5)
• 一个翻译模式是一个形如(u,v)的串对,其中: u是SDTS基础源文法的一个句型,它是由VN和VT中元 素组成的串。 而v称为与其对应的翻译,它是由VN和Δ中元素组成 的串。 • 翻译模式的定义如下: ①(S,S)是一个翻译模式,且这两个S是相关的(S是 SDTS的开始符号). ②(aAb,a’Ab’)是一个翻译模式,且两个A是相关的: 此外,若A→g,g’是R中的一条规则,那么(agb, a’g’b’)也是一个翻译模式。规则中g和g’的非终结 符之间的相关性也必须带进这种翻译模式之中。
• 翻译模式是一个形如(u,v)串对 • 例如对输入串 -[a+c]-b的翻译过程 (E,E)=>(E-T2, E T2 SUB) =>(-T1-T2, T1 NEG T2 SUB) =>(-[E]-T2, E NEG T2 SUB) =>(-[E+T1]-T2, T1 E ADD NEG T2 SUB) =>(-[T3+T1]-T2, T1 T3 ADD NEG T2 SUB) =>(-[A+T1]-T2, T1A ADD NEG T2 SUB) =>(-[a+T1]-T2, T1 x ADD NEG T2 SUB) =>(-[a+A]-T2, A x ADD NEG T2 SUB) =>(-[a+c]-T2, z x ADD NEG T2 SUB) =>(-[a+c]-A, z x ADD NEG A SUB) =>(-[a+c]-b, z x ADD NEG y SUB)

编译原理课件chap08(陈火旺)

编译原理课件chap08(陈火旺)

• •
8.2.1 栈式存储分配与活动记录 使用栈式存储分配法意味着程序运 行时,每当进入一个过程(或函数)就有一 个相应的活动记录累筑于栈顶,此记录 含有连接数据、形式单元、局部变量、 局部数组的内情向量和临时工作单元等; 在进入过程和执行过程的可执行语句之 前,再把局部数组所需空间累筑于栈顶, 从而形成过程工作时的完整数据区。
TOP
临时工作单元 内情向量 简单变量 形式单元 2 1 参数个数 返回地址 老SP
SP
0
第八章 运行时存储空间组织
4 3 TOP+3 2 1 TOP SP 0
参数个数n

T2 T1 P的活动记录 现行SP值
第八章 运行时存储空间组织
8.2 简单的栈式存储分配
• 我们首先考虑一种简单程序语言的 实现,这种语言没有分程序结构,过程 定义不允许嵌套,但允许过程的递归调 用,允许过程含有可变数组。例如,C语 言除不允许含有可变数组外,就是这样 一种语言。C语言的程序结构如下:
第八章 运行时存储空间组织
• • • • • • • • •
第八章 运行时存储空间组织

满足这些条件的语言有FORTRAN,还有 BASIC等语言。在这些语言中,编译程序可以完 全确定程序中数据项所在的地址(通常为相对于 各数据区起始地址的位移量)。由于过程调用不 允许递归,因此数据项的存储地址就与过程相联 系。过程调用所使用的局部数据区可以直接安排 在过程的目标代码之后,并把各数据项的存储地 址填入相关的目标代码中,以便在过程运行时访 问这个局部数据区。在此,不存在对存储区的再 利用问题;目标程序执行时不必进行运行时的存 储空间管理,过程的进入和退出变得极为简单。
第八章 运行时存储空间组织

编译原理chapter8

编译原理chapter8

对于任意一棵树,将它重写为等价的没有上 对于任意一棵树, 述任何一种情况的树: 述任何一种情况的树:
重写成一列不含SEQ和ESEQ结点的 重写成一列不含SEQ和ESEQ结点的规范树 结点的规范树 (canonical tree); tree); 将这一列树分组组合成其内不含转移和标号的基 将这一列树分组组合成其内不含转移和标号的基 本块(basic block)集合 集合; 本块(basic block)集合; 对基本块排序并形成一组轨迹 对基本块排序并形成一组轨迹(trace),轨迹中每 轨迹(trace), 一个CJUMP之后都直接跟随它的 之后都直接跟随它的false标号 标号。 一个CJUMP之后都直接跟随它的false标号。
Moving CALLS to Top Level
Tree语言允许将 Tree语言允许将CALL结点作为子表达式。 语言允许将CALL结点作为子表达式 结点作为子表达式。 但是,在实际应用中CALL的实现是:将结果返回 的实现是: 但是,在实际应用中CALL的实现是 到同一个规定的返回值寄存器 返回值寄存器TEMP(RV)中 到同一个规定的返回值寄存器TEMP(RV)中。 举例: BINOP( PLUS, CALL(…), CALL(…)) 利用重写规则解决:将每一个返回值立即赋给一个 利用重写规则解决: 新的临时寄存器。 新的临时寄存器。
Algorithm: Algorithm:
“subexpression-extraction” method; subexpression“subexpression“subexpression-insertion” method. 给定一个已清除了所有子表达式中的ESEQ的表达 给定一个已清除了所有子表达式中的ESEQ的表达 式或语句, 式或语句,算法将生成该表达式或语句的一个新版 本。 函数do_exp和do_stm辅助函数 函数do_exp和do_stm辅助函数recorder,使得 辅助函数recorder, recorder能够根据给它的指针表从右至左地从一个 recorder能够根据给它的指针表从右至左地从一个 表达式e 中抽出语句s 表达式ei中抽出语句si 。

编译原理compiler8

编译原理compiler8
图8.1 求基本块内变量的待用信息(例8.1) 初始
9
1. 二、寄存器描述和地址描述 2. 为了在代码生成中充分利用寄存器,生成尽
可能简短的代码,将使用寄存器描述数组 RVALUE[Ri]记录寄存器Ri是空闲着,还是已 分配给某些变量;将使用变量地址描述数组 AVALUE[A]来记录变量A的现行值是存放在 某个寄存器中,还是在某个主存单元中,或 者既在寄存器中又在主存中。
12
(3) 如果已无可用寄存器,即寄存器均被占用,则
只能从被占用的寄存器中选择一个Ri,先将占用 Ri的变量的现行值逐一保存到主存单元中,然后
才可分配给x使用。选择标准是使这种复制副本的
代价尽可能小,很明显,最好选在主存单元中已
副本的占用Ri的变量,或者该变量在P以后不再被 引用或在最远的将来才会被引用。在这种情况下,
op Ri, c(Rj) (Ri)op((Ri)+c) Ri (4) 间接型:
op Ri, *Rj (Ri)op((Rj)) Ri
op Ri, *M (Ri)op((M)) Ri
op Ri, *c(Rj) (Ri)op(((Ri)+c)) Ri 5
其他操作指令的指令意义为:
(1) MOV Ri, M (2) MOV M, Ri
3
二、目标机器 目标机多种多样,要生成好的目标代码,必须熟悉目标机, 特别是指令系统的细节。作为一般讨论,我们不打算讨论 十分依赖于目标机器细节的内容,当然也不可能生成完整 的满意的代码。我们只讨论一般技术,只针对一种抽象的 目标机,它是简单的,作为各种目标机的子集,它是公共 的。 目标机具有几个通用寄存器,它们同时可作为变址器。
2
第八章 代码生成
§8.1 目标代码

编译原理8

编译原理8
产生式 (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.valF.val T.val:=F.val F.val:=E.val F.val:=digit.lexval
编译原理 计算机学院 李金厚
一个性质
考虑终结符和非终结符可能拥有属性的情 况,那么
1. 非终结符既可以有综合属性,也可以有继承 属性,但文法的开始符号是例外,它没有继 承属性 2. 终结符只有综合属性,它们由词法程序提供
编译原理 计算机学院 李金厚
属性文法:例1
简单算术表达式求值的语义描述
编译原理 计算机学院 李金厚
目标指令
5. INT 为被调用过程或主程序在运行栈中开辟 数据区;a域为开辟的单元个数 6. JMP 无条件转移指令;a为转向地址 7. JPC 条件转移指令;当栈顶的布尔变量的值 为非真时,转向a域的地址;否则,顺序地往 下执行 8. OPR 一般和运算有关;OPR的l域为0;a域 的内容决定操作的含义,见下页说明
编译原理 计算机学院 李金厚
属性依赖图
针对说明语句的语法和语义规则,对句子 real id1, id2, id3分析树给出依赖图
产生式 (0) D→TL (1) T→int (2) T→real (3) L→L1, id1 (4) L→id2
语义规则 L.in=T.type T.type:=integer T.type:=real L.in:=L.in addtype(id1.entry, L.in) addtype(id2.entry, L.in

编译原理第八章

编译原理第八章

逆波兰表示很容易扩充到表达式以外的范围。
只要遵守运算对象后直接紧跟它们的运算符的规 则即可。 比如把转语句GOTO L写为“L jump ", 运算对象L为语句标号,运算符jump表示转到某个标 号L 。 再比如条件语句if E then S1 else S2 可表示为:ES1S2¥,把if then else看成三目运 算符,用¥来表示。
生成后缀式的属性文法 产生式 语义规则 S→id:=E Print( || E.code || ―:=‖)
E→E1+E2 E.code := E1.code || E2.code || ‖+‖ E→E1*E2 E.code := E1.code || E2.code || ‖*‖ E.code := E1.code || ―-― E→ -E1 E→ (E1) E.code := E1.code E.code := E→ id E→ num E.code := num.val; 属性 code 表示生成的代码
句子 int id1,id2 的语法树,使用 情况。
表示属性的传递
S-属性定义(S-属性文法)
仅包含综合属性的语法制导定义
如:算术表达式求值的属性文法
L-属性定义(L-属性文法)

既包括综合属性,又包括继承属性,即对 于所有A→X1 X2 … Xn,每一个属性 都是一个综合属性,或者Xi 属性计算仅 使用A X1 X2 … Xi-1 的属性
假如语法分析方法是自下而上的。在用某 一产生式进行归约的同时就执行相应的语 义动作,在分析出一个句子时,这个句子 的"值"也就同时产生了
3、属性文法的定义:
一个属性文法是一个三元组: A=(G,V,F),

编译原理chapter8 代码生成

编译原理chapter8 代码生成

精品文档
11
MOV top, sp
ADD #caller.recordsize,top 返回序列包括两个部分: GOTO *0(SP)/*返回到调用过程*/ MOV sp, top SUB #caller.recordsize, SP 8.2.3 名字的运行地址 x:=0 静态分配区域的开始地址是static, x的相对地址12,则x的实际地 址应为static+12。 static [12]:=0
算法8.1 划分三地址程序形成基本块
输入:一个三地址语句序列。 输出:一个基本块表,其中每一条三地址 语句仅在一个块中。 方法:
ADD #caller. recordsize,SP/*将调用过程
的活动记录的长度加入到SP中*/ MOV #here+16,*SP/*存储返回地址*/ GOTO callee.code-area/*转移到被调用过
程的代码的第一条指令*/ 属性caller.recordsize代表一个活动记录的大小。
精品文档
12
如果静态区域是从地址100开始,则上述语 句的目标代码为: MOV #0,112
栈式分配,用一个display表存取非局部名
字,又假定该display表是存放在一些寄存器 中,并且x是局部于一个活动记录的变量,该 活动记录的display表指针在寄存器R3中,那 么,x:=0翻译成为如下三地址语句; t1:=12+R3 *t1:=0 其中t1中存放的是x的地址。
*/ action1 call p action2 halt /*p的代码 */ action3 return
S的活动记录 p的活动记录 返回地址 返回地址
arr
buf
i
n
j
精品文档
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
依赖关系; ❖ ③ 如果q是某个产生式中文法符号V的继承属性,
那么,属性q的值仅依赖于该产生式右部位于V左边 的符号的属性。
8.6 中间代码形式
中间代码形式是指用来表述源程序并与之等效的一 种编码方式,可根据具体情况将它设计成各种形 式。 8.6.1 逆波兰表示法 特点:运算符直接写在其运算对象之后。 ❖ 不再有括号 ❖ 运算对象出现的次序未变,同一层中运算符则按 其优先级出现 ❖ 求值过程简单
❖ 除了最右边的w之外,(输出)终结符不可能出现 在翻译成分之中,那么,称这个SDTS为简单后缀 的(Simple Post Fix)。
❖ 定理8.2 对其基础源文法为LR(k)的每一简单后缀 的SDTS,存在一确定的LR(k) PDT, ①它接收从该 基础源文法可推导出的每一句子;②它将这种句 子的翻译作为输出。
对应的抽象代码形成
8.7 属性翻译文法的应用
由以上分析可将原文法改造成:
ST else S2, Sub1
①生成 S2 的中间代码 ②设置位置标号 12
TI then S1, Sub2
① 生成 S1 的中间代码 ② 生成无条件转 12 的代码 ③ 设置位置标号 11
① 生成计算 E 的中间代码 Iif E, Sub3 ② 生成若 E 之值为 false, 则转 11 的中间代码
8.7 属性翻译文法的应用
8.7.4 条件语句的翻译 基本思路: ❖ ① 先对定义它的文法进行改造,以便能在相应处添
加上语义子程序; ❖ ② 根据它的语义,设计出相应语义子程序的动作。
8.7 属性翻译文法的应用
计算 E
true
false
执行 S1
执行 S2
后继语句
条件语句的语义
① 计算E ② 若E之值为false,则转⑤ ③ 执行S1 ④ goto ⑥ ⑤ 执行S2 ⑥ (后继语句)
8.6 中间代码形式
8.6.2 逆波兰表示法的推广 只要遵循将算符直接写在运算对象之后的原则,则可推 广之。
8.6.3 四元式 一般形式:〈运算符〉〈运算量1〉〈运算量2〉〈结果〉 ❖ 出现的次序是对应语法成分的计算次序 ❖ 可以随时引进临时工作变量,之间的联系通过临时变量
进行的 ❖ 调整四元式的位置比较容易 ❖ 过多引进临时变量,导致存贮空间的浪费
❖ 通常规定:每个文法符号的继承属性和综合属性之 交集为空。
8.5 属性文法
8.5.1 L属性文法 L属性文法也称为自上而下的属性翻译文法,适合 于用来指导自上而下的分析过程。其定义如下:
❖ ① 产生式右部任一文法符号V的继承属性仅依赖于 下述两种属性值中的一种:
i) 产生式左部的继承属性; ii) 产生式右部但位于V左边的符号的任何属性。
Case e of 3: S1; 5: S2; 9:S3
end
3
标号
S2
Case 语句
5
标号
S3
nil
9
CASE语句的AST
8.5 属性文法
❖ 属性文法(Attribute Grammar)也称为属性翻译文 法。属性文法以上下文无关文法为基础,只不过为 每个文法符号配备了一些属性。属性分为两种,一 种称为继承属性(Inherited Attribute),另一种称 为综合属性(Synthesized Attribute)。
如果SDTS的基础源文法是二义性的,那么就不存在 确定的PDT。若SDTS的基础源文法是LL(1),那么, 它的PDT是确定的,而且对每一个可接收的输入串 恰好存在一个翻译。
8.3 简单后缀SDTS和自下而上翻译器
❖ 如果一个SDTS是简单的,而且它的每个翻译规则 都有下述形式:Aa0B1a1B2a2…Bkak,B1B2…Bkw
SC S(1)
{Backpatch (S(n1e)xt , Cguad);Snext := Cfalse;
GEN (goto Cguad)}
8.7 属性翻译文法的应用
for i := 1 step 1 until n do A[i]:= 0 对应的四元式序列为 :
(100) :=
1 @INDEX
(101) :=
❖ ① 从中剪掉终结符号结点; ❖ ② 根据适当的翻译规则,重排每个中间结点的孩子; ❖ ③ 添加对应于输出符号集中的终结符结点。
8.2 简单SDTS和自上而下翻译器
❖ 如果每一规则的翻译成分中,非终结符出现的次序 与它们在源成分出现的次序相同,则称一个SDTS是 简单的(simple)。
❖ 定理8.1 如果T=(VN, VT, , R, S)是其基础源文法为 LL(k)的简单SDTS,那么,存在一个自上而下的确 定的下推翻译器PDT(Push–Down Translater),它接 收T的输入语言中的任何符号串并产生对应的输出 串。
此 外 , 若 Ag, g 是 R 中 的 一 条 规 则 , 那 么 (agb, agb)也是一个翻译模式。规则中g和g的非终结符 之间的相关性也必须带进这种翻译模式之中。
8.1 一般原理和树变换
8.1.2 树变换 语法制导的翻译过程可用语法树来说明,可看做从 一棵树到另一棵树的变换,其变换过程如下:
❖ AST也可作为一个多遍编译程序的中间语言结构。采 用AST表示法有助于代码的产生和优化。
8.4 抽象语法树的构造
将语法树简化成一个AST的方式: ❖ 去掉与单非产生式相关的子树,并上提相关分支
上的终结符结点。如果第一棵语法子树也对应于 某个单非产生式,则去掉根结点及其连线。 ❖ 对于直接包含运算符的多个子树,上提运算符并 让它取代其父结点。 ❖ 去掉括号,并上提运算符,让它取代其结点。最 后得到的语法树便是一个AST。
8.7 属性翻译文法的应用
8.7.5 迭代语句的翻译
❖ 形式:Swhile E do S
❖ 用于翻译这类循环的属性翻译文法是
Wwhile {Wguad := Nextguad; }
CW E do {Cguad :=Wguad; Backpatch (Etrue, Nextguad); Cfalse:=Efalse}
8.3 简单后缀SDTS和自下而上翻译器
8.3.1 后缀翻译 8.3.2 IF–THEN–ELSE控制语句 ❖ 将原来的单一产生式拆成三个产生式 ❖ 引进含“then”和“else”关键字的产生式 ❖ 使用空产生式来实现 8.3.3 函数调用
8.4 抽象语法树的构造
❖ 抽象语法树AST(Abstract-Syntax Tree)是某个语言 结构的一种简洁的树形表示形式,它只需包含该结 构尚须转换或归约的信息。任何语法结构(例如表 达式、控制结构和说明)都可以用AST表示。
8.4 抽象语法树的构造
8.4.1 自下而上构造AST 8.4.2 AST的拓广 AST也可表示数组元素、 过程调用、控制结构和 说明等
ARRAY 访问
x
e1
e2
en
x(e1, e2, …, en)
数组访问(或过程调用)的AST
8.4 抽象语法树的构造
CASE
e
Case 语句
标号
S1
Case 语句
1
X1
(102) :=
n
X2
(103) >@INDEX
X2 T1
(104) jumpf (106) T1
(105) jump –
(106) “语句A[i]:= 0的代码”…
+ @INDEX X1 T2 := T2 @INDEX jump (103)
The end.
(q, a, Y)包含(r, g, z)
8.2 简单SDTS和自上而下翻译器
如果P满足下述两个条件,则称P是确定的:
❖ ① 对所有的状态q,输入串a和栈符号Z, (q, a, Z)至 多只包含一个元素。
❖ ② 若(q, , Z)非空,则不存在符号a(a)使得(q, a, Z)非空,即对于某个状态和栈符号,在空移动和非 空移动之间不应存在冲突。
8.7 属性翻译文法的应用
8.7.3 布尔表达式到四元式的翻译 ❖ 作用:用做控制条件;计算逻辑值。 ❖ 文法:BBBBBB(B)idB rop B
其中,、、为布尔(逻辑)运算符;rop为关系 运算符(>,≥,,≤,=,≠);id为布尔(逻辑) 变量或布尔(逻辑)常数;B rop B为关系表达式。 ❖ 布尔表达式的求值方法: ① 通过逐步计算出各部分的值来计算整个表达式。 ② 利用布尔运算符的性质计算其值
第八章 语法制导翻译法
❖ 语法制导翻译法,就是在语法分析的过程中, 依随分析的过程,根据每个产生式添加的语义动 作进行翻译的方法。
❖ 本章介绍语法制导翻译法的基本原理及其在中 间代码生成中的应用。
8.1 一般原理和树变换
8.1.1 一般原理 ❖ 语法制导翻译法(SDTS)由一个源语言、一个目标
语言和一组翻译规则组成,这组规则可将任何源语 言符号串翻译成对应的目标语言串。SDTS的翻译规 则是文法中的产生式再添加上语义动作。
难,不便于优化
8.7 属性翻译文法的应用
8.7.1 综合属性与自下而上定值 每个非终结符的属性值都是根据位于其下面那些符 号的属性值来确定的,即按一种自下而上的方式来 确定的。
8.7.2 继承属性和自上而下定值 非终结符〈V list〉的属性值或者根据其上层非终结 符的属性来确定或者根据产生式右部其它符号的属 性来确定。这种属性值是根据自上而下方式确定的。
❖ 什么叫SDTS?——为每个产生式配一个语义子程 序,在语义分析过程中,在选用某个产生式的同时, 调用配备的语义子程序来完成相应的翻译工作的一 种方法。
8.1 一般原理和树变换
SDTS的形式定义为: ❖ SDTS是一个五元组T=(VT, VN, , R, S),
其中,VT是一个有穷的输入字母表 ,包含源语言中的符号; VN是一个有穷的非终结符号集合; 是一个有穷的输出字母表,包含出现在翻译串或输出串
相关文档
最新文档