1、void apart(Chomsky *p,int i) /分开产生式左右部void VNVT(Chomsky *p)/求VN和VTint zero(Chomsky *p)/0型文法int one(Chomsky *p)/1型文法int two(Chomsky *p)/2型文法int three(Chomsky *p)/3型文法void change(Chomsky *p)/正规文法到正规式的转换函数五:出错分析1: #include忽视了c+语言中的头文件应当去掉.h,须再另加上using namespace std;2:规则分解不对,导致结果出错。3:太多循环嵌套容易造成程序出错,养成把括
2、号提前打好的习惯。六:实验结果与分析不是正规文法的不能转换:是正规文法的才可以转换:七:源代码#includeusing namespace std;#define max 50int NONE=1;string strings,noend,end;/非终结符与终结符存储int n;/产生式总数 string left; string right; int j; for(j=0;jstrings.length();j+) if(stringsj=-) pi.left=strings.substr(0,j); pi.right=strings.substr(j+1,strings.length(
3、)-j); int i,j; for(i=0;i=A&pi.leftj100) noend+=pi.leftj; else if(end.find(pi.leftj) end+=pi.leftj;(int)pi.right.length(); if(!(pi.rightjpi.rightj end+=pi.rightj; else if(noend.find(pi.rightj) noend+=pi.rightj; int flag(0),count(0); if(pi.leftj) /有否非终结符 flag+; if(flag0) flag=0; count+; else break; /左
4、部没有非终结符,结束 if(count=n) return 1; /属于0型文法 else coutendl所输产生式不属于任何文法。endl; NONE=0; return 0; int flag(0); int i; if(zero(p) for(i=0; if(pi.right.length()此文法属于0型文法,即短语文法。 return 0; /不属于1型文法 else if(flag=0) return 1; /属于1型文法 else return 0; if(one(p)i+) if(pi.left.length()!=1)|!(pi.left0pi.left0pi.right0
5、pi.right1 coutaA,A-bA的产生式为A-aA|bA的形式 pi.right=pi.right+|+pj.right; pj.left=; pj.right= else if(pi.right1=pj.right1&pi.left0!=pj.right1)/合并形如S-aA,S-bA的产生式为S- pi.right=pi.right+ if(pi.right.length()=1&pj.right.length()=1&pi.left=pj.left)/合并形如S-a,S-b,S-c的产生式为S-a|b|c的形式 pj.left= pj.right=i+)/提取形如S-aA|bA
6、的公因式为S-(a|b)A的形式 flag=pi.right.length(); if(pi.right.length()2&=pi.right1&pi.right2=| for(j=1;flag-1;j=j+3) pi.rightj= if(j=flag-1) pi.right=(+pi.right.substr(0,pi.right.length()-1)+)+pi.right.substr(pi.right.length()-1); if(pi.left0=pi.rightpi.right.length()-1&pi.right.length()1) for(j=0; if(pi.lef
7、t=pj.left&j!=i) for(m=0;mpj.right.length();m+) if(=pj.rightm&pj.rightm=0)/当所有产生式的右部均为终结符构成时停止转换 for(i=0,flag=flag-1;pi.right.length(); if(=pi.rightj& for(m=0; if(pm.left0=pi.rightj&m! pi.right=pi.right.substr(0,j)+pm.right+pi.right.substr(j+1); pm.left= pm.right= break; /再次合并左部相等的产生式 if(pi.left0=pj.
8、left0&i!=j) if(pj.right.length()void main().编译原理实验三:正规文法到正规式的转换.请输入正规文法(三型文法)的产生式总数及各产生式:其中左右部之间用表示,空用#表示 cin Chomsky *p=new Chomskymax; cinstrings; apart(p,i); VNVT(p); if(three(p)/只有当输入为正规文法时才进行转换,否则实验退出!转换后的正规式为: change(p);i+)/输出转换后的文法 if(pi.left0!=NULL) coutpi.left= for(j=0; if(pi.rightj! coutpi.rightj;该文法不属于正规文法,实验结束!
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1