实验目的及要求.docx
- 文档编号:13053232
- 上传时间:2023-04-22
- 格式:DOCX
- 页数:20
- 大小:106.43KB
实验目的及要求.docx
《实验目的及要求.docx》由会员分享,可在线阅读,更多相关《实验目的及要求.docx(20页珍藏版)》请在冰豆网上搜索。
实验目的及要求
编译原理
实
验
报
告
日期:
班级:
题目:
组员:
1实验目的及要求
1.通过设计、编写、调试一个具体的词法分析程序,加深对词法分析原理的理解。
2.掌握在对程序设计语言源程序进行扫描的过程中,将其分解为各类单词的词法分析方法。
2实验平台
Windows+VC+Win32Console
3实验步骤
1.查询资料,了解词法分析器的工作过程与原理。
2.分析题目,整理出基本设计思路。
3.实践编码,将设计思想转换用c语言编码实现,编译运行。
4.测试功能,多次设置包含不同字符,关键字的待解析文件,仔细察看运行结果,检测该分析器的分析结果是否正确。
通过最终的测试发现问题,逐渐完善代码中设置的分析对象与关键字表,拓宽分析范围提高分析能力。
4实验内容
4.1实现下述功能,并将分析结果保存在文件中.(既可以参考范例程序,也可以独立完成)
程序输入/输出示例:
输入一段C语言程序,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、界符。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)
输入源程序示例:
main()
{
inta,b=10;
intc;
c=a+b*20;
}
输出固定表格如下
单词类型
单词种别
标识符
1
保留字
2
常量
3
运算符
4
分界符
5
保留字
地址指针
int
1
float
2
main
3
printf
4
…
…
运算符表4
分界符表5
界符
地址指针
,
1
;
2
(
3
)
4
{
5
…
…
算符
地址指针
+
1
-
2
*
3
/
4
=
5
…
…
输出动态表格如下
标识符
地址指针
a
1
b
2
c
3
常量
地址指针
10
1
20
2
符号表
单词名称
类别
地址指针
int
2
1
c
1
3
;
5
2
c
1
3
=
4
5
a
1
1
+
4
1
b
1
2
*
4
3
20
3
2
;
5
2
单词名称
类别
地址指针
int
2
1
c
1
3
;
5
2
c
1
3
=
4
5
a
1
1
+
4
1
b
1
2
*
4
3
20
3
2
;
5
2
}
5
6
4.2程序:
#include
#include
#include
#include
//定义关键字
char*Key[10]={"main","void","int","char","printf","scanf","else","if","return"};
charWord[20],ch;//存储识别出的单词流
intIsAlpha(charc){//判断是否为字母
if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A')))return1;
elsereturn0;
}
intIsNum(charc){//判断是否为数字
if(c>='0'&&c<='9')return1;
elsereturn0;
}
intIsKey(char*Word){//识别关键字函数
intm,i;
for(i=0;i<9;i++){
if((m=strcmp(Word,Key[i]))==0)
{
if(i==0)
return2;
else
return1;
}
}
return0;
}
voidscanner(FILE*fp){//扫描函数
charWord[20]={'\0'};
charch;
inti,c;
ch=fgetc(fp);//获取字符,指针fp并自动指向下一个字符
if(IsAlpha(ch)){//判断该字符是否是字母
Word[0]=ch;
ch=fgetc(fp);
i=1;
while(IsNum(ch)||IsAlpha(ch)){//判断该字符是否是字母或数字
Word[i]=ch;
i++;
ch=fgetc(fp);
}
Word[i]='\0';//'\0'代表字符结束(空格)
fseek(fp,-1,1);//回退一个字符
c=IsKey(Word);//判断是否是关键字
if(c==0)printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│1\t│1\t\t│\n",Word);//不是关键字
elseif(c==2)
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│2\t│3\t\t│\n",Word);
else
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│3\t│1\t\t│\n",Word);//输出关键字
}
else//开始判断的字符不是字母
if(IsNum(ch)){//判断是否是数字
Word[0]=ch;
ch=fgetc(fp);
i=1;
while(IsNum(ch)){
Word[i]=ch;
i++;
ch=fgetc(fp);
}
Word[i]='\0';
fseek(fp,-1,1);//回退
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│3\t│1\t\t│\n",Word);
}
else//开始判断的字符不是字母也不是数字
{
Word[0]=ch;
switch(ch){
case'[':
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│5\t│7\t\t│\n",Word);break;
case']':
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│5\t│9\t\t│\n",Word);break;
case'(':
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│5\t│3\t\t│\n",Word);break;
case')':
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│5\t│4\t\t│\n",Word);break;
case'{':
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│5\t│5\t\t│\n",Word);break;
case'}':
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│5\t│6\t\t│\n",Word);break;
case',':
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│5\t│1\t\t│\n",Word);break;
case'"':
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│5\t│8\t\t│\n",Word);break;
case';':
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│5\t│2\t\t│\n",Word);break;
case'+':
ch=fgetc(fp);
Word[1]=ch;
if(ch=='='){
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word);//运算符"+="
}
elseif(ch=='+'){
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word);//判断结果为"++"
}
else{
fseek(fp,-1,1);
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│1\t\t│\n",Word);//判断结果为"+"
}
break;
case'-':
ch=fgetc(fp);
Word[1]=ch;
if(ch=='='){
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word);}
elseif(ch=='-'){
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word);//判断结果为"--"
}
else{
fseek(fp,-1,1);
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│2\t\t│\n",Word);//判断结果为"-"
}
break;
case'*':
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│3\t\t│\n",Word);break;
case'/':
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│4\t\t│\n",Word);break;
case'!
':
case'=':
ch=fgetc(fp);
if(ch=='='){
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word);
}
else{
fseek(fp,-1,1);
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│5\t\t│\n",Word);
}
break;
case'<':
ch=fgetc(fp);
Word[1]=ch;
if(ch=='='){
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word);//判断结果为运算符"<="
}
elseif(ch=='<'){
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word);//判断结果为"<<"
}
else{
fseek(fp,-1,1);
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word);//判断结果为"<"
}
break;
case'>':
ch=fgetc(fp);
Word[1]=ch;
if(ch=='=')printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word);
else{
fseek(fp,-1,1);
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word);
}
break;
case'%':
ch=fgetc(fp);
Word[1]=ch;
if(ch=='='){printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t\t│4\t│6\t\t│\n",Word);}
if(IsAlpha(ch))printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t│类型标识符\t│\t│\n",Word);
else{
fseek(fp,-1,1);
printf("\t\t├───────┼───┼───────┤\n\t\t│%s\t│取余运算符\t│\t\n",Word);
}
break;
default:
printf("\t\t├───────┼───┼───────┤\n\t\t│无法识别字符!
\t\t\t\t│\n");break;
}
}
}
main()
{
charin_fn[30];//文件路径
FILE*fp;
printf("\n请输入源文件名(包括路径和后缀名):
");
while(true){
gets(in_fn);
//scanf("%s",in_fn);
if((fp=fopen(in_fn,"r"))!
=NULL)break;//读取文件内容,并返回文件指针,该指针指向文件的第一个字符
elseprintf("文件路径错误!
请重新输入:
");
}
printf("\n****************************单词类别表****************************\n");
printf("\t\t┌───────┬───────┐\n\t\t│单词类型\t│单词种别\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│标识符\t│1\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│保留字\t│2\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│常量\t│3\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│运算符\t│4\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│分界符\t│5\t│\n",Word);
printf("\t\t└───────┴───────┘\n",Word);
printf("\n****************************保留字表******************************\n");
printf("\t\t┌───────┬───────┐\n\t\t│保留字\t│地址指针\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│int\t│1\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│float\t│2\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│main\t│3\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│printf\t│4\t│\n",Word);
printf("\t\t└───────┴───────┘\n",Word);
printf("\n****************************运算符表******************************\n");
printf("\t\t┌───────┬───────┐\n\t\t│算符\t│地址指针\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│+\t│1\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│-\t│2\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│*\t│3\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│/\t│4\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│=\t│5\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│其他\t│6\t│\n",Word);
printf("\t\t└───────┴───────┘\n",Word);
printf("\n****************************分界符表******************************\n");
printf("\t\t┌───────┬───────┐\n\t\t│界符\t│地址指针\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│,\t│1\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│;\t│2\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│(\t│3\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│)\t│4\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│{\t│5\t│\n",Word);
printf("\t\t├───────┼───────┤\n\t\t│}\t│6\t│\n",Word);
printf("\t\t└───────┴───────┘\n",Word);
printf("\n****************************词法分析结果如下******************************\n");
printf("\t\t┌───────┬───┬───────┐\n\t\t│单词名称\t│类别\t│地址指针\t│\n",Word);
do{
ch=fgetc(fp);
if(ch=='#')break;//文件以#结尾,作为扫描结束条件
elseif(ch==''||ch=='\t'||ch=='\n'){}//忽略空格,空白,和换行
else{
fseek(fp,-1,1);//回退一个字节开始识别单词流
scanner(fp);
}
}while(ch!
='#');
printf("\t\t└───────┴───┴───────┘\n",Word);
return(0);
}
5实验结果
5.1解析源文件:
main()
{
inta,b=10;
intc;
c=a+b*20;
}
#
5.2解析结果:
6实验总结分析
在本次实验,使我们再次浏览了有关C语言的一些基本知识,特别是对文件,字符串进行基本操作的方法。
C语言中没有string类型,因此本实验中的对字符串提取与识别均借助#include
让我们练习对字符串函数应用的同时也提高了自己的逻辑思维能力。
在本次实验中,我纠正了一个一直以来的概念错误:
main不是关键字,它定义为程序的入口,是主函数!
在本实验中,虽然我把main初始化在关键字表(字符指针类型数组)*Key[10]中,当与该数组中字符串进行比较时,若与main匹配成功,则返回2,若为其他关键字则返回1,以此来把main从关键字中区别出来。
在本实验中的关键字表只初始化了几个常用的关键字,还可继续扩充(只需扩大数组,向其中补充要添加的关键字)。
如果要对本程序中未识别的c语言中的一些其他的字符进行扩充(目前处理为不可识别字符),可在程序代码中继续添加case选项,分别对相应要识别的特殊字符加以描述。
程序中,我们利用特殊符号构造表格,使画面美观,易于观察。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 目的 要求