- 添加 .gitignore 文件,忽略编译器生成的二进制文件 - 重构 lexer.c 文件,改进了关键字处理和字符串处理 - 更新前端的前端、解析器和 AST 相关文件,以适应新的词法分析器 - 优化了 token 相关的定义和函数,引入了新的 token 类型
87 lines
2.1 KiB
C
87 lines
2.1 KiB
C
#include <lib/core.h>
|
||
#include "lexer_log.h"
|
||
#include "token.h"
|
||
|
||
#define ROUND_IDX(idx) ((idx) % tokbuf->cap)
|
||
|
||
tok_t* pop_tok(tok_stream_t* tokbuf) {
|
||
if (tokbuf->size == 0) {
|
||
LEX_ERROR("no token to pop");
|
||
return NULL;
|
||
}
|
||
int idx = tokbuf->cur;
|
||
tokbuf->cur = ROUND_IDX(idx + 1);
|
||
tokbuf->size -= 1;
|
||
return tokbuf->buf + idx;
|
||
}
|
||
|
||
void flush_peek_tok(tok_stream_t* tokbuf) {
|
||
tokbuf->peek = tokbuf->cur;
|
||
}
|
||
|
||
void init_tokbuf(tok_stream_t *tokbuf, void *stream, tok_stream_get_func gettok) {
|
||
tokbuf->cur = 0;
|
||
tokbuf->end = 0;
|
||
tokbuf->peek = 0;
|
||
tokbuf->size = 0;
|
||
tokbuf->stream = stream;
|
||
tokbuf->gettok = gettok;
|
||
tokbuf->buf = NULL;
|
||
tokbuf->cap = 0;
|
||
}
|
||
|
||
tok_t *peek_tok(tok_stream_t *tokbuf) {
|
||
Assert(tokbuf->size <= tokbuf->cap);
|
||
int idx = tokbuf->peek;
|
||
tokbuf->peek = ROUND_IDX(idx + 1);
|
||
|
||
if (idx == tokbuf->end) {
|
||
if (tokbuf->size == tokbuf->cap) {
|
||
LEX_ERROR("peek_tok buffer overflow");
|
||
return NULL;
|
||
}
|
||
if (tokbuf->gettok == NULL) {
|
||
LEX_ERROR("peek_tok can not got tok");
|
||
return NULL;
|
||
}
|
||
tokbuf->gettok(tokbuf->stream, &(tokbuf->buf[idx]));
|
||
tokbuf->size++;
|
||
tokbuf->end = tokbuf->peek;
|
||
}
|
||
|
||
return &(tokbuf->buf[idx]);
|
||
}
|
||
|
||
cc_tktype_t peek_tok_type(tok_stream_t* tokbuf) {
|
||
return peek_tok(tokbuf)->sub_type;
|
||
}
|
||
|
||
int expect_pop_tok(tok_stream_t* tokbuf, cc_tktype_t type) {
|
||
flush_peek_tok(tokbuf);
|
||
tok_t* tok = peek_tok(tokbuf);
|
||
if (tok->sub_type != type) {
|
||
LEX_ERROR("expected tok `%s` but got `%s`", get_tok_name(type), get_tok_name(tok->type));
|
||
return 0;
|
||
} else {
|
||
pop_tok(tokbuf);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
// 生成字符串映射(根据需求选择#str或#name)
|
||
static const char* token_strings[] = {
|
||
// 普通token使用#str
|
||
#define X(str, basic, tok) [tok] = #str,
|
||
TOKEN_TABLE
|
||
#undef X
|
||
|
||
// 关键字使用#name
|
||
#define X(name, std, tok) [tok] = #name,
|
||
KEYWORD_TABLE
|
||
#undef X
|
||
};
|
||
|
||
const char* get_tok_name(cc_tktype_t type) {
|
||
return token_strings[type];
|
||
}
|