C语言之Chomsky文法类型判断

时间:2022-09-12 17:00:58

文法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型文法:右侧只有一个终结符或只有一个终结符后接一个非终结符
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;
		}
		else 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;
}