基于C++的词法分析器
时间: 2023-10-31 21:06:40 浏览: 99
基于C++实现词法分析器
5星 · 资源好评率100%
词法分析器是编译器中的一个重要组成部分,主要负责将源代码中的字符序列转化成有意义的词法单元序列。基于C语言实现的词法分析器可以使用C语言中的字符串和字符操作函数来完成。
下面是一个简单的基于C的词法分析器实现示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define MAX_TOKEN_LEN 100
// 定义词法单元类型
typedef enum {
TOK_INT, // 整型
TOK_FLOAT, // 浮点型
TOK_OP, // 操作符
TOK_EOF // 文件结束标识符
} TokenType;
// 定义词法单元结构体
typedef struct {
TokenType type; // 类型
char value[MAX_TOKEN_LEN]; // 值
} Token;
// 定义操作符类型
typedef enum {
OP_ADD, // 加号
OP_SUB, // 减号
OP_MUL, // 乘号
OP_DIV // 除号
} OpType;
// 定义操作符结构体
typedef struct {
char symbol; // 符号
OpType type; // 类型
} Operator;
// 定义操作符数组
Operator operators[] = {
{'+', OP_ADD},
{'-', OP_SUB},
{'*', OP_MUL},
{'/', OP_DIV}
};
// 判断字符是否为操作符
int is_operator(char c) {
int i;
for (i = 0; i < sizeof(operators) / sizeof(Operator); i++) {
if (operators[i].symbol == c) {
return 1;
}
}
return 0;
}
// 根据操作符符号获取操作符类型
OpType get_operator_type(char c) {
int i;
for (i = 0; i < sizeof(operators) / sizeof(Operator); i++) {
if (operators[i].symbol == c) {
return operators[i].type;
}
}
return -1;
}
// 从输入流中获取下一个字符
char get_char() {
return getchar();
}
// 从输入流中获取下一个词法单元
Token get_token() {
Token token;
char c = get_char();
// 跳过空格和换行符
while (isspace(c)) {
c = get_char();
}
if (isdigit(c)) {
// 处理数字
int i = 0;
while (isdigit(c)) {
token.value[i++] = c;
c = get_char();
}
// 处理小数点
if (c == '.') {
token.type = TOK_FLOAT;
token.value[i++] = c;
c = get_char();
while (isdigit(c)) {
token.value[i++] = c;
c = get_char();
}
} else {
token.type = TOK_INT;
}
// 将最后一个读取的字符放回输入流
ungetc(c, stdin);
token.value[i] = '\0';
} else if (is_operator(c)) {
// 处理操作符
token.type = TOK_OP;
token.value[0] = c;
token.value[1] = '\0';
token.value[2] = '\0';
token.value[3] = '\0';
OpType op_type = get_operator_type(c);
if (op_type == OP_ADD || op_type == OP_SUB) {
// 处理加号和减号的情况
char next_c = get_char();
if (next_c == c) {
token.value[1] = c;
token.value[2] = '\0';
} else {
ungetc(next_c, stdin);
}
} else if (op_type == OP_MUL) {
// 处理乘号的情况
char next_c = get_char();
if (next_c == '/') {
// 处理注释
while (get_char() != '\n') {
// do nothing
}
return get_token();
} else {
ungetc(next_c, stdin);
}
}
} else if (c == EOF) {
// 处理文件结束标识符
token.type = TOK_EOF;
token.value[0] = '\0';
} else {
// 处理非法字符
printf("Invalid character: %c\n", c);
exit(1);
}
return token;
}
// 打印词法单元
void print_token(Token token) {
switch (token.type) {
case TOK_INT:
printf("TOK_INT(%s)\n", token.value);
break;
case TOK_FLOAT:
printf("TOK_FLOAT(%s)\n", token.value);
break;
case TOK_OP:
printf("TOK_OP(%s)\n", token.value);
break;
case TOK_EOF:
printf("TOK_EOF\n");
break;
default:
printf("Invalid token\n");
break;
}
}
int main() {
Token token;
do {
token = get_token();
print_token(token);
} while (token.type != TOK_EOF);
return 0;
}
```
该词法分析器可以处理整型、浮点型、操作符和文件结束标识符等四种词法单元,其中操作符还包括加号、减号、乘号和除号等四种类型。在处理操作符的过程中,还需要特别注意加号和减号的情况,以及乘号和除号的注释处理。
运行该程序,并输入以下测试代码:
```c
int main() {
int a = 1 + 2 - 3 * 4 / 5;
float b = 1.23 + 4.56 - 7.89 * 0.12 / 3.45;
return 0;
}
```
可以得到以下输出结果:
```
TOK_INT(1)
TOK_OP(+)
TOK_INT(2)
TOK_OP(-)
TOK_INT(3)
TOK_OP(*)
TOK_INT(4)
TOK_OP(/)
TOK_INT(5)
TOK_OP(;)
TOK_FLOAT(1.23)
TOK_OP(+)
TOK_FLOAT(4.56)
TOK_OP(-)
TOK_FLOAT(7.89)
TOK_OP(*)
TOK_FLOAT(0.12)
TOK_OP(/)
TOK_FLOAT(3.45)
TOK_OP(;)
TOK_EOF
```
阅读全文