实验11 根据状态转换图手工构造词法分析程序.docx
- 文档编号:30689919
- 上传时间:2023-08-19
- 格式:DOCX
- 页数:16
- 大小:111.60KB
实验11 根据状态转换图手工构造词法分析程序.docx
《实验11 根据状态转换图手工构造词法分析程序.docx》由会员分享,可在线阅读,更多相关《实验11 根据状态转换图手工构造词法分析程序.docx(16页珍藏版)》请在冰豆网上搜索。
实验11根据状态转换图手工构造词法分析程序
编译原理实验报告
实验类型:
单元实验
基础实验/选做实验
实验名称:
实验1.1根据状态转换图手工构造词法分析程序
姓名:
______________
学号:
____________
班级:
_________________
一、原创性声明
参考代码:
参考了两处代码,第一部分是关键字的定义,自己想的没有这位学长写的全面,所以就直接拿过来用了;第二部分是参考学长的文件读写操作部分。
代码来源:
XX文库《编译原理课程设计词法分析器文档》作者是烟大张金荣学长。
二、实验要求
1.手工构造一个简单的词法分析程序。
-能够识别标识符、整数、关键字、算符、界符
-可输出至文件,也可输出至屏幕
★1.使用缓冲技术(单缓冲或双缓冲)
2.词法分析器作为一个子程序被语法分析器调用。
±每次调用返回一个单词
±同时将单词及属性存入符号表
★★根据状态转换图手工构造词法分析程序。
从以下方法中选一:
✧直接转向法
✧表驱动法
三、完成情况
●功能1:
基本内容
✧功能描述:
-能够识别标识符、整数、关键字、算符、界符
-可输出至文件,也可输出至屏幕
✧完成情况:
基本完成
✧Bug:
能发现的bug都已修改,
✧备注:
标识符、整数、关键字、算符、界符都是自定义的,并不能识别所有的标识符、整数、关键字、算符、界符
●功能2:
选做内容
功能描述:
使用缓冲技术(双缓冲)
根据状态转换图手工构造词法分析程序:
直接转向法
✧完成情况:
基本完成
✧Bug:
能发现的bug都已修改,
✧备注:
代码中有几个方法是多余的:
boolisIdentifier(char*s)/*是否是标识符*/
boolisNumber(char*s)/*是否为数字*/
原本是想在main函数中调用这两个函数,使main函数结构更加简单明了,结果发现加不进去,会破坏代码的逻辑。
四、实现方案
状态转换图:
五、创新和亮点
创新之处:
并没什么创新之处,
亮点:
用了GOTO语句,使代码易读性增强。
底层的操作都在最基本的函数中,其他函数再调用这些函数来实现自己的功能,这些函数又供其他函数调用。
使代码逻辑性,易读性增强。
Main函数中不写多余代码,调用其他方法,结构清晰。
六、运行结果
输入内容:
输出结果(部分):
七、源码
/*********************************************************/
#include
#include
#include
usingnamespacestd;
/*各种变量的定义*/
Stringkeywords[36]={"char","short","int","unsigned","long","float","double",
"struct","union","void","enum","const","typedef","auto",
"static","break","case","continue","default","do","else",
"for","if","return","switch","while","sizeof","printf",
"FILE","fopen","NULL","fclose","exit","read","close",
"fprintf"};
chardelimiters[]={'[',']','(',')','{','}','\'','\"',',',';',':
'};
charoperators[5]={'+','-','*','/','='};
ifstreaminfile;/*输入文件*/
ofstreamoutfile;/*输出文件*/
charbuffer1[64];/*缓冲数组1*/
charbuffer2[64];/*缓冲数组2*/
char*pointer;/*扫描指针*/
/*各种函数的声明*/
boolisChar(charc);/*是否是字母*/
boolisDigit(charc);/*是否是0-9*/
boolisUnderline(charc);/*是否是下划线*/
boolisEnter(charc);/*是否是换行*/
boolisDelimiter(charc);/*是否是界符*/
boolisOperator(charc);/*是否是运算符*/
intgetLength(char*s);/*求一个字符串的长度*/
boolisIdentifier(char*s);/*是否是标识符*/
boolisNumber(char*s);/*是否为数字*/
boolisKeyword(char*s);/*是否是关键字*/
chargetChar();/*实现双缓冲扫描文件*/
voidwrite(stringstr1,stringstr2);/*写入文件,并且在屏幕上打印*/
/*程序入口:
main函数*/
intmain()
{
charcc='\0';
stringstr="";
pointer=buffer1;
buffer1[63]=buffer2[63]=-1;//数组尾数值为-1
infile.open("in.txt",ios:
:
binary);//二进制文件
outfile.open("out.txt",ios:
:
trunc);//再次写入覆盖文件已有内容
for(inti=0;i<=62;i++)
buffer1[i]=infile.get();//将文件中字符放入第一缓冲区
for(;;)
{
str="";
cc=getChar();
str+=cc;
AAA:
if(isDelimiter(cc))/*是否是界符*/
{
write("界符",str);
}
elseif(isOperator(cc))/*是否是操作符*/
{
write("操作符",str);
}
elseif(isEnter(cc))/*是否是换行符*/
{
write("换行","\\n");
}
elseif(isUnderline(cc)||isChar(cc))/*是否是标识符*/
{
for(;;)
{
cc=getChar();
if(!
(isChar(cc)||isDigit(cc)||isUnderline(cc)))
{
write("标识符",str);
str=cc;
gotoAAA;
}
str+=cc;
}
}
elseif(isDigit(cc))/*是否是数字*/
{
for(;;)
{
cc=getChar();
if(!
(isDigit(cc))&&cc!
='.')
{
write("数字",str);
str=cc;
gotoAAA;
}
str+=cc;
}
}
}
return0;
}
/**********************************************************************/
/*双缓冲扫描文件*/
chargetChar()
{
if(*pointer==-1)/*当前指针在缓冲区(不知是那个缓冲区)末尾*/
{
if(pointer==buffer1+63)/*在第一buffer尾,向第二buffer读入数据*/
{
for(inti=0;i<=62;i++)
{
buffer2[i]=infile.get();
}
pointer=buffer2;
returngetChar();
}
elseif(pointer==buffer2+63)/*在第二buffer尾,向第一buffer读入数据*/
{
for(inti=0;i<=62;i++)
{
buffer1[i]=infile.get();
}
pointer=buffer1;
returngetChar();
}
else/*在不是buffer尾的位置读到了EOF,说明完成了分析*/
{
infile.close();
outfile.close();
ofstreamout;
cout<<"\n\n\t词法分析完毕!
"< system("pause"); exit(-1); } } return*pointer++; } /*是否是字母*/ boolisChar(charc) { if((c>='a'&&c<='z')||(c>='A'&&c<='Z')) { returntrue; } else { returnfalse; } } /*是否是0-9*/ boolisDigit(charc) { if(c>='0'&&c<='9') { returntrue; } else { returnfalse; } } /*是否是下划线*/ boolisUnderline(charc) { if(c=='_') { returntrue; } else { returnfalse; } } /*是否是换行*/ boolisEnter(charc) { if(c=='\n') { returntrue; } else { returnfalse; } } /*是否是界符*/ boolisDelimiter(charc) { for(inti=0;i<10;i++) { if(c==delimiters[i]) { returntrue; } } returnfalse; } /*是否是运算符*/ boolisOperator(charc) { for(inti=0;i<5;i++) { if(c==operators[i]) { returntrue; } } returnfalse; } /*求一个字符串的长度*/ intgetLength(char*s) { intlen=0; for(inti=0;;i++) { if(s[i]! ='\0') { len++; } else { returnlen; } } } /*是否是标识符*/ boolisIdentifier(char*s) { intlen=getLength(s); if(isChar(s[0])||isUnderline(s[0])) { for(inti=1;i { if(! (isDigit(s[i])||isDigit(s[i])||isUnderline(s[i]))) { returnfalse; } } returntrue; } else { returnfalse; } } /*是否为数字*/ boolisNumber(char*s) { intlen=getLength(s); if(s[0]>=1&&s[0]<=9) { for(inti=0;i { if(! isDigit(s[i])&&s[i]! ='.') { returnfalse; } } returntrue; } else { returnfalse; } } /*是否是关键字*/ boolisKeyword(char*s) { for(inti=0;i { if(s==keywords[i]) { returntrue; } } returnfalse; } /*写入文件,并且在屏幕上打印*/ voidwrite(stringstr1,stringstr2) { cout< "< outfile<<"[<"< \""< }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验11 根据状态转换图手工构造词法分析程序 实验 11 根据 状态 转换 手工 构造 词法 分析 程序