C语言之Chomsky文法类型判断

 

文法G[S] = {VN,VT,P,S}:

其中VN(非终结符),VT(终结符),P(产生式集),是非空的有限集;

S属于VN,是文法的开始符号;

 

根据产生式集来判断文法的类型:

 

#include<stdio.h>
#include<string.h>

#define len 3

//0型文法:左侧必须含有非终结符
int zeroJudge(char part[2][10])
{
	int i = 0;
	//判断产生式左值是否全为非终结符
	while(part[0][i] != '\0'){
		/*if(part[0][i] < 65 || (part[0][i] > 90 && part[0][i] < 97) || part[0][i] > 122){
			printf("含有非法符号,不合法产生式!\n");
			return -1;
		}
		else*/ 
		if((part[0][i] >= 97 && part[0][i] <= 122)){
			if(i == (strlen(part[0])-1)){
				printf("左侧全为终结符,不合法产生式!\n");
				return 0;
			}
		}
		else if(part[0][i] >= 65 && part[0][i] <= 90){
			//合法产生式
			break;
		}
		i++;
	}
	return 1;
}


//1型文法:右侧的字符长度大于等于左侧
int oneJudge(char part[2][10])
{
	if(strlen(part[1]) >= strlen(part[0]))
	{
		return 1;
	}
	return 0;
}


//2型文法:左侧仅含一个非终结符
int twoJudge(char part[2][10])
{
	if((1 == strlen(part[0])) && (part[0][0] >= 65 && part[0][0] <= 90))
	{
		return 1;
	}
	return 0;
}


//3型文法:产生式必须型如:A->Aa|a或A->aA|a
int threeJudge(char part[2][10])
{
	if((1 == strlen(part[1])) && (part[1][0] >= 97 && part[1][0] <= 122))
	{
		return 1;
	}
	if(2 == strlen(part[1])){
		if((part[1][0] >= 65 && part[1][0] <= 90) && (part[1][1] >= 97 && part[1][1] <= 122))
		{
			return 1;
		}
		if((part[1][0] >= 97 && part[1][0] <= 122) && (part[1][1] >= 65 && part[1][1] <= 90))
		{
			return 1;
		}
	}
	return 0;
}

void judge(int flag)
{
	switch(flag)
	{
	case 0:
		printf("0型文法!\n");
		break;
	case 1:
		printf("1型文法!\n");
		break;
	case 2:
		printf("2型文法!\n");
		break;
	case 3:
		printf("3型文法!\n");
		break;
	}
}

int main()
{
	char gram[len][20];
	int i = 0;
	int j = 0;
	int m = 0;
	const char *split = "=";
	char *p;
	char part[2][10];
	int flag = 4;
	
	//存储文法
	while(i < len){
		scanf("%s",&gram[i]);
		i++;
	}

	//判断文法类型
	for(j = 0; j < len; j++){
		//根据"="分割  得到文法产生式的左右两部分
		p = strtok (gram[j],split);
		m = 0;
		while(p!=NULL) {
			strcpy(part[m],p);
			m++;
			//分割下一个产生式
			p = strtok(NULL,split);
		}

		if(zeroJudge(part))
		{
			if(oneJudge(part))
			{
				if(twoJudge(part))
				{
					if(threeJudge(part))
					{
						if(flag < 3)
							;
						else
							flag = 3;
					}
					else{
						if(flag < 2)
							;
						else
							flag = 2;
					}
				}
				else{
					if(flag < 1)
						;
					else
						flag = 1;
				}
			}
			else{
				flag = 0;
			}
		}
	}
	judge(flag);
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值