feat(parser): 添加声明列表支持并重构解析逻辑

- 添加 SCC_AST_DECL_LIST 节点类型用于表示声明列表
- 实现 scc_ast_decl_list_init 函数来初始化声明列表节点
- 重构 scc_parse_declaration 函数以支持逗号分隔的多个变量声明
- 分离类型说明符解析到独立的 scc_parse_declaration_specifiers 函数
- 支持 typedef 和多变量声明如 'int a, b;' 和 'int a = 1, b = 2;'
- 在 ast_dump 中添加对声明列表节点的打印支持

refactor(ast): 统一使用 scc_vec_foreach 宏替换手动循环

- 将 ast_dump.c 中的多个手动索引循环改为使用 scc_vec_foreach
- 提高代码可读性和安全性
- 避免索引越界错误

fix(parser): 修复语义分析中结构体符号表冲突

- 为结构体、联合体和枚举符号名添加前缀避免命名冲突
- 使用 '$S_'、'$U_'、'$E_' 前缀分别标识结构体、联合体和枚举

refactor(log): 统一终止处理方式

- 将 log_exit 替换为 log_abort 以更准确反映行为
- 更新相关依赖模块的实现

style(parser): 移除未使用的参数和清理代码

- 在 argparse.c 中添加 (void) 参数注释处理未使用的参数
- 清理 parse_expr.c 中未使用的函数声明
- 优化 parse_type.c 中的错误处理流程
This commit is contained in:
zzy
2026-03-14 14:04:24 +08:00
parent 8fcfeda14e
commit eb969cdbf7
26 changed files with 344 additions and 165 deletions

View File

@@ -258,25 +258,33 @@ scc_ast_expr_t *scc_parse_initializer(scc_parser_t *parser,
}
scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) {
scc_ast_decl_t *decl = scc_parse_declarator(parser);
const scc_lexer_tok_t *tok_ptr = null;
scc_ast_decl_t *decl_list = null;
scc_ast_decl_vec_t decl_list_vec;
scc_vec_init(decl_list_vec);
scc_ast_type_t *type = scc_parse_declaration_specifiers(parser);
if (type == null) {
return null;
}
scc_ast_decl_specifier_t spec = type->quals;
// FIXME drop typedef inline and ...
type->quals.is_typedef = false;
scc_ast_decl_t *decl = null;
CONTINUE:
decl = scc_parse_declarator(parser, type);
if (decl == null) {
return null;
}
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (tok_ptr->type == SCC_TOK_SEMICOLON) {
scc_parser_next_consume(parser, null);
goto RETURN;
} else if (tok_ptr->type == SCC_TOK_ASSIGN) {
tok_ptr = scc_parser_peek(parser);
if (tok_ptr->type == SCC_TOK_ASSIGN) {
scc_parser_next_consume(parser, null);
// TODO maybe memory leak
scc_ast_expr_t *lvalue = scc_malloc(sizeof(scc_ast_expr_t));
scc_ast_expr_lvalue_init(lvalue, decl->var.type);
decl->var.init = scc_parse_initializer(parser, lvalue);
if (!scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) {
SCC_ERROR(scc_parser_got_current_pos(parser), "expect semicolon");
}
goto RETURN;
} else if (tok_ptr->type == SCC_TOK_L_BRACE) {
scc_ast_stmt_t *body = scc_parse_statement(parser);
Assert(decl->base.type == SCC_AST_DECL_FUNC);
@@ -285,13 +293,56 @@ scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) {
Assert(decl->func.type->base.type == SCC_AST_TYPE_FUNCTION);
Assert(decl->func.body != null);
Assert(decl->func.body->base.type == SCC_AST_STMT_COMPOUND);
goto RETURN;
}
tok_ptr = scc_parser_peek(parser);
if (tok_ptr->type == SCC_TOK_SEMICOLON) {
scc_parser_next_consume(parser, null);
if (spec.is_typedef) {
if (decl_list) {
scc_vec_foreach(decl_list_vec, i) {
decl = scc_vec_at(decl_list_vec, i);
scc_ast_decl_typedef_init(decl, decl->name, type);
}
} else {
scc_ast_decl_typedef_init(decl, decl->name, decl->var.type);
}
}
if (decl_list != null) {
scc_vec_push(decl_list_vec, decl);
scc_vec_foreach(decl_list_vec, i) {
decl = scc_vec_at(decl_list_vec, i);
scc_parse_decl_sema(parser, decl);
}
scc_ast_decl_list_init(decl_list, &decl_list_vec);
decl = decl_list;
} else {
scc_parse_decl_sema(parser, decl);
}
goto RETURN;
} else if (tok_ptr->type == SCC_TOK_COMMA) {
scc_parser_next_consume(parser, null);
if (decl_list == null) {
decl_list = scc_malloc(sizeof(scc_ast_decl_t));
Assert(decl_list != null);
scc_vec_push(decl_list_vec, decl);
} else {
Assert(scc_vec_size(decl_list_vec) != 0);
decl->var.type = scc_vec_at(decl_list_vec, 0)->var.type;
scc_vec_push(decl_list_vec, decl);
}
goto CONTINUE;
} else {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected ';' or '=' or '{'");
UNREACHABLE();
// FIXME memory leak
goto ERROR;
}
RETURN:
scc_parse_decl_sema(parser, decl);
return decl;
ERROR:
return null;
}