编译原理实验规格文法转化为正规式.docx
《编译原理实验规格文法转化为正规式.docx》由会员分享,可在线阅读,更多相关《编译原理实验规格文法转化为正规式.docx(12页珍藏版)》请在冰豆网上搜索。
编译原理实验规格文法转化为正规式
实验二正规文法正规式
实验名称:
由正规文法构造正规式
实验要求:
输入任意的正规文法,输出相应的正规式。
即:
输入:
任意的正规文法;
输出:
相应的正规式。
实验目的:
1.熟练掌握正规文法到正规式的转换规则;
2.设计并实现将正规文法转化为正规式的方法;
3.理解正规文法和正规式的等价性。
实验原理:
(1)正规文法:
定义:
设G=(VN,VT,P,S),如果它的每个产生式A αB或Aα(A Bα或Aα),其中A和B都是非终结符,α∈VT*,则文法G是3型文法(正规文法,正则文法,有穷状态文法),简称RG。
表示:
Ø<标识符><字母>|<标识符>(<字母>|<数字>)
Ø<字母>表示任意英文字母,<数字>表示任意数字
☞若文法中所有的产生式均为A αB或Aα形式,则此文法为右线性的
☞若文法中所有的产生式均为A Bα或Aα形式,则此文法为左线性的
(2)正规式:
起源:
正则表达式萌芽于20世纪40年代的神经生理学研究,由著名数学家StephenKleene第一个正式描述。
在一篇题为《正则集代数》的论文中定义了“正则集”,并在其上定义了一个代数系统,并且引入了一种记号系统来描述正则集,这种记号系统被他称为“正则表达式”。
定义:
◆设A是非空的有限字母表,A={ai|i=1,2,……n},则
1.,和ai(i=1,2,……n)都是正规式;
2.若、是正规式,则|、•、*、*也是正规式;
3.正规式只能通过有限次使用1,2规则获得。
☞1)“|”读作为“或”,也可写作为“+”或“,”;“•”读作连接。
☞2)仅由字母表A={ai|i=1,2,……n}上的正规式
所组成的语言称作正规集,记作L()。
☞3)利用正规集相同,可用来证明相应正规式等价。
(3)正规文法与正规式之间的转化
一个正规语言可以由正规文法定义,也可以由正规式定义,对任意一个正规文法存在一个定义同一个语言的正规式。
反之,对每个正规式,存在生成同一个语言的正规文法。
图正规文法正规式的转换规则
转换步骤:
步骤1由正规文法G的各个产生式写出对应的正规方程式,得到联立方程组。
步骤2把方程组中的非终结符当作变元。
步骤3求此正规式方程组的解,得到关于开始符号S的解:
S=w,w∈VT*,w就是所求正规式。
测试数据:
测试数据1:
A->xB
A->y
B->xB
B->yA
测试数据2
S->aA
S->a
A->aA
A->dA
A->a
A->d
测试数据3
S->aA
S->cB
S->a
A->aB
A->bB
A->b
B->cB
B->bA
B->c
源代码:
#include
#include
usingnamespacestd;
stringss[30]={"",""};
stringdww[15]={"",""};
stringsnt="";
stringdst[8]={"",""};
stringdonesnt="";
intnum=0;
intdstl=0;
intdwl=0;
voidsetdst()
{
for(inti=0;i<8;i++)
dst[i]="";
dstl=0;
}
voidgetsnt()
{
for(inti=0;i{
if(snt.find(ss[i].at(0))==-1)
snt+=ss[i].at(0);
}
}
stringdispose1(stringtemp1)
{
stringdf="";
for(inti=0;i{
intk=(int)temp1.at(i);
stringft=ss[k].substr(3);
if(i==0)
df+=ft;
else
{
df+='|';
df+=ft;
}
ss[k]="";
}
returndf;
}
stringdispose3(stringtemp3)
{
stringdf="";
for(inti=0;i{
intk=(int)temp3.at(i);
stringtemp=ss[k].substr(3);
stringsttr=temp.substr(0,temp.size()-1);
if(i==0)
df+=sttr;
else
{
df+='|';
df+=sttr;
}
ss[k]="";
}
returndf;
}
voiderass()
{
for(inti=0;i<30;i++)
{
if(ss[i]=="")
{
for(intj=i+1;j<30;j++)
{
if(ss[j]!
="")
break;
}
ss[i]=ss[j];
ss[j]="";
}
if(i==num)
{
ss[num]="";
break;
}
}
}
voidhandle(stringcs,stringssnot)
{
charcc=cs.at(0);
stringtemp1="";
stringtemp2="";
stringtemp3="";
inti=0;
boolflagg=false;
while(!
flagg)
{
flagg=true;
for(i=0;i{
for(intj=0;j{
if(ss[i].find(donesnt.at(j))!
=-1)
{
flagg=false;
boolflag=false;
stringsk=ss[i];
for(intk=0;k{
if(dww[k].at(0)==donesnt.at(j))
{
stringdwtemp=dww[k].substr(3);
if(!
flag)
{
intlk=ss[i].find(donesnt.at(j));
ss[i].replace(lk,1,dwtemp);
flag=true;
}
else
{
ss[num]=sk;
intlk=ss[num].find(donesnt.at(j));
ss[num].replace(lk,1,dwtemp);
num++;
}
}
}
}
}
}
}
setdst();
for(i=0;i{
stringtemp="";
if(ss[i].at(0)==cc)
{
temp=ss[i].substr(3);
if(temp.find(cc)!
=-1)
temp3+=i;
else
{
boolflag=false;
for(intj=0;j{
chardd=ssnot.at(j);
if(temp.find(dd)!
=-1)
{
temp2+=i;
dst[dstl]=ss[i];
dstl++;
ss[i]="";
flag=true;
j=ssnot.size();
}
}
if(!
flag)
temp1+=i;
}
}
}
i=temp1.size();
num-=i;
i=temp2.size();
num-=i;
i=temp3.size();
num-=i;
i=0;
stringdis1str="";
stringdis2str="";
stringtemm="";
if(num>0)
{
dis1str="(";
dis1str+=dispose1(temp1);
dis1str+=")";
}
else
{
if(temp3.size()==0)
dis1str=dispose1(temp1);
else
{
dis1str="(";
dis1str+=dispose1(temp1);
dis1str+=")";
}
}
temm+=dispose3(temp3);
if(temp3.size()==0)
dis2str="";
else
{
if(temm.size()==1)
dis2str=temm;
else
{
dis2str="(";
dis2str+=temm;
dis2str+=")";
}
dis2str+="*";
}
if(dis1str=="()")
dis1str="";
dis2str+=dis1str;
stringarrow="->";
arrow+=dis2str;
dww[dwl]+=cs;
dww[dwl]+=arrow;
dwl++;
for(i=0;i{
dww[dwl]=dst[i];
dwl++;
}
erass();
}
intmain()
{
cout<<"输入文法以#结束"<inti=0;
for(;i<15;i++)
{
stringtem="";
cin>>tem;
if(tem=="#")
break;
ss[i]=tem;
}
num=i;
getsnt();
for(i=snt.size()-1;i>=0;i--)
{
stringssnot=snt.substr(0,i);
stringcs="";
cs+=snt.at(i);
handle(cs,ssnot);
donesnt+=cs;
}
cout<return0;
}