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