由正规则文法构造正规则式.docx

上传人:b****5 文档编号:11942317 上传时间:2023-04-16 格式:DOCX 页数:13 大小:79.40KB
下载 相关 举报
由正规则文法构造正规则式.docx_第1页
第1页 / 共13页
由正规则文法构造正规则式.docx_第2页
第2页 / 共13页
由正规则文法构造正规则式.docx_第3页
第3页 / 共13页
由正规则文法构造正规则式.docx_第4页
第4页 / 共13页
由正规则文法构造正规则式.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

由正规则文法构造正规则式.docx

《由正规则文法构造正规则式.docx》由会员分享,可在线阅读,更多相关《由正规则文法构造正规则式.docx(13页珍藏版)》请在冰豆网上搜索。

由正规则文法构造正规则式.docx

由正规则文法构造正规则式

由正规(则)文法构造正规(则)式

姓名:

学号:

指导老师:

时间:

一、实验目的:

了解三型文法,正则表达式和正则集的概念;了解正则表达式的性质以及正则表达式和正则文法之间的关系。

给出一个文法能判断其文法类型,并且能将一个正规文法转化为正规式。

二、实验内容:

判断文法是第几类文法,并将正规文法转化为正规式。

三、程序流程:

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型文法,正规文法。

尤其加深了我对正规文法的理解。

我学会了如何将一个正规文法转化为一个正规式。

而且还锻炼了我编写程序的能力,总之,收获颇多。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1