文法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;
}