用C语言写一个消除文法左递归的代码
时间: 2023-12-29 13:44:51 浏览: 102
以下是一个简单的C语言代码示例,用于消除文法中的左递归:
```
#include <stdio.h>
#include <string.h>
#define MAX_SIZE 100
int main() {
char prod[MAX_SIZE][MAX_SIZE], nonTerm[MAX_SIZE];
int n, i, j, k;
printf("Enter the number of productions: ");
scanf("%d", &n);
printf("Enter the productions: \n");
for(i=0; i<n; i++) {
scanf("%s", prod[i]);
}
printf("Enter the non-terminal: ");
scanf("%s", nonTerm);
for(i=0; i<n; i++) {
if(prod[i][0] == nonTerm[0]) {
char alpha[MAX_SIZE] = "", beta[MAX_SIZE] = "";
int flag = 0;
for(j=2; j<strlen(prod[i]); j++) {
if(prod[i][j] == '|' || j == strlen(prod[i])-1) {
if(j == strlen(prod[i])-1) {
strncat(beta, &prod[i][j], 1);
}
if(flag == 0) {
strcat(alpha, &prod[i][j+1]);
flag = 1;
} else {
strcat(beta, &prod[i][j+1]);
}
}
}
printf("%c' -> %s%c'\n", nonTerm[0], beta, nonTerm[0]);
for(j=0; j<n; j++) {
if(prod[j][0] == nonTerm[0]) {
char newProd[MAX_SIZE] = "";
strcat(newProd, alpha);
strcat(newProd, "'");
strcat(newProd, "|");
strcat(newProd, prod[j]+2);
printf("%c -> %s\n", nonTerm[0], newProd);
} else {
printf("%s\n", prod[j]);
}
}
printf("%c' -> epsilon\n", nonTerm[0]);
break;
}
}
if(i == n) {
printf("No left recursion found!\n");
}
return 0;
}
```
这个程序接受用户输入的文法产生式和非终结符,并使用以下算法消除文法中的左递归:
1. 扫描每个产生式,如果它的左部与输入的非终结符相同,则将其分解为两个子串 alpha 和 beta,其中 beta 开头的符号与输入的非终结符相同。
2. 使用新的非终结符替换原始产生式的左部,并生成两个新的产生式,一个是新的非终结符和 beta,另一个是新的非终结符和 alpha 后跟新的非终结符的符号。
3. 如果原始产生式右部结束,那么添加一个新的产生式,将新的非终结符替换为 epsilon。
这个程序只处理一个左递归的情况,如果文法中有多个左递归,需要对每个左递归运行该程序。
阅读全文