由正规则文法构造正规则式.docx
- 文档编号:11942317
- 上传时间:2023-04-16
- 格式:DOCX
- 页数:13
- 大小:79.40KB
由正规则文法构造正规则式.docx
《由正规则文法构造正规则式.docx》由会员分享,可在线阅读,更多相关《由正规则文法构造正规则式.docx(13页珍藏版)》请在冰豆网上搜索。
由正规则文法构造正规则式
由正规(则)文法构造正规(则)式
姓名:
学号:
指导老师:
时间:
一、实验目的:
了解三型文法,正则表达式和正则集的概念;了解正则表达式的性质以及正则表达式和正则文法之间的关系。
给出一个文法能判断其文法类型,并且能将一个正规文法转化为正规式。
二、实验内容:
判断文法是第几类文法,并将正规文法转化为正规式。
三、程序流程:
1.程序流程图
2.正规文法转为正规式流程图
四、实验代码:
#include
#include
usingnamespacestd;
structCSS
{
stringleft;//产生式左部
stringright;//产生式右部
};
boolIsZero(CSS*p,intn)//判断0型文法(左部不含非终结符则不是0型文法)
{
inti,j;
for(i=0;i { for(j=0;j { if(p[i].left[j]>='A'&&p[i].left[j]<='Z') break; } if(j==p[i].left.length()) { cout<<"该文法不是0型文法"< returnfalse; } } if(i==n) returntrue;//如果每个产生式都能找到非终结符 } boolIsFirst(CSS*p,intn)//判断1型文法(右边长度大于等于左边长度) { if(IsZero(p,n))//先判断是否是0型文法 { inti; for(i=0;i { if((p[i].left.length()>p[i].right.length())&&p[i].right.length()! =0)//判断产生式左部长度是否大于右部 break; } if(i==n) returntrue; cout<<"该文法是一个0型文法"< } returnfalse; } boolIsSecond(CSS*p,intn)//判断2型文法(左部是一个非终结符) { inti; if(IsFirst(p,n))//同上,先判断低级文法是否成立 { for(i=0;i { if((p[i].left.length()! =1)||! (p[i].left[0]>='A'&&p[i].left[0]<='Z'))//判断产生式左部长度是否为一,左部第一个是否是非终结符 break; } if(i==n) returntrue; cout<<"该文法是1型文法"< } returnfalse; } boolIsThird(CSS*p,intn)//判断3型文法(形如A→a,A→aB的形式) { inti; if(IsSecond(p,n))//同上,先判断是否是2型文法 { for(i=0;i { if((p[i].right.length()==0)||(p[i].right.length()>=3)||(p[i].right[0]>='A'&&p[i].right[0]<='Z'))//判断产生式右部字符个数是否是1或者2,判断右部第一个字符是否是非终结符 break; } if(i==n) { for(i=0;i { if(p[i].right.length()==2)//如果右边长度为2,则判断第二个字符是否是非终结符 { if(! (p[i].right[1]>='A'&&p[i].right[1]<='Z')) break; } } if(i==n) { cout<<"该文法属于3型文法"< returntrue; } cout<<"该文法属于2型文法"< } } returnfalse; } //正规文法转换为正规式 voidtransfer(CSS*p,intn) { inti,j,m,flag; //合并产生式 for(i=0;i for(j=i+1;j { //合并形如A->aA,A->bA的产生式为A->aA|bA的形式 if((p[i].left==p[j].left)&&(p[i].right[1]==p[j].right[1])) { p[i].right=p[i].right+"|"+p[j].right; p[j].left=""; p[j].right=""; } //正规文法到正规式的转换规则3(合并形如S->a,S->b,S->c的产生式为S->a|b|c的形式) if(p[i].right.length()==1&&p[j].right.length()==1&&p[i].left==p[j].left) { p[i].right=p[i].right+"|"+p[j].right; p[j].left=""; p[j].right=""; } } //提取形如S->aA|bA的公因式为S->(a|b)A的形式 for(i=0;i { flag=p[i].right.length(); if(p[i].right.length()>2&&'A'<=p[i].right[1]&&p[i].right[1]<='Z'&&p[i].right[2]=='|') { for(j=1;j { p[i].right[j]=''; } if(j==flag-1) p[i].right="("+p[i].right.substr(0,p[i].right.length()-1)+")"+p[i].right.substr(p[i].right.length()-1); } } //正规文法到正规式的转换规则2(A->xA|y--->A->x*(y)) for(i=0;i { if(p[i].left[0]==p[i].right[p[i].right.length()-1]&&p[i].right.length()>1) { for(j=0;j if(p[i].left==p[j].left&&j! =i) { for(m=0;m if('A'<=p[j].right[m]&&p[j].right[m]<='Z') break; if(m==p[j].right.length()) { p[i].right=p[i].right.substr(0,p[i].right.length()-1)+"*"+"("+p[j].right+")"; p[j].right=""; p[j].left=""; } } } } //转换规则(S->(xx)AA->aA转化为S->(xx)a*A) for(i=0;i { if(p[i].right.length()>1&&p[i].left[0]! =p[i].right[p[i].right.length()-1]) { for(j=0;j { if(p[j].right.length()>1&&p[i].right[p[i].right.length()-1]==p[j].left[0]&&p[j].left[0]==p[j].right[p[j].right.length()-1]) { p[i].right=p[i].right.substr(0,p[i].right.length()-1)+p[j].right.substr(0,p[j].right.length()-1)+"*"+p[j].right[p[j].right.length()-1]; p[j].right=""; p[j].left=""; } } } } //将表达式右部所有非终结符替换 flag=n; while(flag>=0)//当所有产生式的右部均为终结符构成时停止转换 for(i=0,flag=flag-1;i for(j=0;j if('A'<=p[i].right[j]&&p[i].right[j]<='Z') { for(m=0;m { if(p[m].left[0]==p[i].right[j]&&m! =i) { p[i].right=p[i].right.substr(0,j)+p[m].right+p[i].right.substr(j+1); p[m].left=""; p[m].right=""; break; } } } //再次合并左部相等的产生式 for(i=0;i for(j=0;j { if(p[i].left[0]==p[j].left[0]&&i! =j) { if(p[j].right.length()>1) { p[i].right=p[i].right+"|"+"("+p[j].right+")"; p[j].left=""; p[j].right=""; } else { p[i].right=p[i].right+"|"+p[j].right; p[j].left=""; p[j].right=""; } } } } intmain() { inti,j,n; stringinput; while(true) { cout<<"请输入文法产生式个数N"< cin>>n; CSS*p=newCSS[n];//初始化产生式数组 for(i=0;i { input.erase();//清除 cin>>input;//输入 for(j=0;j { if(input[j]=='-') { p[i].left=input.substr(0,j); p[i].right=input.substr(j+2,input.length()); } } } if(IsThird(p,n))//调用文法类型判断,自顶向下,如果是正规文法,则输出正规式 { cout<<"该文法属于正规文法,它的正规式如下: "< transfer(p,n); for(i=0;i { if(p[i].left[0]! =NULL) { cout< for(j=0;j { if(p[i].right[j]! ='') cout< } } } cout< } } return0; } 六、运行截图 五、设计总结 经过本次实验,加深了我对文法类型的理解,我学会了如何识别一个0型文法,1型文法,2型文法,正规文法。 尤其加深了我对正规文法的理解。 我学会了如何将一个正规文法转化为一个正规式。 而且还锻炼了我编写程序的能力,总之,收获颇多。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 规则 文法 构造
![提示](https://static.bdocx.com/images/bang_tan.gif)