《编译原理及实践实验课程》实验一 C++源代码单词扫描程序(词法分析)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
院系:计算机学院
实验课程:编译原理及实践实验课程
实验项目:C++源代码单词扫描程序(词法分析)指导老师:XXX
开课时间:XXXX~ XXXX年度第 1学期
专业:XXXX
班级:XXXX级本X班
学生:XXX
学号:XXXXXXXX
实验一:C++源代码单词扫描程序(词法分析)
一、实验题目
C++包含了多种符号类型,主要有标识符、数(包括整数、浮点数)、关键字、注释、字符串、特殊符号、运算符号等等。
通过编写一个C++源代码打你扫描程序,实现对扫描文件进行词法分析,并输出分析结果。
二、实验功能
1. C++源代码扫描程序识别C++记号
C++语言包含了几种类型的记号:标识符,关键字,数(包括整数、浮点数),字符串、注释、特殊符号(分界符)和运算符号等。
2. 打开一个C++源文件,打印出所有以上的记号
3. 要求应用程序应为Windows界面
4. 选作部分:
为了提高C++源程序的可读性,C++程序在书写过程中加入了空行、空格、缩进、注释等。
假设你想牺牲可读性,以节省磁盘空间,那么你可以存贮一个删除了所有不必要空格和注释的C++源程序的压缩文本。
因此,程序中还应该有这样的压缩功能。
5. 选作部分:
进一步思考或实现——如何进一步实现减小源文件大小的压缩功能。
6. 应该书写完善的软件文档。
三、实验思路
1. 通过文件流方式,实现字符的读取,因此先定义文件流名:
FILE *fp; //定义文件名,在文件流使用
2. 对于读取出来的字符,进行类型的判断,分别从以下函数实现:
(1)当读取的是字符串时,则调用字符串处理函数,声明如下:
c har string(char c[]); //字符串处理函数声明
(2)当读取的是字母时,则调用字母处理函数,声明如下:
char letter(char ch); //字母处理函数声明
(3)当读取的是数字时,则调用数字处理函数,声明如下:
char number(char ch); //数字处理函数声明
(4)当读取的既不是字符串,也不是字母,又不是数字,则调用其他处理函数,声明如下:
char other(char ch); //其他处理函数声明
3. 为了空格、换行等进行判断识别,调用了头文件为“ctype.h”中的函数isspace( )、isdigit( )、isalnum( )等。
四、源代码
1. 全局变量声明和定义
/**********全局变量的声明和定义***********/
FILE *fp; //定义文件名,在文件流使用
char string(char c[]); //定义字符串,用于字符串处理
char ch;
//定义字符数组,用于存放关键字
char *keyword[41]={"include","iostream","iostream.h","string","stdio","stdio.h","math.h", //头文件中关键字
"int","double","float","char","long","short","enum","struct", "typedef",//数据类型中的关键字
"if","else","switch","case","default","break","continue","return", //条件选择中的关键字
"do", "while","for","goto","Loop","cin","cout", "printf","sizeof", //循环中的关键字
"const","static","signed","unsigned","union","volatile","void","main"
//其他的关键字
};
//定于字符数组,用于存放运算符
char *operate[6]={"+","-","*","/","++","--"};
//定义字符数组,用于存放特殊符号
char
*symbol[31]={"%","$","^","&","_","#","<","<=","=",">",">=","<>","<<","==","!=","&&","||","!",
",",";", ":=", ".", "(", ")", "{", "}","&&","||","!","()",">>"
};
//定义字符数组,用于存放注释符号
char *note[3]={"//","/*","*/"};
2. 字符串处理函数
char string(char c[]) //字符串处理函数定义
{
int i=0 ;
char stri[100];
stri[i]=c[0];
ch=fgetc(fp);
while (ch!='"')
{
stri[++i]=ch;
ch=fgetc(fp);
}
stri[++i]=ch;
stri[++i]='\0';
cout<<stri<<" "<<"字符串"<<endl;
return (ch);
}
3. 字母处理函数
char letter(char ch) //字母处理函数定义
{
int i=-1;
char letter[50];
while (isalnum(ch)||ch=='.') //是字母、头文件处理{
letter[++i]=ch;
ch=fgetc(fp);
}
letter[i+1]='\0';
if (search(letter,1))
{
cout<<letter<<" "<<"关键字"<<endl;
}
else
{
cout<<letter<<" "<<"标识符"<<endl;
}
return (ch);
}
4. 字母处理函数
char number(char ch) //数字处理函数声明
{
int i=-1;
char num[20];
while (isdigit(ch)!=0)
{
num[++i]=ch;
ch=fgetc(fp);
}
if(isalpha(ch)!=0)
{
while(!isspace(ch))
{
num[++i]=ch;
ch=fgetc(fp);
}
num[i+1]='\0';
cout<<num<<""<<"error!"<<endl;
goto loop;
}
num[i+1]='\0';
cout<<num<<" "<<"数字"<<endl;
loop: return (ch);
}
5. 其他处理函数
char other(char ch) //其他函数处理定义
{
int i=-1;
char other[1000];
if (isspace(ch)) //是空格
{
ch=fgetc(fp);
goto loop;
}
while ((!isspace(ch))&&(!isalnum(ch))) //不是空格且不是字母或数字{
other[++i]=ch;
ch=fgetc(fp); //若是字母,不是空格的判断没有写出来}
other[i+1]='\0';
if (search(other,2))
cout<<other<<" "<<"算数运算符"<<endl;
else
if (search(other,3))
cout<<other<<" "<<"特殊符号"<<endl;
else
if (search(other,3))
cout<<other<<" "<<"注释符"<<endl;
loop: return (ch);
}
6. 符号匹配查找函数
int search(char searchstr[],int type) //符号匹配查找函数定义{
int i;
switch (type)
{
case 1:
for(i=0;i<41;i++)
{
if(strcmp(keyword[i],searchstr)==0)
return 1;
}
case 2:
for(i=0;i<6;i++)
{
if(strcmp(operate[i],searchstr)==0)
return 1;
}
break;
case 3:
for(i=0;i<31;i++)
{
if(strcmp(symbol[i],searchstr)==0)
return 1;
}
break;
case 4:
for(i=0;i<3;i++)
{
if(!strcmp(note[i],searchstr)&&i==2)
{
string(searchstr);
break;
}
else
if(!strcmp(note[i],searchstr))
return 1;
}
break;
}
return 0;
}
7. 主函数
void main () //主函数,人机交互的接口
{
cout<<"**********************C++源代码单词扫描程序(词法分析)************************"<<endl;
cout<<"____________________________________________________________________ ___________"<<endl;
cout<<endl;
char str,c, FileName[100];
while(1)
{
cout<<"请输入需扫描分析的文件名(包括文件扩展名):";
cin>>FileName;
fp=fopen(FileName,"r"); //判断文件是否存在
if(fp==0)
cout<<"指定文件不存在,请输入正确的文件名!"<<endl<<endl;
else
{
cout<<endl<<FileName<<"扫描结果:"<<endl;
cout<<"____________________"<<endl;
str=fgetc(fp);
while (str!=EOF)
{
if (isalpha(str))
str=letter(str);
else
{
if (isdigit(str))
str=number(str);
else
str=other(str);
}
}
}
}
c=getch();
}
五、程序执行结果
1. 初始界面
2. 当输入文件名不符合条件时,提醒重新输入
3. 输入符合条件的文件名后,进行词法分析,并输出分析结果
六、实验小结
1. 通过这次实验,使得自己对于编程更加熟悉了,之前很久没有编写程序,
导致这次实验做的时间周期比较长,还出现开始时无从下手的情况。
最后在同学的帮助和上网找资料的情况下,慢慢解决的问题。
以后自己会多多编程的。
2. 因为个人能力不够,程序还是有欠缺,最后的分析结果有些问题,不过收
获比较大。
对于编译原理有了初步认识,为下面的学习提供了很大的帮助。
3. 接下来会再修改程序出现的问题,再次完善自己的代码。