#include<bits/stdc++.h>
using namespace std;
map<char,int>getnum;
char getchar_[100];
vector<string>proce;
int table[100][100];
int num=0;
int numvt=0;
string first[100];
string follow[200];
void readin()
{
memset(table,-1,sizeof(table));
getnum['#']=0;
getchar_[0]='#';
printf("请输入所有的终结符:");
char x;
do
{
cin>>x;
getnum[x]=++num;
getchar_[num]=x;
}
while(cin.peek()!='\n');
numvt=++num;
getnum['@']=numvt;
getchar_[num]=('@');
cout<<"请输入所有非终结符:"<<endl;
do
{
cin>>x;
getnum[x]=++num;
getchar_[num]=x;
}
while(cin.peek()!='\n');
cout<<"输入产生式集合"<<endl;
string pro;
while(cin>>pro&&pro!="end")
{
string ss;
ss+=pro[0];
for(int i=3; i<pro.size(); i++)
{
if(pro[i]=='|')
{
proce.push_back(ss);
ss.clear();
ss+=pro[0];
}
else
{
ss+=pro[i];
}
}
proce.push_back(ss);
}
}
void bingji(string&a,string b)
{
set<char>se;
for(int i=0; i<a.size(); i++)
se.insert(a[i]);
for(int i=0; i<b.size(); i++)
se.insert(b[i]);
string ans;
set<char>::iterator it;
for(it=se.begin(); it!=se.end(); it++)
ans+=*it;
a=ans;
}
string get_f(int vn,int&has_0)
{
if(vn==numvt)has_0=1;
if(vn<numvt)return first[vn];
string ans;
for(int i=0; i<proce.size(); i++)
{
if(getnum[proce[i][0]]==vn)
ans+=get_f(getnum[proce[i][1]],has_0);
}
return ans;
}
void getfirst()
{
for(int i=1; i<=numvt; i++)
{
first[i]+=('0'+i);
}
for(int j=0; j<proce.size(); j++)
{
int k=0;
int has_0=0;
do
{
has_0=0;
k++;
if(k==proce[j].size())
{
first[getnum[proce[j][0]]]+=('0'+numvt);
break;
}
bingji(first[getnum[proce[j][0]]],get_f(getnum[proce[j][k]],has_0));
}
while(has_0);
}
}
void print_first()
{
cout<<"first集:"<<endl;
for(int i=numvt+1; i<=num; i++)
{
cout<<"first["<<getchar_[i]<<"]:";
for(int j=0; j<first[i].size(); j++)
cout<<getchar_[first[i][j]-'0']<<"";
cout<<endl;
}
cout<<endl;
}
void getfollow()
{
bingji(follow[getnum[proce[0][0]]],"0");
for(int j=0; j<proce.size(); j++)
{
for(int jj=1; jj<proce[j].size(); jj++)
{
if(getnum[proce[j][jj]]<=numvt)continue;
int k=jj;
int has_0;
do
{
has_0=0;
k++;
if(k==proce[j].size())
{
bingji(follow[getnum[proce[j][jj]]],follow[getnum[proce[j][0]]]);
break;
}
bingji(follow[getnum[proce[j][jj]]],get_f(getnum[proce[j][k]],has_0));
}
while(has_0);
}
}
}
void gettable()
{
for(int i=0; i<proce.size(); i++)
{
if(proce[i][1]=='@')
{
string flw=follow[getnum[proce[i][0]]];
for(int k=0; k<flw.size(); k++)
{
table[getnum[proce[i][0]]][flw[k]-'0']=i;
}
}
string temps=first[getnum[proce[i][1]]];
for(int j=0; j<temps.size(); j++)
{
if(temps[j]!=('0'+numvt))
{
table[getnum[proce[i][0]]][temps[j]-'0']=i;
}
else
{
string flw=follow[getnum[proce[i][1]]];
for(int k=0; k<flw.size(); k++)
{
table[getnum[proce[i][0]]][flw[k]-'0']=i;
}
}
}
}
}
string get_proce(int i)
{
if(i<0)return"";
string ans;
ans+=proce[i][0];
ans+="->";
for(int j=1; j<proce[i].size(); j++)
ans+=proce[i][j];
return ans;
}
void print_table()
{
cout<<"预测分析表:"<<endl;
for(int i=0; i<numvt; i++)
cout<<'\t'<<getchar_[i];
cout<<endl;
for(int i=numvt+1; i<=num; i++)
{
cout<<getchar_[i];
for(int j=0; j<numvt; j++)
{
cout<<'\t'<<get_proce(table[i][j]);
}
cout<<endl;
}
cout<<endl;
}
void print_follow()
{
cout<<"follow集:"<<endl;
for(int i=numvt+1; i<=num; i++)
{
cout<<"follow["<<getchar_[i]<<"]:";
for(int j=0; j<follow[i].size(); j++)
cout<<getchar_[follow[i][j]-'0']<<"";
cout<<endl;
}
cout<<endl;
}
string word;
string shuchu;
bool analyze()
{
stack<char>sta;
sta.push('#');
sta.push(proce[0][0]);
shuchu.push_back('#');
shuchu.push_back(proce[0][0]);
int i=0;
while(!sta.empty())
{
int cur=sta.top();
sta.pop();
if(cur==word[i])
{
word[i]=NULL;
if(!shuchu.empty())
shuchu.clear();
i++;
}
else if(cur=='#')
{
return 1;
}
else if(table[getnum[cur]][getnum[word[i]]]!=-1)
{
int k=table[getnum[cur]][getnum[word[i]]];
cout<<shuchu<<"";
cout<<word<<"#"<<"";
cout<<proce[k][0]<<"->";
for(int j=1; j<proce[k].size(); j++)
cout<<proce[k][j];
cout<<endl;
shuchu.clear();
for(int j=proce[k].size()-1; j>0; j--)
{
if(proce[k][j]!='@')
{
sta.push(proce[k][j]);
shuchu.push_back(proce[k][j]);
}
}
}
else
{
return 0;
}
}
return 1;
}
int main()
{
readin();
getfirst();
getfollow();
getfollow();
gettable();
print_first();
print_follow();
print_table();
// cout<<"请输入字:"<<endl;
// cin>>word;
// if(analyze())
// cout<<"succeed!"<<endl;
// else
// {
// cout<<"error!"<<endl;
// }
return 0;
}