《编译原理》实验指导书.docx
- 文档编号:23734643
- 上传时间:2023-05-20
- 格式:DOCX
- 页数:52
- 大小:68.26KB
《编译原理》实验指导书.docx
《《编译原理》实验指导书.docx》由会员分享,可在线阅读,更多相关《《编译原理》实验指导书.docx(52页珍藏版)》请在冰豆网上搜索。
《编译原理》实验指导书
编译原理
实验与课程设计指导书
2016年10月
目录
一、课程简介2
二、实验目的2
三、实验环境2
四、实验任务2
五、实验项目3
实验一.词法分析3
实验二.自顶向下语法分析8
实验三.自底向上语法分析10
实验四.语义分析11
实验五.中间代码生成12
六、课程设计13
七、考核方式13
八、参考文献14
九、附录——PL0语言编译源程序清单(部分)15
编译原理实验与课程设计指导
一、课程简介
1.课程名称:
编译原理(PrincipleofCompiler)
2.课程总学时:
64学时[理论:
48学时;实验:
16学时
3.课程总学分:
4学分
二、实验目的
编译原理是计算机类专业特别是计算机软件专业的一门重要专业课。
设置该课程的目的在于系统地向学生讲述编译系统的结构、工作流程及编译程序各组成部分的设计原理和实现技术,使学生通过学习既掌握编译理论和方法方面的基本知识,也具有设计、实现、分析和维护编译程序等方面的初步能力。
编译原理是一门理论性和实践性都比较强的课程。
进行上机实验的目的是使学生通过完成上机实验题目加深对课堂教学内容的理解。
同时培养学生实际动手能力。
三、实验环境
微机CPUP4以上,256M以上内存,安装好C语言,或C++,或VisualC++开发环境。
四、实验任务
用C/C++/VisualC++语言编写某语言的词法分析程序、语法分析程序、语义分析程序、中间代码生成程序。
五、实验项目
实验一.词法分析
1.实验目的
●根据PL/0语言的文法规范,编写PL/0语言的词法分析程序。
●通过设计调试词法分析程序,实现从源程序中分出各种单词的方法;加深对课堂教学的理解;提高词法分析方法的实践能力。
●掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的法。
●掌握词法分析的实现方法。
●上机调试编出的词法分析程序。
2.实验准备
微机CPUP4以上,256M以上内存,安装好C语言,或C++,或VisualC++.
3.实验时间
4学时
4.实验内容
(1)试用手工编码方式构造识别以下给定单词的某一语言的词法分析程序。
(2)语言中具有的单词包括五个有代表性的关键字begin、end、if、then、else;标识符;整型常数;六种关系运算符;一个赋值符和四个算术运算符。
参考实现方法简述如下。
(3)单词的分类:
构造上述语言中的各类单词符号及其分类码表。
表1语言中的各类单词符号及其分类码表
单词符号
类别编码
类别码的助记符
单词值
begin
1
BEGIN
end
2
END
if
3
IF
then
4
THEN
else
5
ELSE
标识符
6
ID
字母打头的字母数字串
整常数
7
INT
数字串
<
8
LT
<=
9
LE
=
10
EQ
<>
11
NE
>
12
GT
>=
13
GE
:
=
14
IS
+
15
PL
-
16
MI
*
17
MU
/
18
DI
5、实验方法与处理过程
在一个程序设计语言中,一般都含有若干类单词符号,为此可首先为每类单词建立一张状态转换图,然后将这些状态转换图合并成一张统一的状态图,即得到了一个有限自动机,再进行必要的确定化和状态数最小化处理,最后据此构造词法分析程序。
在此为了使词法分析程序结构比较清晰,且尽量避免某些枝节问题的纠缠,假定要编译的语言中,全部关键字都是保留字,程序员不得将它们作为源程序中的标识符;在源程序的输入文本中,关键字、标识符、整常数之间,若未出现关系和算术运算符以及赋值符,则至少须用一个空白字符加以分隔。
作了这些限制以后,就可以把关键字和标识符的识别统一进行处理。
即每当开始识别一个单词时,若扫视到的第一个字符为字母,则把后续输入的字母或数字字符依次进行拼接,直至扫视到非字母、数字字符为止,以期获得一个尽可能长的字母数字字符串,然后以此字符串查所谓保留字表(此保留字表已事先造好),若查到此字符串,则取出相应的类别码;反之,则表明该字符串应为一标识符。
采用上述策略后,针对表I中部分单词可以构造一个如图1所示的有限自动机(以状态转换图表示)。
在图1中添加了当进行状态转移时,词法分析程序应执行的语义动作。
根据图1,可用C语言编写出符合以上几项要求的一个相应的扫描器程序,如程序一所示。
图1识别表I所列语言中的部分单词的DFA及相关的语义过程
图1及程序一中所出现的语义变量及语义函数的含义和功能说明如下。
函数GETCHAR:
每调用一次,就把扫描指示器当前所指示的源程序字符送入字符变量ch,然后把扫描指示器前推一个字符位置。
字符数组TOKEN:
用来依次存放一个单词词文中的各个字符。
函数CAT:
每调用一次,就把当前ch中的字符拼接于TOKEN中所存字符串的右边。
函数LOOKUP:
每调用一次,就以TOKEN中的字符串查保留字表,若查到,就将相应关键字的类别码赋给整型变量c;否则将c置为零。
函数RETRACT:
每调用一次,就把扫描指示器回退一个字符位置(即退回多读的那个字符)。
函数OUT:
一般仅在进入终态时调用此函数,调用的形式为OUT(c,VAL)。
其中,实参c为相应单词的类别码或其助记符;当所识别的单词为标识符和整数时,实参VAL为TOKEN(即词文分别为字母数字串和数字串),对于其余种类的单词,VAL均为空串。
函数OUT的功能是,在送出一个单词的内部表示之后,返回到调用该词法分析程序的那个程序。
程序一根据图1编写的扫描器
#include
#include
#include
#defineID6
#defineINT7
#defineLT8
#defineLE9
#defineEQ10
#defineNE11
#defineGT12
#defineGE13
charTOKEN[20];
externintlookup(char*);
externvoidout(int,char*);
externreport_error(void);
voidscanner_example(FILE*fp)
{
charch;inti,c;
ch=fgetc(fp);
if(isalpha(ch))/*itmustbeaidentifer!
*/
{
TOKEN[0]=ch;ch=fgetc(fp);i=1;
while(isalnum(ch))
{
TOKEN[i]=ch;i++;
ch=fgetc(fp);
}
TOKEN[i]=′\0′
fseek(fp,-1,1);/*retract*/
c=lookup(TOKEN);
if(c==0)out(ID,TOKEN);elseout(c,"");
}
else
if(isdigit(ch))
{
TOKEN[0]=ch;ch=fgetc(fp);i=1;
while(isdigit(ch))
{
TOKEN[i]=ch;i++;
ch=fgetc(fp);
}
TOKEN[i]=′\0′;
fseek(fp,-1,1);
out(INT,TOKEN);
}
else
switch(ch)
{
case′<′:
ch=fgetc(fp);
if(ch==′=′)out(LE,"");
elseif(ch==′>′)out(NE,"");
else
{
fseek(fp,-1,1);
out(LT,"");
}
break;
case′=′:
out(EQ,"");break;
case′>′:
ch=fgetc(fp);
if(ch==′=′)out(GE,"");
else
{
fseek(fp,-1,1);
out(GT,"");
}
break;
default:
report_error();break;
}
return;
}
提示:
扫描器所用的若干函数以及主程序有待于具体编写,并需事先建立好保留字表,以备查询。
另外,在扫描源程序字符串时,一旦识别出关键字、标识符、整常数以及运算符中之一,即以二元式形式(类别编码,值)输出单词。
每次调用词法分析程序,它均能自动继续扫描下去,形成下一个单词,直至整个源程序全部扫描完毕,并形成相应的单词串形式的源程序。
6、输出结果:
以文件形式输入的例子至少应包含两行以上的源代码,并以对照的形式将扫描器的分析结果输出,必要时给出正误信息。
例:
以下例题说明运行时的输入输出效果:
输入:
consta=10;
varb,c;
begin
read(b);
c:
=a+b;
write(c)
end.
输出:
(constsym,const)
(ident,a)
(eql,=)
(number,10)
(semicolon,;)
(varsym,var)
(ident,b)
(comma,,)
(ident,c)
(semicolon,;)
(beginsym,begin)
(readsym,read)
(lparen,()
(ident,b)
(rparen,))
(semicolon,;)
(ident,c)
(becomes,:
=)
(ident,a)
(plus,+)
(ident,b)
(semicolon,;)
(writesym,write)
(lparen,()
(ident,c)
(rparen,))
(endsym,end)
实验二.自顶向下语法分析
1.实验目的
(1)通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。
(2)选择最有代表性的语法分析方法递归子程序法;选择对各种常见程序语言都具备的语法结构,如赋值语句,特别是表达式,作为分析对象。
2.实验准备
微机CPUP4以上,256M以上内存,安装好C语言,或C++,或VisualC++.
3.实验时间
4学时
4.实验内容
●构造递归下降LL
(1)语法分析器。
完成P87,例4.12
5.实验要求
●语法分析器的编写方法采用递归子程序法。
扩充完整例4.12的程序部分。
●输入文法的句子,作为表达式语法分析器的输入,进行语法解析,对于语法正确的表达式,报告“语法正确”;
●对于语法错误的表达式,报告“语法错误”,指出错误原因。
●把语法分析器设计成一个独立一遍的过程。
6.输入输出
输入:
至少找到2个句子,其中一个是文法的句子,另一个不是,分别输入。
输出:
对于语法正确的表达式,报告“语法正确”;
对于语法错误的表达式,报告“语法错误”,指出错误原因。
实验三.自底向上语法分析
1.实验目的
给出算符优先关系表的构造方法,将FIRSTVT集合和LASTVT集合的算法扩充成程序。
2.实验准备
微机CPUP4以上,256M以上内存,安装好C语言,或C++,或VisualC++.
3.实验时间
4学时
4.实验内容
构造求FIRSTVT集合和LASTVT集合的程序。
5.实验要求
●扩充P113求FIRSTVT集合的算法。
●完成LASTVT集合的算法。
6.输入输出
输入:
文法。
输出:
FIRSTVT集合和LASTVT集合。
实验四.语义分析
1.实验目的
●通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法范畴变换为某种中间代码的语义翻译方法。
●掌握目前普遍采用的语义分析方法──语法制导翻译技术。
●要求在语法分析程序中添加语义处理,对于语法正确的算术表达式,输出其计算值。
2.实验准备
微机CPUP4以上,256M以上内存,安装好C语言,或C++,或VisualC++.
3.实验时间
4学时
4.实验内容
在表达式的语法分析程序里,添加语义处理部分。
5.实验要求
●语义分析对象重点考虑经过语法分析后已是正确的语法范畴,实习重点是语义子程序。
●在实验三“语法分析器”的里面添加PL/0语言“表达式”部分的语义处理。
●计算表达式的语义值。
6.输入输出
输入:
算术表达式,例如:
2+3*5作为输入。
输出:
17
实验五.中间代码生成
1.实验目的
要求在语法分析程序中添加语义处理,对于语法正确的表达式,输出其中间代码。
2.实验准备
微机CPUP4以上,256M以上内存,安装好C语言,或C++,或VisualC++.
3.实验时间
4学时
4.实验内容
在实验三的表达式语法分析程序里,添加语义处理部分输出表达式的中间代码,用四元式序列表示。
5.实验要求
●在实验三“语法分析器”的里面添加PL/0语言“表达式”部分的语义处理,输出表达式的中间代码。
●中间代码用四元式序列表示。
6.输入输出
输入:
表达式,例如:
a*(b+c)。
输出:
(+bct1)
(*at1t2)
六、课程设计
1、选题(四选一):
(1)构造递归下降分析程序语法分析器
(2)构造预测分析表语法分析器
(3)构造算符优先分析语法分析器
(4)构造LR(0)分析法语法分析器
2、设计方法:
小组分工,合作完成。
从小到大,逐步扩展。
按照文法和程序的特点,逐步完成设计和测试。
3、设计报告:
应包括:
报告标题、主要工作概述、具体内容(算法部分)、开发经验等。
七、考核方式
1、实验报告和课程设计报告
实验独立完成,提交实验报告;
课程设计采用分组的形式,3人一组,每个实习小组交一份课程设计报告,格式要求绝对规范!
内容应包括以下内容:
●题目
●设计思想
●算法
●调试数据(输入/输出)
2、评分标准
●由指导教师根据实验验收情况并结合实验报告质量及学习态度等进行评分。
●课程设计作为独立考查课,学分为1。
八、参考文献
[1]《编译原理》(第二版),张素琴、吕映芝、蒋维杜,清华大学出版社,2005年出版。
[2]《编译程序设计原理》,杜书敏、王永宁,北京大学出版社,1988年出版。
[3]《计算机编译原理》,张幸儿,科学出版社,1999年出版。
[4]《编译程序原理与技术》,李赣生等,清华大学出版社,1997年10月出版。
九、附录——PL0语言编译源程序清单(部分)
源代码
pl0c.h
/*关键字个数*/
#definenorw13
/*名字表容量*/
#definetxmax100
/*所有的add1用于定义数组*/
#definetxmaxadd1101
/*number的最大位数*/
#definenmax14
/*符号的最大长度*/
#defineal10
/*地址上界*/
#defineamax2047
/*最大允许过程嵌套声明层数*/
#definelevmax3
/*最多的虚拟机代码数*/
#definecxmax200
#definecxmaxadd1201
/*当函数中会发生fatalerror时,返回-1告知调用它的函数,最终退出程序*/
#definegetsymdoif(-1==getsym())return-1
#definegetchdoif(-1==getch())return-1
#definetestdo(a,b,c)if(-1==test(a,b,c))return-1
#definegendo(a,b,c)if(-1==gen(a,b,c))return-1
#defineexpressiondo(a,b,c)if(-1==expression(a,b,c))return-1
#definefactordo(a,b,c)if(-1==factor(a,b,c))return-1
#definetermdo(a,b,c)if(-1==term(a,b,c))return-1
#defineconditiondo(a,b,c)if(-1==condition(a,b,c))return-1
#definestatementdo(a,b,c)if(-1==statement(a,b,c))return-1
#defineconstdeclarationdo(a,b,c)if(-1==constdeclaration(a,b,c))return-1
#definevardeclarationdo(a,b,c)if(-1==vardeclaration(a,b,c))return-1
typedefenum{false,true}bool;
/*符号*/
enumsymbol{nul,ident,number,plus,minus,times,slash,oddsym,eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,semicolon,period,becomes,beginsym,endsym,ifsym,thensym,whilesym,writesym,readsym,dosym,callsym,constsym,varsym,procsym};
#definesymnum32
/*名字表中的类型*/
enumobject{constant,variable,procedur};
/*虚拟机代码*/
enumfct{lit,opr,lod,sto,cal,inte,jmp,jpc};
#definefctnum8
/*虚拟机代码结构*/
structinstruction
{
enumfctf;/*虚拟机代码指令*/
intl;/*引用层与声明层的层次差*/
inta;/*根据f的不同而不同*/
};
FILE*fas;/*输出名字表*/
FILE*fa;/*输出虚拟机代码*/
FILE*fa1;/*输出源文件及其各行对应的首地址*/
FILE*fa2;/*输出结果*/
boollistswitch;/*显示虚拟机代码与否*/
booltableswitch;/*显示名字表与否*/
charch;/*获取字符的缓冲区,getch使用*/
enumsymbolsym;/*当前的符号*/
charid[al];/*当前ident*/
intnum;/*当前number*/
intcc,ll,kk;/*getch使用的计数器,cc表示当前字符(ch)的位置*/
intcx;/*虚拟机代码指针*/
charline[81];/*读取行缓冲区*/
chara[al];/*临时符号*/
structinstructioncode[cxmaxadd1];/*存放虚拟机代码的数组*/
charword[norw][al];/*保留字*/
enumsymbolwsym[norw];/*保留字对应的符号值*/
enumsymbolssym[256];/*单字符的符号值*/
charmnemonic[fctnum][5];/*虚拟机代码指令名称*/
booldeclbegsys[symnum];/*表示声明开始的符号集合*/
boolstatbegsys[symnum];/*表示语句开始的符号集合*/
boolfacbegsys[symnum];/*表示因子开始的符号集合*/
/*名字表结构*/
structtablestruct
{
charname[al];/*名字*/
enumobjectkind;/*类型:
const,varorprocedure*/
intval;/*数值,仅const使用*/
intlevel;/*所处层,仅const不使用*/
intadr;/*地址,仅const不使用*/
intsize;/*需要分配的数据区空间,仅procedure使用*/
};
structtablestructtable[txmaxadd1];/*名字表*/
FILE*fin;
FILE*fout;
charfname[al];
interr;/*错误计数器*/
voiderror(intn);
intgetsym();
intgetch();
voidinit();
intgen(enumfctx,inty,intz);
inttest(bool*s1,bool*s2,intn);
intinset(inte,bool*s);
intaddset(bool*sr,bool*s1,bool*s2,intn);
intsubset(bool*sr,bool*s1,bool*s2,intn);
intmulset(bool*sr,bool*s1,bool*s2,intn);
intblock(intlev,inttx,bool*fsys);
voidinterpret();
intfactor(bool*fsys,int*ptx,intlev);
intterm(bool*fsys,int*ptx,intlev);
intcondition(bool*fsys,int*ptx,intlev);
intexpression(bool*fsys,int*ptx,intlev);
intstatement(bool*fsys,int*ptx,intlev);
voidlistcode(intcx0);
intvardeclaration(int*ptx,intlev,int*pdx);
intconstdeclaration(int*ptx,intlev,int*pdx);
intpostion(char*idt,inttx);
voidenter(enumobjectk,int*ptx,intlev,int*pdx);
intbase(intl,int*s,intb);
pl0c.c
/*
Windows下c语言PL/0编译程序
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译原理 编译 原理 实验 指导书