《LL1语法分析程序.docx》由会员分享,可在线阅读,更多相关《LL1语法分析程序.docx(29页珍藏版)》请在优知文库上搜索。
1、编译原理上机试验报告题目:1.1.(I)语法分析程序1 .设计要求(1)对输入文法,它能推断是否为1.1.(I)文法,若是,则转(2):否则报错并终止;(2)输入已知文法,由程序自动生成它的1.1.(D分析表:(3)对于给定的输入串,应能推断识别该串是否为给定文法的句型。2 .分析该程序可分为如下几步:(1)读入文法(2)推断正误(3)若无误,推断是否为1.1.(D文法(4)若是,构造分析表;(5)由总控算法推断输入符号串是否为该文法的句型。3 .流程图ftincludeintcount=0;/*分解的产生式的个数*/charstart:*起先符号*/chartermin50;*终结符号*/c
2、harnon_ter50;/*非终结符号*/charv50;/*全部符号*/charleft50:/*左部*/charright5050;/*右部*/intnumber;/*全部终结符和非终结符的总数*/charfirst5050,follow5050;/*各产生式右部的FIRST和左部的FO1.1.OW集合*/charfirst!5050;*全部单个符号的FIRST集合*/charselect5050;/*各单个产生式的SE1.ECT集合*/charf50,F50;/*记录各符号的FIRST和FO1.1.OW是否已求过*/charempty20;/*记录可干脆推出C的符号*/charTEMF
3、j50;/*求FO1.1.OW时存放某一符号串的FIRST集合*/intvalidity=l;/*表示输入文法是否有效*/int11=1;/*表示输入文法是否为1.1.(I)文法*/intM2020;/*分析表*/*用户输入时运用*/charchoose;charempt20;*求_emp()时运用*/charfo20;*求FO1.1.OW集合时运用*/推断一个字符是否在指定字符串中intin(charc,char*p)/inti;size_ti;if(strlen(p)=0)return(0);for(i=0;i+)if(pi=c)return(1);*若在,返回1*/if(i=strlen
4、(p)return(0);*若不在,返回0*/得到一个不是非终结符的符号charc()charc=,;while(in(c,non_ter)=l)c+;return(c);分解含有左递归的产生式voidrecur(char*point)/*完整的产生式在point口中*/intj,m=0,n=3,k:chartemp20,ch;ch=cO;*得到一个非终结符*/k=strlen(non_ter):non_terk=ch;non_terk+l=,0,:for(j=0;size_t(j)=strlen(point)-1;j+)if(pointn=point0)*假如I后的首符号和左部相同*/for
5、(j=n+l;size_t(j)=strlen(point)-1;j+)while(pointj!=,j,&pointj!三,0,)tempm+=pointj+;leftcount=ch;memcpy(rightcount,temp,m);rightcountm=ch:rightcountm+l,0,;m=0;count+;if(pointj=I,)n=j+l;break:else*假如I后的首符号和左部不同*/leftcount=ch:rightcount0=,;rightcount1,0,;count+;for(j=n:size_t(j)tempEm+=pointj:elseleftcou
6、nt=point0;memcpy(rightcount,temp,m);rightcountm=ch:rightcountm+l=0;printf(*count=%d*,count);m=0;count+:leftcount=point0;memcpy(rightcount,temp,m):rightcountm=ch;rightcountm+l=,0,:count+;m=0;分解不含有左递归的产生式voidnon_re(char*point)intm=0,J;chartemp20;for(j=3;size_t(j)=strlen(point)-1;j+)if(pointj!三,)tempm+
7、=pointj:elseleftcount=point0;memcpy(rightcount,temp,m);rightcountm=,0,;m=0:count+;leftcount=point0:memcpy(rightcount,temp,m);rightcountm=,0;count+;m=0:读入一个文法chargrammer(char*t,char*n,char*left,charright5050)charvn50,vt50;chars:charp5050;inti,j,k:printf11请输入文法的非终结符号串:”);scanf(*%sw,vn):getchar();i=str
8、len(vn);mcmcpy(n,vn,i);ni三0,;PrintfC请输入文法的终结符号串:scanf(*%s*,vt);getchar();i=strlen(vt);memcpy(t,vt,i);ti=0,;PrintfC请输入文法的起先符号:scanfC%c*,&s);getchar();Printf(请输入文法产生式的条数:”);SCanf(,&i);getchar();for(j=l;j=i:j+)Printf(请输入文法的第%d条(共%d条)产生式:”,j,i);scanfC%sa,pj-l);getchar0:for(j=0;j)Iprintf(*ninputerror!”);
9、Validity=O:returnC0);/*检测输入错误*/for(k=0;k=i-l;k+)/*分解输入的各产生式*/if(pk3pk0)recur(pk);elsenon_re(pk);return(三);将单个符号或符号串并入另一符号串voidmerge(char*d,char*s,inttype)*d是目标符号串,S是源串,type=l,源串中的一一并并入目串:type=2,源串中的八不并入目串*/i11ti,j;for(i=O:size_t(i)=str1en(三)-1;i+)if(type=2si=*,)elsefor(j=0;j+)if(size-t(j)strlen(d)ft
10、ftsi=dj)break;if(size_t(j)=strlen(d)dj=si;dj+l三,0,;break;求全部能干脆推出C的符号Voidcmp(charc)/*即求全部由C推出的符号*/chartemp10;inti;for(i=0;i=count-l;i+)if(righti0=c&strlen(righti)=1)tempO=lefti;templ=*0;merge(empty,temp,1);emp(lefti):求某一符号能否推出一int_emp(charc)/*若能推出,返回1;否则,返回O*/inti,j,k,result=1,mark=0;chartemp20;temp
11、0=c;templ=,0,;merge(empt,temp,1):if(in(c,empty)=1)return(l):for(i=0;i+)if(i=count)return(0);if(lefti=c)*找一个左部为C的产生式*/j=strlen(righti);*j为右部的长度*/if(j=l&in(righti0,empty)=1)return(1);elseif(j=lin(righti0,termin)=l)return(0):elsefor(k=0;k=j-1;k+)if(in(rightik,empt)=1)mark=l;if(mark=1)continue;elsefor(k
12、=0;k0,:merge(empt,temp,1);if(result=0&icount)continue:elseif(resu11=1&icount)return(1);推断读入的文法是否正确i11tjudgeOinti,j;for(i=0;i=count-l;i+)if(in(lefti,non_ter)=0)*若左部不在非终结符中,报错*/printf(*nerrorl!*);validity=。;return(0):for(j=0;size_t(J)=strle11(righti)-1;j+)if(in(rightij,non_ter)=0&in(rightij1termin)=O&rightij!-,)*若右部某一符号不在非终结符、终结符中且不为-,报错*/printf(*nerror2!z,):validity=O;return(0);return(1);求单个符号的FlRSTvoidfirst2(inti)*i为符号在全部输入符号中的序号*/charc,temp20;intj,k,m;c=vi;charch=,;emp(ch);if(in(c,termin)=l)*若为终结符*/firstli=c;firstl=0;*若为非终结符*/elseif(in(c,non_ter)=1)for(j=0:j=c