1、北邮编译原理词法分析报告程序报告材料程序设计一词法分析程序一实验题目和要求题目:词法分析程序的设计与实现。实验容:设计并实现C语言的词法分析程序,要求如下。(1)、可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号。(2)、可以识别并读取源程序中的注释。(3)、可以统计源程序汇总的语句行数、单词个数和字符个数,其中标点和空格不计算为单词,并输出统计结果(4)、检查源程序中存在的错误,并可以报告错误所在的行列位置。(5)、发现源程序中存在的错误后,进行适当的恢复,使词法分析可以继续进行,通过一次词法分析处理,可以检查并报告源程序中存在的所有错误。实验要求:方法1:采用
2、C/C+作为实现语言,手工编写词法分析程序。方法2:通过编写LEX源程序,利用LEX软件工具自动生成词法分析程序。二程序设计思路 采用C+来编写此程序。根据书上的函数、变量提示写出各种函数、整体框架。大部分变量名称与书上相同。 画出符号间转换自动机模型,之后根据自动机写函数、错误判断。 缓冲区用数组完成,标记位置的指针用int型来表示。 用lnum存储语句行数,wordnum存储单词个数,charnum存储字符个数。标点和空格不计算为单词。 错误所在的行列位置存储在error.txt文件当中。3程序运行结果举例Code.txt: #includemain() int num,n=0,m,l,t
3、; printf(please input an integer:); scanf(%d,&num); /dsfsdf for(l=0;num!=0;l+) m=num%10; /sdfafda for(t=0;t!=l;t+) m=m*2; /dafdaf n=nm; num=num/10; /*dafdas2323*/ printf(/the result is %d /,n); return 0 ;窗口运行结果:= *词法分析系统*=请输入需要分析的文件名称:code.txt-处理完毕。共出现1个错误。共有21行,33个单词,236个字符。结果请在token_table.txt中查看。=
4、请按任意键继续. . .Token.txt;单词 记号# #include id relop,GTmain id( () ) int intnum id, ,n id= relop,EQ0 num, ,m id, ,l id, ,t id; ;printf id( () ); ;scanf id( (, ,& &num id) ); ;for for( (l id= relop,EQ0 num; ;num id!= RELOP,UE0 num; ;l id+ + +) ) m id= relop,EQnum id% %10 num; ;for for( (t id= relop,EQ0 num
5、; ;t id!= RELOP,UEl id; ;t id+ + +) )m id= relop,EQm id* *2 num; ;n id= relop,EQnm id; ;num id= relop,EQnum id/ /10 num; ; printf id( (, ,n id) ); ;return return0 num; ; Error.txt:1.在第1行第15列出现非法字符Note.txt:line6.双引号间字符:please input an integer:line7.双引号间字符:%dline7.ddsfsdfline10.ssdfafdaline12.ddafdafl
6、ine14.dafdas2323line17.双引号间字符:/the result is %d /Count.txt:共有21行,33个单词,236个字符。四源代码头文件:#include#include#include#include#include#includeusing namespace std;全局变量:const int MAXBUFFER=62; /缓冲区容量 const int LB=30; /左缓冲区大小 const int LRB=61; /左+右缓冲区大小const int KEY=32; /关键字个数 fstream code_file;intum;/列数 int l
7、b_end,rb_end,forward; /左右缓冲区结束位置,向前指针 int lready,rready; /标记左右缓冲区是否已经录入过容 char bufferMAXBUFFER; /缓冲区 char C; /当前读入的字符 string token;/存放单词的字符串 int keynum,errornum; /关键字的序列号 ; error的个数 int lnum,wordnum,charnum;/语句数 单词数 字符数 char *keyKEY=auto,const,double,float,int,short,struct ,unsigned,break,continue,e
8、lse,for,long,signed ,switch,void,case,default,enum,goto,register ,static,typedef,volatile,char,do,extern,if ,return,sizeof,union,while; /关键字表 函数:void fillbuf(int x) if(x=0) /填充左半区 if(lready=0) /左半区未填充 code_file.read(buffer,LB); /读入LB个字符到buffer左半区中 if(code_file.gcount()!=lb_end) /如果读入的字符不足LB个在之后添加EOF
9、 buffercode_file.gcount()=EOF; else lready=0; else /填充右半区 if(rready=0) code_file.read(buffer+LB+1,LB); /读入LB个字符到buffer右半区中 if(code_file.gcount()!=LB) buffercode_file.gcount()+LB+1=EOF; else rready=0; void get_nbc();void get_char() C=bufferforward; /获取当前字符 if(C=EOF) return; else if(C=n) um=0; /列=0 ln
10、um+; /+1行 else if(C=33 & C=126) charnum+; /字母或数字或符号的话+1字符 /cout第charnum字符-Cendl; um+; forward+; if(bufferforward=EOF) if(forward=lb_end) /到左区结束位置 填充右半区 fillbuf(1); forward+; if(forward=rb_end) /到右区结束位置 填充左半区 向前指针回到开始位置 fillbuf(0); forward=0; void retract()/向前指针后退一个字符 charnum-; um-; if(forward=0) lre
11、ady=1; /避免重新读取 forward=rb_end-1; /后退一个字符 else if(forward=lb_end) rready=1; forward-; else forward-;void get_nbc() /若C中的字符为空字符则反复调用直到非空字符为止 while(C= | C=t| C=0 | C=n) get_char(); retract();int reserve(string word)/查关键字表 返回0表示token中的字符串是标识符 1表示关键字 for(keynum=0;keynumKEY;keynum+) if(pare(keykeynum)=0)
12、return 1; return 0;主函数:main() cout=endl;cout *词法分析系统* endl;cout=endlendl; cout请输入需要分析的文件名称:s; code_file.open(s); int p; while(code_file=NULL) cout无此文件,打开失败。请重新输入:s; code_file.open(s); /初始化 lb_end=LB; rb_end=LRB; forward=0; lready=rready=0; lnum=1; um=0; wordnum=charnum=0; bufferlb_end=bufferrb_end=E
13、OF; fillbuf(0); errornum=0; cout-endl; fstream token_table,error,count,note; error.open(error.txt,ios_base:out); /保存错误 count.open(count.txt,ios_base:out); /保存语句数单词数字符数计数 note.open(note.txt,ios_base:out); /保存注释 token_table.open(token.txt,ios_base:out);/输出的记号 token_table单词tt 记号64 & C96 & C64 & C96 & C
14、47 & C58) | C=_) /字母或数字或下划线 token=token+C; get_char(); if(C!= & C!=t& C!=0 & C!=n) retract(); wordnum+; /这是一个单词 if(reserve(token)=0)/这是一个标识符 token_tabletokentt idendl; else /这是一个关键字 token_tabletokentttokenendl; else if(C=) get_char(); while(C!=) token=token+C; get_char(); notelinelnum.双引号间字符: token4
15、7 & C47 & C47 & C47 & C47 & C47 & C58) token=token+C; get_char(); if(C!= & C!=t& C!=0 & C!=n) retract();/后退一位后退出 else retract(); errornum+; errorerrornum.在第lnum 行第cnum列出现错误 47 & C47 & C58) token=token+C; get_char(); if(C!= & C!=t& C!=0 & C!=n) retract();/后退一位后退出 else retract(); errornum+; errorerror
16、num.在第lnum行第 cnum列出现错误endl; else /退出 if(C!= & C!=t& C!=0 & C!=n) retract(); else/记录错误 退出此if重新判断 retract(); errornum+; errorerrornum.在第lnum行第cnum列出现错误 47 & C47 & C58) token=token+C; get_char(); if(C!= & C!=t& C!=0 & C!=n) retract();/后退一位后退出 else retract(); errornum+; errorerrornum.在第lnum行 第cnum列出现错误4
17、7 & C47 & C58) token=token+C; get_char(); if(C!= & C!=t& C!=0 & C!=n) retract();/后退一位后退出 else retract(); errornum+; errorerrornum.在第lnum行第 cnum列出现错误endl; else if(C!= & C!=t& C!=0 & C!=n) retract(); token_tabletokentt numendl; else switch(C) case : /或者=或者 get_char(); if(C=) token_table=tt relop,LE) t
18、oken_tablett relop,NEendl; else token_tablett relop,LT:/或者= get_char(); if(C=) token_table=tt relop,GEendl; else token_tablett relop,GTendl; if(C!= & C!=t& C!=0 & C!=n) retract(); break; case =: /= token_table=tt relop,EQendl; break; case : /:=或者: get_char(); token_tabletoken:tt :endl; if(C!= & C!=t
19、& C!=0 & C!=n) retract(); break; case !: /!= get_char(); if(C=) token_table!=tt RELOP,UEendl; else if(C!= & C!=t& C!=0 & C!=n) retract(); token_table!tt !endl; break; case /: /过滤注释 get_char(); if(C=/) /过滤掉/开头的注释 get_char(); notelinelnum.C; while(C!=n) noteC; et_char(); noteendl; else if(C=*) /过滤掉/*开
20、头的注释 notelinelnum.; while(1) get_char(); while(C!=*) noteC; get_char(); get_char(); if(C=/) noteendl; break; else note*C; else if(C!= & C!=t& C!=0 & C!=n) retract(); token_table/tt /endl; break; case#: case+: case-: case(: case): case: case: case ;: case%: case,: case *: case&: case: case: token_tableCtt Cendl; break; default: errornum+; errorerrornum.在第lnum行第cnum列出现非法字符endl; cout处
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1