#include #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]; }