#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
char grammer[200][200];
char stack[200]={'\0'};
int sp=0;
int p1=0;
int vtnum,vnnum,pronum;
char vtsign[200];
char vnsign[200];
char firstSet[200][200];
char followSet[200][200];
int M[200][200];
int findvt(char ch)
{
int i;
for( i=0;i<vtnum;i++)
if(vtsign[i]==ch)
break;
return i;
}
int findvn(char ch)
{
int i;
for(i=0;i<vnnum;i++)
if(vnsign[i]==ch)
break;
return i;
}
int addfirstSet(char X,char c)
{
int i,j,k,m;
i=findvt(c);
if(i<vtnum)
{
j=findvn(X);
firstSet[j][i]=1;
}
else{
j=findvn(X);
m=findvn(c);
for(k=0;k<=vtnum;k++)
{
if(firstSet[m][k]==1)
firstSet[j][k]=1;
}
}
return 1;
}
bool haveEmpty(char c)
{
int i,j;
i=findvt(c);
if(i<vtnum)
return false;
else{
j=findvn(c);
if(firstSet[j][vtnum]==1)
return true;
else
return false;
}
}
int addfollowSet(char X,char c,int kind)
{
int i,j,k,m;
i=findvt(c);
if(i<vtnum)
{
j=findvn(X);
followSet[j][i]=1;
}
else{
if(kind==0){
j=findvn(X);
m=findvn(c);
for(k=0;k<=vtnum;k++)
{
if(followSet[m][k]==1)
followSet[j][k]=1;
}
}
else{
j=findvn(X);
m=findvn(c);
for(k=0;k<vtnum;k++)
{
if(firstSet[m][k]==1)
followSet[j][k]=1;
}
}
}
return 1;
}
int first(char X)
{
int i,j,k,m,p,flag;
for(i=0;i<pronum;i++)
{
if(grammer[i][0]==X)
{
p=3;
if(grammer[i][p]=='$')
{
j=findvn(X);
firstSet[j][vtnum]=1;
}
else{
while(grammer[i][p]!='\0')
{
int q=findvt(grammer[i][p]);
if(q<vtnum){
addfirstSet(X,grammer[i][p]);
break;
}
else if(q>=vtnum){
k=findvn(grammer[i][p]);
flag=0;
for(m=0;m<=vtnum;m++)
{
if(firstSet[k][m]==1)
{
flag=1;
break;
}
}
if(flag==0)
first(grammer[i][p]);
addfirstSet(X,grammer[i][p]);
if(haveEmpty(grammer[i][p]))
p++;
else
break;
}
}
}
}
}
return 1;
}
int follow(char X)
{
int i,j,k,p,flag;
char ch;
followSet[0][vtnum]=1;
for(i=0;i<pronum;i++)
{
p=3;
while(grammer[i][p]!='\0'&&grammer[i][p]!=X)
p++;
if(grammer[i][p]==X)
{
ch=grammer[i][p++];
if(grammer[i][p]=='\0')
{
j=findvn(grammer[i][0]);
flag=0;
for(k=0;k<=vtnum;k++)
{
if(followSet[j][k]==1)
{
flag=1;
break;
}
}
if(flag==0&&grammer[i][0]!=X)
follow(grammer[i][0]);
addfollowSet(X,grammer[i][0],0);
}
else{
while(haveEmpty(grammer[i][p])&&grammer[i][p]!='\0')
{
addfollowSet(X,grammer[i][p],1);
j=findvn(grammer[i][0]);
flag=0;
for(k=0;k<=vtnum;k++)
{
if(followSet[j][k]==1)
{
flag=1;
break;
}
}
if(flag==0&&grammer[i][0]!=X)
follow(grammer[i][0]);
addfollowSet(X,grammer[i][0],0);
p++;
}
if(!haveEmpty(grammer[i][p]))
addfollowSet(X,grammer[i][p],1);
}
}
}
return 1;
}
int initAnalysis()
{
int i,j;
for(i=0;i<vnnum;i++)
for(j=0;j<=vtnum;j++)
{
M[i][j]=-1;
}
return 1;
}
int analysis()
{
int i,j,k,m,n,x;
for(x=0;x<pronum;x++)
{
i=findvn(grammer[x][0]);
m=findvt(grammer[x][3]);
if(grammer[x][3]!='$')
{
for(j=0;j<vtnum;j++)
{
if(firstSet[i][j]==1)
{
if(m<vtnum)
{
if(M[i][j]==-1&&grammer[x][3]==vtsign[j])
M[i][j]=x;
}
else{
n=findvn(grammer[x][3]);
if(M[i][j]==-1&&firstSet[n][j]==1)
M[i][j]=x;
}
}
}
}
if(haveEmpty(grammer[x][0]))
{
for(k=0;k<=vtnum;k++)
{
if(followSet[i][k]==1)
M[i][k]=x;
}
}
}
return 1;
}
int control()
{
int i,j,k,m,n,x,y,flag=0;
char c1[20]={'\0'};
char c2;
stack[sp++]='#';
stack[sp++]=vnsign[0];
printf("\n请输入要分析的句型(以#结尾):");
i=0;
char c=getchar();
while(c!='#')
{
c1[i++]=c;
c=getchar();
}
c1[i]='#';
printf("\n分析过程:\n\n分析栈 输入串 所用规则 ");
while(c1[p1]!='\0')
{
printf("\n");
for(i=0;stack[i]!='\0';i++)
printf("%c",stack[i]);
for(k=0;k<20-i;k++)
printf(" ");
m=0;
for(i=p1;c1[i]!='\0';i++)
{
printf("%c",c1[i]);
m++;
}
for(i=0;i<20-m;i++)
printf(" ");
c2=stack[sp-1];
stack[sp-1]='\0';
sp--;
i=findvt(c2);
if(i<vtnum)
{
if(c2==c1[p1])
{
p1++;
printf(" ");
}
else
break;
}
else
{
if(c2=='#')
{
if(c1[p1]==c2)
{
flag=1;
break;
}
else
break;
}
else
{
m=findvn(c2);
n=findvt(c1[p1]);
if(M[m][n]!=-1)
{
j=M[m][n];
printf("%s",grammer[j]);
k=3;
while(grammer[j][k]!='\0')
k++;
if(grammer[j][3]!='$')
{
for(y=k-1;y>=3;y--)
{
stack[sp++]=grammer[j][y];
stack[sp]='\0';
}
}
}
else break;
}
}
}
if(flag==1)
printf("\n\nSucceed,输入的句型符合该文法!\n");
else
printf("\n\nError,输入的句型和文法不符!\n");
return 1;
}
int printf_table()
{
int i,j,p;
printf("\n预测分析表为:\n");;
printf(" ");
for(i=0;i<vtnum;i++)
{
printf("%c ",vtsign[i]);
}
printf("# \n");
for(i=0;i<vnnum;i++)
{
printf("%c ",vnsign[i]);
for(j=0;j<=vtnum;j++)
{
if(M[i][j]!=-1)
{
int k=M[i][j];
int m=strlen(grammer[k]);
printf("%s",grammer[k]);
for(p=0;p<10-m;p++)
printf(" ");
}
else{
for(p=0;p<10;p++)
printf(" ");
}
}
printf("\n");
}
return 1;
}
int main()
{
int i,j;
for(i=0;i<200;i++)
for(j=0;j<200;j++)
grammer[i][j]='\0';
printf("非终结符号串:");
scanf("%s",vnsign);
getchar();
vnnum=strlen(vnsign);
printf("终结符号串:");
scanf("%s",vtsign);
getchar();
vtnum=strlen(vtsign);
printf("产生式个数:");
scanf("%d",&pronum);
printf("文法:\n");
for(i=0;i<pronum;i++)
{
scanf("%s",grammer[i]);
getchar();
}
for(i=0;i<vnnum;i++)
for(j=0;j<=vtnum;j++)
firstSet[i][j]=0;
for(i=0;i<vnnum;i++)
first(vnsign[i]);
for(i=0;i<vnnum;i++)
for(j=0;j<=vtnum;j++)
followSet[i][j]=0;
for(i=0;i<vnnum;i++)
follow(vnsign[i]);
initAnalysis();
analysis();
printf_table();
control();
system("pause");
}
非终结符:
ETFAB
终结符:
+*()i
文法:
E->TA
A->+TA
A->$
T->FB
B->*FB
B->$
F->(E)
F->i
输入:
(i)*i#
如有疑问,可以评论私信