#include<bits/stdc++.h>
using namespace std;
int Norterminal(char c)
{
if(c>='A'&&c<='Z')
return 1;
else if(c!=':'&&c!='='&&c!='<'&&c!='>'&&c!=' '&&c!='|')
return 0;
}
struct LR
{
string nape;//项
vector<string> str;
string later;//后继关系
};
int main()
{
cout<<"请输入文法(以#结束)"<<endl;
vector<string> strN; //保存文法
LR Lr[100];
//输入文法
string grammer;
cin>>grammer;
string nonterm="";
strN.push_back(grammer);
for(int i=0;grammer!="#";i++)
{
cin>>grammer;
strN.push_back(grammer);
}
//变为增广文法
string s="Z::=";
s+=strN[0][0];
s+='#';
strN.insert(strN.begin(),s);
for(int i=0;i<strN.size();i++)
{
if(Norterminal(strN[i][0]))
nonterm+=strN[i][0];
string ustr(nonterm);
sort(ustr.begin(), ustr.end());
ustr.erase(unique(ustr.begin(), ustr.end()), ustr.end() );
nonterm=ustr;
}
nonterm.erase(nonterm.end() - 1);
// cout<<nonterm<<endl;
//求解初始项集的闭包
// cout<<"初始项集"<<endl;
Lr[0].str.push_back(strN[0]);
char non;
//找第一个终结符
if(Norterminal(strN[0][4]))
{
Lr[0].nape=s[0];
non=strN[0][4];
Lr[0].str[0][3]='.';
Lr[0].str[0][2]='>';
Lr[0].str[0][1]='-';
}
for(int j=1;j<strN.size();j++)
{
if(non==strN[j][0])
{
Lr[0].str.push_back(strN[j]);
int h=Lr[0].str.size();
Lr[0].str[h-1][3]='.';
Lr[0].str[h-1][2]='>';
Lr[0].str[h-1][1]='-';
if(Norterminal(strN[j][4])&&strN[j][4]!=non)
{
for(int g=1;g<strN.size();g++)
{
if(strN[g][4]==non&&j!=g)
{
Lr[0].str.push_back(strN[g]);
int h1=Lr[0].str.size();
Lr[0].str[h1-1][3]='.';
Lr[0].str[h1-1][2]='>';
Lr[0].str[h1-1][1]='-';
}
}
non=strN[j][4];
}
}
}
/* for(int i=0;i<Lr[0].str.size();i++)
{
for(int j=0;j<Lr[0].str.size();j++)
{
if(Lr[0].str[i].compare(Lr[0].str[j])==0&&i!=j)
Lr[0].str.erase(Lr[0].str.begin()+j);
}
cout<<Lr[0].str[i]<<endl;
} */
/*求解项集规范族 */
//求解当前项集中的终结符与非终结符以便于后续的存放。
string nont;//存放当前闭包$后边遇到的字母
int totalnum=1;
//偶数遍历
for(int r=0;r<totalnum;r++)
{
nont="";
for(int i=0;i<Lr[r].str.size();i++)
{
for(int j=0;j<Lr[r].str[i].length();j++)
{
if(Lr[r].str[i][j]=='.'&&j+1!=Lr[r].str[i].length())
{
nont+=Lr[r].str[i][j+1];
}
}
string ustr(nont);
sort(ustr.begin(), ustr.end());
ustr.erase(unique(ustr.begin(), ustr.end()), ustr.end() );
nont=ustr;
//Lr[r].later=nont;
}
// now=r;
//cout<<nont<<":"<<r<<endl;
for(int i=0;i<nont.length();i++)
{
Lr[totalnum+i].nape=nont[i];
}
//将.后移
for(int i=0;i<Lr[r].str.size();i++)
{
for(int j=0;j<Lr[r].str[i].length();j++)
{
if(Lr[r].str[i][j]=='.')
{
for(int l=0;l<nont.length();l++)
{
if(Lr[r].str[i][j+1]==Lr[totalnum+l].nape[0])
{
Lr[r].str[i].erase(Lr[r].str[i].begin()+j);
Lr[r].str[i].insert(Lr[r].str[i].begin()+j+1,'.');
Lr[totalnum+l].str.push_back(Lr[r].str[i]);
Lr[r].str[i].erase(Lr[r].str[i].begin()+j+1);
Lr[r].str[i].insert(Lr[r].str[i].begin()+j,'.');
}
}
}
}
}
//若遇到终结符进行闭包运算
for(int i=0;i<nont.length();i++)
{
for(int k=0;k<Lr[totalnum+i].str.size();k++)
{
for(int g=0;g<Lr[totalnum+i].str[k].length();g++)
{
if(Lr[totalnum+i].str[k][g]=='.'&&g+1!=Lr[totalnum+i].str[k].length())
{
if(Norterminal(Lr[totalnum+i].str[k][g+1]))
{
non=Lr[totalnum+i].str[k][g+1];
for(int j1=1;j1<strN.size();j1++)
{
if(non==strN[j1][0])
{
Lr[totalnum+i].str.push_back(strN[j1]);
int h=Lr[totalnum+i].str.size();
Lr[totalnum+i].str[h-1][3]='.';
Lr[totalnum+i].str[h-1][2]='>';
Lr[totalnum+i].str[h-1][1]='-';
if(Norterminal(strN[j1][4]))
{
for(int g1=1;g1<strN.size();g1++)
{
if(strN[g1][4]==non&&j1!=g1&&strN[g][0]==strN[g1][4])
{
Lr[totalnum+i].str.push_back(strN[g1]);
int h1=Lr[totalnum+i].str.size();
Lr[totalnum+i].str[h1-1][3]='.';
Lr[totalnum+i].str[h1-1][2]='>';
Lr[totalnum+i].str[h1-1][1]='-';
}
}
non=strN[j1][4];
}
}
}
break;
}
}
}
break;
}
}
r+=1;
if(nont.length()!=0)
totalnum+=nont.length();
}
//奇数遍历
for(int r=1;r<totalnum;r++)
{
nont="";
for(int i=0;i<Lr[r].str.size();i++)
{
for(int j=0;j<Lr[r].str[i].length();j++)
{
if(Lr[r].str[i][j]=='.'&&j+1!=Lr[r].str[i].length())
{
nont+=Lr[r].str[i][j+1];
}
}
string ustr(nont);
sort(ustr.begin(), ustr.end());
ustr.erase(unique(ustr.begin(), ustr.end()), ustr.end() );
nont=ustr;
// Lr[r].later=nont;
}
// now=r;
//cout<<nont<<":"<<r<<endl;
for(int i=0;i<nont.length();i++)
{
Lr[totalnum+i].nape=nont[i];
}
//将.后移
for(int i=0;i<Lr[r].str.size();i++)
{
for(int j=0;j<Lr[r].str[i].length();j++)
{
if(Lr[r].str[i][j]=='.')
{
for(int l=0;l<nont.length();l++)
{
if(Lr[r].str[i][j+1]==Lr[totalnum+l].nape[0])
{
Lr[r].str[i].erase(Lr[r].str[i].begin()+j);
Lr[r].str[i].insert(Lr[r].str[i].begin()+j+1,'.');
Lr[totalnum+l].str.push_back(Lr[r].str[i]);
Lr[r].str[i].erase(Lr[r].str[i].begin()+j+1);
Lr[r].str[i].insert(Lr[r].str[i].begin()+j,'.');
}
}
}
}
}
//若遇到终结符进行闭包运算
for(int i=0;i<nont.length();i++)
{
for(int k=0;k<Lr[totalnum+i].str.size();k++)
{
for(int g=0;g<Lr[totalnum+i].str[k].length();g++)
{
if(Lr[totalnum+i].str[k][g]=='.'&&g+1!=Lr[totalnum+i].str[k].length())
{
if(Norterminal(Lr[totalnum+i].str[k][g+1]))
{
non=Lr[totalnum+i].str[k][g+1];
for(int j1=1;j1<strN.size();j1++)
{
if(non==strN[j1][0])
{
Lr[totalnum+i].str.push_back(strN[j1]);
int h=Lr[totalnum+i].str.size();
Lr[totalnum+i].str[h-1][3]='.';
Lr[totalnum+i].str[h-1][2]='>';
Lr[totalnum+i].str[h-1][1]='-';
if(Norterminal(strN[j1][4]))
{
for(int g1=1;g1<strN.size();g1++)
{
if(strN[g1][4]==non&&j1!=g1&&strN[g][0]==strN[g1][4])
{
Lr[totalnum+i].str.push_back(strN[g1]);
int h1=Lr[totalnum+i].str.size();
Lr[totalnum+i].str[h1-1][3]='.';
Lr[totalnum+i].str[h1-1][2]='>';
Lr[totalnum+i].str[h1-1][1]='-';
}
}
non=strN[j1][4];
}
}
}
break;
}
}
}
break;
}
}
r+=1;
if(nont.length()!=0)
totalnum+=nont.length();
}
cout<<totalnum<<endl;
for(int i=0;i<totalnum;i++)
{
if(Lr[i].str.size()>0)
{
cout<<Lr[i].nape<<"后继项集"<<i<<Lr[i].later<<endl;
for(int p=0;p<Lr[i].str.size();p++)
{
sort(Lr[i].str.begin(),Lr[i].str.end());
Lr[i].str.erase(unique(Lr[i].str.begin(), Lr[i].str.end()), Lr[i].str.end());
cout<<Lr[i].str[p]<<endl;
}
}
}
/*清除相同的项*/
//cout<<"相同的vector"<<endl;
for(int i=0;i<totalnum;i++)
{
for(int j=0;j!=i,j<totalnum;j++)
{
if(j!=i&&Lr[i].str==Lr[j].str)
{
/* cout<<Lr[j].nape<<"后继项集"<<j+1<<endl;
//打印相同的项
/* for(int p=0;p<Lr[j].str.size();p++)
{
cout<<Lr[j].str[p]<<endl;
}*/
Lr[j].str.clear();
//totalnum--;
break;
}
}
}
int termnum=0;
for(int i=0;i<totalnum;i++)
{
if(Lr[i].str.size()>0)
{
termnum++;
}
}
// cout<<"项的个数为"<<termnum<<endl;
/* cout<<"清除相同的vector后的结果:"<<endl; */
//cout<<totalnum<<endl;
cout<<"项集规范族为:"<<endl;
int termID=0;//项的编号
for(int i=0;i<totalnum;i++)
{
bool flag=false;
if(Lr[i].str.size()>0)
{
//求解后继项
nont="";
for(int l=0;l<Lr[i].str.size();l++)
{
for(int j=0;j<Lr[i].str[l].length();j++)
{
if(Lr[i].str[l][j]=='.'&&j+1!=Lr[i].str[l].length())
{
nont+=Lr[i].str[l][j+1];
}
}
string ustr(nont);
sort(ustr.begin(), ustr.end());
ustr.erase(unique(ustr.begin(), ustr.end()), ustr.end() );
nont=ustr;
Lr[i].later=nont;
}
if(Lr[i].nape[0]=='#')
{
flag=true;
cout<<termnum-1<<"\t"<<Lr[i].nape<<"后继项集"<<endl;
}
if(flag==false)
{
cout<<termID++<<"\t";
cout<<Lr[i].nape<<"后继项集"<<endl;//<<"具体为:"<<Lr[i].later<<endl;
}
for(int p=0;p<Lr[i].str.size();p++)
{
cout<<"\t"<<Lr[i].str[p]<<endl;
}
}
}
}
输入文法:
E::=aA
E::=bB
A::=d
A::=cA
B::=cB
B::=d
#
运行结果: