编译原理实验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]);
}
输入请按照此方式
以下输出方式