编译原理课程实验报告实验项目:算数表达式解释器的设计与实现专业班级:***********学生姓名:微博账号:航帅ottp学号:************课程教师:******指导教师:******实验时间:2016年11月09日计算机科学系实验目的:1.了解并掌握自顶向下语法分析的思想,熟悉递归下降子程序分析法。2.了解并掌握语法制导翻译法,掌握采用递归子程序进行语义分析的方法。实验要求:1.要求此算术表达式的解释器能够识别和计算加减乘除四则运算式。2.要求采用递归下降子程序法编写语法分析器。实验内容:用适当的程序设计语言编制一个算术表达式的解释器,并完成相应的调试,要求该程序能够读入一个算术表达式,运行后给出计算的结果。实验思路:用所编的“词法分析器”将源程序扫描成一个个的单词符号,将单词符号序列号和相应的单词符号保存在结构体数组c[]中。调用采用递归下降子程序法编写的算术表达式的“语法分析器”,对语义分析得到的表达式进行计算。实验设计、过程及结果:(1)实验程序代码设计#includestdio.h#includestdlib.h#includestring.h#includectype.h//************************词法分析器************************charch;//存放最新读进的源程序字符charstrToken[20];//存放字符串的字符数组structCiyu{intcode;chars[20];}c[100];//存放词法分析结果intm;//词法分析得到的单词符号数boolIsLetter(charletter)//判断ch是否为字母{if(isalpha(letter)!=0)return1;elsereturn0;}boolIsDigit(chardigit)//判断ch是否为数字{if(isdigit(digit)!=0)return1;elsereturn0;}voidEmpty(intxiabiao){for(intj=0;j=xiabiao;j++)strToken[j]='\0';}voidReserve(char*strToken)//判断是关键字还是标识符并输出{if(strcmp(strToken,void)==0){c[m].code=1;strcpy(c[m++].s,void);}elseif(strcmp(strToken,main)==0){c[m].code=2;strcpy(c[m++].s,main);}elseif(strcmp(strToken,int)==0){c[m].code=3;strcpy(c[m++].s,int);}elseif(strcmp(strToken,char)==0){c[m].code=4;strcpy(c[m++].s,char);}elseif(strcmp(strToken,scanf)==0){c[m].code=5;strcpy(c[m++].s,scanf);}elseif(strcmp(strToken,printf)==0){c[m].code=6;strcpy(c[m++].s,printf);}elseif(strcmp(strToken,if)==0){c[m].code=7;strcpy(c[m++].s,if);}elseif(strcmp(strToken,else)==0){c[m].code=8;strcpy(c[m++].s,else);}elseif(strcmp(strToken,do)==0){c[m].code=9;strcpy(c[m++].s,do);}elseif(strcmp(strToken,while)==0){c[m].code=10;strcpy(c[m++].s,while);}elseif(strcmp(strToken,for)==0){c[m].code=11;strcpy(c[m++].s,for);}elseif(strcmp(strToken,return)==0){c[m].code=12;strcpy(c[m++].s,return);}else{c[m].code=39;strcpy(c[m++].s,strToken);}}voidLexicalAnalyzer(FILE*f)//词法分析主要函数{Empty(19);ch=fgetc(f);inti=0;if(IsLetter(ch)){while(IsLetter(ch)||IsDigit(ch)){strToken[i]=ch;i++;ch=fgetc(f);}fseek(f,-1,1);Reserve(strToken);}elseif(IsDigit(ch)){while(IsDigit(ch)){strToken[i]=ch;i++;ch=fgetc(f);}fseek(f,-1,1);c[m].code=40;strcpy(c[m++].s,strToken);}elseif(ch=='+'){ch=fgetc(f);if(ch=='+'){c[m].code=26;strcpy(c[m++].s,++);}elseif(ch=='='){c[m].code=28;strcpy(c[m++].s,+=);}else{fseek(f,-1,1);c[m].code=13;strcpy(c[m++].s,+);}}elseif(ch=='-'){ch=fgetc(f);if(ch=='-'){c[m].code=27;strcpy(c[m++].s,--);}elseif(ch=='='){c[m].code=29;strcpy(c[m++].s,-=);}else{fseek(f,-1,1);c[m].code=14;strcpy(c[m++].s,-);}}elseif(ch=='='){ch=fgetc(f);if(ch=='='){c[m].code=24;strcpy(c[m++].s,==);}else{fseek(f,-1,1);c[m].code=18;strcpy(c[m++].s,=);}}elseif(ch=='!'){ch=fgetc(f);if(ch=='='){c[m].code=25;strcpy(c[m++].s,!=);}else{fseek(f,-1,1);c[m].code=19;strcpy(c[m++].s,!);}}elseif(ch==''){ch=fgetc(f);if(ch=='='){c[m].code=22;strcpy(c[m++].s,=);}else{fseek(f,-1,1);c[m].code=20;strcpy(c[m++].s,);}}elseif(ch==''){ch=fgetc(f);if(ch=='='){c[m].code=23;strcpy(c[m++].s,=);}else{fseek(f,-1,1);c[m].code=21;strcpy(c[m++].s,);}}elseif(ch=='*'){c[m].code=15;strcpy(c[m++].s,*);}elseif(ch=='/'){c[m].code=16;strcpy(c[m++].s,/);}elseif(ch=='%'){c[m].code=17;strcpy(c[m++].s,%);}elseif(ch==','){c[m].code=30;strcpy(c[m++].s,,);}elseif(ch==';'){c[m].code=31;strcpy(c[m++].s,;);}elseif(ch=='\'){c[m].code=32;strcpy(c[m++].s,\);}elseif(ch=='('){c[m].code=33;strcpy(c[m++].s,();}elseif(ch==')'){c[m].code=34;strcpy(c[m++].s,));}elseif(ch=='{'){c[m].code=35;strcpy(c[m++].s,{);}elseif(ch=='}'){c[m].code=36;strcpy(c[m++].s,});}elseif(ch=='['){c[m].code=37;strcpy(c[m++].s,[);}elseif(ch==']'){c[m].code=38;strcpy(c[m++].s,]);}elseif(ch=='\''){c[m].code=41;strcpy(c[m++].s,\');}elseprintf(*词法分析错误处理*\n);}//************************语法分析器************************doubleE(int&n);doubleE1(int&n);doubleT(int&n);doubleT1(int&n);doubleF(int&n);doubleE(int&n){returnT(n)+E1(n);}doubleE1(int&n){if(c[n].code==13){n++;returnT(n)+E1(n);}elseif(c[n].code==14){n++;return-T(n)+E1(n);}elsereturn0;}doubleT(int&n){returnF(n)*T1(n);}doubleT1(int&n){if(c[n].code==15){n++;returnF(n)*T1(n);}elseif(c[n].code==16){n++;return1/F(n)*T1(n);}elsereturn1;}doubleF(int&n){if(c[n].code==33){n++;doublee=E(n);if(c[n].code==34){n++;returne;}else{printf(*语法分析错误处理*\n);return-1;}}elseif(c[n].code==40){doublex=strtod(c[n].s,NULL);n++;returnx;}else{printf(*语法分析错误处理*\n);return-1;}}//************************主函数************************voidmain()//主函数{m=0;intn=0;FILE*p;p=fopen(E:\\Tonghang.txt,r);if(p==NULL){printf(Openfilefailed,can'tgoon!\n);return;}else{do{ch=fgetc(p);if(ch=='#')break;elseif(isspace(ch)!=0){}else{fseek(p,-1,1);LexicalAnalyzer(p);}}while(ch!='#');}fclose(p);printf(%f\n,E(n));}(2)实验过程与运行结果在E盘新建“Tonghang.txt”文件并输入如下所示源程序,运行算数表达式的解释器程序,得到算数表达式的结果。收获与体会:通过编程制作算数表达式解释器,我加深了对编译程序的工作过程的认识,尤其是对词法分析和语法分析的认识。词法分析的任务是从左至右逐个字符地对源程序进行扫描,产生一个个单词符号;语法分析的任务是在词法分析识别出单词符号串的基础上,分析并判断程序的语法结构是否符合语法规则。此外,我也加强了编程能力,培养了耐心。编程过程中不会的问题可以网上搜索,也可以查阅资料,还可以向老师请教,总有办法解决困难。编程的路还很长,我应该加强锻炼。最后,感谢老师对我的悉心指导。教师评语:教师签名:年月日实验成绩