编译原理实验三正规文法到正规式转换.docx

上传人:b****5 文档编号:4363447 上传时间:2022-11-30 格式:DOCX 页数:14 大小:194.30KB
下载 相关 举报
编译原理实验三正规文法到正规式转换.docx_第1页
第1页 / 共14页
编译原理实验三正规文法到正规式转换.docx_第2页
第2页 / 共14页
编译原理实验三正规文法到正规式转换.docx_第3页
第3页 / 共14页
编译原理实验三正规文法到正规式转换.docx_第4页
第4页 / 共14页
编译原理实验三正规文法到正规式转换.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

编译原理实验三正规文法到正规式转换.docx

《编译原理实验三正规文法到正规式转换.docx》由会员分享,可在线阅读,更多相关《编译原理实验三正规文法到正规式转换.docx(14页珍藏版)》请在冰豆网上搜索。

编译原理实验三正规文法到正规式转换.docx

编译原理实验三正规文法到正规式转换

实验三:

正规文法到正规式的转换

一:

要求

输入任意的正规文法,输出相应的正规式

二:

实验目的

1.熟练掌握正规文法到正规式的转换规则

2.理解正规文法与正规式的等价性

三:

实验原理

1.一个正规语言可以由正规文法定义,也可以由正规式定义,对任意一个正规文法,存在一个定义同一个语言的正规式,反之,对每个正规式,存在生成同一个语言的正规文法

2正规文法与正规式的转换规则:

1.A-〉xB,B->y则:

A=xy

2.A-〉xA,A->y则:

A-〉x*y

3.A-〉x,A-〉y则:

A=x|y

 

四:

数据结构与算法

structChomsky

{

stringleft;

stringright;

};

voidapart(Chomsky*p,inti)//分开产生式左右部

voidVNVT(Chomsky*p)//求VN与VT

intzero(Chomsky*p)//0型文法

intone(Chomsky*p)//1型文法

inttwo(Chomsky*p)//2型文法

intthree(Chomsky*p)//3型文法

voidchange(Chomsky*p)//正规文法到正规式的转换函数

五:

出错分析

1:

#include忽视了c++语言中的头文件应当去掉.h,须再另加上usingnamespacestd;

2:

规则分解不对,导致结果出错。

3:

太多循环嵌套容易造成程序出错,养成把括号提前打好的习惯。

 

六:

实验结果与分析

不是正规文法的不能转换:

是正规文法的才可以转换:

七:

源代码

#include

#include

usingnamespacestd;

#definemax50

intNONE=1;

stringstrings,noend,end;//非终结符与终结符存储

intn;//产生式总数

structChomsky

{

stringleft;

stringright;

};

voidapart(Chomsky*p,inti)//分开产生式左右部

{

intj;

for(j=0;j

if(strings[j]=='-')

{

p[i].left=strings.substr(0,j);

p[i].right=strings.substr(j+1,strings.length()-j);

}

}

voidVNVT(Chomsky*p)//求VN与VT

{

inti,j;

for(i=0;i

{

for(j=0;j<(int)p[i].left.length();j++)

{

if((p[i].left[j]>='A'&&p[i].left[j]<='Z'))//非终结符判断

{

if(noend.find(p[i].left[j])>100)

noend+=p[i].left[j];

}

else

{

if(end.find(p[i].left[j])>100)

end+=p[i].left[j];

}

}

for(j=0;j<(int)p[i].right.length();j++)

{

if(!

(p[i].right[j]>='A'&&p[i].right[j]<='Z'))//终结符判断

{

if(end.find(p[i].right[j])>100)

end+=p[i].right[j];

}

else

{

if(noend.find(p[i].right[j])>100)

noend+=p[i].right[j];

}

}

}

}

intzero(Chomsky*p)//0型文法

{

intflag(0),count(0);

inti,j;

for(i=0;i

{

for(j=0;j<(int)p[i].left.length();j++)

{

if(p[i].left[j]>='A'&&p[i].left[j]<='Z')//有否非终结符

flag++;

}

if(flag>0)

{

flag=0;

count++;

}

else

break;//左部没有非终结符,结束

}

if(count==n)

return1;//属于0型文法

else

{

cout<

"<

NONE=0;

return0;

}

}

 

intone(Chomsky*p)//1型文法

{

intflag(0);

inti;

if(zero(p))

{

for(i=0;i

{

if(p[i].right.length()

{

flag++;

break;

}

}

}

else

flag--;

if(flag>0)

{

cout<

"<

return0;//不属于1型文法

}

else

if(flag==0)

return1;//属于1型文法

else

return0;

}

 

inttwo(Chomsky*p)//2型文法

{

intflag(0);

inti;

if(one(p))

{

for(i=0;i

if((p[i].left.length()!

=1)||!

(p[i].left[0]>='A'&&p[i].left[0]<='Z'))//左部不属于一个字符或不属于非终结符

{

flag++;

break;

}

}

else

flag--;

if(flag>0)

{

cout<

"<

return0;//不属于2型文法

}

else

if(flag==0)

{

return1;//属于2型文法

}

else

return0;

}

 

intthree(Chomsky*p)//3型文法

{

intflag=0;

inti;

if(two(p))

{

for(i=0;i

if(!

(p[i].right.length()==1||p[i].right.length()==2)||(p[i].right[0]>='A'&&p[i].right[0]<='Z'))//右部字符个数不是1或2,或首字符是非终结符

{

flag++;

break;

}

else

if((p[i].right.length()==2)&&!

(p[i].right[1]>='A'&&p[i].right[1]<='Z'))//第二个字符不是非终结符

{

flag++;

break;

}

}

else

flag--;

if(flag>0)

{

cout<<"此文法属于2型文法,即上下文无关文法。

"<

i=n;

return0;

}

else

if(flag==0)

{

cout<<"此文法属于3型文法,即正规文法。

"<

return1;

}

else

return0;

}

voidchange(Chomsky*p)//正规文法到正规式的转换函数

{

inti,j,m,flag;//合并产生式

for(i=0;i

for(j=i+1;j

{

if((p[i].left==p[j].left)&&(p[i].right[1]==p[j].right[1]))

{

if(p[i].right[1]==p[j].right[1]&&p[i].left[0]==p[j].right[1])//合并形如A->aA,A->bA的产生式为A->aA|bA的形式

{

p[i].right=p[i].right+"|"+p[j].right;

p[j].left="";

p[j].right="";

}

else

if(p[i].right[1]==p[j].right[1]&&p[i].left[0]!

=p[j].right[1])//合并形如S->aA,S->bA的产生式为S->aA|bA的形式

{

p[i].right=p[i].right+"|"+p[j].right;

p[j].left="";

p[j].right="";

}

}

if(p[i].right.length()==1&&p[j].right.length()==1&&p[i].left==p[j].left)//合并形如S->a,S->b,S->c的产生式为S->a|b|c的形式

{

p[i].right=p[i].right+"|"+p[j].right;

p[j].left="";

p[j].right="";

}

}

for(i=0;iaA|bA的公因式为S->(a|b)A的形式

{

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);

}

}

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="";

}

}

}

}

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="";

}

}

}

}

 

voidmain()

{

inti,j;

cout<<"....................编译原理实验三:

正规文法到正规式的转换...................."<

cout<<"请输入正规文法(三型文法)的产生式总数及各产生式:

"<

cin>>n;

Chomsky*p=newChomsky[max];

for(i=0;i

{

cin>>strings;

apart(p,i);

}

VNVT(p);

if(three(p))//只有当输入为正规文法时才进行转换,否则实验退出!

{

cout<<"转换后的正规式为:

"<

change(p);

for(i=0;i

{

if(p[i].left[0]!

=NULL)

{

cout<

for(j=0;j

{

if(p[i].right[j]!

='')

cout<

}

}

}

}

else

cout<<"该文法不属于正规文法,实验结束!

!

"<

}

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

当前位置:首页 > 工程科技 > 环境科学食品科学

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

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