预测分析法基本思路求解first集合和follow集合,之后构造预测分析表,用到的结构体为GRAM,其中包含该非终结符a以及其对应的first和follow,输入格式如下(以#结束输入)
E::=TE’
E’::=+TE’|ε
T::=FT’
T’::=*FT’|ε
F::=(E)|i
#
#include<bits/stdc++.h>
using namespace std;
//判断终结符和非终结符 返回1是非终结符 返回0是终结符
int Norterminal(char c)
{
if(c>='A'&&c<='Z')
return 1;
else if(c!=':'&&c!='='&&c!='<'&&c!='>'&&c!=' '&&c!='|')
return 0;
else
return -1;
}
struct GRAM
{
//$代表空
string a;
string first;
string follow;
};
struct LIST
{
int num;
string s;
};
int main()
{
GRAM gram[50];
string grammer;
cout<<"请输入文法(以#结束)"<<endl;
std::vector<string> strN;
cin>>grammer;//输入规则
strN.push_back(grammer);
int num=1; //文法个数
char str[10][80];
const char *ch = "|";
char *result;
vector<string> strN1; //存处理过“|”规则的
for(int i=0;i<grammer.length();i++)
{
str[0][i]=grammer[i];
}
for(int h=grammer.length();h<80;h++)
{
str[0][h]=NULL;
}
result = strtok(str[0],ch);
while(result!=NULL)
{
strN1.push_back(result);
result = strtok(NULL,ch);
}
for(int i=1;grammer!="#";i++)
{
cin>>grammer;
strN.push_back(grammer);
num++;
/*处理转换的规则形式输入部分*/
for(int h=0;h<grammer.length();h++)
{
str[i][h]=grammer[h];
}
for(int h=grammer.length();h<80;h++)
{
str[i][h]=NULL;
}
result = strtok(str[i],ch);
while(result!=NULL)
{
strN1.push_back(result);
result = strtok(NULL,ch);
}
}
int count=0;
/*
获取first集合
*/
//直接获取first终结符
for(unsigned i=0;i<strN.size();i++)
{
gram[i].a=strN[i][0];
gram[i].first="";
if(!Norterminal(strN[i][4]))
{
gram[i].first=strN[i][4];
}
for(unsigned k=5;k<strN[i].length()&&k+1<strN[i].length();k++)
{
if(strN[i][k]=='|')
{
if(!Norterminal(strN[i][k+1]))
{
gram[i].first+=strN[i][k+1];
}
}
}
}
for(unsigned i=0;i<strN.size();i++)
{
if(gram[i].first!="")
count++;
}
//当第一个字符是非终结符时
while(count!=num)
{
for(unsigned i=0;i<strN.size();i++)
{
for(unsigned k=0;k<strN.size();k++)
{
if(gram[k].a[0]==strN[i][4]&&gram[k].first!=""&&k!=i&&gram[i].first=="")
{
gram[i].first=gram[k].first;
count++;
break;
}
}
}
}
//打印显示对应关系
cout<<"first集合为:"<<endl;
for(unsigned i=0;i<strN.size();i++)
{
cout<<gram[i].a<<" "<<gram[i].first<<endl;
}
/*
获取follow集合
*/
gram[0].follow="#";
for(unsigned i=1;i<strN.size();i++)
{
gram[i].follow="";
}
//求显而易见的follow
for(unsigned i=0;i<strN.size();i++)
{
for(unsigned k=0;k<strN.size();k++)
{
for(int j=4;j<strN[k].length();j++)
{
if(gram[i].a[0]==strN[k][j])
{
if(!Norterminal(strN[k][j+1]))
{
gram[i].follow+=strN[k][j+1];
}
else
{
for(unsigned l=0;l<strN[k].size();l++)
{
if(strN[k][j+1]==gram[l].a[0])
{
gram[i].follow+=gram[l].first;
}
}
}
}
}
}
}
//删除first中的$
for(unsigned i=0;i<strN.size();i++)
{
if(gram[i].follow!="")
{
for(int k=0;k<gram[i].follow.length();k++)
{
if(gram[i].follow[k]=='$')
{
gram[i].follow[k]=NULL;
}
if(gram[i].follow[k]==NULL)
{
gram[i].follow.erase(gram[i].follow.begin()+k);
}
}
}
}
//求该符号后边是非终结符且非终结符可以为空
for(unsigned i=0;i<strN.size();i++)
{
if(gram[i].a[0]==strN[i][0])
{
if(strN[i].find('|')==-1)
{
for(unsigned k=0;k<strN.size();k++)
{
if(strN[i][strN[i].length()-1]==strN[k][0])
{
if(strN[k].find('$'))
{
for(unsigned l=0;l<strN.size();l++)
{
if(strN[i][strN[i].length()-2]==strN[l][0])
{
gram[l].follow+=gram[i].follow;
//去相同的符号
string ustr(gram[l].follow);
sort(ustr.begin(), ustr.end());
ustr.erase(unique(ustr.begin(), ustr.end()), ustr.end() );
gram[l].follow=ustr;
}
}
}
}
}
}
else
{
for(int j=4;j<strN[i].length()&&j-1>=0;j++)
{
if(strN[i][j]=='|')
{
if(Norterminal(strN[i][j-1]))
{
gram[j-1].follow+=gram[i].follow;
string ustr(gram[j-1].follow);
sort(ustr.begin(), ustr.end());
ustr.erase(unique(ustr.begin(), ustr.end()), ustr.end() );
gram[j-1].follow=ustr;
}
}
}
}
}
}
for(unsigned i=0;i<strN.size();i++)
{
if(gram[i].a[0]==strN[i][0])
{
if(strN[i].find('|')==-1)
{
if(Norterminal(strN[i][strN[i].length()-1]))
{
for(unsigned l=0;l<strN.size();l++)
{
if(strN[i][strN[i].length()-1]==strN[l][0])
{
gram[l].follow+=gram[i].follow;
//去相同的符号
string ustr(gram[l].follow);
sort(ustr.begin(), ustr.end());
ustr.erase(unique(ustr.begin(), ustr.end()), ustr.end() );
gram[l].follow=ustr;
}
}
}
}
}
}
cout<<"follow集合为:"<<endl;
for(unsigned i=0;i<strN.size();i++)
{
cout<<gram[i].a<<" "<<gram[i].follow<<endl;
}
string term="";
string nonterm="";
cout<<"终结符和#为:"<<endl;
for(unsigned i=0;i<strN.size();i++)
{
for(int j=0;j<strN[i].length();j++)
{
if(!Norterminal(strN[i][j])&&strN[i][j]!='$')
term+=strN[i][j];
}
string ustr(term);
//sort(ustr.begin(), ustr.end());
ustr.erase(unique(ustr.begin(), ustr.end()), ustr.end() );
term=ustr;
}
cout<<term<<endl;
cout<<"非终结符为:"<<endl;
for(unsigned i=0;i<strN.size();i++)
{
if(strN[i][0]!='#')
nonterm+=strN[i][0];
}
cout<<nonterm<<endl;
/*转换规则形式*/
cout<<"转换后的规则形式为:"<<endl;
LIST listgram[strN1.size()];
int listnumber =0;
for(unsigned i=0;i<strN1.size()&&i-1>=0;i++)
{
if(strN1[i].find("::")==-1)
{
string add="";
add=add+strN1[i-1][0]+"::="+strN1[i];
strN1[i]=add;
}
cout<<strN1[i]<<endl;
listgram[i].s=strN1[i];
listgram[i].num=i;
listnumber++;
}
/*构造预测分析表*/
int list[nonterm.length()][term.length()];
for(int i=0;i<nonterm.length();i++)
{
for(int j=0;j<term.length();j++)
{
list[i][j]=-1;
}
}
for(unsigned i=0;i<strN1.size()-1;i++)
{
if(strN1[i][4]!='$')
{
if(Norterminal(strN1[i][4]))
{
for(unsigned k=0;k<strN.size();k++)
{
for(unsigned f=0;f<strN.size();f++)
if(strN1[i][0]==gram[f].a[0])
{
if(strN1[i][4]==gram[k].a[0])//比较E::=TG 比较T的
{
for(int l=0;l<gram[k].first.length();l++)
{
for(int h=0;h<term.length();h++)
{
if(gram[k].first[l]==term[h])
{
list[f][h]=i;
}
}
}
}
}
}
}
else
{
for(unsigned k=0;k<strN.size()&&k-1>=0;k++)
{
for(unsigned f=0;f<strN.size();f++)
if(strN1[i][0]==gram[f].a[0])
{
if(strN1[i][0]==gram[k].a[0])
{
for(int h=0;h<term.length();h++)
{
if(strN1[i][4]==term[h])
{
list[f][h]=i;
}
}
}
}
}
}
}
else
{
for(unsigned k=0;k<strN.size()&&k-1>=0;k++)
{
if(strN1[i][0]==gram[k].a[0])
{
for(int l=0;l<gram[k].follow.length();l++)
{
for(int h=0;h<term.length();h++)
{
if(gram[k].follow[l]==term[h])
{
list[k][h]=i;
}
}
}
}
}
}
}
cout<<"预测分析表为:"<<endl;
for(int i=0;i<nonterm.length();i++)
{
for(int j=0;j<term.length();j++)
{
cout<<list[i][j]<<" ";
}
cout<<endl;
}
int k1;
//cout<<listgram[i].s<<endl;
cout<<" |";
for(int i=0;i<term.length();i++)
{
//cout<<" "<<term[i]<<" " ;
// printf("%5c",term[i]);
cout<<setw(10)<<term[i];
cout<<"|";
}
cout<<endl;
cout<<"____________________________________________________________________________"<<endl;
//cout<<" "<<nonterm[0]<<" ";
for(int i=0;i<nonterm.length();i++)
{
printf("%2c",nonterm[i]);
cout<<" "<<"|";
for(int j=0;j<term.length();j++)
{
//cout<<" "<<nonterm[h]<<" ";
for(k1=0;k1<listnumber-1;k1++)
{
if(list[i][j]==listgram[k1].num)
{
cout<<setw(10)<<listgram[k1].s<<"|";
// printf("%7s ",listgram[k1].s);
break;
}
}
if((listnumber-1)==k1)
cout<<setw(11)<<"|";
}
cout<<endl;
cout<<"____________________________________________________________________________"<<endl;
}
}
其中G代表E’ H代表T’ J代表F’。运行结果如下: