#include<stdio.h>
#include<string.h>
typedef struct{
char left[10]; //产生式的左部
char right[10]; //产生式的右部
}regular;
regular re[100];
int main()
{printf("******Chomsky文法类型判断*******(以0为产生式输入的结束符)\n");
while(1)
{//char vn[100]; //存放产生式中非终结符
//char vt[100]; //存放产生式中的终结符
int flagoo[6]={0};//标志位,有5中状态,错误文法、0型、1型、2型、3型分别表示flagoo的0~5
int i=0;
while(scanf("%s",&re[i].left)&&re[i].left[0]!='0')
{getchar();
scanf("%s",&re[i].right);
getchar();
i++;
}//输入P的产生式
char *q1,*q2;//分别指向产生式的左部和右部
int Llen,Rlen;//表示左部和右部的字符长度
//用来处理每一个产生式,看他们属于哪个文法类型
int j;
for(j=0;j<i;j++)
{q1=re[j].left;
q2=re[j].right;
Llen=strlen(re[j].left);
Rlen=strlen(re[j].right);
int flag=0;//标志位,用来表示左部字符串中是否有非终止符。有,则为1,否则,为0
int flag1=2,flag2=2;//标志位,用来表示右部字符串第一个是否为终止符和第二个是否为终止符。有,则为1,否则,为0
//该循环目的在于寻找产生式左部是否存在非终结符
int k;
for(k=0;k<Llen;k++)
{
if(re[j].left[k]<='Z'&&re[j].left[k]>='A')
{flag=1;break;}
}
//该循环目的在于寻找产生式右部第一个第二个是否为非终结符
if(re[j].right[0]<='Z'&&re[j].right[0]>='A')
flag1=1;
if(re[j].right[1]<='Z'&&re[j].right[1]>='A')
flag2=1;
//该循环目的在于寻找产生式右部第一个第二个是否为终结符
if(re[j].right[0]<='z'&&re[j].right[0]>='a')
flag1=0;
if(re[j].right[1]<='z'&&re[j].right[1]>='a')
flag2=0;
if(re[j].right[0]=='#')flag1=2;
//接下来这一段,主要是判别该产生式是哪个类型
if(flag==1)
{
if(Llen<Rlen||Llen==Rlen)
{
if(Llen==1){
if(Rlen==1&&flag1==0)
{flagoo[5]++;
flagoo[4]++;
flagoo[3]++;
flagoo[2]++;
flagoo[1]++;
}
else if(flag1==0&&flag2==1&&Rlen==2)
{
flagoo[4]++;
flagoo[3]++;
flagoo[2]++;
flagoo[1]++;
}//3型文法--右线性文法
else if(flag1==1&&flag2==0&&Rlen==2)
{
flagoo[5]++;
flagoo[3]++;
flagoo[2]++;
flagoo[1]++;
}//3型文法--左线型文法
else {
flagoo[3]++;
flagoo[2]++;
flagoo[1]++;
}//2型文法
}
else {
flagoo[2]++;
flagoo[1]++;
}//1型文法
}
else{
flagoo[1]++; //0型文法
}
}
else {flagoo[0]=1;break;}//错误文法
}
//将结果输出
if(flagoo[4]==i)printf("3型文法--右线型文法!!!\n");
else if (flagoo[5]==i)printf("3型文法--左线型文法!!!\n");
else if(flagoo[3]==i)printf("2型文法!!!\n");
else if(flagoo[2]==i)printf("1型文法!!!\n");
else if(flagoo[1]==i)printf("0型文法!!!\n");
else if(flagoo[0]==1)printf("错误文法!!!\n");
printf("\nG=(VN,VT,P,S)\n");
printf("P:\n");
int ip;
for(ip=0;ip<i;ip++)
{printf("%s->%s\n",re[ip].left,re[ip].right);}
printf("\n\n是否开始输入下一个文法?(y/n)\n");
char yes;
getchar();
scanf("%c",&yes);
if(yes=='n')break;
}
return 0;
}
Chomsky文法类型判断
最新推荐文章于 2024-06-22 18:23:55 发布