编译原理第八章

合集下载

编译原理第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 概述
静态存储分配策略

编译原理-第八章

编译原理-第八章
依赖关系; ❖ ③ 如果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
后继语句
条件语句的语义

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

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

将if-then-else看作一个完整的操作符,则e、x和 y 分别是三个操作数,这显然是一个三元运算。根据后缀式 的特点,它的后缀式可以写为:
exy if-then-else(记为: exy¥) 但是,这样的表示有个弱点。按照算法的计算次序,e、 x和y均需计算,而实际上,根据条件e的取值,计算x则不 计算y,计算y则不计算x。
一、逆波兰表示 典型特征是操作数在前,操作符紧跟其后。 特点:由于操作符紧跟操作数之后,因此只要知道操作 符有几个操作数,每一步的运算就可以确定。
1、 表达式的表示:
例:a+b 例:-a+b*c 例: (a+b)*c ab+ a@bc*+ ab+c* <左部><表达式的逆波兰式> ::=
2、 赋值语句的逆波兰表示:
E → E1 + E2
E → E1 * E2 E → (E1) E → num
E.val := E1.val + E2.val;
val[top] := val[top]+val[top+2];
E.val := E1.val * E2.val; E.val := E1.val; E.val := num.lexval;
第八章 语法制导翻译和中间代码生成
• 教学要求:本章介绍编译程序的第三个阶段语 义分析及中间代码生成的设计原理和实现方法,
要求理解语法制导翻译、语义动作的基本概念;
掌握语义规则和中间代码的表示形式。 • 教学重点:语义规则,中间代码的表示形式, 自下而上分析制导翻译概述。
语义处理功能: • 1、静态语义审查:验证语法结构合理 的程序是否真正有意义。 • 2、解释执行动态语义、生成代码:执 行真正的翻译(生成中间代码或目标代 码)。

编译原理蒋宗礼课件第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 整理与查找
符号表作为一个多元组,表中元组的排列组织是构造符号 表的重要成分。在编译程序的整个工作过程中,符号表被 频繁地用来建立表项,找查表项,填充和引用表项的属性 。因此表项的排列组织对该系统运行的效率起着十分重要 的作用。在编译程序中,符号表项的组织传统上采用三种 构造方法。即线性法,二分法及散列法。

编译原理 第八章

编译原理 第八章
义子程序。
例 算术表达式求值的语义描述
(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等语言。在这些语言中,编译程序可以完 全确定程序中数据项所在的地址(通常为相对于 各数据区起始地址的位移量)。由于过程调用不 允许递归,因此数据项的存储地址就与过程相联 系。过程调用所使用的局部数据区可以直接安排 在过程的目标代码之后,并把各数据项的存储地 址填入相关的目标代码中,以便在过程运行时访 问这个局部数据区。在此,不存在对存储区的再 利用问题;目标程序执行时不必进行运行时的存 储空间管理,过程的进入和退出变得极为简单。
第八章 运行时存储空间组织

安徽大学《编译原理》第8章课件

安徽大学《编译原理》第8章课件

(1) ( - C D T1 )
T1 := C - D
(2) ( * B T1 T2)
T2 := B * T1
(3) ( + A T2 T3)
T3 := A + T2
(4) ( - C D T4)
或 T4 := C - D
(5) ( ^ T4 N T5)
T5 := T4 ^ N
(6) ( / E T5 T6)
S id := E { S.type := if lookup_type (id.entry) = E.type then ok else type_error }
S if E then S1 { S.type := if E.type=bool then S1.type else type_error }
• int i[3,5];
• extern float i; • float i[3,4];
3
实现符号表的数据结构
• 线性表 • 有序表 • 二叉搜索树 • Hash表
4
创建符号表的时机
• 在语义分析前,最常见的是在语法分析的
同时创建。
5
作用域的问题
• 体现符号的作用域和可见性是符号表组织
与设计的一个重要方面
并返回该名字的存储位置 || 是TAC 语句序列之间的链接运算
S id := E { S.code := E.code || gen(id .place ‘:=’ E.place) } E id { E.place := id .place;E.code:=“” }
E int { E.place := newtemp; E.code := gen (E.place ‘:=’ int .val) }

编译原理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 。

编译原理第八章

编译原理第八章

逆波兰表示很容易扩充到表达式以外的范围。
只要遵守运算对象后直接紧跟它们的运算符的规 则即可。 比如把转语句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),

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

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

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

编译原理 第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 符号表

编译原理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
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

s6 r2 r4 s4 r6
s6 r1 r3 r5 s4 s4
r2 r4
acc r2 r4
1
2
3
s5 r6
s5 s5
8
2 9
3 3 10
r6 s11 r1 r3 r5
r6
s7 r3 r5
r1 r3 r5
24
表达式2 + 3 ∗ 5的求值
25
L-属性文法的语义处理
采用自上而下的方式可以较方便地进行
在两种情况下,属性b依赖于属性c1,c2…ck
5
AX1 X2 …Xn A的综合属性S(A)计算公式 S(A):=f(I(X1),…,I(Xn)) Xj的继承属性T(Xj)计算公式 T(Xj):=f(I(A),... I(Xn))
出现在产生式左边的继承属性和出现在产生式右边的 综合属性不由所给定的产生式的属性计算规则进行计算, 它们由其它产生式的属性规则计算或者由属性计算器的参 数提供。 1)非终结符既可有综合属性也可有继承属性,例外:文法 开始符号没有继承属性. 2)终结符只有综合属性,它们由词法程序提供.
11
3*5+4的带注释的分析树
继承属性

一个结点的继承属性值是由此结点的父结点和(或) 兄弟结点的某些属性来决定的。
生 产 式 D TL T int T real L L1,id L id 语 义 规 则 L.in:=T.type T.type=integer T.type:=real
(可以只是f(c1,c2,…ck) ,此时b结点为一个虚结点)
for i :=1 to k do
从ci结点到b结点构造一条有向边
17
在某些情况下可用一遍扫描实现属性文法的语 义规则计算-------在语法分析的同时完成语义规则的 计算,无须明显地构造语法树或构造属性之间的依 赖图。
单遍实现对于编译效率非常重要
23
文法G’ [S] 的LR 分析表
(0)SE (1)E E+T (2) E T (3)T TF (4) T F (5)F (E) (6)F d
状态 0 1 2 3 4 5 6 7 8 9 10 11
ACTION
d + ( ) # E
GOTO
T F
s5 s7 r4
s4
F:关于属性的属性断言或谓词集.每个断言与一个产生式
相联.而此断言只引用该产生式左端或右端的终结符或非 终结符相联的属性(语义子程序)
4
属性通常分为两类:综合属性和继承属性。 “自下而上”传递信息 “自上而下”传递信息
属性文法中,对应于每个产生式A都有一套与之相关联的 语义规则,每条规则的形式为b:=f(c1,c2…ck) f是一个函数, b和c1,c2…ck是该产生式文法符号的属性. (1)如果b是A的一个属性,c1,c2…ck是产生式右部文法符号的 属性或A的其他属性,则称b是A的综合属性 ( 2 )如果 b 是产生式右部某个文法符号 X 的一个属性 , 并且 c1,c2…ck是A或产生式右边任何文法符号的属性 ,则 称b是文 法符号X 的继承属性
a2
a3
L.in= real

.
语句real a1,a2,a3的 分析树,采用自上而 下的分析方法
13
a1
8.2 语法制导翻译概论

在语法分析过程中,随着分析的步步进展,根据每个产 生式所对应的语义子程序(或语义规则描述的语义动作) 进行翻译的办法称作语法制导翻译。
说明: 语法制导翻译是在语法分析过程中同时进行的; 一旦用到某个产生式推导/归约时,调用相应的语义子 程序进行翻译。 目的:用语法制导翻译的方法来说明程序设计语言 的结构怎样被翻译成中间形式
integer T.type:=real
L1.in:=L.in addtype(id.entry,L.in) addtype(id.entry,L.in)
L id
L.in= real
T.type=real
real
L.in= real
. ,
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 T.val=3 F.val=3 digit.lexval=3
*
如果一个语法制 导定义仅仅使用 综合属性,则称 这种语法制导定 义为S属性定义。 通常采用自底向 上的方法对其分 析树加注释,即 从树叶到树根, 按照语义规则计 算每个节点的属 性值。
L E E T T F F
E E1+T T T1 * F F (E) digit
T.val:=T1.val F.val T.val:=F.val F.val:=E.val F.val:=digit.lexval
以3*5+4为例说明
10
综合属性val
在语法制导定义中,一条语义规则完成一个计算属性 值的动作。digit是终结符,只使用综合属性,且其属 性值由词法分析器提供,通常不要计算属性值。
8
表达式文法 E→T+T| T or T T → n | true|false
E → T1 + T2 { T1.type = int T2.type= T1.type E.type :=int T1.type = bool T2.type= T1.type E.type :=bool T.type := int
7
属性文法举例
识别语言 L = { anbncn n 1} ?
产生式 S ABC A A1a A a B B1b Bb C C1c Cc 语义动作/限定条件 {(A.num=B.num) and (B.num=C.num) } { A.num := A1.num + 1 } { A.num := 1 } { B.num := B1.num + 1 } { B.num := 1 } { C.num := C1.num + 1 } { C.num := 1 }
16
构造算法
for 分析树中每一个结点n do for 结点n所用产生式的每个语义规则中涉及的每一个属性a do
为a在依赖图中建立一个结点;
for 结点n所用产生式中每个形如f(c1,c2,…ck)的语义规则 do
为该规则在依赖图中也建立一个结点(称为虚结点);
for 分析树中每一个结点n do for 结点n所用产生式对应的每个语义规则 b:=f(c1,c2,…ck) do
语义分析工具:常用属性文法来说明程序设计语言语义
3
8.1 属性文法
属性文法(attribute grammar)是一个三元 组:A=(G,V,F)
G:是一个上下文无关文法(形式化) V:有穷的属性集,每个属性与文法的一个终结符或非终结符
相连,这些属性代表与文法符号相关信息,如它的类型、值、 代码序列、符号表内容等等 . 属性可以进行计算和传递。属性加工的过程即是语义处理 的过程(并非每个文法符号都有属性,属性与具体产生式 的语义相关)
6
非终结符A,B和C,其中A有一个继承属性a和一个综合 属性b,B有综合属性c,C有继承属性d, 对ABC可能有语义规则 C.d:=B.c+1 A.b:=A.a+B.c 而属性A.a和 B.c是在其他地方计算的。 语义规则所描述的工作可以包括属性计算、静态语 义检查、符号表操作、代码(中间)生成等等。有 些语义规则可能产生副作用(如产生代码),也可 能是个函数,通常把这样的语义规则写成过程调用 或过程段。
21
采用LR分析技术进行S-属性文法的语义处理
语义动作中的综合属性可以通过存在于当前语义栈
栈顶部分的属性进行计算 例如,假设有相应于产生式 AXYZ 的语义规则 A.a := f(X.x, Y.y, Z.z)
在 XYZ 归约为 A 之前,Z.x, Y.y, 和 X.z 分别存放 于语义栈的 top,top-1 和 top-2 的相应域中,因 此 A.a 可以顺利求出
E → T1 or T2
T→n T → true
{
{
} } } }
{ T.type := bool
T → false
{ T.type := bool
类型检查的属性文法
}
9
综合属性
在分析树中,如果一个结点的某一个属性由其子结点的属性 确定,该属性为该结点的综合属性。 产 生 式 语 义 规 则 Print(E.val) E.val:=E1.val+T.val E.val:=T.val 过程Print 打印E表达 式 的值。
第八章 语法制导 翻译和中间代码 生成
主要内容:

属性文法与语法制导翻译 中间代码:逆波兰式、三元式、四元式、抽象语 法树的表示 常见语句的翻译( 布尔表达式,控制语句,循 环,数组 )
2
语义分析
语义分析的任务:在词法分析和语法分析基础上,分析 源程序含义,在理解含义的基础上为生成相应的目标 代码作好准备或直接生成目标代码。 1)静态语义检查 类型检查、运算、维数、越界 2)语义翻译(具体的动作) 语句的翻译(中间代码或目标代码生成) 语义分析方法:大多编译器采用语法制导翻译方法
19
S-属性文法的语义处理

通常采用自下而上的方式进行
若采用LR分析技术,可以通过扩充分析栈中的域, 形成语义栈来存放综合属性的值,计算相应产生式 左部文法符号的综合属性值刚好发生在每一步归约 之前的时刻
20
采用LR分析技术进行S-属性文法的语义处理
扩充分析栈中的域形成语义栈存放综合属性的值
具体的实现希望在单遍扫描中完成翻译
一个一般的属性文法的翻译器可能是很难建立 的,然而有一大类属性文法的翻译器很容易建立
相关文档
最新文档