From 9d85dc130d4a12f8df21e91c8c0818582d0a4ed7 Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Wed, 18 Feb 2026 18:17:52 +0800 Subject: [PATCH] =?UTF-8?q?feat(lexer):=20=E6=B7=BB=E5=8A=A0=E8=AF=8D?= =?UTF-8?q?=E6=B3=95=E5=88=86=E6=9E=90=E5=99=A8=E5=AF=B9##=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E7=AC=A6=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重命名lexer_token.h为scc_lexer_token.h以保持命名一致性 - 在词法分析器中实现##操作符的识别和处理 - 修改头文件包含路径和类型定义的位置 - 修复token结构体定义的顺序问题 fix(lexer): 初始化lexer中的cur变量避免未初始化问题 - 在scc_lexer_get_token函数中初始化scc_sstream_char_t cur变量 refactor(core): 增强ring缓冲区功能并添加cstring比较函数 - 在scc_core_ring.h中添加空值检查防止fill函数为空时崩溃 - 添加scc_ring_by_buffer宏用于通过缓冲区创建ring实例 - 在scc_core_str.h中添加scc_cstring_cmp函数用于字符串比较 --- libs/lexer/include/scc_lexer.h | 4 +--- .../{lexer_token.h => scc_lexer_token.h} | 17 ++++++++++++----- libs/lexer/src/lexer.c | 8 ++++++-- libs/lexer/src/token.c | 2 +- runtime/scc_core/include/scc_core_ring.h | 14 +++++++++++++- runtime/scc_core/include/scc_core_str.h | 5 +++++ 6 files changed, 38 insertions(+), 12 deletions(-) rename libs/lexer/include/{lexer_token.h => scc_lexer_token.h} (97%) diff --git a/libs/lexer/include/scc_lexer.h b/libs/lexer/include/scc_lexer.h index c8c246f..787473a 100644 --- a/libs/lexer/include/scc_lexer.h +++ b/libs/lexer/include/scc_lexer.h @@ -6,13 +6,11 @@ #ifndef __SCC_LEXER_H__ #define __SCC_LEXER_H__ -#include "lexer_token.h" +#include "scc_lexer_token.h" #include #include #include -typedef SCC_RING(scc_lexer_tok_t) scc_lexer_tok_ring_t; -typedef SCC_VEC(scc_lexer_tok_t) scc_lexer_tok_vec_t; /** * @brief 词法分析器核心结构体 * diff --git a/libs/lexer/include/lexer_token.h b/libs/lexer/include/scc_lexer_token.h similarity index 97% rename from libs/lexer/include/lexer_token.h rename to libs/lexer/include/scc_lexer_token.h index d646574..6149123 100644 --- a/libs/lexer/include/lexer_token.h +++ b/libs/lexer/include/scc_lexer_token.h @@ -4,6 +4,12 @@ #include #include +#include +struct scc_lexer_token; +typedef struct scc_lexer_token scc_lexer_tok_t; +typedef SCC_RING(scc_lexer_tok_t) scc_lexer_tok_ring_t; +typedef SCC_VEC(scc_lexer_tok_t) scc_lexer_tok_vec_t; + typedef enum scc_cstd { SCC_CSTD_C89, SCC_CSTD_C99, @@ -82,6 +88,7 @@ typedef enum scc_cstd { X(blank , SCC_TOK_SUBTYPE_EMPTYSPACE, SCC_TOK_BLANK ) \ X(endline , SCC_TOK_SUBTYPE_EMPTYSPACE, SCC_TOK_ENDLINE ) \ X("#" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_SHARP ) \ + X("##" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_SHARP_SHARP ) \ X("==" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_EQ ) \ X("=" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ASSIGN ) \ X("++" , SCC_TOK_SUBTYPE_OPERATOR, SCC_TOK_ADD_ADD ) \ @@ -166,18 +173,18 @@ typedef enum scc_tok_subtype { SCC_TOK_SUBTYPE_EOF // 结束标记 } scc_tok_subtype_t; -scc_tok_subtype_t scc_get_tok_subtype(scc_tok_type_t type); -const char *scc_get_tok_name(scc_tok_type_t type); - /** * @brief 词法分析结果 * @warning 需要手动释放lexeme否则会出现内存泄漏 */ -typedef struct scc_lexer_token { +struct scc_lexer_token { scc_tok_type_t type; scc_cstring_t lexeme; scc_pos_t loc; -} scc_lexer_tok_t; +}; + +scc_tok_subtype_t scc_get_tok_subtype(scc_tok_type_t type); +const char *scc_get_tok_name(scc_tok_type_t type); static inline void scc_lexer_tok_drop(scc_lexer_tok_t *tok) { scc_cstring_free(&tok->lexeme); diff --git a/libs/lexer/src/lexer.c b/libs/lexer/src/lexer.c index 3212195..9e228ee 100644 --- a/libs/lexer/src/lexer.c +++ b/libs/lexer/src/lexer.c @@ -88,7 +88,7 @@ static inline cbool next_char(scc_lexer_t *lexer, scc_cstring_t *lexeme, #define set_err_token(token) ((token)->type = SCC_TOK_UNKNOWN) void scc_lexer_get_token(scc_lexer_t *lexer, scc_lexer_tok_t *token) { - scc_sstream_char_t cur; + scc_sstream_char_t cur = {0}; scc_cstring_t lex = scc_cstring_create(); // 临时lexeme // 尝试预览第一个字符 @@ -439,7 +439,11 @@ void scc_lexer_get_token(scc_lexer_t *lexer, scc_lexer_tok_t *token) { token->type = SCC_TOK_COND; break; case '#': - token->type = SCC_TOK_SHARP; + if (next.character == '#') { + token->type = SCC_TOK_SHARP_SHARP; + next_char(lexer, &lex, &cur); + } else + token->type = SCC_TOK_SHARP; break; default: token->type = SCC_TOK_UNKNOWN; diff --git a/libs/lexer/src/token.c b/libs/lexer/src/token.c index 947295d..f7689c3 100644 --- a/libs/lexer/src/token.c +++ b/libs/lexer/src/token.c @@ -1,4 +1,4 @@ -#include +#include // 生成字符串映射(根据需求选择#str或#name) static const char *token_strings[] = { diff --git a/runtime/scc_core/include/scc_core_ring.h b/runtime/scc_core/include/scc_core_ring.h index a2fd2c1..4dc1511 100644 --- a/runtime/scc_core/include/scc_core_ring.h +++ b/runtime/scc_core/include/scc_core_ring.h @@ -51,7 +51,8 @@ break; \ } \ usize phys_tail = scc_ring_phys(ring, (ring).tail); \ - if (!(ring).fill(&(ring).data[phys_tail], (ring).userdata)) { \ + if ((ring).fill == null || \ + !(ring).fill(&(ring).data[phys_tail], (ring).userdata)) { \ ok = 0; \ break; \ } \ @@ -79,6 +80,17 @@ (ring).userdata = (_userdata); \ } while (0) +#define scc_ring_by_buffer(ring, buffer, size) \ + do { \ + (ring).data = (buffer); \ + (ring).cap = (size); \ + (ring).head = 0; \ + (ring).probe = 0; \ + (ring).tail = (size); \ + (ring).fill = null; \ + (ring).userdata = null; \ + } while (0) + /** * @brief 释放环形缓冲区内存 * @param ring 环形缓冲区变量 diff --git a/runtime/scc_core/include/scc_core_str.h b/runtime/scc_core/include/scc_core_str.h index 62ac199..7f57b64 100644 --- a/runtime/scc_core/include/scc_core_str.h +++ b/runtime/scc_core/include/scc_core_str.h @@ -194,6 +194,11 @@ static inline char *scc_cstring_as_cstr(const scc_cstring_t *str) { return str->data; } +static inline int scc_cstring_cmp(const scc_cstring_t *str1, + const scc_cstring_t *str2) { + return scc_strcmp(scc_cstring_as_cstr(str1), scc_cstring_as_cstr(str2)); +} + static inline char *scc_cstring_move_cstr(scc_cstring_t *str) { if (str == null || str->data == null) { return null;