#include<iostream>
using namespace std;
char data[20][20]; //存储算符优先关系
char lable[20]; //终结符集
char str[20][10]; //分析输入串
char formula[10][30]; //存储产生式
char First[10][10]; //FIRSTVT集
char Last[10][10]; //LASTVT集
int Tcharacter(char c); //判断终结符
int Index(char c); //返回下标
void FirstVt(char c); //求FIRSTVT集
void LastVt(char c); //求LASTVT集
void Table(); //创建算符优先分析表
int num; //输入文法产生式个数
int f_flag[10]= {0};
int l_flag[10]= {0};
void FirstVt(char c)
{
int i,j,k,m,n;
for(i=0; i<num; i++)
{
if(formula[i][0]==c)
break;
}
if(f_flag[i]==0)
{
n=First[i][0]+1;
m=0;
do
{
if(m==2||formula[i][m]=='|')
{
if(Tcharacter(formula[i][m+1]))
{
First[i][n]=formula[i][m+1];
n++;
}
else
{
if(Tcharacter(formula[i][m+2]))
{
First[i][n]=formula[i][m+2];
n++;
}
if(formula[i][m+1]!=c)
{
FirstVt(formula[i][m+1]);
for(j=0; j<num; j++)
{
if(formula[j][0]==formula[i][m+1])
break;
}
for(k=0; k<First[j][0]; k++)
{
int t;
for(t=0; t<n; t++)
{
if(First[i][t]==First[j][k+1])
break;
}
if(t==n)
{
First[i][n]=First[j][k+1];
n++;
}
}
}
}
}
m++;
}
while(formula[i][m]!='\0');
First[i][n]='\0';
First[i][0]=--n;
f_flag[i]=1;
}
}
void LastVt(char c)
{
int i,j,k,m,n;
for(i=0; i<num; i++)
{
if(formula[i][0]==c)
break;
}
if(l_flag[i]==0)
{
n=Last[i][0]+1;
m=0;
do
{
if(formula[i][m+1]=='\0'||formula[i][m+1]=='|')
{
if(Tcharacter(formula[i][m]))
{
Last[i][n]=formula[i][m];
n++;
}
else
{
if(Tcharacter(formula[i][m-1]))
{
Last[i][n]=formula[i][m-1];
n++;
}
if(formula[i][m]!=c)
{
LastVt(formula[i][m]);
for(j=0; j<num; j++)
{
if(formula[j][0]==formula[i][m])
break;
}
for(k=0; k<Last[j][0]; k++)
{
int t;
for(t=0; t<n; t++)
{
if(Last[i][t]==Last[j][k+1])
break;
}
if(t==n)
{
Last[i][n]=Last[j][k+1];
n++;
}
}
}
}
}
m++;
}
while(formula[i][m]!='\0');
Last[i][n]='\0';
Last[i][0]=--n;
l_flag[i]=1;
}
}
void Table()
{
char text[20][10];
int i,j,k,t,l,x=0,y=0;
int r1;
int m,n;
x=0;
for(i=0; i<num; i++)
{
FirstVt(formula[i][0]);
LastVt(formula[i][0]);
}
for(i=0; i<num; i++)
{
text[x][y]=formula[i][0];
y++;
for(j=1; formula[i][j]!='\0'; j++)
{
if(formula[i][j]=='|')
{
text[x][y]='\0';
x++;
y=0;
text[x][y]=formula[i][0];
y++;
text[x][y++]='-';
text[x][y++]='>';
}
else
{
text[x][y]=formula[i][j];
y++;
}
}
text[x][y]='\0';
x++;
y=0;
}
r1=x;
for(i=0; i<x; i++)
{
str[i][0]=text[i][0];
for(j=3,l=1; text[i][j]!='\0'; j++,l++)
str[i][l]=text[i][j];
str[i][l]='\0';
}
for(i=0; i<x; i++)
{
for(j=1; text[i][j+1]!='\0'; j++)
{
if(Tcharacter(text[i][j])&&Tcharacter(text[i][j+1]))
{
m=Index(text[i][j]);
n=Index(text[i][j+1]);
data[m][n]='=';
}
if(text[i][j+2]!='\0'&&Tcharacter(text[i][j])&&Tcharacter(text[i][j+2])&&!Tcharacter(text[i][j+1]))
{
m=Index(text[i][j]);
n=Index(text[i][j+2]);
data[m][n]='=';
}
if(Tcharacter(text[i][j])&&!Tcharacter(text[i][j+1]))
{
for(k=0; k<num; k++)
{
if(formula[k][0]==text[i][j+1])
break;
}
m=Index(text[i][j]);
for(t=0; t<First[k][0]; t++)
{
n=Index(First[k][t+1]);
data[m][n]='<';
}
}
if(!Tcharacter(text[i][j])&&Tcharacter(text[i][j+1]))
{
for(k=0; k<num; k++)
{
if(formula[k][0]==text[i][j])
break;
}
n=Index(text[i][j+1]);
for(t=0; t<Last[k][0]; t++)
{
m=Index(Last[k][t+1]);
data[m][n]='>';
}
}
}
}
m=Index('#');
for(t=0; t<First[0][0]; t++)
{
n=Index(First[0][t+1]);
data[m][n]='<';
}
n=Index('#');
for(t=0; t<Last[0][0]; t++)
{
m=Index(Last[0][t+1]);
data[m][n]='>';
}
data[n][n]='=';
}
int Index(char c)
{
int i;
for(i=0; lable[i]!='\0'; i++)
{
if(c==lable[i])
return i;
}
return -1;
}
int Tcharacter(char c)
{
int i;
for(i=0; lable[i]!='\0'; i++)
{
if(c==lable[i])
return 1;
}
return 0;
}
int main()
{
int i,j,k=0;
string word;
cout<<"输入文法产生式个数:"<<endl;
cin>>num;
cout<<"输入文法产生式:"<<endl;
for(i=0; i<num; i++)
{
cin>>formula[i];
First[i][0]=0; //first[i][0]和last[i][0]分别表示st[i][0]非终极符的FIRSTVT集和LASTVT集中元素的个数
Last[i][0]=0;
}
cout<<endl;
for(i=0; i<num; i++) //判断文法是否合法
{
for(j=0; formula[i][j]!='\0'; j++)
{
if(formula[i][0]<'A'||formula[i][0]>'Z')
{
cout<<"所输入的不是算符文法!"<<endl;
return 0;
}
if(formula[i][j]>='A'&&formula[i][j]<='Z')
{
if(formula[i][j+1]>='A'&&formula[i][j+1]<='Z')
{
cout<<"所输入的不是算符文法!"<<endl;
return 0;
}
}
}
}
for(i=0; i<num; i++)
{
for(j=0; formula[i][j]!='\0'; j++)
{
if((formula[i][j]<'A'||formula[i][j]>'Z')&&formula[i][j]!='-'&&formula[i][j]!='>'&&formula[i][j]!='|')
lable[k++]=formula[i][j];
}
}
lable[k]='#';
lable[k+1]='\0';
Table();
cout<<"FIRSTVT集如下:"<<endl;
for(i=0; i<num; i++)
{
cout<<formula[i][0]<<":"<<" ";
for(j=0; j<First[i][0]; j++)
{
cout<<First[i][j+1]<<" ";
}
cout<<endl;
}
cout<<"LASTVT集如下:"<<endl;
for(i=0; i<num; i++)
{
cout<<formula[i][0]<<":"<<" ";
for(j=0; j<Last[i][0]; j++)
{
cout<<Last[i][j+1]<<" ";
}
cout<<endl;
}
cout<<endl;
cout<<"算符优先分析表如下:"<<endl;
for(i=0; lable[i]!='\0'; i++)
cout<<"\t"<<lable[i];
cout<<endl;
for(i=0; i<k+1; i++)
{
cout<<lable[i]<<"\t";
for(j=0; j<k+1; j++)
{
cout<<data[i][j]<<"\t";
}
cout<<endl;
}
cout<<endl;
for(i=0; i<k+1; i++)
{
for(j=0; j<k+1; j++)
{
if(data[i][j]=='>'&&data[j][i]!='<'&&data[j][i]!='\0') break;
else if(data[i][j]=='<'&&data[j][i]!='>'&&data[j][i]!='\0') break;
else if(data[i][j]=='='&&data[j][i]!='='&&data[j][i]!='\0') break;
}
}
if(i==(k+1)&&j==(k+1)) cout<<"该文法是算符优先文法!"<<endl;
else
{
cout<<"该文法不是算符优先文法!"<<endl;
return 0;
}
}
测试用例与结果