【编译原理课程徐旭东老师课件@北工大】part8
编译原理简明教程(第2版)第8章
④ 若NODE(A)=null,则把A附加到结点n,并令NODE(A)= n;否则,先 从NODE(A)的附加标记集中将A删去(注意,若NODE(A)有前驱或 NODE(A)是叶结点,则不能将A删去),然后再把A附加到新的结点n, 并令NODE(A)= n。
例:构造以下基本块的DAG
(1) (:=, 3.14, _, T1) (2) (*, 2, T1, T2) (3) (+, R, r, T3) (4) (*, T2, T3, A) (5) (:=, A, _, B) (6) (*, 2, T1, T4) (7) (+, R, r, T5) (8) (*, T4, T5, T6) (9) (-, R, r, T7) (10) (*, T5, T7, B)
8.1.3
优化技术简介
Байду номын сангаас
1、合并常量运算
运算对象是常量或在编译时已知,则在编译时直接计算 出结果,不必等到运行时再去计算。
例: x := 3.14 * 2 ; y := 2 * 5 * a ; z := x + 0.5 ;
合并常量元算后: x := 6.28; y := 10 * a ; z := 6.78 ;
优化可在编译的不同阶段进行:
源代码设计阶段 ------
程序员选择好的算法和语句
语义分析阶段
------ 如何生成高质量的中间代码
中间代码 ------ 采用优化技术
目标代码
------ 有效利用寄存器、指令、处理机
8.1.2
代码优化的分类
1、与机器的相关性 与机器有关的优化:寄存器的优化、多处理机的 优化、特殊指令的优化、无 只有一个 用代码的消除。 入口和一 与机器无关的优化:基本块的优化、循环优化。 个出口 2、优化范围 局部优化:基本程序块上进行的优化 全局优化:全局程序范围内的优化
编译原理,清华大学,第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、解释执行动态语义、生成代码:执 行真正的翻译(生成中间代码或目标代 码)。
编译原理课程.doc
《编译原理》课程教学大纲课程代码:课程名称:编译原理/Compile Principle课程类型:专业课学时学分:48学时/3学分适用专业:计算机科学与技术开课部门:灾害信息工程系一、课程的地位、目的和任务《编译原理》是计算机专业的一门重要的专业基础课程,它的主要任务是系统地介绍编译程序的基本原理、基本实现方法,编译方面的最新技术及其研究发展方向。
通过本课程的学习,应使学生掌握高级程序设计语言的编译原理及其基本实现技术,了解编译方面的最新技术发展和研究方向,具有设计、实现编译程序的基本能力。
二、课程与相关课程的联系与分工编译原理与操作系统原理、数据库系统原理、计算机系统结构关系密切同时它的研究对象是计算机语言的编译过程,所以本门课程的先修课是高级语言程序设计、数据结构、操作系统原理、数据库系统原理、计算机系统结构。
通过教学使学生了解、掌握高级语言编译程序构造的一般原理和基本实现方法。
即:词法分析--语法分析--中间代码生成--优化--目标代码生成。
而且,编译技术所涉及的建模技术同样适合其他软件的建模,也帮助学生提高运用所学知识进行独立分析问题和解决问题的能力。
本课程的后续课程是计算理论。
三、教学内容与基本要求课程内容要按章、节、目的顺序列出,并按“了解”、“理解”和“掌握”等层次,对主要“知识点”、“能力点”提出基本要求。
同时指明教学的重点和难点所在。
大学计算机基础、体育等课程也可以根据内容分块。
第一章概述1.教学内容1.1 程序设计语言与翻译程序1.2 编译过程和编译程序的结构1.3 编译程序的构造1.4 编译程序的发展与应用1.5 小结1.6 习题2.重点难点重点:通用程序设计语言的主要特征;编译器在计算机系统中的地位和作用;编译器的基本工作原理;编译器各个阶段的工作与任务;编译器的编写工具。
难点:编译器的基本工作原理。
3.基本要求理解什么是编译程序,了解编译程序工作的基本过程及其各阶段的基本任务,熟悉编译程序总体框架,了解编译程序的生成过程和构造工具。
北京航空大学本科编译原理课件
123是汇编程序、编译程序以及各种变换程序的总称。
4567891011121314151617181920一遍扫描即可完成整个编译工作的称为一遍扫描编译程序 其结构为: S.P.取单词 返回单词 词法分析 整理目标程序 停机 语法分析 语法成分 返回分析结果 语义分析生成 目标程序O.P.北京航空航天大学计算机学院21三、前端和后端 根据编译程序各部分功能,将编译程序分成前端和后端。
前端:通常将与源程序有关的编译部分称为前端。
词法分析、语法分析、语义分析、中间代码生成、 代码优化 -------分析部分 特点:与源语言有关后端:与目标机有关的部分称为后端。
目标程序生成(与目标机有关的优化) -------综合部分 特点:与目标机有关北京航空航天大学计算机学院 22四、 编译程序的前后处理器源程序:多文件、宏定义和宏替换(调用),包含文件 目标程序:一般为汇编程序或可重定位的机器代码框架源程序 预处理器 源程序 编译程序 目标程序(汇编) 汇编程序 可运行的机器代码 可重定位机器码 (Obj文件)北京航空航天大学计算机学院 23可重定位机器码 (文件组) 连接编辑 可执行文件 加载器 库目标、可重 定位目标文件1.4 编译技术的应用[ 语法制导的结构化编辑器 [ 程序格式化工具 [ 软件分析与测试工具 [ 程序理解工具 [ 高级语言的翻译工具 [ 等等北京航空航天大学计算机学院24。
【编译原理课程徐旭东老师课件@北工大】part6
c,c1,c2,…,ci-1是A, X1,X2,…,Xi-1的属性
如:例6-2 L.in
这种属性叫做继承(Inherited)属性
8/20/2012
20
3. 属性分类——继承属性
A→X1X2…Xn Xi.in=f(c,c1,c2,…,ck)
A
c
1≤k<i≤n x1
c1
x2 … xk
c2 ck Xi.in
31
8/20/2012
非S-属性定义
D→T L
T→int
L.in := T.type
T.type := „integer‟
继承
固有
T→real
T.type := „real‟
固有
继承
L→L1,id L1.in := L.in L → id
8/20/2012
addtype(id.entry, L.in)
addtype(id.entry, L.in)
32
6.L-属性定义(L-属性文法)
包含综合属性和继承属性的属性文法 (语法制导定义)
L-attributed Definition L-attributed Grammar 如:算术表达式求值的属性文法、说明 语句的属性文法
8/20/2012
综合属性
A→X1X2…Xn
A.s=f(c1,c2,…,ck)
A
A.in
A.s
x1 c1
x2 c
2
xn c
n
8/20/2012
26
3. 属性分类——固有属性
语言中的标识符、常数(数值的、符号 的)、常量,它们的属性是用户给定的、 不变的
北方工业大学《编译原理》期中试卷2019
北方工业大学《编译原理》课程期中答案2019年春季学期开课学院:信息学院考试方式:闭卷考试时间:95分钟班级姓名学号 1. 编译程序的输出是机器语言语言程序。
2. 一个上下文无关文法包含一组开始符号和一组终结符号。
3. 一个文法具有二义性,是该文法有两个不同的推导方式。
4. 词法分析时,单词符号有五种类别,其中常数没有属性信息。
5. 语法分析时,必须先消除文法中的左递归。
6. 构造LR 分析器的任务就是构造LR 分析表。
7. 递归下降分析法是自上向下分析法。
8. 某计算机上的某编译程序在另一台计算机上能直接使用的必要条件是两台计算机的操作系统功能完全相同。
9. LL(1)文法是无二义的文法。
10. SLR 分析法的S 是简单的意思。
1. ×;2. ×;3. ×;4. ×;5. ×;6. √;7. √;8. ×;9. √; 10 .√。
A .词法分析器B .语法分析器C .语义分析D .目标代码生成器 2、下列对编译程序描述正确的是( )。
订线装( ) ( ) ( ) ( )( ) ( ) ( ) ( ) ( ) ( )A.编译程序能把一种语言程序转换成另一种语言程序B.编译程序只是对高级语言的翻译C.链接程序只有链接功能D.优化是对目标代码的优化3、已知下列文法G[S],请问它的语言是()。
G[S]: S→dAA→aA | aA.{d m a n|n>1, m>1} B.{da n|n>0}C.{da n d|n>=1} D.{a n d|n>0}4、下列正规表达式中与(a* | b*)c等价的表达是()。
A.a *c| b*c B.a* | b*c C.a *c | b* D.(a | b)*c5)。
A.以1开头的二进制数组成的集合B.以0结尾的二进制数组成的集合C.含奇数个1和0的二进制数组成的集合D.以1开头,0结尾的二进制数组成的集合6、DFA与NFA的描述正确的是()。
东北大学秦皇岛分校编译原理课件 第五章
是LL(1) 文法!!
FIRST(*FD)={*}, FOLLOW(D)=FOLLOW(T)=FIRST(B)FOLLOW(B)={+,#,)}
对于F,只需要考虑FIRST集合:FIRST((E))={(},FIRST(i)={i},交为空。 12
G[ E]:
(1) (4) (7)
E –> TE’ T –> FT’ F –> (E)
增加新的非终结符号 将形如U→y1|y2|…|ym|Ux1|Ux2|…|Uxn 的规则改写成: U→y1 A |y2 A |…|ym A A → x1 A |x2 A |…|xn A| ε
23
消除左递归
例:E → E+T|T T →T*F|F F →(E)| a
G[ E]: (1) (3) (5) (7) E → TE’ E’ → F → (E) (2) E’ → +TE’ (4) T → FT’ (8) F →a
9
如何计算FOLLOW集合
FOLLOW(U)是由文法的所有句型U的后继终结符 或“#”组成的。 求FOLLOW(U)的算法为:
(1)如果U为文法的识别符号,令#∈FOLLOW(U); (2)如有形如 A→U 的规则,则 FIRST( )中非 ε 的元素属于 FOLLOW(U); (3)如有形如 A →U 或 A →U 而 FIRST()含有 ε 元素这样的 规则,则 FOLLOW(A)的元素属于FOLLOW(U)。 注:(2)(3)即为规则A→U 中, 可为ε或有 →ε的情况。
E’ –> +TE’ |
14
课堂练习:判断文法G[S]是否为LL(1)文法
G[S]: S →AB A →bBC C →aC| ε B →a|Sb
编译原理简明教程(第2版)[冯秀芳,崔冬华,段富][电子教.pptx
#include <stdio.h> int lineno = 1; %}
number {digit}+(\.{digit}+?(E[+]?{digit }+)?
line
*.\n
%%
13.2 词法分析自动生成工具 13.2.1 LEX系列词法分析自动生成工具简介
{ws} if
{ /* 没有动作或没有返回 */ } {return (IF);}
2. 第1和第2个双百分号之间出现的是:规则部分,由一系列带有C代码的正则表达 式组成,每个转换规则的格式为 模式 {动作};其中每个模式是一个正则表 达式,可以使用声明部分给出的正则定义。当匹配相对应的正则表达式时,这些 动作对应的C代码片段就会被执行。
3. 第2个双百分号之后出现的是:规则部分各个动作需要使用的所有辅助函数,这 部分是可选内容。
13.2.1 LEX系列词法分析自动生成工具简介
2.正则表达式的Lex约定
正则表达式(regular expression):是一种可以用于模式匹配和替换的强有力 的工具。
【例13.2】为一个带符号的数集写出正则表达式,这个集合可能包含一个小数 部分或一个以字母E开头的指数部分。
参考解答: (“+”|“-”)?[0-9]+( “.” [0-9]*)?(E(“+”|“”)?[0-9]+)?
“<=”
{yylval = LE; return(RELOP);}
“=” “<>”
{yylval = EQ; return(RELOP);} {yylval = NE; return(RELOP);}
“>”
{yylval = GT; return(RELOP);}
【编译原理课件2@北工大】part9
例2-1: 表达式计算 (优先级处理)
可 提 高 效 率 ,
可 处 理 二 义 性 文 法
expr : expr '+' expr { $$ = $1 + $3; } | expr '-' expr { $$ = $1 - $3; } | expr '*' expr { $$ = $1 * $3; } | expr '/' expr { $$ = $1 / $3; } | „(„ expr „)‟ { $$ = $2; } | „-‟ expr %prec UMINUS { $$ = - $2; } | NUMBER ; %% yylex( ) { int c; while( (c=getchar()) == „ „ ); if( c!=„.‟ && !isdigit(c) ) return c; ungetc( c, stdin ); // 回退字符 scanf( “%f”, &yylval ); return NUMBER; }
设置单词种别
设置单词属性
整数的值、标识符的符号表入口 Lookup( text ) 用于获得符号表入口
词法规格说明例
定义部分见下页 %% if then while do 0 | [1-9][0-9]* [A-Za-z][A-Za-z0-9]* . %% { { { { { return IF; } return THEN; } return WHILE; } return DO; } yylval = atoi(yytext); return INT; } { yylval = Lookup(yytext); return IDEN; } { printf(“Error: %s”, yytext); }
北航编译原理课件 08.错误处理
北京航空航天大学计算机学院
3.目标程序运行时错误检测与处理 目标程序运行时错误检测与处理. 目标程序运行时错误检测与处理 下标变量下标值越界 计算结果溢出 动态存储分配数据区溢出 · 在编译时生成检测该类错误的代码。 在编译时生成检测该类错误的代码。 对于这类错误,要正确的报告出错误位置很难,因为 对于这类错误,要正确的报告出错误位置很难,因为 要正确的报告出错误位置很难 目标程序与源程序之间难以建立位置上的对应关系 一般处理办法: 当目标程序运行检测到这类错误时,就调用异常 处理程序,打印错误信息和运行现场(寄存器和存储 器中的值)等, 然后停止程序运行。
有时候报错不一定十分准确 位置和性质), ),需进一步分析 (位置和性质),需进一步分析
:= B+ *C
缺“]”or n 表达式语法错 m
错误编号
例
begin ........ i := 1 step 1 ............ end
until n do
北京航空航天大学计算机学院
8
8.4 错误处理技术
发现错误后, 发现错误后,在报告错误的同时还要对错误进行 处理,以方便编译能进行下去。目前有两种处理办法: 处理,以方便编译能进行下去。目前有两种处理办法: 1. 错误改正:指编译诊察出错误以后,根据文法进 错误改正:指编译诊察出错误以后, 行错误改正。 行错误改正。 如:A[i , j :=B+*C 但不是总能做到,如 但不是总能做到 如A:=B-C*D+E) 2. 错误局部化处理:指当编译程序发现错误后,尽可 错误局部化处理:指当编译程序发现错误后, 能把错误的影响限制在一个局部 的范围, 的范围,避免错误扩散和影响 程序其他部分的分析。 程序其他部分的分析。
071编译原理习题(全)@北工大
检验:语言所有的句子均可由文法 G[S]推导出来, 文法 G[S]推导出来的所有终结符号串均 为语言 L(G[S])的句子.
例 6 设有文法 G[S]:
S→S*S|S+S|(S)|i
该文法是否为二义文法?
【解】该文法是二义文法,因为该文法存在句子 i*i+i,该句子有两棵不同的语法树如图 2
a.E→T|Eθ1T|Eθ2T T→F|Tθ3F F→(E)|I
b. E→T|Tθ1E|Tθ2E T→F|Fθ3T F→(E)|I
c. E→T|Eθ3T T→F|Tθ1F|Tθ2F
4
F→(E)|I
d. E→T|Tθ3 E
T→F|Fθ1T|Fθ2T
F→(E)|I
【解】对于一个包含运算符的语言,运算符的结合顺序、运算符的优先级在文法中反映为递
由于只关心0的个数的奇偶数我们可以把二进制串分成多段来考虑第1段为二进制串的开始到第1个0为止这一段包含1个0并且0的前面有0个或多个1对于剩下的二进制串按照每段包含两个0的方式去划分即以0开始以0结尾中间可以有0个或多个1如果一个二进制串被这样划分完后剩下的部分如果全部是全1串这些1串在前面划分的串之间或最后则该二进制串就具有奇数个0所以该二进制可以这0组成所以包含奇数个0的正规表达式为
语言和文法
重点与难点
重点:文法、推导与归约、短语与句柄。 难点:文法、推导、归约、短语、句柄、文法的二义性、用文法表示语言。
基本要求
掌握语言的描述、形式定义、文法、文法分类的概念以及形式文法的应用,了解二义性 文法,熟练掌握推导与规约、短语与句柄及用文法描述语言、正则语言、上下文无关文法、 语法分析树。
此文法所表示的语言是什么? 【解】
北航编译原理课件 04.语法分析
北京航空航天大学计算机学院
12
规则二 若有文法规则: ∷ 若有文法规则:U∷=x|y|……|z|Uv 其特点是:具有一个直接左递归的右部并位于最后, 其特点是:具有一个直接左递归的右部并位于最后, 这表明该语法类U是由 是由x或 这表明该语法类 是由 或y……或z其后随有零个 或 其后随有零个 或多个v组成 组成。 或多个 组成。 U⇒Uv ⇒ Uv v ⇒ Uv vv ⇒ …… ⇒ 可以改写为U∷ ∴ 可以改写为 ∷=(x|y|……|z){v} 通过以上两条规则,就能消除文法的直接左递归, 通过以上两条规则,就能消除文法的直接左递归, 并保持文法的等价性。 并保持文法的等价性。
北京航空航天大学计算机学院 21
效率低的原因 1) 语法分析要重做 2) 语义处理工作要推倒重来 设文法G(不具左递归性),U 设文法 (不具左递归性), ∈Vn ), U::= α 1 | α 2 | α 3
R∷=Sa|a ∷ Q∷=Sab|ab|b ∷
S∷=Sabc|abc|bc|c ∷ S∷=(abc|bc|c){abc} ∷
北京航空航天大学计算机学院
19
最后得到文法为: 最后得到文法为 S∷=(abc|bc|c){abc} ∷ Q∷=Sab|ab|b ∷ R∷=Sa|a ∷ 可以看出其中关于Q和R的规则是多余的规则 可以看出其中关于 和 的规则是多余的规则 ∴经过压缩后 S∷=(abc|bc|c){abc} ∷ 可以证明改写前后的文法是等价的
否则 S ∉ L(G[Z])
主要问题: 主要问题 左递归问题 回溯问题
主要方法: 主要方法 • 递归子程序法 • LL分析法 分析法
北京航空航天大学计自底向上分析算法的基本思想为:
+ 若Z ⇐ S
精品课程编译原理-PPT课件第8章 语法制导与中间代码生成
(3)一致性检查。在很多场合要求对象只能被 定义一次。例如Pascal语言规定同一标识符在一 个分程序中只能被说明一次,同一case语句的标 号不能相同,枚举类型的元素不能重复出现等等。
(4)上下文相关性检查。比如,变量名字必 须先声明后引用;
(5)名字的作用域分析。各变量的作用域可 能是不一样的,要通过分析明确各变量的作用域。
例子: a:=b*c+b*d的相应三元组
①(*, b, c) b*c ②(*, b, d) b*d ③(+, (1),(2)) b*c+b*d ④(:=,(3), a) a:=b*c+b*d
例子:tri(A*B+C) =tri(A*B)||tri(c)||2:(+,①≥,C) =1:(*, A,B) A*B 2:(+,①,C) A*B+C
8.2.2 S-属性文法和自下而上翻译 一般的属性文法的翻译器很难建立,然 而L-属性文法的翻译器很容易建立。
L-属性文法的一个特例叫S-属性文法。 S-属性文法是只含有综合属性的属性文法。
8.2.3 L-属性文法在自下而上分析中实现 L-属性文法允许一次遍历就计算出所以的 属性值。
8.3 中间代码的形式
3*5+6的带注释的分析树
只使用综合属性.
T.val=3 F.val=3
E.val=15 T.val=15
*
L
E.val=21
+
F.val=5
T.val=6 F.val=6 digit.lexval=6
digit.lexval=5
digit.lexval=3
3*5+6的带注释的分析树
继承属性
一个结点的继承属性值是由此结点的父结点和/或兄弟结 点的某些属性来决定的。
《编译原理》课件
六、代码生成
了解目标机器的指令系统和存储结构,以及它们对代码生成的影响。 学习寄存器分配和目标代码生成的基本原理和方法。
七、附录
参考文献提供了进一步学习编译原理的资源。 课程总结将回顾课程中学到的重要知识,并概述关键概念和技术。 问题解答将回答学生在课程学习中提出的问题。 课程评价将收集学生对课程的反馈和评价,以便对将来的课程进行改进。
《编译原理》PPT课件
编译原理PPT课件将带您深入了解编译原理的重要概念和技术。这个课程介绍 了编译原理的意义以及编译过程的概述。
一、引言
课程介绍编译原理的重要性,让您理解为什么编译原理对于软件开发非常关 键。 编译过程的概述将带您了解传统的编译过程中涉及的各个阶段和任务。
二、词法分析
词法分析是编译过程中的第一步,了解词法分析的作用以及它在编译器中的 实现。 掌握正则表达式和有限自动机的概念,这些是实现词法分骤,理解它的作用和不同的语法分析方法。 学习上下文无关文法以及LL(1)语法分析器和LR(1)语法分析器的实现原理。
四、语义分析
语义分析是编译过程中的重要一环,了解它的作用和涉及的任务。 学习语义动作、符号表管理和类型检查,以及如何进行语法制导翻译。
五、中间代码生成
整套课件:编译原理(北京工业大学)
第1章 引论
• 1.1 计算机语言的发展 • 1.2 翻译系统 • 1.3 编译系统的功能分析 • 1.4 编译程序总体结构 • 1.5 编译程序的生成
• 1.6 编译技术的应用
1.1 计算机语言的发展
• 机器语言(Machine Language) • 汇编语言(Assemble Language)
– 辅助语法检查、语义检查 – 完成静态绑定、管理编译过程
• Hash表、链表等各种查、填表技术
8、错误处理
•进行各种错误的检查、报告、纠正,以及相 应的续编译处理(如:错误的定位与局部化)
–词法:拼写…… –语法:语句结构、表达式结构…… –语义:类型不匹配……
模块分类
• 分析:词法分析、语法分析、语义分析 • 综合:中间代码生成、代码优化、目标
• 功能:词法分析器从左到右扫描源程序(字 符串),并将其转换成单词(记号—Token) 串;同时查词法错误,进行标识符登记—— 符号表管理。
• 输入:字符串 • 输出:(种别码,属性值)——序对
– 属性值——token的机内表示
2、语法分析
• 语法分析器(Syntax Analyzer,又叫Parser ) 完成语法分析
• 程序分析
– 词法、语法、语义
• 分析综合
– 语句的翻译、代码生成
• 例如:标识符左值与右值的绑定(binding)
– 变量:存储单元 – 函数:目标代码序列
1.4 编译程序总体结构请参阅P5图1.1
源程序
词法分析器
出
表
单词符号
语法分析器
错
格
语法单位
语义分析与中间代码生成器 处
管
中间代码
代码优化器
slide08
语法制导的语义计算基础
《编译原理》
语法制导的语义计算基础
本讲导引 属性文法 基于属性文法的语义计算 基于翻译模式的语义计算
《编译原理》
本讲导引
《编译原理》
语法制导的(Syntax-Directed)语义计算
以语法定义(上下文无关文法)为基础
用于各种语义分析与翻译过程:静态语义检查,中间 代码(甚至目标代码)生成等 用于语义计算规则及计算过程的定义 用于自动构造工具的设计(如 Yacc)
原理与方法
属性文法(侧重于语义计算规则的定义)
翻译模式(侧重于语义计算过程的定义)
本讲导引
属性文法举例
识别语言 L = { anbncn n 1} ?
产生式 S ABC A A1a Aa 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 }
《编译原理》
语义动作
{ 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 := d.lexval }
属性文法
概念
《编译原理》
北航编译原理课件 10.语义分析和代码生成
北京航空航天大学计算机学院
16
16
@svardef动作符号是把 ,i 和t 填入符号表中。 动作符号是把n, 填入符号表中。 动作符号是把 procedure svardef( t, i, n ); j := tableinsert ( n, t, i ); /*将有关信息填入符号表 将有关信息填入符号表*/ 将有关信息填入符号表 if j = 0 //填表时要检查是否重名 填表时要检查是否重名 then errmsg ( duplident , statementno); else if j = -1 //符号表已满 符号表已满 then errmsg( tblovflow, statementno); end svardef;
北京航空航天大学计算机学院
12
12
动作程序 @dec_on↑x 是把符号表当前可用表项的入口地址(指向符 是把符号表当前可用表项的入口地址( 号表入口的指针, 表项下标值)赋给属性变量x 号表入口的指针,或称 表项下标值)赋给属性变量 。 @name_defn ↓n是将由各实体名所得的 继承属性值,依次填 是将由各实体名所得的n继承属性值 继承属性值, 入从x开始的符号表中 开始的符号表中。 入从 开始的符号表中。
–继承属性为值形参 继承属性为值形参 –综合属性为变量形参 综合属性为变量形参
• 语法成分翻译动作子程序参数设置: 语法成分翻译动作子程序参数设置:
–继承属性为值形参 继承属性为值形参 –综合属性不设形参,而作为动作子程序的返回值 综合属性不设形参, 综合属性不设形参 RETURN语句返回 语句返回) (由RETURN语句返回)
………
北京航空航天大学计算机学院
8
8
指令名称 等于比较 不等比较 大于比较 小于比较 大于等于 小于等于 逻辑与 逻辑或 逻辑非 转子 分配
编译原理课件-语法分析-自下而上--LR(0)项目集规范族的构造
(2) E→bB
(3) A→cA
c
a
A •d
I2:Ea•A A •cA
I0: S'•E E •aA
E •bB
A •d E
I1: S' E•
(4) A→d (5) B→cB (6) B→d
b I3: Eb•B B •cB
c
B •d
I8: Bc•B c B •cB
B •d
A I10:Ac A•
d d I6:A d•
b) 对初态集或其它所构造的项目集应用转换函数 GO(I,X) = CLOSURE(J)求出新状态J的项目集
c) 重复b)直到不出现新的项目为止
算法
Procedure itemsets(G')
Begin
初态的项目集
C:= { CLOSURE({S' •S }) }
应用状态转换
Repeat
函数得到新的 项目集
A I4:EaA•
例:构造LR(0) 分析表
B I7:EbB•
d
d I9:B d• B I11:BcB•
(0) S'→E (1) E→aA (2) E→bB (3) A→cA (4) A→d (5) B→cB (6) B→d
LR0 分析表
状
ACTION
GOTO
态 a b c d $ EA B
0 S2 S3
*
G': S'→S
[0]
1
3
S
b
S→aAcBe [1]
a
A
b
A→b
[2]
0
2
4
5
c
A→Ab
[3]
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
上次课主要内容
C.true
回填技术 S1.begin S → if C then S1 的 翻译 C.true := newlabel; S1.next := S.next; C.false:= S.next; S.code := C.code ||gen( C.true':' ) S.next ||S1.code
动态(Dynamic)绑定:运行时指定(具体地址/ 相对地址)
如:动态数组
过程/函数名的绑定
为过程指定程序代码段入口地址 静态绑定:编译时指定相对地址
(词法分析:在符号表中建立过程的表项) 语义分析:构造目标代码,填写过程的入口地址 如:一般的函数、子例程 运行时指定——函数名作为形式参数(formals) 如:函数指针、虚函数(C++)
静态存储分配策略介绍
顺序分配算法 按照程序段出现的先后顺序逐段分配
1/22 程序段 区域 1 0~21 2 22~36 3 37~54 4 55~71 5 72~94 6 95~104 共需要105个存储单元 能用更少的空间么?
2/15
3/18
4/17
6/10
5/23
程序段之间的调用关系
程序段号/所需数据空间
访问链
例子——函数的活动记录
int sub( i, p ) int i; char *p; { char buf[32]; buf[i] = *(p + i); return i + 1; }
临时变量: t1,t2,t3
局部变量:buf[32] 机器状态:R0, …, R9, SP, PC, PS 参数:i, p
绑定的时机与策略
语言定义的标识符的生存期决定最 终绑定的时机
全局变量:全程有效——程序装入时
局部变量:分段有效——进入过程或分 程序时
变量名的绑定
静态(Static)绑定:编译时指定(相对地址)
词法分析期间——在符号表中建立变量的表项 回忆:说明语句的语义分析:字节数计算,填写变 量地址
X=T=5,Y=Z=A=2 A:=A+1=2+1
传值调用: 2
Y
Z 7
A=3
A=7
A:=A+T=3+5
8
8.4 过程调用
过程(procedure)
子程序(subroutine)、函数(function) 形参和实参的结合:参数计算与传递 调用与返回
过程的定义与调用
工作方式
调用方:当前环境的保存与恢复 被调方:构造环境,参数绑定
复制恢复 Copy-Restore
将参数的左、右值同时传给被调用者, 被调用者直接使用右值,并将计算结果 按照左值返回给调用者
形式参数X A的地址 A的值
实际参数A
A
调用者
传值/传地址
被调用者
传名调用Call-by-Name
将被调过程的过程体复制到调用处,并 将每一个形参“文字地”替换成实参 用换名子程序实现Thunk 是一种早期的语言ALGOL用的一种参数 传递方式
过程调用语句的代码结构
过程调用语句 id(E1,E2, … ,En)
E1.code a1:=E1.place … En.code an:=En.place 动态存储分配相关工作 goto pc+n+1 param a1 … param an call id.place,n
需要一个队列存放a1, a2, …, an,以生成
用于动态数据结构
存储空间的动态分配和释放
实现方法:
将内存空间分为若干块,根据用户要求分配
无法满足时,调用无用单元收集程序将被释 放的块收集起来重新分配
8.3 参数传递
传值调用 call-by-value
过程调用时计算实参(Actual),将值存到活动记录 形参(Formal)绑定于活动记录的实参域 形式参数X
用途
过程的局部环境 活动记录
运行栈
活动记录
特点
嵌套调用次序 先进后出 生存期限于本次调用 自动释放
活动记录
活动记录
数组存储区
过程数据 区结构
本 过 程 所 辖 分 程 序 存 储 区
……
第 一 层 分 程 序 临时工作单元 局部数组说明 局部变量 分程序TOP
SPn
SPn-1
P
begin real x,y,z x=a y=x*2+b z=1/y begin int a,b,c …… begin S1 S2 char name,from,a …… end …… end …… Sub2(x,y) …… end
静态存储分配无法克服的问题2
递归调用问题
栈式存储分配
栈(Stack)式存储分配
主程序 A:=2; B:=3; P(A+B, A, A);
子程序 P(X,Y,Z); {Y:=Y+1;
换名 A:=A+1=3 A:=A+A+B=3+3+3
Print A
Z:=Z+X}
复制恢复:
9
临时单元: T:A+B=5
X=T=5,Y=Z=A=2 Y:=Y+1=3 Z:=Z+X=2+5=7
传地址:
上次课主要内容
运行环境
绑定:静态、动态 静态分配 动态分配
层次单元法
栈式(Stack)存储分配策略
堆式(Heap)存储分配策略
上次课主要内容
参数传递
传值调用 call-by-value 引用调用 Call-by-Reference/Address 复制恢复 Copy-Restore 传名调用Call-by-Name
8.1 绑定(Binding)
Binding的概念
将符号名和相应目标数据(的地址)对应起来
标识符与数据目标的对应
变量名──数据存储单元地址
过程名、函数名──程序段入口地址
相关问题
变量和过程的作用域,决定绑定的有效期
分段式程序 Program layer Int a,b,c Begin …… Sub(a+b,b,a) …… End Subroutine Sub(x,y,z) Real a,b,c Begin …… End
返回值
控制链
Display
过程说明语句的翻译
说明语句: Procedure id(X1,X2,…,Xn)
分析参数的类型、分配地址
统计参数和返回值的空间需求 与调用语句配合完成形/实参数的结合
符号表处理
完成过程名的属性登记
过程说明语句代码结构
说明语句: Procedure id(X1,X2,…,Xn) 代码结构 X1.code 按参数传递要求实现参数X1的传递,或者完成传递准备; X2.code 按参数传递要求实现参数X2的传递,或者完成传递准备; …… Xn.code 按参数传递要求实现参数Xn的传递,或者完成传递准备; 完成动态存储分配相关的工作; 进入过程体
过程调用的实现
1) 在过程 f 中调用过程 p 时
临时变量 局部变量
a. f 对实在参数求值,将结果存入 p 的 活动记录参数域 b. 在 p 的活动记录中存放返回地址和当 前栈顶指针 c. 按照活动记录的大小,上移栈顶指针 d. 控制转到 p 的入口(过程体)
机器状态
参数
C.code S1.code
C.false
上次课主要内容
C.true S → if C then S1 else S2 的 翻译 S1.begin C.true := newlabel;
C.code S1.code
C.false
C.false := newlabel; S1.next := S2.next := S.next; S.code := C.code || gen( C.true':' )||
嵌套式程序 Program layer Int a,b,c Procedure Sub1(x,y,z) Int x,y,z Procedure add(a,b) Real a,b Begin Real x,y,z x=a y=x*2+b z=1/y End Begin …… End Procedure Sub2(x,y) …… Begin …… end
goto S.next
S1.code || gen( 'goto' S.next ) ||
gen( C.false':' ) || S2.code S.next
S2.code
上次课主要内容
S → while C do S1翻译
S.begin := S1.next := newlabel; C.true := S1.begin := newlabel; C.false := S.next;
S.begin C.true S1.begin
C.code C.false
S.code := gen( S.begin':' ) ||
C.code || gen( C.true':' ) || S1.code ||
S1.code goto S.begin S.next