《编译原理》实验指导书.docx
- 文档编号:26000577
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:33
- 大小:103.42KB
《编译原理》实验指导书.docx
《《编译原理》实验指导书.docx》由会员分享,可在线阅读,更多相关《《编译原理》实验指导书.docx(33页珍藏版)》请在冰豆网上搜索。
《编译原理》实验指导书
《编译原理》实验指导书
太原科技大学计算机学院
2006-3-1
序
《编译原理》是国内外各高等院校计算机科学技术类专业,特别是计算机软件专业的一门重要专业课程。
该课程系统地向学生介绍编译程序的结构、工作流程及编译程序各组成部分的设计原理和实现技术。
由于该课程理论性和实践性都比较强,内容较为抽象复杂,涉及到大量的软件设计和算法,因此,一直是一门比较难学的课程。
为了使学生更好地理解和掌握编译原理和技术的基本概念、基本原理和实现方法,实践环节非常重要,只有通过上机进行程序设计,才能使学生对比较抽象的教学内容产生具体的感性认识,增强学生综合分析问题、解决问题的能力,并对提高学生软件设计水平大有益处。
为了配合《编译原理》课程的教学,考虑到本课程的内容和特点,本指导书设置了七个综合性实验,分别侧重于词法分析、NFA的确定化、非递归预测分析、算符优先分析器的构造、LR分析、语义分析和中间代码的生成、基于DAG的基本块优化,以支持编译程序的各个阶段,基本涵盖了《编译原理》课程的主要内容。
本指导书可作为《编译原理》课程的实验或课程设计内容,在课程教学的同时,安排学生进行相关的实验。
实验平台可选择在MS-DOS或Windows操作系统环境,使用C/C++的任何版本作为开发工具。
学生在做完试验后,应认真撰写实验报告,内容应包括实验名称、实验目的、实验要求、实验内容、测试或运行结果等。
实验一词法分析
1.实验目的和任务
对C语言的一个子集设计并实现一个简单的词法分析器,掌握利用状态转换图设计词法分析器的基本方法。
2.实验要求
利用该词法分析器完成对源程序字符串的词法分析。
输出形式是源程序的单词符号二元式的代码,并保存到文件中。
3.实验内容
(1)假设该语言中的单词符号及种别编码如下表所示。
单词符号及种别编码
单词符号
种别编码
单词符号
种别编码
Main
1
[
28
Int
2
]
29
Char
3
{
30
If
4
}
31
Else
5
32
For
6
:
33
While
7
;
34
标识符ID
10
>
35
整型常数NUM
20
<
36
=
21
>=
37
+
22
<=
38
-
23
==
39
*
24
!
=
40
/
25
&
41
(
26
&&
42
)
27
||
43
(2)关键字mainintcharifelseforwhile都是小写并都是保留字。
算符和界符:
=+-*/&<<=>>=== !
=&&||,:
;{}[]()
ID和NUM的正规定义式为:
ID→letter(letter|didit)*
NUM→digitdigit*
letter→a|…|z|A|…|Z
digit→0|…|9
如果关键字、标识符和常数之间没有确定的算符或界符作间隔,则至少用一个空格作间隔。
空格由空白、制表符和换行符组成。
(3)设计词法分析器的步骤:
1首先根据上面单词符号表及ID和NUM的正规定义式,构造出状态转换图;
2定义相关的变量和数据结构。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。
如能查到匹配的单词,则该单词为关键字,否则为一般标识符。
关键字表为一个字符串数组,其描述如下:
char*KEY_WORDS[8]={″main″,″int″,″char″,″if″,″else″,″for″,″while″};
用以存放单词符号二元式的数据结构可如下定义:
#defineMAXLENGTH255/*一行允许的字符个数*/
unionWORDCONTENT{/*存放单词符号的内容*/
charT1[MAXLENGTH];/*存放标识符*/
intT2;/*存放整型常数的拼数*/
charT3;/*存放其他符号*/
};
typedefstructWORD{/*单词符号二元式*/
intcode;/*存放种别编码*/
unionWORDCONTENTvalue;
}WORD;
3按照编译程序一遍扫描的要求,把词法分析器Scaner作为一个独立的子程序来设计,通过对Scaner的反复调用识别出所有的单词符号;
4当Scaner识别出一个单词符号时,则将该单词符号的二元式写入到输出文件中。
若Scaner无法识别出一个单词符号时,则调用错误处理程序PrintError,显示当前扫描到的字符及其所在行、列位置,并跳过该字符重新开始识别单词符号。
(4)测试该设计词法分析器,可对下面的源程序进行词法分析:
main()
{
inti=10;
while(i)i=i-1;
}
输出如下二元式代码序列:
(1,main)(26,()(27,))(30,{)(2,int)(10,i)(21,=)(20,10)(34,;)(7,while)(26,()(10,i)(27,))(10,i)(21,=)(10,i)(23,-)(20,1)(34,;)(31,})
实验二NFA的确定化
1.实验目的和任务
设计并实现将NFA确定化为DFA的子集构造算法,从而更好地理解有限自动机之间的等价性,掌握词法分析器自动产生器的构造技术。
该算法也是构造LR分析器的基础。
2.实验要求
设计并实现计算状态集合I的ε闭包的算法ε_Closure(I)和转换函数Move(I,a),并在此基础上实现子集构造算法Subset_Construction。
利用该从NFA到DFA的转换程序Subset_Construction,任意输入一个NFAN=(S,Σ,δ,s0,F),输出一个接收同一语言的DFAM=(S’,Σ,δ’,s0’,F’)。
3.实验内容
(1)令I是NFAN的状态集S的一个子集,I的ε闭包的ε_Closure(I)构造规则如下:
(a)若s∈I,则s∈ε_Closure(I);
(b)若s∈I,则ε_Closure({s})∈ε_Closure(I)
根据上面的规则,下面给出了一个计算I的ε闭包的算法ε_Closure(I)。
SETS;
SETε_Closure(input)
SET*input;
{
S=input;/*初始化*/
push();/*把输入状态集中的全部状态压入栈中*/
while(栈非空){
Nfa_statei;
pop();/*把栈顶元素弹出并送入i*/
if(存在δ(i,ε)=j)
if(j不在S中){
把i加到S中;
把j压入栈中;
}
}
returnS;/*返回ε_Closure(input)集合*/
}
完成上述算法的设计。
(2)令I是NFAN的状态集S的一个子集,a∈Σ,转换函数Move(I,a)定义为:
Move(I,a)=ε_Closure(J)
其中,J={s’|s∈I且δ(s,a)=s’}
转换函数Move(I,a)的设计通过调用ε_Closure(input)实现,完成该函数的设计。
(3)从NFAN构造一个和其等价的DFAM的子集构造算法,就是要为DFAM构造状态转换表Trans,表中的每个状态是NFAN状态的集合,DFAM将“并行”地模拟NFAN面对输入符号串所有可能的移动。
下面给出了子集构造算法Subset_Construction的框架,请完成其设计过程。
有关数据结构:
States[]:
是一个M的数组,每个状态有两个域,set域存放N的状态集合,flg域为一标识。
Trans[]:
是M的转移矩阵(输入字母表Σ元素个数×最大状态数),Trans[i][a]=下一状态。
I:
M的当前状态号
a:
输入符号,a∈Σ
Nstates[]:
M的下一新状态号
S:
定义M的一个状态的N的状态集
初始化:
tates[0].set=ε_Closure({N的初态})
States[0].flg=FALSE
Nstates=1
i=0
S=Ф
Trans初始化为无状态’-’
while(States[i]的flg为FALSE){
States[i].flg=TRUE;
for(每个输入符号a∈Σ){
S=ε_Closure(Move(States[i].set,a));
if(S非空)
if(States中没有set域等于S的状态){
States[Nstates].set=S;
States[Nstates].flg=FALSE;
Trans[i][a]=Nstates++;
}
elseTrans[i][a]=States中一个set域为S的下标;
}
}
此算法的输出M主要由Trans矩阵描述,其中省略了每个状态是否为终态的描述,应加以完善。
(4)测试用例
对下图所示的NFAN用子集构造算法Subset_Construction确定化。
NFAN的初态为12,DFAM的初态为ε_Closure({12})。
整个转换过程可用下表来概括。
DFA
状态
NFA
状态
ε_Closure
Move(’D’)Move(’.’)Move(’e’)
终
态
NFA
DFA
NFA
DFA
NFA
DFA
0
1
2
3
4
5
{12}
{1,5}
{8}
{15}
{10}
{16}
{0,2,4,6,12}
{0,1,3,4,5,7,13,14,18,19}
{8,9}
{15}
{9,10,11,13,14,18,19}
{15,16,17,19}
{1,5}
{1,5}
{10}
{16}
{10}
{16}
1
1
4
5
4
5
Φ
{8}
Φ
Φ
Φ
Φ
-
2
-
-
-
-
Φ
{15}
Φ
Φ
{15}
Φ
-
3
-
-
3
-
否
是
否
否
是
是
DFAM的状态转换图如下。
实验三非递归预测分析
1.实验目的和任务
设计一个非递归预测分析器,实现对表达式语言的分析,理解自上而下语法分析方法的基本思想,掌握设计非递归预测分析器的基本方法。
2.实验要求
建立文法及其LL
(1)分析表表示的数据结构,设计并实现相应的预测分析器,对源程序经词法分析后生成的二元式代码流进行预测分析,如果输入串是文法定义的句子则输出“是”,否则输出“否”。
3.实验内容
(1)文法描述及其LL
(1)分析表
表达式语言(XL)的语法规则如下:
1.程序→表达式;
2.|表达式;程序
3.表达式→表达式+项
4.|项
5.项→项*因式
6.|因式
7.因式→num_or_id
8.|(表达式)
将该语言的文法转换为如下的LL
(1)文法:
1prgm→expr;prgm’8term→factorterm’
2prgm’→prgm9term’→*factorterm’
3prgm’→ε10term’→ε
4expr→termexpr’11factor→(expr)
5expr→ε12factor→num
6expr’→+termexpr’13system_goal→prgm
7expr’→ε
该LL
(1)文法的LL
(1)分析表如下:
T
N
Num
+
*
(
)
;
#
prgm
1
1
1
prgm’
2
2
2
3
expr
4
4
5
5
expr’
6
7
7
term
8
8
term’
10
9
10
10
factor
12
11
system_goal
13
13
13
对文法中每个文法符号指定一个常数值,符号编码表如下:
文法符号
常数值
备注
(
Num
+
)
;
*
#
4
6
2
5
1
3
0
终结符
(#为输入结束标志)
Expr
expr’
term
term’
factor
prgm
prgm’
system_goal
258
260
259
262
261
256
257
263
非终结符
(2)文法及其LL
(1)分析表的数据结构
文法的产生式可用数组Yy_pushtab[]存放。
数组的第一个下标是产生式号,第一个产生式的序号为0;每列按逆序存放该产生式右部各符号的常数值,并以0结束。
对于该表达式语言XL的LL
(1)分析表,可用数组Yy_d[]存放。
第一个下标是非终结符数值,第二个下标是终结符数值,数组元素的值为:
0(表示接受),1(表示产生式号),-1(表示语法错)。
数组Yy_d[]的具体内容及表示如下:
0123456
#;+*()Num
-1
0
-1
-1
0
-1
0
2
1
-1
-1
1
-1
1
-1
4
-1
-1
3
4
3
-1
-1
-1
-1
7
-1
7
-1
6
5
-1
-1
6
-1
-1
-1
-1
-1
10
-1
11
-1
9
9
8
-1
9
-1
-1
12
-1
-1
12
-1
12
prgm256
prgm’257
expr258
term259
expr’260
factor261
term’262
system_goal263
数组Yy_pushtab[]的具体内容及表示如下:
(3)预测分析器总控程序结构
预测分析器总控程序使用上面的两个表Yy_pushtab、Yy_d和一个分析栈(元素类型为int),其结构如下:
初始化;/*把开始符号的常数值压入分析站,输入指向第一个输入符号*/
while(分析栈非空){
if(栈顶常数表示一个终结符)
if(该常数和输入符号的常数不等)
报语法错;
else{
把一个数从栈顶弹出;
advance读下一输入符号;
}
else{/*栈顶的常数表示一个非终结符*/
what_to_do=Yy_d[栈顶常数][当前输入符号的常数];
if(what_to_do==-1)
报语法错;
else{
把栈顶元素弹出栈;
把Yy_pushtab[what_to_do]中列出的全部常数压入分析栈;
}
}
}
请实现该程序。
在程序中添加输出栈内容的功能,以便和手工模拟分析过程作比较。
(4)用预测分析器和手工模拟两种方式对文法的句子1+2;进行分析。
综合分析过程可用下表表示。
栈(符号)
栈(数值)
输入串
What_to_do
system_goal
prgm
prgm’;expr
prgm’;expr’term
prgm’;expr’term’factor
prgm’;expr’term’Num
prgm’;expr’term’
prgm’;expr’
prgm’;expr’term+
prgm’;expr’term
prgm’;expr’term’factor
prgm’;expr’term’Num
prgm’;expr’term’
prgm’;expr’
prgm’;
prgm’
263
256
2571258
2571260259
2571260262261
25712602626
2571260262
2571260
25712602592
2571260259
2571260262261
25712602626
2571260262
2571260
2571260262
257
1+2;#
1+2;#
1+2;#
1+2;#
1+2;#
1+2;#
+2;#
+2;#
+2;#
2;#
2;#
2;#
;#
;#
;#
#
12
0
3
7
11
9
5
7
11
9
6
2
(5)请考虑如何设计并实现LL
(1)分析表的自动生成程序。
实验四算符优先分析器的构造
1.实验目的和任务
(1)理解自底向上的语法分析的基本思想。
(2)理解算符优先文法的概念。
(3)掌握算符分析表和优先函数的构造。
(4)掌握算符优先分析器的工作原理和工作流程。
2.实验原理
算符优先分析法是一种简单、直观、广为使用的语法分析方法,这种方法特别适用于程序设计语言中的表达式的分析。
算符优先分析法就是仿照算术表达式的运算过程而提出的一种自底向上的语法分析方法,它可以分析算符优先文法,分析的基本思想是:
根据文法终结符之间的优先关系,通过比较相邻算符的优先次序来确定句型中的最左素短语,并进行归约。
所谓的算符优先文法是指:
对算符文法中任意两个终结符对a、b之间至多有一种优先关系成立的文法,而算符文法G中的任何一个产生式中都不包含两个非终结符相邻的情况。
对于满足这样条件的文法,我们就可以用算符优先分析法对其进行分析。
确定了符合要求的文法之后,自底向上的分析方法的关键就是如何在当前句型中寻找可归约的子串,算符优先分析法在归约过程中,通过终结符之间的优先关系确定当前的句型中的最左素短语,和非终结符无关,只需知道把当前句型中的最左素短语归约为一非终结符,不必知道该非终结符的名字是什么,这样也就去掉了单非终结符的归约,一旦找到最左素短语,就将它归约成一个非终结符。
在算符优先分析法分析过程中,可以设置一个栈S,用来存放归约或者待形成最左素短语的符号串,用一个工作单元a存放当前读入的输入字符,归约成功的标志是当读入的输入字符是句子的结束符号#时,栈S中只剩下#N。
3.实验内容
给定一个上下文无关文法G:
<常量说明部分>→const<常量定义>{,<常量定义>}
<常量定义>→<标识符>=<无符号整数>
<无符号整数>→<数字>{<数字>}
<变量说明部分>→{var}01<标识符>{,<标识符>}:
integer;∣{var}01<标识符>{,<标识符>}:
real;∣{var}01<标识符>{,<标识符>}:
boolean;
<标识符>→<字母>{<字母>∣<数字>}
<语句部分>→<语句>∣<复合语句>
<复合语句>→begin<语句>{;begin<语句>end;}end.
<语句>→<赋值语句>∣<条件语句>∣<循环语句>
<赋值语句>→<标识符>:
=<表达式>
<表达式>→[+∣-]<项>∣<表达式>+<项>∣<表达式>-<项>
<项>→<因子>∣<项>*<因子>∣<项>/<因子>
<因子>→<标识符>∣<常量>∣(<表达式>)
<常量>→<无符号整数>
<条件语句>→if<条件>then<语句>else<语句>
<条件>→<表达式><关系运算符><表达式>{(and∣or)<表达式><关系运算符><表达式>}
<循环语句>→while(<条件>){(and∣or)(<条件>)}do<语句>
<关系运算符>→=∣<∣>∣≤∣≥
<字母>→a∣b∣c∣…∣z∣A∣B∣C∣…∣Z
<数字>→0∣1∣2∣…∣9
编写程序,构造上述文法G的算符优先分析器,使其能实现如下功能:
(1)扫描单词的内部表示形式,按语言的语法规则识别出语法单位(语句等);
(2)对各语法单位进行语法检查;
(3)若发现单词的组成有错误时,输出有关的出错信息。
实验五LR分析
1.实验目的和任务
设计一个LR分析器,实现对表达式语言的分析,加深对LR语法分析方法的基本思想的理解,掌握LR分析器设计和实现的基本方法。
2.实验要求
建立文法及其LR分析表表示的数据结构,设计并实现一个LALR
(1)的分析器,对源程序经词法分析后生成的二元式代码流进行分析,如果输入串是文法定义的句子则输出“是”,否则输出“否”。
3.实验内容
(1)文法描述及其LALR
(1)分析表
描述表达式语言的文法G如下:
1.S→E
2.E→E+T
3.E→T
4.T→T*F
5.T→F
6.F→(E)
7.F→ID
该文法的LALR
(1)分析表如下:
分析表
状态
动作Action表(Yy_action)
转移Goto表(Yy_goto)
#
ID
+
*
(
)
S
E
T
F
0
-
S1
-
-
S2
-
-
3
4
5
1
R6
-
R6
R6
-
R6
-
-
-
-
2
-
S1
-
-
S2
-
-
6
4
5
3
A
-
S7
-
-
-
-
-
-
-
4
R2
-
R2
S8
-
R2
-
-
-
-
5
R4
-
R4
R4
-
R4
-
-
-
-
6
-
-
S7
-
-
S9
-
-
-
-
7
-
S1
-
-
S2
-
-
-
10
5
8
-
S1
-
-
S2
-
-
-
-
11
9
R5
-
R5
R5
-
R5
-
-
-
-
10
R1
-
R1
S8
-
R1
-
-
-
-
11
R3
-
R3
R3
-
R3
-
-
-
-
SN=移进并转移到状态NA=accept接受
RN=按第N条产生式进行规约-=error转移
(2)LR分析器总控程序框架如下:
push(0);
advance();
while(Action[tos][sym]!
=accept)
if(Action[tos][sym]==’-’)error();
elseif(Action[tos][sym]==SN){
push(N);
advance();
}
elseif(Action[tos][sym]==RN{
act(N);
pop(产生式N的右部的符号个数);
push(Goto[新tos][产生式N的左部符号]);
}
accept();
上述算法中的有关函数和符号的意义如下:
accept():
返回成功状态,LR分析器停止工作;
act(N):
执行利用产生式N的归约的动作,通常为产生代码;
adv
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译原理 编译 原理 实验 指导书