Chomsky文法类型判断

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

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值