《编译原理词法分析程序实验报告(共20页).doc》由会员分享,可在线阅读,更多相关《编译原理词法分析程序实验报告(共20页).doc(20页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上正规文法:ELB|N|SS|*|(|)|,|.|:=|;|=|=|NDN|DD0|1|2|3|4|5|6|7|8|9LA|B|C|.|Y|Z|a|b|c|.|y|zBLB|DB|L|D状态图: 空白 字母与数字210 字母 非字母与数字 *4 数字 非数字 5 +6 * . . .87 : = 1001109 = . * . 非= . 120 其他其中一个圆圈的是非终态,两个圆圈的是终态,两个圆圈且带一个*的是终态且多读了一个字符。单词种别定义: 单词符号种别编码单词符号种别编码program116begin2*17end3(18var4)19int5,20and6.
2、21or7:=22not8;23if924then10=27do13=28标示符1429常数(整)15 运行环境介绍:采用C+语言编写,VS2010编译调试。 关键算法描述: ch=fgetc(fp1); lineNum+; if (ch=/) ch=fgetc(fp1); lineNum+; if(ch=/) ch=fgetc(fp1); while (ch!=EOF&ch!=n) ch=fgetc(fp1); if(ch=n) rowNum+; lineNum=0; else break; else if(ch=*&Mark!=1) long len=ftell(fp1); int rn=
3、rowNum; int ln=lineNum; int sign=0; ch=fgetc(fp1); lineNum+; while (ch!=EOF&sign!=2) if(ch=n) rowNum+; lineNum=0; if(ch=/&sign=1)sign=2; else sign=0; if(ch=*)sign=1; ch=fgetc(fp1); lineNum+; if(sign=2) fseek(fp1,-1L,1); lineNum-; else Mark=1; fseek(fp1,len-2,0); lineNum=ln-2; rowNum=rn; ch= ; else E
4、rror_Handle(rowNum,lineNum-1);fseek(fp1,-1L,1);lineNum-; 此段代码主要用于对注释的处理,当读到一个字符是 / ,继续读其下一位字符,如果下一位字符是 / ,则其后整行内容作为注释,不对其进行词法分析,一直往后读直到遇到换行符n 。如果下一位字符是 * ,则一直往后读,直到遇到一个连续的*/,其中间内容作为注释,不对其进行词法分析;如果读到文件结尾也没用遇到一个连续的*/,则将字符指针移回 / 处,并将Mark变量置为1。如果下一位字符不是 / ,也不是 * 或Mark为1,则对/进行报错处理。此过程的状态转换图如下:3214 / 非 *7
5、6 / * * /5 非/ 不是 / ,也不是 * 或Mark为1 状态3表示为行注释,本行/后面的内容都是注释;状态7表示为/* */注释,/*和*/中间的内容为注释;状态5表示既不是行注释,也不是/* */注释,要进行其他处理(如:报错)。由于报错需要准错的指出错误的行号和列号,在程序中定义了两个变量rowNum和lineNum,每当读一个字符时,lineNum加1,当读到换行符时,rowNum加1,并将lineNum置0,在对注释进行处理的时候也遵循这样的操作。这样,即使有注释也可以准确的指出错误的行和列了。 else if(IsLetter(ch)while(IsLetter(ch)|
6、IsDigit(ch) Concat(ch);ch=fgetc(fp1);lineNum+;fseek(fp1,-1L,1);lineNum-;int code=Reserve();if(code=0) int Id_Num=0;vector:size_type i;for(i=0;iId.size();i+)if(stricmp(strToken,Idi.c_str()=0) Id_Num=i+1; break; if(Id_Num=0)Id.push_back(strToken);Tuple t;t.i=14;t.j=Id.size();return t;else Tuple t;t.i=
7、14;t.j=Id_Num;return t;else Tuple t; t.i=code; t.j=-1; return t;此段代码主要是对标识符的处理,若读到一个字母,则一直往后读,直到读到的字符不是一个字母或数字,然后调用Reserve()函数判断此字符串是不是关键字,若是关键字则返回此关键字的种别编码;若是标识符,则查标识符表,若标识符表中无此标识符,则将此标识符加入标识符表,然后返回标识符的种别编码和在标识符表中的位置。最后将字符指针向前移一位else if(IsDigit(ch)while(IsDigit(ch) Concat(ch);ch=fgetc(fp1);lineNum+
8、;fseek(fp1,-1L,1);lineNum-; int Id_Num=0;vector:size_type i;for(i=0;i=3 and n5 then j:=j-1; end . 测试结果:测试用例:program aa ; var int a ; begin a:=2; while a3 then /*Here is a comment*/ begin if a=5 then a:=4+a else a:=2*a; end /another comment else a:=a+1; end.测试结果:实验总结:通过这次实验,掌握了词法的形式化描述,熟悉了状态转换图,掌握了词法
9、分析的一些基本思想,实验中也遇到了不少问题,但是通过查询有关资料,都一一解决了,学到了不少的东西。最后,感谢易萍雯老师的精心讲解。附件(源代码):#include stdafx.h#include #include #include #include #include #include #include using namespace std;struct Tuple int i;int j; class Lex_analysis FILE *fp1; char fname1100; char ch; char*RS 13; char strToken100; int rowNum; int
10、lineNum; int Isopen; int Mark; vector Id; vector Constant; vector Error_info;public: Lex_analysis() Isopen=0;rowNum=1;lineNum=0;Mark=0;RS0=program;RS1=begin; RS2=end;RS3=var;RS4=int;RS5=and;RS6=or;RS7=not;RS8=if;RS9=then;RS10=else;RS11=while;RS12=do; ; int Reserve(); int IsLetter(char ch); int IsDig
11、it(char ch); void Concat(char ch); void Error_Handle(int n,int m); void display_Error_info(); void dispaly_Id(); void dispaly_Constant(); Tuple Analysis(); ;Tuple Lex_analysis:Analysis() memset(strToken,0,sizeof(strToken); if(Isopen=0) cout请?输?入?要癮进?行D词洙?法?分?析?的?文?件t路径?fname1; if(fp1=fopen(fname1,r)
12、=NULL) printf(Cannot open file!); _getch(); exit(1); Isopen=1; while (ch!=EOF) ch=fgetc(fp1); lineNum+; if (ch=/) ch=fgetc(fp1); lineNum+; if(ch=/) ch=fgetc(fp1); while (ch!=EOF&ch!=n) ch=fgetc(fp1); if(ch=n) rowNum+; lineNum=0; else break; else if(ch=*&Mark!=1) long len=ftell(fp1); int rn=rowNum; i
13、nt ln=lineNum; int sign=0; ch=fgetc(fp1); lineNum+; while (ch!=EOF&sign!=2) if(ch=n) rowNum+; lineNum=0; if(ch=/&sign=1)sign=2; else sign=0; if(ch=*)sign=1; ch=fgetc(fp1); lineNum+; if(sign=2) fseek(fp1,-1L,1); lineNum-; else Mark=1; fseek(fp1,len-2,0); lineNum=ln-2; rowNum=rn; ch= ; else Error_Hand
14、le(rowNum,lineNum-1);fseek(fp1,-1L,1);lineNum-; else if(ch=EOF);else if(ch= );else if(ch=t)lineNum=lineNum+3;else if(ch=n) rowNum+; lineNum=0; else if(IsLetter(ch)while(IsLetter(ch)|IsDigit(ch) Concat(ch);ch=fgetc(fp1);lineNum+;fseek(fp1,-1L,1);lineNum-;int code=Reserve();if(code=0) int Id_Num=0;vec
15、tor:size_type i;for(i=0;iId.size();i+)if(stricmp(strToken,Idi.c_str()=0) Id_Num=i+1; break; if(Id_Num=0)Id.push_back(strToken);Tuple t;t.i=14;t.j=Id.size();return t;else Tuple t;t.i=14;t.j=Id_Num;return t;else Tuple t; t.i=code; t.j=-1; return t;else if(IsDigit(ch)while(IsDigit(ch) Concat(ch);ch=fge
16、tc(fp1);lineNum+;fseek(fp1,-1L,1);lineNum-; int Id_Num=0;vector:size_type i;for(i=0;i) ch=fgetc(fp1); if(ch=) Tuple t; t.i= 27; t.j=-1; return t; fseek(fp1,-1L,1); lineNum-; Tuple t; t.i= 24; t.j=-1; return t;else if(ch=) Tuple t; t.i= 29; t.j=-1; return t; fseek(fp1,-1L,1); lineNum-; Tuple t; t.i=
17、25; t.j=-1; return t;else if(ch=) Tuple t; t.i= 26; t.j=-1; return t;else Error_Handle(rowNum,lineNum); fclose(fp1); Tuple t; t.i=-1; t.j=-1; return t; int Lex_analysis: Reserve()for(int i=1;i=a&ch=A&ch=0&ch=9)return 1;return 0;void Lex_analysis:Error_Handle(int n,int m)Tuple t;t.i=n;t.j=m;Error_inf
18、o.push_back(t);void Lex_analysis:display_Error_info()cout错误信息:endl;vector:size_type i; for(i=0;iError_info.size();i+) couti+1 :未识别的符号在Error_infoi.i行DError_infoi.j列endl;void Lex_analysis:dispaly_Id() cout标示符表endl; vector:size_type i; for(i=0;iId.size();i+) couti+1 Idiendl;void Lex_analysis:dispaly_Co
19、nstant() cout常数表endl; vector:size_type i; for(i=0;iConstant.size();i+) couti+1 Constantiendl;int _tmain(int argc, _TCHAR* argv)Lex_analysis L1;Tuple tupl;tupl=L1.Analysis();while(tupl.i!=-1)cout(tupl.i ;if(tupl.j=-1)cout-)endl;else couttupl.j)endl;tupl=L1.Analysis();L1.dispaly_Id();L1.dispaly_Constant();L1.display_Error_info();getch();return 0;专心-专注-专业