写一个c语言消除文法左递归代码
时间: 2023-12-24 09:06:09 浏览: 290
c实现消除文法左递归
4星 · 用户满意度95%
以下是一个简单的消除文法左递归的C语言代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_RULES 100 // 最大产生式数量
#define MAX_LENGTH 100 // 最大产生式长度
char rules[MAX_RULES][MAX_LENGTH]; // 存储产生式
int numRules = 0; // 产生式数量
// 检查是否有左递归,并进行消除
void eliminateLeftRecursion(char nonTerminal) {
int i, j;
int hasLeftRecursion = 0;
// 检查是否有左递归
for (i = 0; i < numRules; i++) {
if (rules[i][0] == nonTerminal && rules[i][2] == nonTerminal) {
hasLeftRecursion = 1;
break;
}
}
// 如果有左递归,则进行消除
if (hasLeftRecursion) {
char newNonTerminal = nonTerminal + 1;
int numNewRules = 0;
char newRules[MAX_RULES][MAX_LENGTH];
// 生成新的非终结符和产生式
for (i = 0; i < numRules; i++) {
if (rules[i][0] == nonTerminal) {
// 消除左递归
int length = strlen(rules[i]);
for (j = 2; j < length; j++) {
newRules[numNewRules][j - 2] = rules[i][j];
}
newRules[numNewRules][length - 2] = newNonTerminal;
newRules[numNewRules][length - 1] = '\0';
numNewRules++;
}
}
newRules[numNewRules][0] = '\0';
strcpy(rules[numRules], newNonTerminal);
strcat(rules[numRules], "->");
strcat(rules[numRules], "epsilon");
numRules++;
// 添加新的产生式
for (i = 0; i < numRules; i++) {
if (rules[i][0] == nonTerminal) {
// 添加新的产生式
int length = strlen(rules[i]);
rules[i][length - 1] = newNonTerminal;
rules[i][length] = '\0';
}
}
// 添加原来的产生式
for (i = 0; i < numNewRules; i++) {
strcat(rules[numRules], newRules[i]);
strcat(rules[numRules], newNonTerminal);
numRules++;
}
// 递归消除新的非终结符的左递归
eliminateLeftRecursion(newNonTerminal);
}
}
int main() {
int i;
// 输入产生式
printf("请输入产生式(以#结束):\n");
while (1) {
char rule[MAX_LENGTH];
scanf("%s", rule);
if (rule[0] == '#') {
break;
}
strcpy(rules[numRules], rule);
numRules++;
}
// 消除左递归
for (i = 0; i < numRules; i++) {
eliminateLeftRecursion(rules[i][0]);
}
// 输出消除左递归后的产生式
printf("消除左递归后的产生式:\n");
for (i = 0; i < numRules; i++) {
printf("%s\n", rules[i]);
}
return 0;
}
```
阅读全文