From a52ff33e30741a610d5ee861936f6facb456f450 Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Thu, 19 Feb 2026 15:56:05 +0800 Subject: [PATCH] =?UTF-8?q?feat(ast):=20=E6=9B=B4=E6=96=B0AST=E5=AD=97?= =?UTF-8?q?=E9=9D=A2=E9=87=8F=E8=A1=A8=E7=A4=BA=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更新AST定义以使用词素字符串代替常量值, 并修改AST转储功能以正确显示字面量内容。 BREAKING CHANGE: AST表达式结构体中literal成员从value改为lexme字段。 refactor(pproc): 重构宏展开和文件包含逻辑 将宏展开函数重构为独立接口,实现文件包含处理逻辑, 改进预处理器的状态管理机制。 fix(sstream): 修复文件流初始化错误码返回 修正文件打开失败时的错误码返回值,确保调用方能正确处理异常情况。 --- libs/ast/include/ast_def.h | 3 +- libs/ast/src/ast_dump.c | 8 +-- libs/pproc/include/pproc_expand.h | 7 +++ libs/pproc/include/scc_pproc.h | 12 ++--- libs/pproc/src/pproc_directive.c | 4 ++ libs/pproc/src/pproc_expand.c | 23 ++++++--- libs/pproc/src/pproc_include.c | 84 +++++++++++++++++++++++++++++++ libs/pproc/src/scc_pproc.c | 38 ++++++++++++-- libs/sstream/src/scc_sstream.c | 4 +- 9 files changed, 156 insertions(+), 27 deletions(-) diff --git a/libs/ast/include/ast_def.h b/libs/ast/include/ast_def.h index e06a503..c51e14a 100644 --- a/libs/ast/include/ast_def.h +++ b/libs/ast/include/ast_def.h @@ -2,6 +2,7 @@ #define __SCC_AST_DEF_H__ #include +#include /** * @brief AST 节点类型枚举 @@ -310,7 +311,7 @@ struct scc_ast_expr { } compound_literal; // 字面量 struct { - scc_cvalue_t value; + scc_cstring_t lexme; } literal; // 标识符 struct { diff --git a/libs/ast/src/ast_dump.c b/libs/ast/src/ast_dump.c index c46f77a..38853d5 100644 --- a/libs/ast/src/ast_dump.c +++ b/libs/ast/src/ast_dump.c @@ -392,16 +392,10 @@ static void dump_expr_impl(scc_ast_expr_t *expr, scc_tree_dump_ctx_t *ctx) { PRINT_QUOTED_VALUE(ctx, get_op_str(expr->unary.op)); break; case SCC_AST_EXPR_INT_LITERAL: - PRINT_VALUE(ctx, " %lld", expr->literal.value.i); - break; case SCC_AST_EXPR_FLOAT_LITERAL: - PRINT_VALUE(ctx, " %f", expr->literal.value.f); - break; case SCC_AST_EXPR_CHAR_LITERAL: - PRINT_VALUE(ctx, " '%c'", (char)expr->literal.value.ch); - break; case SCC_AST_EXPR_STRING_LITERAL: - PRINT_VALUE(ctx, " \"%s\"", expr->literal.value.cstr.data); + PRINT_VALUE(ctx, " %s", expr->literal.lexme); break; case SCC_AST_EXPR_IDENTIFIER: if (expr->identifier.name) { diff --git a/libs/pproc/include/pproc_expand.h b/libs/pproc/include/pproc_expand.h index 8a96917..18e28bc 100644 --- a/libs/pproc/include/pproc_expand.h +++ b/libs/pproc/include/pproc_expand.h @@ -22,5 +22,12 @@ scc_lexer_array_to_ring(scc_lexer_tok_vec_t *array) { } void scc_pproc_expand_macro(scc_pproc_expand_t *expand_ctx); +void scc_pproc_expand_by_src(scc_pproc_macro_table_t *macro_table, + scc_lexer_tok_ring_t *input, + scc_lexer_tok_ring_t *output, + const scc_pproc_macro_t *macro); +void scc_pproc_expand_by_vec(scc_pproc_macro_table_t *macro_table, + scc_lexer_tok_vec_t *input, + scc_lexer_tok_ring_t *output); #endif /* __SCC_PPROC_EXPAND_H__ */ diff --git a/libs/pproc/include/scc_pproc.h b/libs/pproc/include/scc_pproc.h index 0f240e4..579caad 100644 --- a/libs/pproc/include/scc_pproc.h +++ b/libs/pproc/include/scc_pproc.h @@ -21,16 +21,16 @@ typedef struct { } scc_pproc_if_state_t; typedef SCC_VEC(scc_pproc_if_state_t) scc_pproc_if_stack_t; -// 文件包含栈 typedef struct { - scc_lexer_t *lexer; // 当前文件的 lexer - scc_lexer_tok_ring_t *tok_ring; // 当前文件的 token 环(由 lexer 提供) - // 可能还需要保存当前位置等 + scc_sstream_t sstream; + scc_lexer_t lexer; + scc_lexer_tok_ring_t *ring; } scc_pproc_file_state_t; -typedef SCC_VEC(scc_pproc_file_state_t) scc_pproc_file_stack_t; +typedef SCC_VEC(scc_pproc_file_state_t *) scc_pproc_file_stack_t; typedef SCC_VEC(scc_lexer_tok_ring_t *) scc_pproc_ring_vec_t; typedef struct scc_pproc { + scc_lexer_tok_ring_t *org_ring; scc_lexer_tok_ring_t *cur_ring; scc_lexer_tok_ring_t expanded_ring; scc_strpool_t strpool; @@ -49,7 +49,7 @@ scc_lexer_tok_ring_t *scc_pproc_to_ring(scc_pproc_t *pp, int ring_size); void scc_pproc_drop(scc_pproc_t *pp); void scc_pproc_handle_directive(scc_pproc_t *pp); -void scc_pproc_expand_by_src(scc_pproc_t *pp, const scc_pproc_macro_t *macro); +void scc_pproc_parse_include(scc_pproc_t *pp); void scc_pproc_parse_macro_arguments(scc_lexer_tok_ring_t *ring, scc_lexer_tok_vec_t *args, int need_full); void scc_pproc_parse_function_macro(scc_pproc_t *pp, diff --git a/libs/pproc/src/pproc_directive.c b/libs/pproc/src/pproc_directive.c index 7009e38..25615ad 100644 --- a/libs/pproc/src/pproc_directive.c +++ b/libs/pproc/src/pproc_directive.c @@ -271,6 +271,9 @@ void scc_pproc_handle_directive(scc_pproc_t *pp) { return; } case SCC_PP_TOK_INCLUDE: + scc_lexer_tok_drop(&tok); + scc_pproc_parse_include(pp); + return; case SCC_PP_TOK_IF: case SCC_PP_TOK_IFDEF: case SCC_PP_TOK_IFNDEF: @@ -279,6 +282,7 @@ void scc_pproc_handle_directive(scc_pproc_t *pp) { case SCC_PP_TOK_ELIFDEF: case SCC_PP_TOK_ELIFNDEF: case SCC_PP_TOK_ENDIF: + goto ERROR; case SCC_PP_TOK_LINE: case SCC_PP_TOK_EMBED: goto ERROR; diff --git a/libs/pproc/src/pproc_expand.c b/libs/pproc/src/pproc_expand.c index 3886751..909ca40 100644 --- a/libs/pproc/src/pproc_expand.c +++ b/libs/pproc/src/pproc_expand.c @@ -81,26 +81,35 @@ static inline void scc_copy_expand(scc_pproc_expand_t *expand_ctx, scc_vec_init(copyed_ctx->output); } -void scc_pproc_expand_by_src(scc_pproc_t *pp, const scc_pproc_macro_t *macro) { - scc_pproc_expand_t ctx; +void scc_pproc_expand_by_src(scc_pproc_macro_table_t *macro_table, + scc_lexer_tok_ring_t *input, + scc_lexer_tok_ring_t *output, + const scc_pproc_macro_t *macro) { scc_lexer_tok_vec_t expaned_buffer; scc_vec_init(expaned_buffer); int ok; scc_lexer_tok_t tok; - scc_ring_next_consume(*pp->cur_ring, tok, ok); + scc_ring_next_consume(*input, tok, ok); if (macro->type == SCC_PP_MACRO_NONE || ok == false) { UNREACHABLE(); } else if (macro->type == SCC_PP_MACRO_OBJECT) { scc_vec_push(expaned_buffer, tok); } else if (macro->type == SCC_PP_MACRO_FUNCTION) { scc_vec_push(expaned_buffer, tok); - scc_pproc_parse_macro_arguments(pp->cur_ring, &expaned_buffer, true); + scc_pproc_parse_macro_arguments(input, &expaned_buffer, true); } - scc_lexer_tok_ring_t ring = scc_lexer_array_to_ring(&expaned_buffer); + scc_pproc_expand_by_vec(macro_table, &expaned_buffer, output); +} + +void scc_pproc_expand_by_vec(scc_pproc_macro_table_t *macro_table, + scc_lexer_tok_vec_t *input, + scc_lexer_tok_ring_t *output) { + scc_pproc_expand_t ctx; + scc_lexer_tok_ring_t ring = scc_lexer_array_to_ring(input); ctx.input = ˚ - ctx.macro_table = &pp->macro_table; + ctx.macro_table = macro_table; ctx.need_rescan = false; scc_vec_init(ctx.output); scc_pproc_macro_table_t expanded_set; @@ -108,7 +117,7 @@ void scc_pproc_expand_by_src(scc_pproc_t *pp, const scc_pproc_macro_t *macro) { scc_pproc_marco_table_init(ctx.expanded_set); scc_pproc_expand_macro(&ctx); - pp->expanded_ring = scc_lexer_array_to_ring(&ctx.output); + *output = scc_lexer_array_to_ring(&ctx.output); scc_pproc_macro_table_drop(ctx.expanded_set); } diff --git a/libs/pproc/src/pproc_include.c b/libs/pproc/src/pproc_include.c index e69de29..0655d8a 100644 --- a/libs/pproc/src/pproc_include.c +++ b/libs/pproc/src/pproc_include.c @@ -0,0 +1,84 @@ +#include +#include + +static int switch_file_stack(scc_pproc_t *pp, scc_cstring_t fname, + int is_system) { + scc_pproc_file_state_t *file = scc_malloc(sizeof(scc_pproc_file_state_t)); + Assert(file != null); + if (scc_sstream_init(&(file->sstream), fname.data, 1024)) { + return -1; + } + scc_lexer_init(&(file->lexer), scc_sstream_to_ring(&(file->sstream))); + file->ring = scc_lexer_to_ring(&(file->lexer), 8, true); + pp->cur_ring = file->ring; + + scc_vec_push(pp->file_stack, file); + return 0; +} + +void scc_pproc_parse_include(scc_pproc_t *pp) { + int ok; + scc_lexer_tok_t tok; + + scc_lexer_tok_ring_t *stream = pp->cur_ring; + scc_lexer_tok_vec_t org_toks; + scc_vec_init(org_toks); + while (1) { + scc_ring_peek(*stream, tok, ok); + if (ok == false) + break; + scc_ring_next_consume(*stream, tok, ok); + scc_vec_push(org_toks, tok); + // FIXME endline needed? + if (tok.type == SCC_TOK_ENDLINE) + break; + } + + scc_lexer_tok_ring_t out_ring; + scc_pproc_expand_by_vec(&pp->macro_table, &org_toks, &out_ring); + scc_cstring_t line = scc_cstring_create(); + while (1) { + scc_ring_next_consume(out_ring, tok, ok); + if (!ok) + break; + if (scc_get_tok_subtype(tok.type) != SCC_TOK_SUBTYPE_EMPTYSPACE && + scc_get_tok_subtype(tok.type) != SCC_TOK_SUBTYPE_COMMENT) { + scc_cstring_append(&line, &tok.lexeme); + } + scc_lexer_tok_drop(&tok); + } + scc_ring_free(out_ring); + + const char *includename = scc_cstring_as_cstr(&line); + int len = scc_cstring_len(&line); + if (len < 2) { + goto ERROR; + } else if (len == 2) { + goto ERROR; + } else { + if (includename[0] == '\"') { + if (includename[len - 1] != '\"') { + goto ERROR; + } + } else if (includename[0] == '<') { + if (includename[len - 1] != '>') { + goto ERROR; + } + } else { + goto ERROR; + } + } + scc_cstring_t fname = scc_cstring_create(); + for (int i = 1; i < len - 1; i++) { + scc_cstring_append_ch(&fname, includename[i]); + } + scc_cstring_free(&line); + int is_system = includename[0] == '<'; + if (switch_file_stack(pp, fname, is_system)) { + goto ERROR; + } + return; +ERROR: + LOG_ERROR("Invalid include filename need \"FILENAME\" or "); + scc_cstring_free(&line); +} diff --git a/libs/pproc/src/scc_pproc.c b/libs/pproc/src/scc_pproc.c index dd1247a..ceac03c 100644 --- a/libs/pproc/src/scc_pproc.c +++ b/libs/pproc/src/scc_pproc.c @@ -1,10 +1,11 @@ +#include #include -static int pproc_next(scc_pproc_t *pp, scc_lexer_tok_t *out) { +static int pproc_next_one_file(scc_pproc_t *pp, scc_lexer_tok_t *out) { +CONTINUE: scc_lexer_tok_ring_t *stream = pp->cur_ring; scc_lexer_tok_t tok = {0}; int ok = 0; -CONTINUE: if (pp->expanded_ring.cap) { scc_ring_next_consume(pp->expanded_ring, *out, ok); if (ok == false) { @@ -39,7 +40,8 @@ CONTINUE: scc_ring_next_consume(*stream, *out, ok); return ok; } - scc_pproc_expand_by_src(pp, macro); + scc_pproc_expand_by_src(&pp->macro_table, pp->cur_ring, + &pp->expanded_ring, macro); goto CONTINUE; } else { // continue @@ -49,9 +51,37 @@ CONTINUE: return false; } +static int pproc_next(scc_pproc_t *pp, scc_lexer_tok_t *tok) { +CONTINUE: + int ret = pproc_next_one_file(pp, tok); + if (ret != 0) { + return true; + } + + if (scc_vec_size(pp->file_stack) == 0) { + return false; + } + + scc_pproc_file_state_t *file = scc_vec_pop(pp->file_stack); + Assert(file->ring == pp->cur_ring); + scc_lexer_drop_ring(file->ring); + scc_lexer_drop(&(file->lexer)); + scc_sstream_drop(&(file->sstream)); + scc_free(file); + + if (scc_vec_size(pp->file_stack) == 0) { + pp->cur_ring = pp->org_ring; + } else { + pp->cur_ring = + scc_vec_at(pp->file_stack, scc_vec_size(pp->file_stack) - 1)->ring; + } + goto CONTINUE; +} + void scc_pproc_init(scc_pproc_t *pp, scc_lexer_tok_ring_t *input) { Assert(pp != null && input != null); - pp->cur_ring = input; + pp->org_ring = input; + pp->cur_ring = pp->org_ring; scc_ring_init(pp->expanded_ring, 0, 0, 0); scc_pproc_marco_table_init(&pp->macro_table); scc_vec_init(pp->if_stack); diff --git a/libs/sstream/src/scc_sstream.c b/libs/sstream/src/scc_sstream.c index 130ca61..54e5bf2 100644 --- a/libs/sstream/src/scc_sstream.c +++ b/libs/sstream/src/scc_sstream.c @@ -84,13 +84,13 @@ int scc_sstream_init(scc_sstream_t *stream, const char *fname, int ring_size) { scc_file_t file = scc_fopen(fname, SCC_FILE_READ); if (file == null) { LOG_ERROR("Failed to open file: %s", fname); - return 0; + return 1; } usize fsize = scc_fsize(file); if (fsize == 0) { LOG_WARN("file size is 0"); scc_fclose(file); - return 0; + return 2; } char *buffer = (char *)scc_malloc(fsize); scc_memset(buffer, 0, fsize);