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

@@ -507,10 +507,25 @@ static scc_ast_expr_t *parse_cast_expression(scc_parser_t *parser) {
// 一元表达式
static scc_ast_expr_t *parse_unary_expression(scc_parser_t *parser) {
/*
(6.5.3)
unary-expression:
postfix-expression
++ unary-expression
-- unary-expression
unary-operator cast-expression
sizeof unary-expression
sizeof ( type-name )
(6.5.3)
unary-operator: one of
& * + - ~ !
*/
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (!tok_ptr)
return null;
scc_lexer_tok_t tok = {0};
// 处理一元运算符
switch (tok_ptr->type) {
case SCC_TOK_ADD_ADD: // ++x
@@ -529,7 +544,14 @@ static scc_ast_expr_t *parse_unary_expression(scc_parser_t *parser) {
scc_lexer_tok_drop(&op_tok);
// 一元运算符右结合,递归调用 parse_unary_expression
scc_ast_expr_t *operand = parse_unary_expression(parser);
scc_ast_expr_t *operand = null;
if (tok_ptr->type == SCC_TOK_ADD_ADD ||
tok_ptr->type == SCC_TOK_SUB_SUB) {
operand = parse_unary_expression(parser);
} else {
operand = parse_cast_expression(parser);
}
if (!operand) {
parser_sync(parser);
return null;
@@ -563,35 +585,35 @@ static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *parser) {
return null;
}
scc_ast_expr_t *expr = null;
scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
// 尝试解析 sizeof(type-name)
if (next->type == SCC_TOK_L_PAREN) {
scc_parser_store(parser);
scc_ast_type_t *type = scc_parse_type_name(parser);
if (type) {
// 消耗 ')'
if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"expected ')' after type-name in sizeof expression");
}
scc_ast_expr_sizeof_init(null, type);
return expr;
} else {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected type-name after sizeof");
TODO();
scc_parser_next(parser);
scc_ast_type_t *type_name = scc_parse_type_name(parser);
if (type_name == null) {
scc_parser_restore(parser);
goto next;
}
if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
// 消耗 ')'
SCC_ERROR(scc_parser_got_current_pos(parser),
"expected ')' after type-name in sizeof expression");
}
Assert(type_name != null);
scc_ast_expr_sizeof_init(expr, type_name, null);
return expr;
}
// 否则作为 sizeof unary-expression
next:
// 尝试解析 sizeof unary-expression
scc_ast_expr_t *operand = parse_unary_expression(parser);
if (!operand) {
scc_free(expr);
parser_sync(parser);
return null;
} else {
scc_ast_expr_sizeof_init(operand, null);
if (operand != null) {
scc_ast_expr_sizeof_init(expr, null, operand);
return expr;
}
// 否则作为 sizeof(type-name)
return expr;
}
@@ -737,6 +759,14 @@ done:
// 基本表达式
static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
/*
(6.5.1)
primary-expression:
identifier
constant
string-literal
( expression )
*/
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (!tok_ptr)
return null;
@@ -803,66 +833,18 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
return expr;
}
case SCC_TOK_L_PAREN:
return parse_paren_expression(parser);
scc_parser_next_consume(parser, null);
expr = scc_parse_expression(parser);
if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected ')' after expression");
}
return expr;
default:
return null;
}
}
// 处理括号表达式、类型转换、复合字面量
static scc_ast_expr_t *parse_paren_expression(scc_parser_t *parser) {
// 保存位置以便回退
scc_parser_store(parser);
// 尝试解析类型名
scc_ast_type_t *type = scc_parse_type_name(parser);
if (type) {
// 如果成功,下一个应该是 ')'
if (scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
// 是类型转换,解析后面的 cast-expression
scc_ast_expr_t *operand = parse_cast_expression(parser);
if (!operand) {
// FIXME postfix-expression
scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
scc_ast_expr_lvalue_init(expr, type);
operand = scc_parse_initializer(parser, expr);
return operand;
}
scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null);
scc_ast_expr_cast_init(expr, type, operand);
return expr;
} else {
// 不是类型转换,回退并释放 type
scc_parser_restore(parser);
// TODO: scc_ast_type_drop(type);
}
} else {
scc_parser_restore(parser);
}
// 否则作为括号表达式
scc_lexer_tok_t lp;
if (!scc_parser_next_consume(parser, &lp) || lp.type != SCC_TOK_L_PAREN) {
return null;
}
scc_lexer_tok_drop(&lp);
scc_ast_expr_t *inner = scc_parse_expression(parser);
if (!inner) {
parser_sync(parser);
return null;
}
if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
SCC_ERROR(scc_parser_got_current_pos(parser),
"Expected ')' after expression");
parser_sync(parser);
return null;
}
return inner;
}
scc_ast_expr_t *scc_parse_expression(scc_parser_t *parser) {
scc_ast_expr_t *left = scc_parse_assignment_expression(parser);
if (!left)