C语言词法分析器构造实验报告.docx
- 文档编号:9847358
- 上传时间:2023-02-07
- 格式:DOCX
- 页数:12
- 大小:17.80KB
C语言词法分析器构造实验报告.docx
《C语言词法分析器构造实验报告.docx》由会员分享,可在线阅读,更多相关《C语言词法分析器构造实验报告.docx(12页珍藏版)》请在冰豆网上搜索。
C语言词法分析器构造实验报告
C语言词法分析器构造实验报告
02计算机
(2)03xx
一、题目要求:
完成一个C语言的词法分析器的构造。
此词法分析器能识别附值语句、循环语句、条件语句、并能处理注释。
二、设计方案:
这个词法分析器分析的主要关键字有:
main,int,float,char,if,else,for,while,do,switch,case,break;default。
选择要分析的c文件,首先对其去掉注释和与空格处理,再根据字符的不同类型分析。
1、全局数据结构:
字符数组set[]:
存放从文件中读到的所有字符;
str[]:
存放经过注释处理和预空格处理的字符;
strtoken[]:
存放当前分析的字符;
结构体KEYTABLE:
存放关键字及其标号;
全局字符变量ch:
当前读入字符;
全局整型变量sr,to:
数组str,strtoken的指针。
2、以层次图形式描述模块的组成及调用关系
Main()
Analysis()
Set32()
Openfile()Reflesh()
Concat()
GetChar()GetBC()
Process()
Reserve()
GetChar()IsDigit()
IsLetter()
Retract()
3、主要函数的设计要求(功能、参数、返回值):
openfile:
打开文件;
GetChar:
将下一个输入字符读到ch中,搜索指示器前移一字符位置;
GetBC:
检查ch中的字符是否为空白。
若是,则调用GetChar直至ch中进入一个非空白字符;Concat:
将ch中的字符连接到strtoken之后;
IsLetter和IsDigit:
布尔函数过程,分别判断ch中的字符是否为字母和数字;
Reserve:
整型函数过程,对strtoken中的字符串查找关键字表,若是关键字则返回编码,否则返回-1;Retract:
将搜索指示器回调一个字符位置,将ch置为空白字符;
reflesh:
刷新,把strtoken数组置为空;
prearrange1:
将注释部分置为空格;
prearrange2:
预处理空格,去掉多余空格;
analysis:
词法分析;
main:
主函数。
4、状态转换图:
1字母或数字
字母非字母或数字
数字20非数字
字符a
字符b4„=‟
字符c
字符a包括:
=,&,|,+,--
字符b包括:
--,<,>,|,*
字符c包括:
,:
(,),{,},[,],!
#,%,”,/,*,+,--,>,<,.
三、源代码如下:
#include
#include
charset[1000],str[500],strtoken[20];
charsign[50][10],constant[50][10];
charch;
intsr,to,id=0,st=0;
typedefstructkeytable/*放置关键字*/{charname[20];593字符a876intkind;
}KEYTABLE;
KEYTABLEkeyword[]={/*设置关键字*/
{"main",0},
{"int",1},
{"float",2},
{"char",3},
{"if",4},
{"else",5},
{"for",6},
{"while",7},
{"do",8},
{"switch",9},
{"case",10},
{"break",11},
{"default",12},
};
openfile()/*打开文件*/{FILE*fp;
chara,filename[10];
intn=0;
printf("Inputthefilename:
");
gets(filename);
if((fp=fopen(filename,"r"))==NULL){printf("cannotopenfile.\n");
exit
(0);}else
while(!
feof(fp))/*文件不结束,则循环*/{a=getc(fp);/*getc函数带回一个字符,赋给a*/
set[n]=a;/*文件的每一个字符都放入set[]数组中*/
n++;}fclose(fp);/*关闭文件*/
set[n-1]='\0';
printf("\n\n-------------------SourceCode--------------------------\n\n");
puts(set);
printf("\n--------------------------------------------------------\n");}reflesh()/*清空strtoken数组*/{to=0;/*全局变量to是strtoken的指示器*/
strcpy(strtoken,"");}prearrange1()/*预处理程序1*/{inti,a,b,n=0;
do{if(set[n]=='/'&&set[n+1]=='*'){a=n;/*记录第一个注释符的位置*/
while(!
(set[n]=='*'&&set[n+1]=='/'))
n++;
b=n+1;/*记录第二个注释符的位置*/
for(i=a;i<=b;i++)/**/
set[i]='';/*把注释的内容换成空格,等待第二步预处理*/}n++;
}while(set[n]!
='\0');}prearrange2()/*预处理程序2*/{intj=0;
sr=0;/*全局变量sr是str[]的指示器*/
do{if(set[j]==''||set[j]=='\n'){while(set[j]==''||set[j]=='\n')/*扫描到有连续的空格或换行符*/
j++;
str[sr]='';/*用一个空格代替扫描到的连续空格和换行符放入str[]*/
sr++;}else{str[sr]=set[j];/*若当前字符不为空格或换行符就直接放入str[]*/
sr++;
j++;}}while(set[j]!
='\0');
str[sr]='\0';}charGetChar()/*把字符读入全局变量ch中,指示器sr前移*/{ch=str[sr];
sr++;
return(str[sr-1]);}voidGetBC()/*开始读入符号,直至第一个不为空格*/{while(ch==''){ch=GetChar();}}
Concat()/*把ch中的字符放入strtoken[]*/{strtoken[to]=ch;
to++;/*全局变量to是strtoken的指示器*/
strtoken[to]='\0';}intIsLetter()/*判断是否为字母*/{if((ch>=65&&ch<=90)||(ch>=97&&ch<=122))
return
(1);
elsereturn
(0);}intIsDigit()/*判断是否为数字*/{if(ch>=48&&ch<=57)
return
(1);
elsereturn
(0);}intReserve()/*对strtoken中的字符串查找保留字表,若是则返回它的编码,否则返回-1*/{inti,k=0;
for(i=0;i<=20;i++){if(strcmp(strtoken,keyword[i].name)==0)
{k=1;
return(keyword[i].kind);}}
if(k!
=1)
return(-1);}voidRetract()/*指示器sr回调一个字符位置,把ch置为空*/{sr--;
ch='';}intInsertId(){inti,k;
for(i=0;i if(k==0) return(i);}strcpy(sign[id],strtoken);/*插入标识符*/ id++; return(id-1);}intInsertConst(){inti,k; for(i=0;i if(k==0) return(i);}strcpy(constant[st],strtoken);/*插入常数*/ st++; return(st-1);}voidanalysis(){intvalue; reflesh();/*清空strtoken数组*/ prearrange1();/*预处理,使注释内容换成单个空格,放回set[]中*/ prearrange2();/*预处理,使set[]中连续的空格置换成单个空格,并把set[]的内容放到str[]中*/sr=0; GetChar(); GetBC();/*读取第一个字符*/ while(ch! ='\0')/*当不等于结束符,继续执行*/{if(IsLetter()){while(IsLetter()||IsDigit())/*若第一个是字符,继续读取,直到出现空格*/{Concat(); GetChar();}Retract();/*指示器sr回调一个字符位置,把ch置为空*/ value=Reserve();/*对strtoken中的字符串查找保留字表,若是则返回它的编码,否则返回-1*/if(value==-1)/*如果返回值是-1,那就是变量,把它输出*/{InsertId();/*插入标识符*/ printf("\n%s",strtoken); getch();}else/*否则就是关键字,也输出*/{printf("\n%s",strtoken); getch();}reflesh();}elseif(IsDigit()){while(IsDigit())/*否则,若第一个是数字,继续读取,知道出现空格*/{Concat(); GetChar();}Retract(); InsertConst();/*插入常数*/ printf("\n%s",strtoken); getch(); reflesh();}else switch(ch)/*否则,若是下面的符号,就直接把它输出*/ case',': case';': case'(': case')': case'{': case'}': case'[': case']': case'! ': case'#': case'%': case'"': case'/': case'*': Concat(); printf("\n'%s'",strtoken); getch(); reflesh(); break; default: if(ch=='='||ch=='&'||ch=='|'||ch=='+'||ch=='-'){Concat(); GetChar(); if(ch==strtoken[0]) Concat(); else Retract(); printf("\n'%s'",strtoken); getch(); reflesh(); break;/*如果是这些符号,继续读取下一个*//*判断是否为==,&&,||,++,--的情况*/{}elseif(ch=='+'||ch=='-'||ch=='<'||ch=='>'||ch=='! '||ch=='*'){ Concat();/*判断是否为+=,-=,<=,>=,! =,*=的情况*/GetChar(); if(ch=='=') Concat(); else}GetChar(); GetBC();}} main(){clrscr(); openfile(); analysis(); printf(“analysisisover! ”);} 五、测试结果: 1、分析文件test1.c中的程序: Inputthefilename: test.cRetract(); printf("\n'%s'",strtoken); getch(); reflesh(); break;}else{printf("Error! "); getch(); break;}*****************OriginalCode************************ /*HELLO.C--Hello,world*/ #include"stdio.h" #include"conio.h" main(){printf("Hello,world\n"); getch();}***************************************************** '#' include '"' stdio '.' h '"' '#' include '"' conio '.' h '"' main '(' ')' '{' printf '(' '"' Hello ',' worldError! n '"' ')' ';' getch '(' ')' ';' '}' Analysisisover! 六、实验总结: 这个程序主要参考书上关于词法分析器的设计。 在设计过程中仍有遇到很多困难,但经请教同学后,好多问题都并不是想象中的困难。 尽管如此,分析考虑还不全面,例如没有创建符号表和常数表。 这些情况将在在语法和语义分析时进行完善。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 词法 分析器 构造 实验 报告