c语言编写一个完整的词法分析器
时间: 2023-10-29 08:04:46 浏览: 47
一个完整的词法分析器通常包含以下步骤:
1. 读取源代码文件
2. 将源代码转换为字符流
3. 识别单词(也称为token)
4. 生成token序列
下面是一个简单的C语言词法分析器的示例代码:
```c
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX_TOKEN_LEN 100
typedef enum {
TK_RESERVED, // 保留字
TK_IDENT, // 标识符
TK_NUM, // 整数
TK_EOF, // 文件结束标志
} TokenKind;
typedef struct Token Token;
struct Token {
TokenKind kind; // Token的类型
Token *next; // 下一个Token
int val; // Token的值(当kind为TK_NUM时有效)
char *str; // Token的字符串
int len; // Token的长度
};
Token *token; // 当前的Token
char *user_input; // 输入的源代码
void error(char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
exit(1);
}
// 创建Token
Token *new_token(TokenKind kind, Token *cur, char *str, int len) {
Token *tok = calloc(1, sizeof(Token));
tok->kind = kind;
tok->str = str;
tok->len = len;
cur->next = tok;
return tok;
}
// Tokenize函数,将输入的源代码转换为Token序列
Token *tokenize() {
char *p = user_input;
Token head;
head.next = NULL;
Token *cur = &head;
while (*p) {
// 跳过空格
if (isspace(*p)) {
p++;
continue;
}
// 识别保留字
if (strncmp(p, "if", 2) == 0 && !isalnum(p[2])) {
cur = new_token(TK_RESERVED, cur, p, 2);
p += 2;
continue;
}
if (strncmp(p, "else", 4) == 0 && !isalnum(p[4])) {
cur = new_token(TK_RESERVED, cur, p, 4);
p += 4;
continue;
}
// 识别标识符
if (isalpha(*p)) {
int len = 1;
while (isalnum(p[len])) {
len++;
}
cur = new_token(TK_IDENT, cur, p, len);
p += len;
continue;
}
// 识别数字
if (isdigit(*p)) {
cur = new_token(TK_NUM, cur, p, 0);
char *q = p;
cur->val = strtol(p, &p, 10);
cur->len = p - q;
continue;
}
error("无效的字符: '%c'", *p);
}
new_token(TK_EOF, cur, p, 0);
return head.next;
}
int main(int argc, char **argv) {
if (argc != 2) {
error("参数个数无效");
return 1;
}
user_input = argv[1];
token = tokenize();
while (token->kind != TK_EOF) {
printf("Token: %d, str: %s, len: %d, val: %d\n",
token->kind, token->str, token->len, token->val);
token = token->next;
}
return 0;
}
```
这个词法分析器能够识别if、else、标识符和整数。在main函数中,我们将输入的源代码作为参数传递给词法分析器,然后对生成的token序列进行遍历并输出每个Token的信息。