正规文法正规式.docx
《正规文法正规式.docx》由会员分享,可在线阅读,更多相关《正规文法正规式.docx(13页珍藏版)》请在冰点文库上搜索。
![正规文法正规式.docx](https://file1.bingdoc.com/fileroot1/2023-7/5/9b0c532c-d3d5-4498-9c3a-8014c5eb3c46/9b0c532c-d3d5-4498-9c3a-8014c5eb3c461.gif)
正规文法正规式
正规文法-正规式
由正规文法构造正规式
年级_______
专业________
学号________
姓名__________
一、实验目的要求
输入:
任意的正规文法。
输出:
相应的正规式。
二、实验原理
一个正则表达式的值是正则集,它是正则语言的另一种表示法。
不难看出,除了符号Φ外,一个正则表达式的含义类似于正则文法的一个非终结符号规则右部的含义。
例如,对于<数字>:
:
=0/1/2/…/9,由非终结符数字所产生的字符串集合与正则表达式0/1/2/…/9所定义的字符串集合是相同的。
正则集Φ,它对应一个不包含任何句子的语言,引进的目的主要是为了理论上的完备性。
三、实验代码:
#include
#include
#include
#include
usingnamespacestd;
structRule
{
stringleft;//规则左部,因为输入的为2型文法,
stringright;//规则右部
};
structRuleData
{
stringleft;
vectorright;
};
classGrammar
{
private:
vectorgrammar;//文法
Rulerule;//规则
vectorDleft;
RuleDataruledata;
public:
Grammar(){}
~Grammar(){}
voidChangeInput(stringinput);//输入分析
voidShow();//
voidDataChange(intC);//存储结构转换
vectorgrammardata;
};
voidGrammar:
:
ChangeInput(stringinput)//扫描字符串,遇到'-'停止,
{//并跳两格
inthelp1=0;
rule.left.erase();
rule.right.erase();
for(inti=0;i{
if(input[i]=='-')
{
help1=i;
break;
}
rule.left+=input[i];
}
if(help1!
=1)
{
cout<<"不符合要求!
!
";
exit(0);
}
help1=help1+2;
for(intj=help1;j{
rule.right+=input[j];
}
grammar.push_back(rule);
}
voidGrammar:
:
DataChange(intC)
{
inti,j;
if(C==0)//简单->复杂
{
intl=0;
grammardata.clear();
ruledata.left.erase();
ruledata.right.clear();
ruledata.left=grammar[0].left;
ruledata.right.push_back(grammar[0].right);
grammardata.push_back(ruledata);
for(i=1;i{
for(j=0;j{
if(grammar[i].left==grammardata[j].left)
{
grammardata[j].right.push_back(grammar[i].right);
l=1;
break;
}
}
if(l==0)
{
ruledata.left.erase();
ruledata.right.clear();
ruledata.left=grammar[i].left;
ruledata.right.push_back(grammar[i].right);
grammardata.push_back(ruledata);
}
l=0;
}
}
if(C==1)//复杂->简单
{
grammar.clear();
for(i=0;i{
rule.left.erase();
rule.right.erase();
rule.left=grammardata[i].left;
for(j=0;j{
rule.right=grammardata[i].right.at(j);
grammar.push_back(rule);
}
}
}
}
voidGrammar:
:
Show()
{
cout<<"输入的文法的正规式为:
"<for(inti=0;icout<}
classGenerateGtoE:
publicGrammar//正规文法转正规式
{
private:
public:
GenerateGtoE(){}
~GenerateGtoE(){}
voidGenerating();
};
voidGenerateGtoE:
:
Generating()
{
DataChange(0);
//STEP1
//将文法G的所有非终结符形如a1A|a2A|...的候选式
//归并为(a1|a2|...)A的侯选式,其中a∈Vt,A∈Vn
stringZ1="|";
stringZ2="(";
stringZ3=")";
stringZ4="*";
stringhelp1,help2;
for(inti=0;ifor(intj=0;jfor(intk=j+1;k{
help1.erase();
help2.erase();
intcj=grammardata[i].right.at(j).length()-1;
intck=grammardata[i].right.at(k).length()-1;
stringAj=grammardata[i].right.at(j).substr(cj);
stringAk=grammardata[i].right.at(k).substr(ck);
if(Aj==Ak&&Aj>="A"&&Aj<="Z")
{
if(grammardata[i].right.at(j).find(Z2)!
=0)
{
help1=Z1+grammardata[i].right.at(k).substr(0,ck);
help2=Z2+grammardata[i].right.at(j).substr(0,cj);
grammardata[i].right.at(j)=help2+help1+Z3+Aj;
}
else
{
help1=Z1+grammardata[i].right.at(k).substr(0,ck);
help2=grammardata[i].right.at(j).substr(0,cj-1);
grammardata[i].right.at(j)=help2+help1+Z3+Aj;
}
for(intt=k;t{
grammardata[i].right.at(t)=grammardata[i].right.at(t+1);
}
grammardata[i].right.pop_back();
k--;
}
}
//DataChange
(1);
//STEP2
//先将规则变A->(b1|b2...)*(a1|a2|...),再用其替换掉其他规则中的A
//由下而上,逐步替换
for(i=grammardata.size()-1;i>=0;i--)
{
stringhelp;
help.erase();
help1.erase();
help2.erase();
//A的右部的最后的符号为A
for(intj=0;j{
intcj=grammardata[i].right.at(j).length()-1;
//在A的右部集中含有最后符号为A的右部
if(grammardata[i].right.at(j).find(grammardata[i].left)
==cj)
{
//将A->yA变为A->y*,help1="y"+"*",
if(help1.length()==0)
help1=grammardata[i].right.at(j).substr(0,cj);
else
help1+=Z1+grammardata[i].right.at(j).substr(0,cj);
}
else
{
if(help2.empty())
help2=grammardata[i].right.at(j);
else
help2+=Z1+grammardata[i].right.at(j);
if(help2.find(Z2)==string:
:
npos&&help2.find(Z3)==string:
:
npos&&
help2.find(Z1)!
=string:
:
npos)
help2=Z2+help2+Z3;
}
}
grammardata[i].right.clear();
if(help1.empty()==false)
help=help1+Z4;
help+=help2;
grammardata[i].right.push_back(help);
help.erase();
for(j=i-1;j>=0;j--)
for(intk=0;k{
intck=grammardata[j].right.at(k).length()-1;
if(grammardata[j].right.at(k).find(grammardata[i].left)
==ck)
{
help=grammardata[j].right.at(k).substr(0,ck)+
grammardata[i].right.at(0);
grammardata[j].right.at(k)=help;
}
}
}
for(i=0;igrammardata.pop_back();
DataChange
(1);
}
voidmain()
{
stringinput;
GenerateGtoEgg_e;
intN;
cout<<"个数:
";
cin>>N;
cout<<"请输入规则:
"<for(inti=0;i{
input.erase();
cin>>input;
gg_e.ChangeInput(input);
}
gg_e.Generating();
gg_e.Show();
}
四、实验结果
对于正规文法
S→aA|a;
A→(aA|dA)|(a|d);
其正规式应为
S=a(a|d)*.
实验为
S=a(a|d)*(a|d)|£
可以化为S=a(a|d)*。
故实验结果正确。
对于正规文法
S→aB;
B→bA|bB;
A→c|cA;
其正规式应为
S=abb*c*c.
实验为
S=abb*c*c.
故实验结果正确。