电子科大编译原理实验报告得分80分.docx
《电子科大编译原理实验报告得分80分.docx》由会员分享,可在线阅读,更多相关《电子科大编译原理实验报告得分80分.docx(55页珍藏版)》请在冰豆网上搜索。
电子科大编译原理实验报告得分80分
电子科技大学
实验报告
学生姓名:
爸爸学号:
*************指导教师:
陈昆
实验地点:
科研楼A-506实验时间:
2017-04-28
一、实验项目名称:
词法分析器的设计与实现
二、实验学时:
4学时
三、实验原理
1.编译程序要求对高级语言编写的源程序进行分析和合成,生成目标程序。
词法分析是对源程序进行的首次分析,实现词法分析的程序为词法分析程序或词法分析器,也称扫描器。
2.词法分析的功能是:
从左到右逐个地扫描源程序字符串,按照词法规则,识别出单词符号作为输出,对识别过程中发现的词法错误,输出相关的错误信息。
3.识别出来的单词会采用某种中间表现形式,通常一个单词用一个二元式来表示:
(单词类别,单词的属性)。
4.状态转换图简称转化图,是有限有向图,是设计词法分析器的有效工具。
四、实验目的
通过该实验,让同学们自己独立自主的设计词法分析器,使得同学们可以更好的掌握词法分析程序设计的原理及相应的程序设计方法,对编译这门课程也可以有更加深刻理解,同时还可以锻炼编程能力。
五、实验内容
实现求n!
的极小语言的词法分析程序,返回二元式作为输出。
六、实验器材(设备、元器件)
1.操作系统:
WindowsXP
2.开发工具:
VS2013
七、实验步骤
(1)在VS2013中创建工程;
(2)编写输入输出,初始化,错误处理等函数;
(3)建立相应的单词符号与种别对照表,根据状态转换图编写相应的处理函数;
(4)运行代码进行调试;
(5)编写测试需要的输入文件:
.pas文件;
(6)生成.dyd文件。
八、实验数据及结果分析
编码完成后将测试程序放入debug文件夹中,测试程序如下图:
代码运行成功后在debug文件夹中会产生对应的exe,在cmd中运行后,会在debug文件夹中生成后缀为dyd和err的文件,打开dyd如下图所示:
因为没有错误,所以对应的test1.err的文件为空
可以对源程序进行词法分析,如果有错给出出错信息和所在行数,如果无错则生成二元式文件。
九、实验结论
词法分析器的功能是:
从左到右逐个的扫描源程序的字符串,按照词法规则,识别出单词符号作为输出,对识别过程中发现的词法错误,输出有关的错误信息。
十、总结及心得体会
通过本次实验,即对词法分析程序的设计,锻炼了自己的编程能力,同时加深了自己对词法分析器的理解和掌握以及对待编译这门课程的理解,提高了自己的动手能力,在编码的过程中也遇到了许多问题,例如如何解决产生的文件后端对齐等等问题,让我的编码能力在此次实验中得到了一定的提高。
十一、对本实验过程及方法、手段的改进建议
要先了解词法分析器的功能以及输入输出形式,熟练的掌握状态转化图。
报告评分:
指导教师签字:
实验参考源代码如下:
#include
#include
#include
#defineMAX_COUNT2048
#defineILLEGAL_CHAR_ERR1
#defineUNKNOWN_OPERATOR_ERR2
chargetnbc()
{
charch;
ch=getchar();
while
(1)
{
if(ch=='\r'||ch=='\t'||ch=='')
{
ch=getchar();
}
else
{
break;
}
}
returnch;
}
boolletter(charcharacter)
{
if((character>='a'&&character<='z')||(character>='A'&&character<='Z'))
returntrue;
else
returnfalse;
}
booldigit(charcharacter)
{
if(character>='0'&&character<='9')
returntrue;
else
returnfalse;
}
voidretract(char&character)
{
ungetc(character,stdin);
character=NULL;
}
intreserve(char*token)
{
if(strcmp(token,"begin")==0)
return1;
elseif(strcmp(token,"end")==0)
return2;
elseif(strcmp(token,"integer")==0)
return3;
elseif(strcmp(token,"if")==0)
return4;
elseif(strcmp(token,"then")==0)
return5;
elseif(strcmp(token,"else")==0)
return6;
elseif(strcmp(token,"function")==0)
return7;
elseif(strcmp(token,"read")==0)
return8;
elseif(strcmp(token,"write")==0)
return9;
else
return0;
}
intsymbol()
{
return10;
}
intconstant()
{
return11;
}
voidoutput(constchar*token,intkindNum)
{
printf("%16s%2d\n",token,kindNum);
}
boolerror(intlineNum,interrNum)
{
char*errInfo;
switch(errNum)
{
caseILLEGAL_CHAR_ERR:
errInfo="出现字母表以外的非法字符";
break;
caseUNKNOWN_OPERATOR_ERR:
errInfo="出现未知运算符";
break;
default:
errInfo="未知错误";
}
if(fprintf(stderr,"***LINE:
%d%s\n",lineNum,errInfo)>=0)
returntrue;
else
returnfalse;
}
boolLexAnalyze()
{
staticintlineNum=1;
charcharacter;
chartoken[17]="";
character=getnbc();
switch(character)
{
case'\n':
output("EOLN",24);
lineNum++;
break;
caseEOF:
output("EOF",25);
returnfalse;
case'a':
case'b':
case'c':
case'd':
case'e':
case'f':
case'g':
case'h':
case'i':
case'j':
case'k':
case'l':
case'm':
case'n':
case'o':
case'p':
case'q':
case'r':
case's':
case't':
case'u':
case'v':
case'w':
case'x':
case'y':
case'z':
case'A':
case'B':
case'C':
case'D':
case'E':
case'F':
case'G':
case'H':
case'I':
case'J':
case'K':
case'L':
case'M':
case'N':
case'O':
case'P':
case'Q':
case'R':
case'S':
case'T':
case'U':
case'V':
case'W':
case'X':
case'Y':
case'Z':
while(letter(character)||digit(character))
{
chars[2]={character};
strcat(token,s);
character=getchar();
}
retract(character);
intnum;
num=reserve(token);
if(num!
=0)
output(token,num);
else
{
intval;
val=symbol();
output(token,val);
}
break;
case'0':
case'1':
case'2':
case'3':
case'4':
case'5':
case'6':
case'7':
case'8':
case'9':
while(digit(character))
{
chars[2]={character};
strcat(token,s);
character=getchar();
}
retract(character);
intval;
val=constant();
output(token,val);
break;
case'=':
output("=",12);
break;
case'<':
character=getchar();
if(character=='>')
output("<>",13);
elseif(character=='=')
output("<=",14);
else
{
retract(character);
output("<",15);
}
break;
case'>':
character=getchar();
if(character=='=')
output(">=",16);
else
{
retract(character);
output(">",17);
}
break;
case'-':
output("-",18);
break;
case'*':
output("*",19);
break;
case':
':
character=getchar();
if(character=='=')
output(":
=",20);
else
error(lineNum,2);//输出“未知运算符”错误
break;
case'(':
output("(",21);
break;
case')':
output(")",22);
break;
case';':
output(";",23);
break;
default:
error(lineNum,1);
}
returntrue;
}
voidgetPath(char*in,char*out)
{
char*name;
name=strrchr(in,'\\');
if(name!
=NULL)
strncpy(out,in,strlen(in)-strlen(name)+1);
else
strcpy(out,"");
}
voidgetFilename(char*in,char*out)
{
char*fullName;
char*extension;
fullName=strrchr(in,'\\');
extension=strrchr(in,'.');
if(fullName!
=NULL)
strncpy(out,fullName+1,strlen(fullName)-1-strlen(extension));
else
strncpy(out,in,strlen(in)-strlen(extension));
}
boolinit(intargc,char*argv[])
{
if(argc!
=2)
{
returnfalse;
}
else
{
char*inFilename=argv[1];//argv[1];
charoutFilename[MAX_COUNT]="";
charerrFilename[MAX_COUNT]="";
charfilename[MAX_COUNT]="";
charpath[MAX_COUNT]="";
getFilename(inFilename,filename);
getPath(inFilename,path);
strcat(outFilename,path);
strcat(outFilename,filename);
strcat(outFilename,".dyd");
strcat(errFilename,path);
strcat(errFilename,filename);
strcat(errFilename,".err");
if(freopen(inFilename,"r",stdin)!
=NULL&&freopen(outFilename,"w",stdout)!
=NULL&&freopen(errFilename,"w",stderr)!
=NULL)
returntrue;
else
returnfalse;
}
}
voidmain(intargc,char*argv[])
{
if(init(argc,argv))
{
while(LexAnalyze())
{
}
}
fclose(stdin);
fclose(stdout);
fclose(stderr);
return;
}
电子科技大学
实验报告
学生姓名:
爸爸学号:
2222222222222指导教师:
陈昆
实验地点:
科研楼A-504实验时间:
2017-05-14
一、实验项目名称:
递归下降分析器的设计与实现
二、实验学时:
4学时
三、实验原理
1.语法分析是对源程序经过词法分析后转换成的单词流按方法规则进行判断,对能构成正确句子的单词流,给出相应的语法树;对不能构成正确句子的单词流判断其语法错误并做出相应处理。
2.在不含左递归的文法G中,如果对每一个非终结符的所有候选式的第一个终结符集合都是两两互不相交的(即无公共左因子),则可能(仅是可能)构造一个不带回溯的自上而下分析程序,这个分析程序由一组递归过程组成,每个过程对应文法的一个非终结符,这样的分析程序称为递归下降分析程序或递归下降分析器,其分析方法称为递归下降分析方法。
3.语法分析方法有自上而下和自下而上的分析方法。
四、实验目的
通过本次设计递归下降分析器的设计与实现实验,使同学们掌握自上而下的递归分析法的语法分析原理和程序设计方法,了解掌握递归下降分析方法。
五、实验内容
根据给定的方法,编写相应的递归下降的语法分析程序,实现对词法分析后的单词序列的语法检查和程序结构的分析,生成相应的变量名表和过程名表,并将编译中语法检查出来的错误写入相应的文件。
语法错分类:
(1)缺少符号错;
(2)符号匹配错
(3)符号无定义或重复定义。
六、实验器材(设备、元器件)
1.操作系统:
WindowsXP
2.开发工具:
VS2013
七、实验步骤
(1)启动VS2013,创建空白工程项目
(2)消除文法中的左递归;
(3)实现对方法进行递归向下的分析过程;
(4)利用词法分析器生成的二元式文件*.dyd进行语法分析;
(5)编译与调试以上程序;
(6)查看生成的后缀为var,err,pro的文件并进行截图保存
八、实验数据及结果分析
九、实验结论
本次实验实现了语法分析器,实现了语法分析器的功能,更加深刻地理解了递归下降分析法。
十、总结及心得体会
通过该实验,对递归下降分析程序的设计有着更好的掌握,同时锻炼了自己运用C语言进行编程的能力,也加深了自己对语法分析程序的原理的理解与掌握。
十一、对本实验过程及方法、手段的改进建议
先理解递归下降分析法的原理才能写出正确的程序。
报告评分:
指导教师签字:
本实验参考源代码如下:
#include
#include
#include
#defineMAX_COUNT1024
#defineSIGN_UNDEFINED_ERR1
#defineSIGN_REDEFINED_ERR2
#defineSIGN_EXECUTE_ERR3
#defineNO_SIGN_ERR4
#defineSIGN_RESERVE_ERR5
#defineNO_PARA_ERR6
typedefenum{integer}types;
typedefstruct{
charvname[17];
charvproc[17];
boolvkind;
typesvtype;
intvlev;
intvadr;
}varRecord;
typedefstruct{
charpname[17];
typesptype;
intplev;
intvarNum;
intfadr;
intladr;
intparameter;
boolparameterIsDefined;
}proRecord;
voidA();
voidB();
voidC();
voidC_();
voidD();
voidE();
voidF();
voidG();
voidJ();
voidK();
voidL();
voidM();
voidM_();
voidN();
voidO();
voidP();
voidQ();
voidR();
voidR_();
voidS();
voidS_();
voidT();
voidU();
voidW();
voidX();
voidY();
voidZ();
boolinit(intargc,char*argv[]);
boolfinal();
boolerror(intlineNum,interrNum,constchar*sign);
voidgetPath(char*in,char*out);
voidgetFilename(char*in,char*out);
boolnextToken();
boolnextChar();
boolisVarExisted(char*vname,char*vproc,boolvkind);
boolisProExisted(char*vname);
intgetNextToken();
charinput[MAX_COUNT][17];
intkind[MAX_COUNT];
intinputCount;
intpToken;
intpChar;
varRecordcurrentVar;
proRecordcurrentPro;
intlineNum;
varRecordvar[MAX_COUNT];
proRecordpro[MAX_COUNT];
intvarCount;
intproCount;
FILE*inFile;
FILE*outFile;
FILE*errFile;
FILE*varFile;
FILE*proFile;
intmain(intargc,char*argv[])
{
if(init(argc,argv))
{
A();
final();
}
return0;
}
boolinit(intargc,char*argv[])
{
if(argc!
=2)
{
returnfalse;
}
else
{
char*inFilename=argv[1];
charoutFilename[MAX_COUNT]="";
charerrFilename[MAX_COUNT]="";
charvarFilename[MAX_COUNT]="";
charproFilename[MAX_COUNT]="";
charfilename[MAX_COUNT]="";
charpath[MAX_COUNT]="";
//获得文件名(不包括扩展名)和路径
getFilename(inFilename,filename);
getPath(inFilename,path);
strcat(outFilename,path);
strcat(outFilename,filename);
strcat(outFilename,".dys");
strcat(errFilename,path);
strcat(errFilename,filename);
strcat(errFilename,".err");
strcat(v