您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > C语言词法分析器构造实验报告(1)1
C语言词法分析器构造实验报告02计算机(2)2002374203冯绍欣一、题目要求:完成一个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、以层次图形式描述模块的组成及调用关系3、主要函数的设计要求(功能、参数、返回值):openfile:打开文件;GetChar:将下一个输入字符读到ch中,搜索指示器前移一字符位置;GetBC:检查ch中的字符是否为空白。若是,则调用GetChar直至ch中进入一个非空白字符;Main()Openfile()Analysis()Reflesh()Process()Set32()GetChar()GetBC()Concat()Reserve()IsLetter()IsDigit()Retract()GetChar()Concat:将ch中的字符连接到strtoken之后;IsLetter和IsDigit:布尔函数过程,分别判断ch中的字符是否为字母和数字;Reserve:整型函数过程,对strtoken中的字符串查找关键字表,若是关键字则返回编码,否则返回-1;Retract:将搜索指示器回调一个字符位置,将ch置为空白字符;reflesh:刷新,把strtoken数组置为空;prearrange1:将注释部分置为空格;prearrange2:预处理空格,去掉多余空格;analysis:词法分析;main:主函数。4、状态转换图:字母或数字字母非字母或数字数字数字非数字字符a字符a字符b‘=’字符c字符a包括:=,&,|,+,--字符b包括:--,,,|,*字符c包括:,,:,(,),{,},[,],!,#,%,”,/,*,+,--,,,.三、源代码如下:#includestdio.h#includestring.hcharset[1000],str[500],strtoken[20];charsign[50][10],constant[50][10];charch;intsr,to,id=0,st=0;typedefstructkeytable/*放置关键字*/{charname[20];0123467598intkind;}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);}elsewhile(!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;iid;i++){k=strcmp(strtoken,sign[i]);if(k==0)return(i);}strcpy(sign[id],strtoken);/*插入标识符*/id++;return(id-1);}intInsertConst(){inti,k;for(i=0;ist;i++){k=strcmp(strtoken,constant[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();}elseswitch(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();elseRetract();printf(\n'%s',strtoken);getch();reflesh();break;}elseif(ch=='+'||ch=='-'||ch==''||ch==''||ch=='!'||ch=='*'){Concat();/*判断是否为+=,-=,=,=,!=,*=的情况*/GetChar();if(ch=='=')Concat();elseRetract();printf(\n'%s',strtoken);getch();reflesh();break;}else{printf(Error!);getch();break;}}GetChar();GetBC();}}main(){clrscr();openfile();analysis();printf(“analysisisover!”);}五、测试结果:1、分析文件test1.c中的程序:Inputthefilename:test.c*****************OriginalCode************************/*HELLO.C--Hello,world*/#includestdio.h#includeconio.hmain(){printf(Hello,world\n);getch();}*****************************************************'#'include''stdio'.'h'''#'include''
本文标题:C语言词法分析器构造实验报告(1)1
链接地址:https://www.777doc.com/doc-5719606 .html