用c语言编写一个LL1语法分析器
时间: 2023-08-21 19:05:02 浏览: 165
要编写一个 LL(1) 语法分析器,需要先进行语法分析,然后生成一张预测分析表,最后使用该表进行语法分析。
下面是一个简单的 LL(1) 语法分析器的 C 语言代码示例:
```c
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX_PROD 10
#define MAX_TERM 10
char grammar[MAX_PROD][MAX_TERM];
char first_set[MAX_TERM][MAX_TERM];
char follow_set[MAX_TERM][MAX_TERM];
char predict_set[MAX_PROD][MAX_TERM];
char terminals[MAX_TERM];
char non_terminals[MAX_TERM];
int no_of_productions, no_of_terminals, no_of_non_terminals;
void first(char symbol) {
int i, j, k;
for (i = 0; i < no_of_productions; i++) {
if (grammar[i][0] == symbol) {
if (islower(grammar[i][2])) {
for (k = 0; k < no_of_terminals; k++) {
if (grammar[i][2] == terminals[k]) {
first_set[symbol - 'A'][k] = '1';
break;
}
}
} else {
first(grammar[i][2]);
for (j = 0; j < no_of_terminals; j++) {
if (first_set[grammar[i][2] - 'A'][j] == '1') {
first_set[symbol - 'A'][j] = '1';
}
}
}
}
}
}
void follow(char symbol) {
int i, j, k;
if (symbol == grammar[0][0]) {
follow_set[symbol - 'A'][no_of_terminals - 1] = '1';
}
for (i = 0; i < no_of_productions; i++) {
for (j = 2; j < strlen(grammar[i]); j++) {
if (grammar[i][j] == symbol) {
if (grammar[i][j + 1] != '\0') {
if (islower(grammar[i][j + 1])) {
for (k = 0; k < no_of_terminals; k++) {
if (grammar[i][j + 1] == terminals[k]) {
follow_set[symbol - 'A'][k] = '1';
break;
}
}
} else {
int l;
for (l = 0; l < no_of_terminals; l++) {
if (first_set[grammar[i][j + 1] - 'A'][l] == '1') {
follow_set[symbol - 'A'][l] = '1';
}
}
if (first_set[grammar[i][j + 1] - 'A'][no_of_terminals - 2] == '1') {
follow(grammar[i][0]);
}
}
} else if (grammar[i][j + 1] == '\0') {
follow(grammar[i][0]);
}
}
}
}
}
void predict() {
int i, j, k, l;
for (i = 0; i < no_of_productions; i++) {
for (j = 0; j < no_of_terminals; j++) {
if (first_set[grammar[i][2] - 'A'][j] == '1') {
predict_set[i][j] = grammar[i][2];
}
}
if (first_set[grammar[i][2] - 'A'][no_of_terminals - 2] == '1') {
for (k = 0; k < no_of_terminals; k++) {
if (follow_set[grammar[i][0] - 'A'][k] == '1') {
if (predict_set[i][k] != grammar[i][2]) {
predict_set[i][k] = grammar[i][2];
} else {
for (l = 0; l < no_of_terminals; l++) {
if (predict_set[i][l] == grammar[i][2]) {
predict_set[i][l] = '\0';
}
}
}
}
}
}
}
}
int main() {
int i, j;
printf("Enter the number of productions: ");
scanf("%d", &no_of_productions);
printf("Enter the productions:\n");
for (i = 0; i < no_of_productions; i++) {
scanf("%s", grammar[i]);
non_terminals[i] = grammar[i][0];
}
no_of_non_terminals = i;
printf("Enter the number of terminals: ");
scanf("%d", &no_of_terminals);
printf("Enter the terminals:\n");
for (i = 0; i < no_of_terminals; i++) {
scanf(" %c", &terminals[i]);
}
strcpy(terminals + i, "$");
no_of_terminals++;
for (i = 0; i < no_of_non_terminals; i++) {
for (j = 0; j < no_of_terminals; j++) {
first_set[non_terminals[i] - 'A'][j] = '0';
follow_set[non_terminals[i] - 'A'][j] = '0';
}
}
for (i = 0; i < no_of_non_terminals; i++) {
first(non_terminals[i]);
}
follow(grammar[0][0]);
predict();
printf("Predictive Parsing Table:\n");
printf("Non-terminal\tTerminal\tProduction\n");
for (i = 0; i < no_of_non_terminals; i++) {
for (j = 0; j < no_of_terminals; j++) {
if (predict_set[i][j] != '\0') {
printf("%c\t\t%c\t\t%c->%s\n", non_terminals[i], terminals[j], non_terminals[i], predict_set[i]);
}
}
}
return 0;
}
```
该程序可以读入文法和终结符号,然后计算出每个符号的 FIRST 集和 FOLLOW 集,并使用它们构建预测分析表。最后,程序输出预测分析表,以便进行语法分析。
这只是一个简单的 LL(1) 语法分析器实现,如果需要更完整的实现,可以使用更复杂的数据结构和算法,以及更精细的错误处理机制。
阅读全文