编译原理课件 - 西安电子科技大学个人主页

Download Report

Transcript 编译原理课件 - 西安电子科技大学个人主页

编译原理上机辅导
 上机题目
 验收方式
 参考解决方案
1
编译原理上机辅导
 上机题目:实现一个简单语言(Core Programming
Language,CPL)的编译器(解释器)
(或者其它自己想完成的编译器)
 功能要求:接收以CPL编写的程序,对其进行词法分
析、语法分析、语法制导翻译等,然后能够正确的执
行程序。
 目的:
 加深编译原理基础知识的理解:词法分析、语法分
析、语法制导翻译等
 加深相关基础知识的理解:数据结构、操作系统等
 提高编程能力
2
 锻炼独立思考和解决问题的能力
编译原理上机辅导
 Core Programming Language(CPL)
 数据类型:整型变量(常量),布尔变量(常量)
 取值范围{…,
-2, -1, 0, 1, 2, …}, {true, false}
 运算表达式:简单的代数运算,布尔运算
 程序语句:赋值表达式,顺序语句,if-else语句,
while语句
3
编译原理上机辅导
 语言特点:简单、易处理
 如果加入浮点数及相应的除操作,那么该语言的表
达能力相当于C, C++, JAVA等
 便于关注语言实现的本质,而不受繁冗细节的干扰
4
编译原理上机辅导
 大致思路:
设计词法规则;
2. 设计语法规则;
3. 设计语义规则;
4. 编程实现。
1.
5
编译原理上机辅导
验收相关:
时间:最后一次上机(初步预定)
条件:(不合条件者验收成绩默认为及格)
1. 完成CPL词法分析器;
2. 完成CPL语法分析器;
3. 完成CPL语法制导翻译;
方法:
1. 演示程序的功能;
2. 解释程序的源代码;
成绩:
验收成绩+报告成绩(是否雷同)+奖励分
注意:可以2-3人一起做,也可以单独做,原则:每个人必须
6
自己动手
编译原理上机辅导
 参考解决方案
(P97: 3.7编译器编写工具)
 基本框架
CPL
Complier
CPL程序
词法分析器
语法分析器
语义子程序
词法l文件
执行结果
CPL Compiler
C/C++编译器
(1) 手工编写
Lex
C/C++编译器
语法y文件
DBMS
Yacc
语义子程序
(2)工具生成
7
编译原理上机辅导
工具:
1.
2.
3.
编译器:Visual C++
Lex与Yacc:Parser Generator(支持C/C++/Java,带实例)
或者其他自己擅长的语言和环境
参考书:
8
编译原理上机辅导
 词法分析器生成器Lex
Lex是一个词法分析器生成器,接受正规式表示的词法规则,
生成识别正规式所描述语言的源程序,不同版本的Lex支持
不同的高级语言,如C、C++、Java等。
正规式
词法分析器
输入字符序列
驱动器(算法2.1)
分析表(DFA)
人工编写
NFA
记号流
DFA
Lex转化
最小化DFA
分析表+驱动器
9
编译原理上机辅导
利用Lex构造词法分析器:实质为如何设计正规式和语义动作
Lex源程序*.l(三段式):
[定义
C声明
辅助定义正规式
]
%%
规则
词法规则正规式
语义动作(C代码)
[%%
用户子程序
C源程序
]
*.l
lex.yy.c
编编
Lex编 编 编
lex.yy.c
C编 编 编
EXE
EXE
编编编
注意:不同版本的Lex生成的
文件不同
10
编译原理上机辅导
Lex源程序*.l(三段式):
[定义
C声明
辅助定义正规式
]
%%
规则
词法规则正规式
语义动作(C代码)
[%%
用户子程序
C源程序
]
lex.yy.c结构:
(1)声明的C语言部分
(2)词法分析表
(3)词法分析驱动器(yylex())
(4)用户定义子程序
11
编译原理上机辅导
实例:标识符数字识别器
基本步骤:
1. 安装Parser Generator、Visual C++;
2. 分别配置Parser Generator、Visual C++;
3. 使用Parser Generator创建一个工程number

编写l文件mylexer.l;

编译mylexer.l,生成mylexer.h与mylexer.c;
4. 使用VC++创建Win32 Console Application工程number

配置该项目;

加入mylexer.h与mylexer.c,编译工程;

执行标识符数字识别器;
注意:每次修改l文件后,需要重新编译l文件,再重新编译
VC工程
12
编译原理上机辅导
mylexer.l源代码:
//声明部分
%{
#define ID 0
#define NUMBER 1
%}
//C声明:记号类别
将来在Yacc中使用下列语句代替:
%Token ID NUMBER
char [a-zA-Z]
digit [0-9]
//辅助定义正规式
digits
{digit}+
optional_fraction
(.{digits})?
optional_exponent (E[+-]?{digits})?
13
编译原理上机辅导
%%
//词法规则正规式
{char}({char}|{digit})*
{ printf("识别标识符%s:长度为%d\n", yytext, yyleng);
//语义动作:C代码
return ID;
}
{digits}{optional_fraction}{optional_exponent}
{printf(“识别数字%s:长度为%d\n", yytext, yyleng);
return NUMBER;
yytext,yyleng:全局变量,用来存放识
}
别出的输入序列,由词法分析器自动填写
%%
int main(void)
//C源程序
{
printf("词法分析成功,返回记号类别为%d\n", yylex());
}
yylex():词法分析驱动器,根据语法规则
14
返回记号的类别,如ID、NUMBER等。
编译原理上机辅导
执行结果:每次输入一个字符串,输出识别结果
注意:将来Yacc自动调用yylex()返回一个记号
15
编译原理上机辅导
 Flex, Bison
 http://www.360doc.com/content/11/0709/09/865714_
132472615.shtml
… …
16
相关内容回顾
 自上而下的分析
 递归调用子程序
 非递归预测分析器
3.5 自下而上语法分析
 自上而下分析的方法是产生语言的自然过程。
 对于分析语言来讲,自下而上分析的方法更自然,因为语
法分析处理的对象一开始都是终结符组成的串,而不是文
法的开始符号。
 同时,自下而上分析中最一般的方法,LR方法的能力比自
上而下分析的LL方法要强,从而使得LR分析成为最为实
用的语法分析方法。
 两种主要的自下而上分析方法:
① 算符优先分析(不讨论)
② LR分析
18
3.5 自下而上语法分析
 自下而上分析的基本方法
思路:从句子ω开始,从左到右扫
描ω,反复用产生式的左部替换产
生式的右部、谋求对ω的匹配,最
终得到文法的开始符号,或者发
现一个错误。
19
3.5 自下而上语法分析
 例 S  aABe
A  Abc | b
Bd
3.5 自下而上语法分析
 例 S  aABe
A  Abc | b
Bd
abbcde(读入a)
a
3.5 自下而上语法分析
 例 S  aABe
A  Abc | b
Bd
abbcde(再读入b)
a
b
3.5 自下而上语法分析
 例 S  aABe
A  Abc | b
Bd
abbcde
aAbcde(归约:A  b)
A
a
b
3.5 自下而上语法分析
 例 S  aABe
A  Abc | b
Bd
abbcde
aAbcde(再读入b)
A
a
b
b
3.5 自下而上语法分析
 例 S  aABe
A  Abc | b
Bd
abbcde
aAbcde(再读入c)
A
a
b
b
c
3.5 自下而上语法分析
 例 S  aABe
A  Abc | b
Bd
abbcde
aAbcde
aAde(归约A  Abc )
A
A
a
b
b
c
3.5 自下而上语法分析
 例 S  aABe
A  Abc | b
Bd
abbcde
aAbcde
A
aAde(再读入d)
A
a
b
b
c
d
3.5 自下而上语法分析
 例 S  aABe
A  Abc | b
Bd
abbcde
aAbcde
A
aAde
aABe(归约B  d )
a
B
A
b
b
c
d
3.5 自下而上语法分析
 例 S  aABe
A  Abc | b
Bd
abbcde
aAbcde
A
aAde
aABe(再读入e)
B
A
a
b
b
c
d
e
3.5 自下而上语法分析
 例 S  aABe
A  Abc | b
Bd
abbcde
aAbcde
S
A
aAde
aABe
S(归约S  aABe )
a
B
A
b
b
c
d
e
3.5 自下而上语法分析
 例 S  aABe
A  Abc | b
Bd
abbcde
aAbcde
S
A
aAde
aABe
S
B
A
a
b
b
c
d
S rm aABe rm aAde rm aAbcde rm abbcde
e
若存在S =*>αAδ,A=+>β,则称β是句型αβδ相对于A的短
语,3.5 自下而上语法分析
规范规约与“剪句柄”
定义3.13 设αβδ是文法G的一个句型,若存在S =*>αAδ,
A=+>β,则称β是句型αβδ相对于A的短语,特别的,若 有
A→β,则称β是句型αβδ相对于产生式A→β的直接短语。
一个句型的最左直接短语被称为句柄。
1.
直观上,句型是一个完整结构,短语是句型中针对某非终
结符的局部。因此,开始符号S是句型而不是短语。
短语形成的两个要素:
① 从S可以推导出A,即S=*>αAδ;
② 从A至少一次推导出β,即A=+>β。
32
若存在S =*>αAδ,A=+>β,则称β是句型αβδ相对于A的短
语 3.5 自下而上语法分析
[例3.25] 文法、分析树与短语
文法: E→E+T|T
E1
T→T*F|F
E2
+
T1
F→id
句型:id1+id2*id3
分析树(非终结符编 T2 T3 * F2
号是为了说明方便)
F1
F3
id3
短语: id1+id2*id3
(E1)
id1+id2*id3是句型
id1+id2*id3相对于E1的短语
短语: id2*id3 (T1)
id2*id3是句型id1+id2*id3相
对于T1的短语
短语: id1
(E2, T2, F1)
id1是句型id1+id2*id3相对于E2,
T2,F1的短语
id1
直接短语:id1 (F1)
id2 (F3)
id3 (F2)
句柄:
id1 (F1)
id2
短语: id2
(T3, F3)
id2是句型id1+id2*id3相对于T3,
F3的短语
短语: id3
(F2)
id3是句型id1+id2*id3相对于F2
的短语
33
一个句型的最左直接短语被称为句柄。
3.5 自下而上语法分析
定义3.14 若 α是文法G的句子且满足下述条件,则称序列αn,
αn-1,...,α0是α的一个最左归约。
1. αn=α
2. α0=S(S是G 的开始符号)
3. 对任何i(0<i<=n),αi-1是将αi中句柄替换为相应产生式
左部非终结符得到的。
[例3.26]文法(1) S→aABe (2) A→b (3) A→Abc (4) B→d
对句子abbcde的最左归约:
(2)
(3) (4)
(1)
abbcde <= aAbcde <= aAde <= aABe <= S
an
a0
问题:如何直观地看出句柄并进行归约?
提示:最左归约的逆过程是一个最右推导(分别称最右推导和最左
归约为规范推导和规范归约。)
34
3.5 自下而上语法分析
文法(1) S→aABe (2) A→b (3) A→Abc
句子:abbcde最右推导
S
S
a
A
B
e a
A
b c
d
A
A
B
e
b c
d
a
S
S
S
(2) A→b
b
(4) B→d
A
B
a
e
d
(3) A→Abc
A
B
e
(4) B→d
(1) S→aABe
句子:abbcde最左规约(剪句柄)
S
S
a
A
B
A
b c
d
b (2) A→b
e
a
A
B
A
b c
d
e
(3) A→Abc
a
A
S
S
S
B
e
a
A
B
e
d
(4) B→d
35
(1) S→aABe
3.5 自下而上语法分析
从分析树上直观地看,“剪句柄”的方法十分简单。
但是在若干语法分析器中实现剪句柄,有两个问
题需要解决:
① 确定右句型中将要归约的子串(确定句柄);
② 确定如何选择正确的产生式进行归约。
移进-归约:用一个栈“记住”将要归约句柄的前缀,
句柄未形成前移进(动作),形成后归约(动 36
作)。
3.5 自下而上语法分析
 移进-规约分析器(数学模型:下推自动机)
移进-归约分析器与
预
输入记号流
测分析器工作模式完
ip
全相同:仍然以格局
符
的变化为反应。格局
驱动器
top
输出
号
的形式仍然是(栈、
状
剩余输入,动作)。
态
移进-归约
分析从某个初始格局开始,
栈
分析表
经过一系列的格局变化,
(a) 移进-规约分析器模型 达到接收格局,表明分
析成功;或者达到出错
格局,表明发现语法错误。
3.5 自下而上语法分析
2.
移进-归约分析器与预测分析器工作模式完全相同
输入记号流
ip
top
符
号
状
态
栈
驱动器
输入记号流
ip
输出
移进-归约
分析表
(a) 移进-规约分析器模型
移进-归约分析器:
1. 分析方法:格局与格局变换
2. 分析表
3. 驱动器(模拟算法)
4. LR(文法、语言、分析器)
5. SLR分析表的构造
符
top
号
栈
驱动器
输出
预测分析表
(b) 预测分析器模型
预测分析器:
1. 分析方法:格局与格局变换
2. 分析表
3. 驱动器(模拟算法)
4. 预测分析表的构造
5. LL(文法、语言、分析器)38
3.5 自下而上语法分析
输入记号流
ip
top
符
号
状
态
栈
驱动器
输出
对照预测分析:
① 匹配终结符(弹出)
② 最左推导(展开非终结符)
移进-归约
分析表
工作方法:放幻灯,每个幻灯片是一个格局。
格局:(#栈,当前剩余输入#,改变格局的动作)
改变格局的动作:
① 移进(shift):输入序列中的终结符进栈。(匹配终结符)
② 归约(reduce):将栈顶句柄替换为对应非终结符(最左归约)。
③ 接受(accept):宣告分析成功。
④ 报错(error):发现语法错误,调用错误恢复例程。
39
3.5 自下而上语法分析
(1)S→aABe (2)A→b
[例3.27] 用移进-归约方法分析abbcde:
abbcde<=aAbcde<=aAde<=aABe<=S
(3)A→Abc (4)B→d
栈
剩余输入
改变格局的动作
#
abbcde#
移进
结论:
#a
bbcde#
移进
1. 句柄总是在栈顶形成(最左归
#ab
bcde#
归约,(2)A→b
约)。
#aA
bcde#
移进
2. 栈中保留的总是一个右句型
#aAb cde#
移进
的前缀(加上若干终结符形成
#aAbc de#
归约,(3)A→Abc
句型),称为活前缀;
#aA
de#
移进
3. 最左归约是逻辑上从下到上
#aAd e#
归约,(4)B→d
构造一棵分析树,或从下到
#aAB e#
移进
上为分析树剪句柄。
#aABe #
归约,(1)S→aABe
#S
#
接受
需要解决的问题: (由分析表确定)
① 如何保证栈中总是活前缀 (指导移进)
40
② 如何确定栈顶已经形成句柄并选择正确的产生式进行归约(指导归约)
总结
 自下而上分析:归约、短语、直接短语、句柄、规范(最左)
归约
 规范归约的直观表示:剪句柄
 移进-归约分析工作模式:格局与格局变换
41
作业
 P137:3.15, 3.16