feat(ast): 添加内置表达式支持并完善解析器功能

- 添加SCC_AST_EXPR_BUILTIN枚举值用于表示内置表达式
- 定义scc_ast_builtin_expr_type_t枚举包含va_start、va_end、va_copy、va_arg等内置函数类型
- 在AST表达式结构中添加builtin字段以支持内置表达式存储
- 实现scc_ast_decl_unsafe_val_init内联函数用于不安全的声明初始化
- 修改sizeof和alignof表达式初始化函数以支持类型或表达式参数
- 修复默认语句的字段引用错误(default_stmt而非case_stmt)
- 改进词法分析器对整数字面量后缀(U、L、LL等)的处理逻辑
- 重构解析器中的声明解析逻辑,统一使用scc_parse_declarator函数
- 完善结构体、联合体和枚举类型的声明解析,支持仅有名称的前向声明
- 优化初始化列表解析,支持复合字面量的成员访问语法
- 更新参数类型列表解析以正确处理参数声明
- 修复括号表达式的解析逻辑,区分类型转换和普通括号表达式
This commit is contained in:
zzy
2026-03-13 17:39:14 +08:00
parent c99f64708e
commit 8fcfeda14e
12 changed files with 431 additions and 225 deletions

View File

@@ -174,6 +174,7 @@ scc_ast_expr_t *scc_parse_initializer(scc_parser_t *parser,
. identifier
*/
const scc_lexer_tok_t *tok_ptr = null;
scc_lexer_tok_t tok = {0};
tok_ptr = scc_parser_peek(parser);
scc_ast_expr_t *init = null;
if (!(tok_ptr && tok_ptr->type == SCC_TOK_L_BRACE)) {
@@ -191,21 +192,21 @@ scc_ast_expr_t *scc_parse_initializer(scc_parser_t *parser,
scc_vec_init(rhs_exprs);
scc_ast_expr_t *lhs = null;
scc_ast_expr_t *rhs = null;
scc_ast_expr_t *ptr = base;
while (1) {
tok_ptr = scc_parser_peek(parser);
if (tok_ptr->type == SCC_TOK_DOT) {
scc_parser_next_consume(parser, null);
tok_ptr = scc_parser_peek(parser);
if (tok_ptr && tok_ptr->type == SCC_TOK_IDENT) {
scc_parser_next(parser);
scc_parser_next_consume(parser, &tok);
lhs = scc_malloc(sizeof(scc_ast_expr_t));
Assert(lhs != null);
scc_ast_expr_member_init(lhs, base,
scc_cstring_as_cstr(&tok_ptr->lexeme));
scc_ast_expr_member_init(lhs, ptr,
scc_cstring_as_cstr(&tok.lexeme));
if (!scc_parser_consume_if(parser, SCC_TOK_ASSIGN)) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected '='");
ptr = lhs;
continue;
}
rhs = scc_parse_initializer(parser, lhs);
if (rhs == null) {
@@ -215,6 +216,7 @@ scc_ast_expr_t *scc_parse_initializer(scc_parser_t *parser,
}
scc_vec_push(lhs_exprs, lhs);
scc_vec_push(rhs_exprs, rhs);
ptr = base;
} else {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected 'identifier' after '.'");
@@ -228,14 +230,16 @@ scc_ast_expr_t *scc_parse_initializer(scc_parser_t *parser,
}
lhs = scc_malloc(sizeof(scc_ast_expr_t));
Assert(lhs != null);
scc_ast_expr_array_subscript_init(lhs, base, idx);
scc_ast_expr_array_subscript_init(lhs, ptr, idx);
if (!scc_parser_consume_if(parser, SCC_TOK_ASSIGN)) {
SCC_ERROR(scc_parser_got_current_pos(parser), "Expected '='");
ptr = lhs;
continue;
}
rhs = scc_parse_initializer(parser, lhs);
Assert(rhs != null);
scc_vec_push(lhs_exprs, lhs);
scc_vec_push(rhs_exprs, rhs);
ptr = base;
} else if (tok_ptr->type == SCC_TOK_R_BRACE) {
scc_parser_next_consume(parser, null);
break;
@@ -254,31 +258,8 @@ scc_ast_expr_t *scc_parse_initializer(scc_parser_t *parser,
}
scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) {
scc_ast_node_t *type_or_decl = _scc_parse_type(parser);
scc_ast_decl_t *decl = null;
if (type_or_decl == null) {
return null;
}
if (SCC_AST_IS_A(scc_ast_type_t, type_or_decl)) {
scc_ast_type_t *type = SCC_AST_CAST_TO(scc_ast_type_t, type_or_decl);
if (type->base.type == SCC_AST_TYPE_STRUCT ||
type->base.type == SCC_AST_TYPE_UNION) {
Assert(type->record.decl != null);
decl = type->record.decl;
scc_free(type_or_decl); // FIXME
} else if (type->base.type == SCC_AST_TYPE_ENUM) {
Assert(type->enumeration.decl != null);
decl = type->enumeration.decl;
scc_free(type_or_decl); // FIXME
} else {
LOG_WARN("declaration dose not declare anything");
return null;
}
} else if (SCC_AST_IS_A(scc_ast_decl_t, type_or_decl)) {
decl = SCC_AST_CAST_TO(scc_ast_decl_t, type_or_decl);
} else {
SCC_ERROR(scc_parser_got_current_pos(parser), "invalid declaration");
scc_ast_decl_t *decl = scc_parse_declarator(parser);
if (decl == null) {
return null;
}
@@ -305,6 +286,8 @@ scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) {
Assert(decl->func.body != null);
Assert(decl->func.body->base.type == SCC_AST_STMT_COMPOUND);
} else {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected ';' or '=' or '{'");
UNREACHABLE();
}