帮我写一个LL(1)分析器,使用C语言,文法规定:(1)E->TG, (2)G->+TG|-TG, (3)G-> ε,(4)T->FS, (5)S->*FS|/FS, (6)S-> ε, (7)F->(E), (8)F->i
时间: 2023-07-16 17:14:22 浏览: 114
好的,下面是使用C语言实现的LL(1)分析器代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
char lookahead; // 当前读入的字符
void error(char* message) {
printf("Error: %s\n", message);
exit(1);
}
void match(char expected) { // 匹配当前字符
if (lookahead == expected) {
lookahead = getchar(); // 读入下一个字符
} else {
char message[20];
sprintf(message, "expect %c", expected);
error(message);
}
}
void T();
void F();
void G();
void E() {
T();
G();
}
void G() {
if (lookahead == '+' || lookahead == '-') {
match(lookahead);
T();
G();
} else {
// 空产生式
}
}
void T() {
F();
S();
}
void S() {
if (lookahead == '*' || lookahead == '/') {
match(lookahead);
F();
S();
} else {
// 空产生式
}
}
void F() {
if (lookahead == '(') {
match('(');
E();
match(')');
} else if (isalpha(lookahead)) {
match('i');
} else {
error("unexpected symbol");
}
}
int main() {
lookahead = getchar();
E();
if (lookahead != '\n') {
error("unexpected symbol");
}
printf("Parsing success!\n");
return 0;
}
```
在主函数中,我们先读入一个字符,然后调用 E() 进行分析。分析结束后,如果还有剩余的字符,就说明输入的表达式不是合法的。
注意这里的匹配函数 match(),它用于匹配当前字符。如果当前字符与期望的字符相同,我们就读入下一个字符;否则就报错。这里使用了 sprintf() 函数将错误信息格式化成字符串,然后调用 error() 函数输出。
LL(1)分析器的核心是产生式的递归调用。在这里,我们按照文法规定实现了 E(), G(), T(), S(), F() 这些函数。每个函数对应一个非终结符号,递归调用其他函数来实现对应的文法规则。
在 E() 函数中,我们先解析 T(),再解析 G()。G() 函数中,如果当前字符是加号或减号,就继续解析 T() 和 G(),否则直接返回。T() 函数中,先解析 F(),再解析 S()。S() 函数中,如果当前字符是乘号或除号,就继续解析 F() 和 S(),否则直接返回。F() 函数中,如果当前字符是左括号,就解析括号内的 E(),否则如果是字母 i,就匹配成功,否则报错。
总之,LL(1)分析器的实现并不复杂,只需要按照产生式规定递归调用对应的函数即可。
阅读全文