编译原理实验LL(1) C语言版本

编译原理实验LL(1) C语言版本

本程序是以#为终结标志
只可以使用我的样例
任何样例都可以正确输出判断表
但是后边的不可以使用
测试的文法
S,AB#
S,dC#
A,!#
A,b#
B,!#
B,aD#
C,AD#
C,d#
D,aS#
D,c#
输入的非终结符
SABCD#
测试样例,测试样例可以使用任何适合本文法的
baadc 接受
baadcc 错误

# include <stdio.h>
# include <stdlib.h>
#include <iostream>
# include<stack>
using namespace std;
//1000表示结束 
//1111表示NULL 
//1400表示为#
stack<int>zhan;
struct node_first
{
	int node_first_number;
	//int flag=0;
	struct node_first *next; 
};
struct node_biao
{
	struct node_first *next;
}vnode[100];
struct node_follow
{
	int node_follow_number;
	int flag=0;
	struct node_follow *next; 
	//struct node_follow *follownext; 
};
struct node_followbiao
{
	struct node_follow *next;
	//struct node_followbiao *next;
}vnodefollow[100];

 struct StrStack//分析栈 
{
	char str[100];//存产生式 
	int top;
};
char GetTop(StrStack *s); 
char popStr(StrStack *s);
int pushStr(StrStack *s,char c);
void shuru();//输入产生式 
void jisuan(); //判断总体产生式 为不为空 
void panduan();//判断1个产生式为不为空 
void firsts();//求first集 
void follows();//求follow集 
int followshuchu(struct node_follow *q,int counts,int k,int i);//输出follow集 
void selects(); 
void qiufenxibiaodashi();
void Storeyucefenxibiao();

int select_biaoji[3][100]={0};//存放产生式中有多少个字母 
int select_ends[100][100];//存放select集 
int follow_ends[100][100];//存放最后的follow集 
int first_ends[100][100];//存放最后的first集 
int endjust_number[100][100];//存放产生式 
char no_end[100]; 
int no_ends[3][100]; 
int no_endnumber[100];//存放非终结符的数字 
int n=0,m=0; //endjust_number[100][100]中有多少行n表示,endjust_number[100][100]有多少列m表示 
int sum=0; //总共有多少个非终结符 
int sumend=0;
int flag[100];	//求空产生式的标记 
int biaoji[100];//求空产生式的标记 
int end[100];//存放终结符 
char  stards; 
char shurushizi[100];//存放分析式 
int Storefenxi[1502][1502]={-1};//存放储存的预测分析表 
int f=0;

int main()
{
	int i=0,j;
	
	for(i=1;i<3;i++)
	{
		for(j=0;j<100;j++)
		no_ends[i][j]=10;
	}
    printf("输入文法中的非终结符:(以#结束的标志)\n");//输入非终结符 
	i=0;
	scanf("%c",&no_end[i]);
	
	while(no_end[i]!='#')
	{
		no_ends[0][abs(no_end[i]-'a')] =abs(no_end[i]-'a');
	    no_ends[1][abs(no_end[i]-'a')]=1;
	    no_ends[2][abs(no_end[i]-'a')]=1;
	    
		no_endnumber[i]=no_end[i]-'a';
		i++;
		scanf("%c",&no_end[i]);
	}
	getchar(); 
	no_end[i]='\0';
	sum=i;
	printf("输入终结符开始符号:");
	scanf("%c",&stards) ;
	getchar();

	printf("输入终结符的符号:\n");	
	char w;
	scanf("%c",&w);
	i=0;
	while(w!='#')
	{
		if(w!='!')
		{
		end[i]=w-'a';	
		}
		else
		end[i]=1111;
		i++;
		scanf("%c",&w);
	}
	end[i]=1400;
	end[i+1]=1000;
	getchar();
	sumend=i+1;
	
	for(i=0;i<sum;i++)
	{
		printf("%c %d ",no_endnumber[i]+'a',no_endnumber[i]);
	}
	printf("\n"); 
	
    printf("输入产生式*****\n");	
	scanf("%c",&shurushizi[f]);
	while(shurushizi[f]!='#')
	{
		f++;
		scanf("%c",&shurushizi[f]);
	}
	getchar();
	shuru();//输入文法
	jisuan();//核心计算是否为空 

	printf("****************输出判断表*************************\n");
	//printf("%d\n",sum);//输出是否为空的表 
	for(i=0;i<sum;i++)
	{
		printf("%4c",no_endnumber[i]+'a');
	}
	printf("\n");
	for(i=0;i<sum;i++)
	{
	    printf("%4d",no_ends[1][abs(no_endnumber[i])]);	
	}
	printf("\n");
	firsts();
	follows();
	selects();
	Storeyucefenxibiao();
	qiufenxibiaodashi();
	
	return 0;
}

void shuru()
{ 
	printf("null以!,1111代替\n");//文法输入过程 
	printf("以1000代替结束标志\n");
	int j=0;
	int i=0;
	n=0,m=0;
	int count=0; 
	char words;
	endjust_number[0][0]=0;
	printf("输入文法算法:\n");
	while(endjust_number[i][j]!=1000)
	{
		i=0;
		scanf("%c,",&words);
		if(words>='A'&&words<='Z')
		{
		     endjust_number[i][j]=words-'a';
		     select_biaoji[i][j]=words-'a';
		}				
		else 		 		    
		{	
		    endjust_number[i][j]=1000;
		    select_biaoji[i][j]=1000;
			break;	
		}		
		while(1)
		{
			i++;
			scanf("%c",&words);
			if((words>='a'&&words<='z')||(words>='A'&&words<='Z'))
			    endjust_number[i][j]=words-'a';
			else if(words=='!')
			    endjust_number[i][j]=1111;
			else if(words=='#')
			{
			  	endjust_number[i][j]=1000;			  	
			    break;
			}
			else 
			{
				endjust_number[i][j]=words-'a';
			}
	    }
	    select_biaoji[1][j]=i;
	    if(n<i)
	    {
	    	n=i;
		}
	    getchar();//收空格 
	    j++;
	    m=j;
	} 
	printf("%d %d\n",n,m);
	printf("*************输出select_biaoji中有多少个产生式*********\n");
	for(j=0;j<m;j++)
	{
		printf("%4c",select_biaoji[0][j]+'a');	
	}
	printf("\n");
	for(j=0;j<m;j++)
	{	
		printf("%4d",select_biaoji[1][j]); 
	}
	printf("\n");
	printf("输出文法的产生式***************\n");
	for(i=0;i<=n;i++)
	{	
		for(j=0;j<m;j++)
		{
			if(i==0)			
				printf("%4c",endjust_number[i][j]+'a');			
			else
			{
				if(endjust_number[i][j]==1111)
					printf("  ε");				
				else if(endjust_number[i][j]==1000)				
					printf("   #");				
				else if(endjust_number[i-1][j]==1000)				
					printf("    ");		
				else if(endjust_number[i-1][j]!=1111)			
					printf("%4c",endjust_number[i][j]+'a');						
			}
		}
		printf("\n");
	}

		
}  
void jisuan()//扫描出空的非终结符 
{
	int i=1,j=0;//no_end中的i是行,j是列 
	int f=0,k=0;//endjust_number中的f是行,k是列 
    int P=30;

	for(j=0;j<100;j++)
	{
	   flag[j]=2;
	   biaoji[j]=0;
	   vnode[j].next=NULL;
	   
	}
	
	int count=0;
	while(1)
	{   
		panduan();	    
		for(j=0;j<sum;j++)//如果每一次每一行的1,2都一样说明是真的 
		{
		 	if(flag[abs(no_endnumber[j])]!=2&&flag[abs(no_endnumber[j])]!=0)
		 	{
		 		//printf("%c",no_endnumber[j]+'a');
		 		count++;
			}
		}
		//printf("%d\n",count);
		if(count==sum)
		{
		 	break;
		}
		else
		{
		 	count=0;
		}
	}
}
void panduan()
{
	int j=0;
	int i=1;
	int k=0;	
    for(j=0;j<m;j++)
	    {
	    	i=1;
		    if((endjust_number[i][j]+'a'>='A'
		    &&endjust_number[i][j]+'a'<='Z')//为非终结符,具有第一个为空的 
		    ||endjust_number[i][j]==1111) 
		    {
			    if(endjust_number[i][j]==1111&&flag[abs(endjust_number[k][j])]==0)
		        {
		    	    //printf("#"); 
		    	    //printf("%c",endjust_number[k][j]+'a');
			        no_ends[1][abs(endjust_number[k][j])]=0;
			        no_ends[2][abs(endjust_number[k][j])]=0;  
			        flag[abs(endjust_number[k][j])]=100; 
		        }
		        else 
		        {   
				     for(i=1;endjust_number[i][j]!=1000;i++)
					 {
					//	printf("$"); 
		    	        //printf("%c",endjust_number[k][j]+'a');
		    	        //printf("%c",endjust_number[i][j]+'a');
				        if(flag[abs(endjust_number[k][j])]!=100)
			            {	
			               no_ends[1][abs(endjust_number[k][j])]=
						   no_ends[1][abs(endjust_number[i][j])];
				        }
				         if(no_ends[1][abs(endjust_number[i][j])]==1)
				        {
				        	break;
						}
				         if(endjust_number[i][j]+'a'>='a'&&endjust_number[i][j]+'a'<='z')
				        {
				        	no_ends[1][abs(endjust_number[k][j])]=1;
						}
				    //   printf("%d",no_ends[1][abs(endjust_number[k][j])]);
				    //   printf("%d",no_ends[1][abs(endjust_number[i][j])]);				   						   
					}
					if(biaoji[abs(endjust_number[k][j])]==
					no_ends[1][abs(endjust_number[k][j])])					
						   	flag[abs(endjust_number[k][j])]=1;						   
					   else					   
						   	flag[abs(endjust_number[k][j])]=0;	
					biaoji[abs(endjust_number[k][j])]=
					no_ends[1][abs(endjust_number[k][j])];         
		         }
		     }
		     else if(flag[abs(endjust_number[k][j])]==2)
		     {
		     	flag[abs(endjust_number[k][j])]=1;
			 }
	    }
	/*	printf("\n过程中非终结符的判断***********\n") ;
	    for(j=0;j<sum;j++)
	    {
		    printf("%4c",no_endnumber[j]+'a');
	    }
	    printf("\n");
	    for(j=0;j<sum;j++)
	    {
		    printf("%4d",no_ends[1][abs(no_endnumber[j])]);
	     }
	      printf("\n\n");*/
} 

void firsts()
{
	int i,j,k=0;
	int count=3;
	struct node_first *head,*p,*tail,*q;
	head=(struct node_first*)malloc(sizeof(struct node_first));
	head->next=NULL;
	head->node_first_number=0;
	tail=head; 
	int counts;
	//printf("%d\n",tail->node_first_number);
	for(j=0;j<m;j++)//终结符
	    {
		    i=1;		    
			head->next=NULL;
		    tail=head;
		    if(endjust_number[i][j]+'a'>='a'&&endjust_number[i][j]+'a'<='z')
		    {   
			   //printf("$终结符:");
		      // printf("%c %c*",endjust_number[k][j]+'a',endjust_number[i][j]+'a');
			   p=(struct node_first*)malloc(sizeof(struct node_first));
			   p->node_first_number=endjust_number[i][j];
			   p->next=NULL;
			   p->next=head->next;
		       head->next=p;
		        
		       q=head;//将求出的值赋给first集 
		       while(q->next!=NULL)
		       {
				    q=q->next;
				//	printf("%c ^",q->node_first_number+'a');
			   }
			q->next=vnode[abs(endjust_number[k][j])].next;//去掉了头指针head
		    vnode[abs(endjust_number[k][j])].next=head->next;
		    q=vnode[abs(endjust_number[k][j])].next;//循环输出一次 
			while(q!=NULL)
			{
			//	counts=q->node_first_number;
				//printf("%c",counts+'a'); 
				q=q->next;
			}
		//	printf("#\n");	 
		//	  
		    }  	
		} 
	for(j=0;j<m;j++)//非终结符
	    {
		    i=1;		    
			head->next=NULL;
		    tail=head;		    
		   if(endjust_number[i][j]+'a'>='A'&&endjust_number[i][j]+'a'<='Z')//非终结符 
		    {
				    for(i=1;i<n;i++)//扫描产生式 
				    {   
				        struct node_first *P,*Q,*T; 
				        if(endjust_number[i][j]+'a'>='a'&&endjust_number[i][j]+'a'<='z')
						{
							//i=1;
						//	printf("3\n");
							Q=vnode[abs(endjust_number[k][j])].next;//扫描first集找到最后节点 
	                        while(Q!=NULL)
	                        {
	                        	T=Q;
	                    	Q=Q->next;
						    }
						    p=(struct node_first*)malloc(sizeof(struct node_first));
						    p->node_first_number=endjust_number[i][j];
							p->next=NULL;
							T->next=p;
							T=p;
							break;
						}	
					   // printf("#xunhuan产生式为空 %d:",i);		                
		               // printf("%c %c ",endjust_number[k][j]+'a',endjust_number[i][j]+'a');
		                Q=vnode[abs(endjust_number[k][j])].next;//扫描first集找到最后节点 
	                    while(Q!=NULL)
	                    {
	                    	T=Q;
	                    	Q=Q->next;
						}
                        p=vnode[abs(endjust_number[i][j])].next;//得到D的first集 
			            //q=p;	
						while(1)
						{   //count=0;
						    if(p==NULL)
						       break;
						    P=(struct node_first*)malloc(sizeof(struct node_first));
						    P->node_first_number=p->node_first_number;
							P->next=NULL; 
							
						  //  printf("%c ",((P->node_first_number)+'a'));
						    T->next=P;
						    T=T->next; 
							p=p->next;
							 
							//tail=P;	//求出尾节点
						   // P=P->next	; 
						}

						if(endjust_number[i+1][j]==1000)
						{
							i=1; 
						//	printf("2\n");
						 	break;
						}
					    if(no_ends[1][abs(endjust_number[i][j])]!=0)//如果产生式不为空结束 
					    { 
					       i=1;
					    //   printf("1\n");
						   break; 
						} 		
				    }
		/*	printf("\n");
		   printf("***************\n");
		    q=vnode[abs(endjust_number[k][j])].next;//循环输出一次 
		    i=0;
			while(q!=NULL)
			{
				counts=q->node_first_number;
			printf("%c ",counts+'a');
				i++;
				q=q->next;
			}
			printf("#\n");	
			*/
		    }
		        
	     }
	i=0;
	printf("输出first集***************\n"); 
	for(j=0;j<sum;j++)
	{ 
		printf("%c:",no_endnumber[j]+'a');
		i=0;
		first_ends[i][abs(no_endnumber[j])]=no_endnumber[j];
		if(no_ends[1][abs(no_endnumber[j])]==0)
		{    
		       printf("ε");
		       i++; 
		       first_ends[i][abs(no_endnumber[j])]=1111;
		}	
		
		p=vnode[abs(no_endnumber[j])].next;//去除重复的元素 
		if(p!=NULL)
		{
			while(p->next!=NULL)
		   {   
		        q=p->next;
			    while(q->node_first_number==p->node_first_number)
			    {
				    p->next=p->next->next;
				    free(q);	
			    }
			    p=p->next;
			//q=p->next;
		    }//printf("$$$\n");
		}
		p=vnode[abs(no_endnumber[j])].next;//输出 	
		while(p!=NULL)
		{	  
		    counts=p->node_first_number;				
			printf("%c ",counts+'a');
			i++;
			first_ends[i][abs(no_endnumber[j])]=counts;
			p=p->next;		
		}
		i++;
		first_ends[i][abs(no_endnumber[j])]=1000;
		printf("\n");
	}
	printf("存储的first集*******************:\n"); 
	for(j=0;j<sum;j++)
	{
		i=0;
		while(first_ends[i][abs(no_endnumber[j])]!=1000)
		{
			if(first_ends[i][abs(no_endnumber[j])]==1111)
			 printf("ε");
			 else 
			printf("%c ",first_ends[i][abs(no_endnumber[j])]+'a');
			i++;
		}
		printf("\n");
	}
}

void follows()//求follow集运算 
{	
	struct node_follow *head,*p,*tail,*q,*Q;
	struct node_first *P;
	int i,j,k=0,l=0;//i,j表示扫描产生式,k表示非终结符,l待定 
	for(j=0;j<100;j++)
	{
	   vnodefollow[j].next=NULL;
	}
	//开始符号加入#
	   p=(struct node_follow*)malloc(sizeof(struct node_follow));
	   p->flag=0;//表示自己申请的结点 
	   p->node_follow_number=1400;
	   p->next=NULL;
	   
	   vnodefollow[abs(stards-'a')].next=p;
	
	while(k<sum)//扫描每一个非终结符 ,k表示非终结符 
	{
		for(j=0;j<m;j++)//横着循环 
	    {
	    	i=1; 
		   while(endjust_number[i][j]!=no_endnumber[k]&&endjust_number[i][j]!=1000)
		   { 
		     // printf("i %d  j %d  ",i,j);
		     // printf("%c  :%c\n",endjust_number[i][j]+'a',no_endnumber[k]+'a');
		      //printf("",);
		        i++;
		   }
		  // printf("判断条件相等  %c  %c\n",endjust_number[i][j]+'a',no_endnumber[k]+'a');   
		          	l=i;//代表i	 
					            
		            while(endjust_number[i][j]!=1000)//竖着循环 
		             {
		             	if(endjust_number[i][j]==1111)
		             	{
		             		i=i+1;
		             		l=i;
						}						 
		         	     if(endjust_number[i+1][j]==1000)//此表示非终结符后边是结束符号follow(左部) 
		         	     {
		         	     	  // printf("follow加入  i+1  %c\n",endjust_number[l][j]+'a');
		         		 	  
							   p=(struct node_follow*)malloc(sizeof(struct node_follow));
						       p->flag=1;
						       p->node_follow_number=abs(endjust_number[0][j]);
						       //p->follownext=vnodefollow[abs(endjust_number[0][j])].next;//新加入的follow 有head作为结点所以不可以动head 
						       p->next=NULL;
							   Q=vnodefollow[abs(endjust_number[l][j])].next;//扫描follow集找到最后节点 
	                            //printf("初始 i 的结点  %c %d\n",(Q->node_follow_number)+'a',Q->flag);
								if(Q==NULL)
								{
								  vnodefollow[abs(endjust_number[l][j])].next=p;
								  break;
								} 
			       
							    while(Q!=NULL)
	                            {
	                           	  q=Q;
	                    	      Q=Q->next;
	                    	     // printf("%d ",q->node_follow_number);
						        } 
								q->next=p;
	                            //p->next=q->next;//本身就有的follow                          
	                           // printf("%c follow集放在后边 %d\n",(endjust_number[0][j])+'a',q->node_follow_number);			   														  
							   break;
					     }
					     else if (endjust_number[i+1][j]+'a'>='A'&&endjust_number[i+1][j]+'a'<='Z')//表示后边是非终结符 
					     {
						      // printf("非终结符 FIRST %c\n",endjust_number[i+1][j]+'a');
						        P=vnode[abs(endjust_number[i+1][j])].next;//非终结符的first集 扫描加入follow中 Q为空输出 
						        head=(struct node_follow*)malloc(sizeof(struct node_follow));
						        head->next=NULL;
						        head->node_follow_number=0;
								tail=head; 
							//	printf("%c\n",P->node_first_number+'a');
						        while(P!=NULL)
						        {
						            p=(struct node_follow*)malloc(sizeof(struct node_follow));
						            p->node_follow_number=P->node_first_number;
						            p->flag=0;
						           // p->follownext=NULL;
						            p->next=NULL;
					 	            tail->next=p;
					 	            tail=p; 	
					 	            P=P->next; 
					 	           // printf("非终结符的first  %c\n",p->node_follow_number+'a');
								}
								Q=vnodefollow[abs(endjust_number[l][j])].next;//扫描follow集找到最后节点 
								if(Q==NULL)
								{
								    vnodefollow[abs(endjust_number[l][j])].next=head->next;
								}
	                            else
								{
								    while(Q->next!=NULL)
	                                {
	                    	           Q=Q->next;
						            }
								    Q->next=head->next; 
								  	
								}
								if(no_ends[1][abs(endjust_number[i+1][j])]==1)
								{
								  //  printf("%c\n",endjust_number[i+1][j]+'a');
									break;
								}
								//l=i;			
					     }
					     else if(endjust_number[i+1][j]+'a'>='a'&&endjust_number[i+1][j]+'a'<='z')//后边是终结符的 
					     {
					     	   //printf("终结符 follows %c\n",endjust_number[i+1][j]+'a');
					 	      
						       p=(struct node_follow*)malloc(sizeof(struct node_follow));
						       p->node_follow_number=endjust_number[i+1][j];
						       p->flag=0;
						       //p->follownext=NULL;
						       p->next=NULL;
					 	       Q=vnodefollow[abs(endjust_number[l][j])].next;//扫描follow集找到最后节点 
							   if(Q==NULL)
							   {
									vnodefollow[abs(endjust_number[l][j])].next=p;
									break;
							   }
	                           while(Q->next!=NULL)
	                           {
	                    	    Q=Q->next;
						        }
								Q->next=p; 
					 	       //printf("终结符前边未出现follow %c\n",p->node_follow_number+'a');
					 	       break;				 	
					     }
					 i++;   
				    }//竖着循环
		            
				
				 
	    }//横着循环 
	    k++;
	}//while 	
	printf("****************输出follow集*****************\n");
	k=0;
	int count;
	int counts;
	while(k<sum)
	{   
	    i=0;
		printf("%4c: ",no_endnumber[k]+'a');
		Q=vnodefollow[abs(no_endnumber[k])].next;//扫描follow集找到最后节点 
	    // follow_ends[i][abs(no_endnumber[k])]=no_endnumber[k]; 
	    while(Q!=NULL)
	    {
	    	if(Q->flag==0)
	        {   
			    follow_ends[i][abs(no_endnumber[k])]=Q->node_follow_number;
			    i++;
				if(Q->node_follow_number==1400)
				{
					printf("#  ");
					//follow_ends[i][abs(no_endnumber[k])]=1400;
					//i++;
				}
				else
				{
					printf("%c  ",Q->node_follow_number+'a');					
				}
	            Q=Q->next;	
			}
			else
			{
				count=Q->node_follow_number;
				counts=Q->node_follow_number;
				//printf("%c&&&  ",(-counts)+'a');
				q=vnodefollow[count].next;//printf("%c&",(-counts)+'a');
				count=0;
				i=followshuchu(q,counts,k,i);
				
				Q=Q->next;
			}
		}
		
		printf("\n"); 
		follow_ends[i][abs(no_endnumber[k])]=1000;
		k++;
	} 
    printf("****************输出化简的follow集*****************\n");
	k=0;
	//int count;
	//int counts;
	while(k<sum)
	{   i=0;
	     j=1;
		printf("%4c: ",no_endnumber[k]+'a');
		while(follow_ends[i][abs(no_endnumber[k])]!=1000)
		{
		     while(follow_ends[j][abs(no_endnumber[k])]!=1000)	
		     {
		     	if(follow_ends[j][abs(no_endnumber[k])]==follow_ends[i][abs(no_endnumber[k])])
		     	{
		     		follow_ends[j][abs(no_endnumber[k])]=1500;
				 }
				 j++;
			 }
			 i++;
			 
		}
		i=0;	
	    while(follow_ends[i][abs(no_endnumber[k])]!=1000)
	    {
	    	if(follow_ends[i][abs(no_endnumber[k])]==1400)
	    	printf("#   ");
	    	else if(follow_ends[i][abs(no_endnumber[k])]!=1500)
	    	printf("%c  ",follow_ends[i][abs(no_endnumber[k])]+'a');
			i++; 
	    }
		printf("\n"); 
		k++;
	} 	
} 
int followshuchu(struct node_follow *Q,int counts,int k,int i)
{	
    //printf("%d",k);
    struct node_follow *q;
	int count;	  
	while(Q!=NULL)
	{   		
	    if(Q->flag==0)
	    {   
	        follow_ends[i][abs(no_endnumber[k])]=Q->node_follow_number;
			i++;
			//printf("%d",Q->flag);
			if(Q->node_follow_number==1400)
			{
				printf("#  ");				 
			}
			else
			{
				printf("%c  ",Q->node_follow_number+'a');
				//follow_ends[i][abs(no_endnumber[k])]=;
			}
	        Q=Q->next;	
		}
		else if(Q->flag==1)
		{       			
			count=Q->node_follow_number;
			if(count==counts)
			{
				break;
			}
			if(count==abs(no_endnumber[k]))
			break;
			q=vnodefollow[count].next;
			i=followshuchu(q,counts,k,i);
			Q=Q->next;
								
		}			
	}
    return i;		
}

void selects()//求select集运算 
{
	int i=1,j=0;//i表示竖着循环,扫描一个产生式;j表示横着扫描多个产生式 
	int k=0;//一直表示first或者follow集的扫描
	int l=1; 
	while(j<m)
	{   
	    select_ends[0][j]=endjust_number[0][j];//产生式左部给予select集 
	    //printf("%c :",select_ends[0][j]+'a');		
		while(endjust_number[i-1][j]!=1000)
		{	
		    if(endjust_number[i][j]==1111)
			{
				i=i+1; 
			} 
		    if(endjust_number[i][j]==1000)//表示后边是结束符号把follow加入 
			{
				k=0;
			//	printf("FOLLOW&%d& ",follow_ends[k][abs(endjust_number[0][j])]);
				while(follow_ends[k][abs(endjust_number[0][j])]!=1000)
				{
					select_ends[l][j]=follow_ends[k][abs(endjust_number[0][j])];
				//	printf(" %d ",select_ends[l][j]); 
					k++;
					l++;
				}
				break;
			}		
			else if(endjust_number[i][j]+'a'>='a'&&endjust_number[i][j]+'a'<='z')//终结符的情况 
			{
				select_ends[l][j]=endjust_number[i][j];//终结符直接加入进去 
				//printf(" %d ",select_ends[l][j]);
				l++;
				break;
				 
			}
			else if(endjust_number[i][j]+'a'>='A'&&endjust_number[i][j]+'a'<='Z')//非终结符 
			{
				k=1;
				//printf("&%d& ",follow_ends[k][abs(endjust_number[i][j])]);
				while(first_ends[k][abs(endjust_number[i][j])]!=1000) //扫描非终结符的first 
				{
						
					select_ends[l][j]=first_ends[k][abs(endjust_number[i][j])];
					//printf(" %d ",select_ends[l][j]);
					k++;
					l++;
				}
				if(no_ends[1][abs(endjust_number[i][j])]==1)
				{
				   break;	
				}				
			}			 
			i++;
		}
		select_ends[l][j]=1000;
		//printf("\n");
		j++;
		i=1;
		l=1; 
	}
	printf("*************输出select集******************\n");
	i=0,j=0;
	while(j<m)
	{   
	    printf("%c :",select_ends[i][j]+'a');
	    i=1;
		while(select_ends[i][j]!=1000)
		{
			 printf("%d %d ",i,j);
			 if(select_ends[i][j]==1111)
			 printf("ε  ");
		     else if(select_ends[i][j]==1400)
		     printf("#   ");
 		     else if(select_ends[i][j]!=1500)
		     printf("%c  ",select_ends[i][j]+'a');
			 i++;	
		}
		i=0;
		printf("\n");
		j++;
	}
	printf("*************输出化简的select集******************\n");
	i=0,j=0,k=1;
	while(j<m)
	{    
	    i=1;
		while(select_ends[i][j]!=1000)
		{
			 k=i+1; 		    
             while(select_ends[k][j]!=1000)
             {
                if(select_ends[i][j]==select_ends[k][j])
             	   select_ends[k][j]=1500;
             	   k++;
			 }	
			 i++;	
		}
		printf("%c :",select_ends[0][j]+'a');
		i=1;
		
		while(select_ends[i][j]!=1000)
		{
			if(select_ends[i][j]==1111);
			  // printf("ε "); 
			else if(select_ends[i][j]==1400)
			 printf("#   ");
			 else if(select_ends[i][j]!=1500)
			 printf("%c  ",select_ends[i][j]+'a');
			 i++;
		}
		i=0;
		printf("\n");
		
		j++;
	}
	
}
/*
int select_biaoji[3][100]={0};//存放产生式中有多少个字母 
int select_ends[100][100];//存放select集 
int follow_ends[100][100];//存放最后的follow集 
int first_ends[100][100];//存放最后的first集 
int endjust_number[100][100];//存放产生式 
char no_end[100]; 
int no_ends[3][100]; 
int no_endnumber[100];//存放非终结符的数字 
int n=0,m=0; //endjust_number[100][100]中有多少行n表示,endjust_number[100][100]有多少列m表示 
int sum=0; //总共有多少个非终结符 
int flag[100];	//求空产生式的标记 
int biaoji[100];//求空产生式的标记 
int end[100];//存放终结符 
char  stards; 
char shurushizi[100];//存放分析式 
int Storefenxi[100][100];//存放储存的预测分析表 
int f=0;
*/
void Storeyucefenxibiao()
{
	int i=0,j=0,k=1,l=0;
	while(l<m)//外层循环 对产生式循环 
	{
		while(select_ends[k][l]!=1000)//内层循环 
		{
			if(select_ends[k][l]!=1500)
			{
			Storefenxi[abs(select_ends[0][l])][select_ends[k][l]]=l+1;
			//printf(" %4d %4d %4d ",Storefenxi[abs(select_ends[0][l])][select_ends[k][l]],select_ends[0][l],select_ends[k][l]);
		}	k++;
		}
	//	printf("\n");
		l++;
		k=1;	
	}
	l=0;
	k=0;
	printf("     ");
	for(i=0;i<sumend;i++)
	{
		if(end[i]==1111)
		printf("    ! ");
		else
		printf(" %4c ",end[i]+'a');
	}
	printf("\n"); 
	for(i=0;i<sum;i++)
	{
	    printf(" %c : ",no_endnumber[i]+'a');
		for(j=0;j<=sumend;j++)
		{
			printf(" %4d ",Storefenxi[abs(no_endnumber[i])][end[j]]);
		}
		printf("\n");
	}
}

void qiufenxibiaodashi()
{
	int flag;
	int i=0,j=0,k=1,l=0;
	int top;
	int biaoji=0;
	int count=0;
    char *p=shurushizi;//产生式 
	StrStack *strStack=(StrStack*)malloc(sizeof(StrStack));//初始化栈,存放分析栈 
	strStack->top=-1;
	strStack->str[strStack->top+1]='\0';
	pushStr(strStack,'#');
    pushStr(strStack,stards);
	printf("\n\t步骤\t分析栈\t剩余串\t产生式或匹配");
	while('#'!=GetTop(strStack) || '#'!=shurushizi[i])
	{
		printf("\n\t%d\t%s\t%s\t",l,strStack->str,p);
		if(shurushizi[i]==GetTop(strStack))
		{
			printf("匹配\n");
			popStr(strStack);
			i++;
			p++;
		}
		else 
		{			
			biaoji=Storefenxi[abs(GetTop(strStack)-'a')][abs(shurushizi[i]-'a')];
			
		     //popStr(strStack);
		     if(biaoji==0)//不存在产生式的地方 
		     {
		     	k=0;
		     	while(end[k]==shurushizi[i])//没有产生式 
		     	{
		     		k++;
					printf("分析出错\n");
					break;
				 }
				 //if(end[k]==1000)
				 printf("输入错误\n");
				 //else
		     	 
		     	return ;
			 }
		    else 
		    {   
		        k=0;
			    while(endjust_number[k][biaoji]!=1000)
		        {
		        	if(endjust_number[k][biaoji-1]!=1111)//出现了空产生式记录 
		        	printf("%c",endjust_number[k][biaoji-1]+'a');
		        	else
		        	{
		        		printf("ε");
		        		flag=k;
					}	        	
		        	k++;
				}
				//flag=GetTop(strStack);
				popStr(strStack);
				if(endjust_number[flag][biaoji-1]!=1111)//排除为空的情况 
				//if()
				{
					for(k=select_biaoji[1][biaoji-1]-1;k>0;k--)
				    {
				    	pushStr(strStack,(endjust_number[k][biaoji-1]+'a'));
				    }
				    flag=0;
				} 
				
			}		
		} 		
		if('#'==GetTop(strStack) && '#'==shurushizi[i])
		printf("\n\t%d\t%s\t%s\t接受",l+1,strStack->str,p);	
	}
	
}

int pushStr(StrStack *s,char c)
{
	if(s->top==100)
	{
        printf("符号栈上溢错误!!");
		return 0;
	}
	s->top++;
    s->str[s->top]=c;
	s->str[s->top+1]='\0';
	return 1;
}
char popStr(StrStack *s)
{
	char ch;
	if(s->top==-1)
	{
		printf("符号栈下溢错误!!");
		return 0;
	}
	ch=s->str[s->top--];
    s->str[s->top+1]='\0';
	return ch;
}
char GetTop(StrStack *s)
{
	if(s->top==-1)
	{
		printf("栈空,不能得到栈顶!!");
		return 0;
	}
	else
		return(s->str[s->top]);
}


输入请按照此方式
输入

以下输出方式
输出
输出
输出

发布了4 篇原创文章 · 获赞 0 · 访问量 510

猜你喜欢

转载自blog.csdn.net/weixin_43902812/article/details/99339814