您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > 实验二-自上而下的语法分析
上海电力学院编译原理实验报告实验题目:自上而下的语法分析院系:计算机科学与技术学院专业年级:20年月日实验二自上而下的语法分析一、实验目的:通过本实验理解语法分析的作用,分析对象、分析的方式和处理的结果,是重点内容。二、实验学时:4学时。三、实验内容根据给出的简单语言的语法构成规则(见五),编制语法分析程序,要求能将词法分析输出的单词文件用给定的语法规则书写的源程序进行语法分析,输出相应的语法分析结果和错误信息。关于错误信息:不要求错误种类,只需给出出错位置(当前的输入符号)。四、实验方法递归下降法及LL(1)分析法。首先需手工将文法改写成LL(1)文法。选用递归下降法时需手工求出各个候选的首符集和非终结符号的FOLLOW集;选用LL(1)分析法时需手工求出预测分析表。对于整数和标识符的识别可以借助实验1。五、文法定义简单的表达式文法如下:E-E+T|E-T|TT-T*F|T/F|FF-(E)|i上式中,i为整数或标识符六、程序源代码#includestdlib.h#includestdio.h#includestring.h/*******************************************/intcount=0;/*分解的产生式的个数*/intnumber;/*所有终结符和非终结符的总数*/charstart;/*开始符号*/chartermin[50];/*终结符号*/charnon_ter[50];/*非终结符号*/charv[50];/*所有符号*/charleft[50];/*左部*/charright[50][50];/*右部*/charfirst[50][50],follow[50][50];/*各产生式右部的FIRST和左部的FOLLOW集合*/charfirst1[50][50];/*所有单个符号的FIRST集合*/charselect[50][50];/*各单个产生式的SELECT集合*/charf[50],F[50];/*记录各符号的FIRST和FOLLOW是否已求过*/charempty[20];/*记录可直接推出^的符号*/charTEMP[50];/*求FOLLOW时存放某一符号串的FIRST集合*/intvalidity=1;/*表示输入文法是否有效*/intll=1;/*表示输入文法是否为LL(1)文法*/intM[20][20];/*分析表*/charchoose;/*用户输入时使用*/charempt[20];/*求_emp()时使用*/charfo[20];/*求FOLLOW集合时使用*/intin(charc,char*p){inti;if(strlen(p)==0)return(0);for(i=0;;i++){if(p[i]==c)return(1);/*若在,返回1*/if(i==strlen(p))return(0);/*若不在,返回0*/}}charc(){charc='A';while(in(c,non_ter)==1)c++;return(c);}voidrecur(char*point){/*完整的产生式在point[]中*/intj,m=0,n=3,k;chartemp[20],ch;ch=c();/*得到一个非终结符*/k=strlen(non_ter);non_ter[k]=ch;non_ter[k+1]='\0';for(j=0;j=strlen(point)-1;j++){if(point[n]==point[0]){/*如果‘|’后的首符号和左部相同*/for(j=n+1;j=strlen(point)-1;j++){while(point[j]!='|'&&point[j]!='\0')temp[m++]=point[j++];left[count]=ch;memcpy(right[count],temp,m);right[count][m]=ch;right[count][m+1]='\0';m=0;count++;if(point[j]=='|'){n=j+1;break;}}}else{/*如果‘|’后的首符号和左部不同*/left[count]=ch;right[count][0]='^';right[count][1]='\0';count++;for(j=n;j=strlen(point)-1;j++){if(point[j]!='|')temp[m++]=point[j];else{left[count]=point[0];memcpy(right[count],temp,m);right[count][m]=ch;right[count][m+1]='\0';printf(count=%d,count);m=0;count++;}}left[count]=point[0];memcpy(right[count],temp,m);right[count][m]=ch;right[count][m+1]='\0';count++;m=0;}}}voidnon_re(char*point){intm=0,j;chartemp[20];for(j=3;j=strlen(point)-1;j++){if(point[j]!='|')temp[m++]=point[j];else{left[count]=point[0];memcpy(right[count],temp,m);right[count][m]='\0';m=0;count++;}}left[count]=point[0];memcpy(right[count],temp,m);right[count][m]='\0';count++;m=0;}chargrammer(char*t,char*n,char*left,charright[50][50]){charvn[50],vt[50];chars;charp[50][50];inti,j,k;printf(请输入文法的非终结符号串:);scanf(%s,vn);getchar();i=strlen(vn);memcpy(n,vn,i);n[i]='\0';printf(请输入文法的终结符号串:);scanf(%s,vt);getchar();i=strlen(vt);memcpy(t,vt,i);t[i]='\0';printf(请输入文法的开始符号:);scanf(%c,&s);getchar();printf(请输入文法产生式的条数:);scanf(%d,&i);getchar();for(j=1;j=i;j++){printf(请输入文法的第%d条(共%d条)产生式:,j,i);scanf(%s,p[j-1]);getchar();}for(j=0;j=i-1;j++)if(p[j][1]!='-'||p[j][2]!=''){printf(\ninputerror!);validity=0;return('\0');}/*检测输入错误*/for(k=0;k=i-1;k++){/*分解输入的各产生式*/if(p[k][3]==p[k][0])recur(p[k]);elsenon_re(p[k]);}return(s);}voidmerge(char*d,char*s,inttype){/*d是目标符号串,s是源串,type=1,源串中的‘^’一并并入目串;type=2,源串中的‘^’不并入目串*/inti,j;for(i=0;i=strlen(s)-1;i++){if(type==2&&s[i]=='^');else{for(j=0;;j++){if(jstrlen(d)&&s[i]==d[j])break;if(j==strlen(d)){d[j]=s[i];d[j+1]='\0';break;}}}}}voidemp(charc){/*即求所有由‘^’推出的符号*/chartemp[10];inti;for(i=0;i=count-1;i++){if(right[i][0]==c&&strlen(right[i])==1){temp[0]=left[i];temp[1]='\0';merge(empty,temp,1);emp(left[i]);}}}int_emp(charc){/*若能推出,返回1;否则,返回0*/inti,j,k,result=1,mark=0;chartemp[20];temp[0]=c;temp[1]='\0';merge(empt,temp,1);if(in(c,empty)==1)return(1);for(i=0;;i++){if(i==count)return(0);if(left[i]==c)/*找一个左部为c的产生式*/{j=strlen(right[i]);/*j为右部的长度*/if(j==1&&in(right[i][0],empty)==1)return(1);elseif(j==1&&in(right[i][0],termin)==1)return(0);else{for(k=0;k=j-1;k++)if(in(right[i][k],empt)==1)mark=1;if(mark==1)continue;else{for(k=0;k=j-1;k++){result*=_emp(right[i][k]);temp[0]=right[i][k];temp[1]='\0';merge(empt,temp,1);}}}if(result==0&&icount)continue;elseif(result==1&&icount)return(1);}}}intjudge(){inti,j;for(i=0;i=count-1;i++){if(in(left[i],non_ter)==0){/*若左部不在非终结符中,报错*/printf(\nerror1!);validity=0;return(0);}for(j=0;j=strlen(right[i])-1;j++){if(in(right[i][j],non_ter)==0&&in(right[i][j],termin)==0&&right[i][j]!='^'){/*若右部某一符号不在非终结符、终结符中且不为‘^’,报错*/printf(\nerror2!);validity=0;return(0);}}}return(1);}voidfirst2(inti){/*i为符号在所有输入符号中的序号*/charc,temp[20];intj,k,m;c=v[i];charch='^';emp(ch);if(in(c,termin)==1)/*若为终结符*/{first1[i][0]=c;first1[i][1]='\0';}elseif(in(c,non_ter)==1)/*若为非终结符*/{for(j=0;j=count-1;j++){if(left[j]==c){if(in(right[j][0],termin)==1||right[j][0]=='^'){temp[0]=right[j][0];temp[1]='\0';merge(first1[i],temp,1);}elseif(in(right[j][0],non_ter)==1){if(right[j][0]==c)continue;for(k=0;;k++)if(v[k]==right[j][0])break;if(f[k]=='0'){first2(k);f[k]='1';}merge(first1[i],first1[k],2);for(k=0;k=strlen(right[j])-1;k++){empt[0]='\0';if(_emp(right[j][k])==1&&kstrlen(right[j])-1){for(m=0;;m++)if(v[m]==right[j][k+
本文标题:实验二-自上而下的语法分析
链接地址:https://www.777doc.com/doc-4762977 .html