C语言 编译原理实验二 预测分析算法的设计与实现

#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#

如有疑问,可以评论私信

  • 9
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值