写一段语法分析器的C语言代码
时间: 2023-11-18 21:02:28 浏览: 70
下面是一个简单的语法分析器的C语言代码示例,用于解析一个简单的表达式语言,包括加、减、乘、除和括号:
```c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX_EXPR_LEN 100
// 定义 token 类型
typedef enum {
TOK_EOF = 0, // 结束符
TOK_NUM, // 数字
TOK_ADD, // 加号
TOK_SUB, // 减号
TOK_MUL, // 乘号
TOK_DIV, // 除号
TOK_LPAREN, // 左括号
TOK_RPAREN // 右括号
} token_type_t;
// 定义 token 结构体
typedef struct {
token_type_t type; // token 类型
double value; // 数字值(如果是数字类型)
} token_t;
// 定义全局变量
char expr[MAX_EXPR_LEN]; // 表达式字符串
int pos = 0; // 当前解析位置
token_t cur_token; // 当前 token
// 函数声明
void next_token();
double parse_expr();
double parse_term();
double parse_factor();
// 获取下一个 token
void next_token() {
char ch = expr[pos];
while (isspace(ch)) {
ch = expr[++pos];
}
if (ch == '\0') {
cur_token.type = TOK_EOF;
return;
} else if (isdigit(ch)) {
cur_token.type = TOK_NUM;
cur_token.value = 0;
while (isdigit(ch)) {
cur_token.value = cur_token.value * 10 + (ch - '0');
ch = expr[++pos];
}
if (ch == '.') {
double k = 0.1;
ch = expr[++pos];
while (isdigit(ch)) {
cur_token.value += k * (ch - '0');
k *= 0.1;
ch = expr[++pos];
}
}
} else if (ch == '+') {
cur_token.type = TOK_ADD;
pos++;
} else if (ch == '-') {
cur_token.type = TOK_SUB;
pos++;
} else if (ch == '*') {
cur_token.type = TOK_MUL;
pos++;
} else if (ch == '/') {
cur_token.type = TOK_DIV;
pos++;
} else if (ch == '(') {
cur_token.type = TOK_LPAREN;
pos++;
} else if (ch == ')') {
cur_token.type = TOK_RPAREN;
pos++;
} else {
fprintf(stderr, "Unknown token '%c'\n", ch);
exit(1);
}
}
// 解析表达式
double parse_expr() {
double result = parse_term();
while (cur_token.type == TOK_ADD || cur_token.type == TOK_SUB) {
if (cur_token.type == TOK_ADD) {
next_token();
result += parse_term();
} else {
next_token();
result -= parse_term();
}
}
return result;
}
// 解析项
double parse_term() {
double result = parse_factor();
while (cur_token.type == TOK_MUL || cur_token.type == TOK_DIV) {
if (cur_token.type == TOK_MUL) {
next_token();
result *= parse_factor();
} else {
next_token();
double divisor = parse_factor();
if (divisor == 0) {
fprintf(stderr, "Division by zero\n");
exit(1);
}
result /= divisor;
}
}
return result;
}
// 解析因子
double parse_factor() {
double result;
if (cur_token.type == TOK_NUM) {
result = cur_token.value;
next_token();
} else if (cur_token.type == TOK_LPAREN) {
next_token();
result = parse_expr();
if (cur_token.type != TOK_RPAREN) {
fprintf(stderr, "Expected ')'\n");
exit(1);
}
next_token();
} else {
fprintf(stderr, "Expected number or '('\n");
exit(1);
}
return result;
}
int main() {
printf("Enter expression: ");
fgets(expr, MAX_EXPR_LEN, stdin);
next_token();
double result = parse_expr();
if (cur_token.type != TOK_EOF) {
fprintf(stderr, "Unexpected token after expression\n");
exit(1);
}
printf("Result: %f\n", result);
return 0;
}
```
该代码使用递归下降的方法进行语法分析,首先定义了 token 类型和结构体,然后实现了获取下一个 token 的函数 `next_token()`,它会忽略空格并根据当前字符判断当前 token 的类型。接下来,分别实现了解析表达式、项和因子三个函数,它们分别递归调用自己或其他函数,并根据当前 token 的类型来决定如何处理。最后,在主函数中获取输入的表达式并解析,输出结果。
阅读全文