feat(ast): 添加LVALUE表达式类型支持并重构表达式创建逻辑

- 新增SCC_AST_EXPR_LVALUE表达式类型用于表示右值
- 重构表达式创建逻辑,移除旧的通用创建函数expr_create
- 使用新的初始化函数替代原有的表达式创建方式
- 更新AST转储功能以支持LVALUE表达式的输出
- 修改sizeof表达式解析逻辑,修复类型转换处理
- 优化各种表达式类型的解析和初始化过程
This commit is contained in:
zzy
2026-03-12 21:58:00 +08:00
parent c46578736a
commit 2d1032c363
4 changed files with 95 additions and 136 deletions

View File

@@ -51,6 +51,7 @@ typedef enum {
SCC_AST_EXPR_SIZE_OF, // sizeof SCC_AST_EXPR_SIZE_OF, // sizeof
SCC_AST_EXPR_ALIGN_OF, // _Alignof SCC_AST_EXPR_ALIGN_OF, // _Alignof
SCC_AST_EXPR_COMPOUND, // 复合字面量 SCC_AST_EXPR_COMPOUND, // 复合字面量
SCC_AST_EXPR_LVALUE, // 右值
// 字面量 // 字面量
SCC_AST_EXPR_INT_LITERAL, // 整数字面量 SCC_AST_EXPR_INT_LITERAL, // 整数字面量
SCC_AST_EXPR_FLOAT_LITERAL, // 浮点字面量 SCC_AST_EXPR_FLOAT_LITERAL, // 浮点字面量

View File

@@ -439,7 +439,7 @@ static inline void scc_ast_expr_lvalue_init(scc_ast_expr_t *expr,
scc_ast_type_t *type) { scc_ast_type_t *type) {
Assert(expr != null && type != null); Assert(expr != null && type != null);
expr->base.loc = scc_pos_create(); expr->base.loc = scc_pos_create();
expr->base.type = SCC_AST_EXPR_IDENTIFIER; expr->base.type = SCC_AST_EXPR_LVALUE;
expr->lvalue.type = type; expr->lvalue.type = type;
} }

View File

@@ -53,6 +53,7 @@ static const char *node_type_names[] = {
[SCC_AST_EXPR_SIZE_OF] = "SizeofExpr", [SCC_AST_EXPR_SIZE_OF] = "SizeofExpr",
[SCC_AST_EXPR_ALIGN_OF] = "AlignofExpr", [SCC_AST_EXPR_ALIGN_OF] = "AlignofExpr",
[SCC_AST_EXPR_COMPOUND] = "CompoundExpr", [SCC_AST_EXPR_COMPOUND] = "CompoundExpr",
[SCC_AST_EXPR_LVALUE] = "LvalueExpr",
[SCC_AST_EXPR_INT_LITERAL] = "IntLiteralExpr", [SCC_AST_EXPR_INT_LITERAL] = "IntLiteralExpr",
[SCC_AST_EXPR_FLOAT_LITERAL] = "FloatLiteralExpr", [SCC_AST_EXPR_FLOAT_LITERAL] = "FloatLiteralExpr",
[SCC_AST_EXPR_CHAR_LITERAL] = "CharLiteralExpr", [SCC_AST_EXPR_CHAR_LITERAL] = "CharLiteralExpr",
@@ -461,15 +462,26 @@ static void dump_expr_impl(scc_ast_expr_t *expr, scc_tree_dump_ctx_t *ctx) {
} }
break; break;
case SCC_AST_EXPR_COMPOUND: case SCC_AST_EXPR_LVALUE:
// dump_child_node((scc_ast_node_t *)expr->compound_literal.type, ctx, dump_child_node((scc_ast_node_t *)expr->lvalue.type, ctx, true);
// false); break;
// // 初始化列表
// for (size_t i = 0; i < expr->compound_literal.init_list.size; i++) { case SCC_AST_EXPR_COMPOUND:;
// dump_child_node( dump_child_node((scc_ast_node_t *)expr->compound.base, ctx, false);
// (scc_ast_node_t *)expr->compound_literal.init_list.data[i], if (scc_vec_size(expr->compound.lhs_exprs) !=
// ctx, i == expr->compound_literal.init_list.size - 1); scc_vec_size(expr->compound.rhs_exprs)) {
// } LOG_ERROR("compound expr lhs and rhs size not equal");
break;
}
usize size = scc_vec_size(expr->compound.lhs_exprs);
for (usize i = 0; i < size; i++) {
dump_child_node(
(scc_ast_node_t *)scc_vec_at(expr->compound.lhs_exprs, i), ctx,
false);
dump_child_node(
(scc_ast_node_t *)scc_vec_at(expr->compound.rhs_exprs, i), ctx,
i + 1 == size);
}
break; break;
default: default:

View File

@@ -132,39 +132,10 @@ typedef enum {
PREC_PRIMARY = 17, // 最高优先级 PREC_PRIMARY = 17, // 最高优先级
} scc_precedence_t; } scc_precedence_t;
static inline scc_ast_expr_t *expr_create(scc_parser_t *parser,
scc_ast_node_type_t type) {
scc_ast_expr_t *expr = (scc_ast_expr_t *)scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null);
expr->base.type = type;
expr->base.loc = scc_pos_create();
return expr;
}
/* ---------------------------- 函数前向声明 ---------------------------- */ /* ---------------------------- 函数前向声明 ---------------------------- */
static scc_ast_expr_t *expr_create(scc_parser_t *parser,
scc_ast_node_type_t type);
static scc_ast_expr_t *parse_expression_with_precedence(scc_parser_t *parser, static scc_ast_expr_t *parse_expression_with_precedence(scc_parser_t *parser,
int min_prec); int min_prec);
// 通用二元解析器(用于左结合各层)
typedef scc_ast_expr_t *(*parse_sub_expr_func)(scc_parser_t *parser);
static scc_ast_expr_t *parse_binary_expression(scc_parser_t *parser,
parse_sub_expr_func parse_sub,
int this_prec);
// 各优先级层(除特殊的外,均调用通用解析器)
static scc_ast_expr_t *parse_multiplicative_expression(scc_parser_t *parser);
static scc_ast_expr_t *parse_additive_expression(scc_parser_t *parser);
static scc_ast_expr_t *parse_shift_expression(scc_parser_t *parser);
static scc_ast_expr_t *parse_relational_expression(scc_parser_t *parser);
static scc_ast_expr_t *parse_equality_expression(scc_parser_t *parser);
static scc_ast_expr_t *parse_bitwise_and_expression(scc_parser_t *parser);
static scc_ast_expr_t *parse_bitwise_xor_expression(scc_parser_t *parser);
static scc_ast_expr_t *parse_bitwise_or_expression(scc_parser_t *parser);
static scc_ast_expr_t *parse_logical_and_expression(scc_parser_t *parser);
static scc_ast_expr_t *parse_logical_or_expression(scc_parser_t *parser);
// 特殊结构:独立解析(右结合、条件、一元、后缀、基本) // 特殊结构:独立解析(右结合、条件、一元、后缀、基本)
static scc_ast_expr_t * static scc_ast_expr_t *
parse_conditional_expression(scc_parser_t *parser); // 右结合 parse_conditional_expression(scc_parser_t *parser); // 右结合
@@ -371,45 +342,6 @@ static void parser_sync(scc_parser_t *parser) {
} }
} }
static scc_ast_expr_t *create_binary_expr(scc_parser_t *parser,
scc_ast_expr_t *left,
scc_ast_expr_t *right,
scc_ast_expr_op_t op) {
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_BINARY);
if (!expr)
return null;
expr->binary.op = op;
expr->binary.lhs = left;
expr->binary.rhs = right;
return expr;
}
static scc_ast_expr_t *create_unary_expr(scc_parser_t *parser,
scc_ast_expr_op_t op,
scc_ast_expr_t *operand) {
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_UNARY);
if (!expr)
return null;
expr->unary.op = op;
expr->unary.operand = operand;
return expr;
}
static scc_ast_expr_t *create_conditional_expr(scc_parser_t *parser,
scc_ast_expr_t *cond,
scc_ast_expr_t *then_expr,
scc_ast_expr_t *else_expr) {
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_COND);
if (!expr)
return null;
expr->cond.cond = cond;
expr->cond.then_expr = then_expr;
expr->cond.else_expr = else_expr;
return expr;
}
// 其他创建函数根据需要添加(如 call、subscript、member 等)
/* ---------------------------- 通用二元解析器 ---------------------------- */ /* ---------------------------- 通用二元解析器 ---------------------------- */
static scc_ast_expr_t *parse_expression_with_precedence(scc_parser_t *parser, static scc_ast_expr_t *parse_expression_with_precedence(scc_parser_t *parser,
int min_prec) { int min_prec) {
@@ -442,7 +374,10 @@ static scc_ast_expr_t *parse_expression_with_precedence(scc_parser_t *parser,
return null; return null;
} }
left = create_binary_expr(parser, left, right, op); scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null);
scc_ast_expr_binary_init(expr, op, left, right);
left = expr;
} }
return left; return left;
} }
@@ -476,16 +411,19 @@ scc_ast_expr_t *scc_parse_assignment_expression(scc_parser_t *parser) {
return null; return null;
} }
left = create_binary_expr(parser, left, right, op); scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null);
scc_ast_expr_binary_init(expr, op, left, right);
left = expr;
} }
return left; return left;
} }
// 条件表达式(右结合) // 条件表达式(右结合)
static scc_ast_expr_t *parse_conditional_expression(scc_parser_t *parser) { static scc_ast_expr_t *parse_conditional_expression(scc_parser_t *parser) {
scc_ast_expr_t *cond = scc_ast_expr_t *cond_expr =
parse_expression_with_precedence(parser, PREC_LOGICAL_OR); parse_expression_with_precedence(parser, PREC_LOGICAL_OR);
if (!cond) if (!cond_expr)
return null; return null;
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
@@ -493,7 +431,7 @@ static scc_ast_expr_t *parse_conditional_expression(scc_parser_t *parser) {
// 消耗 '?' // 消耗 '?'
scc_lexer_tok_t q_tok; scc_lexer_tok_t q_tok;
if (!scc_parser_next_consume(parser, &q_tok)) if (!scc_parser_next_consume(parser, &q_tok))
return cond; return cond_expr;
scc_lexer_tok_drop(&q_tok); scc_lexer_tok_drop(&q_tok);
// 解析中间表达式(可以是任何表达式,包括逗号) // 解析中间表达式(可以是任何表达式,包括逗号)
@@ -518,9 +456,12 @@ static scc_ast_expr_t *parse_conditional_expression(scc_parser_t *parser) {
return null; return null;
} }
cond = create_conditional_expr(parser, cond, then_expr, else_expr); scc_ast_expr_t *cond = scc_malloc(sizeof(scc_ast_expr_t));
Assert(cond != null);
scc_ast_expr_cond_init(cond, cond_expr, then_expr, else_expr);
cond_expr = cond;
} }
return cond; return cond_expr;
} }
// 类型转换表达式 (type-name) cast-expression // 类型转换表达式 (type-name) cast-expression
@@ -543,9 +484,9 @@ static scc_ast_expr_t *parse_cast_expression(scc_parser_t *parser) {
// TODO: 需要 scc_ast_type_drop(type); // TODO: 需要 scc_ast_type_drop(type);
return null; return null;
} }
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_CAST); scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
expr->cast.type = type; Assert(expr != null);
expr->cast.expr = operand; scc_ast_expr_cast_init(expr, type, operand);
return expr; return expr;
} else { } else {
// 不是类型转换,回退 // 不是类型转换,回退
@@ -591,7 +532,11 @@ static scc_ast_expr_t *parse_unary_expression(scc_parser_t *parser) {
parser_sync(parser); parser_sync(parser);
return null; return null;
} }
return create_unary_expr(parser, op, operand);
scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null);
scc_ast_expr_unary_init(expr, op, operand);
return expr;
} }
case SCC_TOK_SIZEOF: case SCC_TOK_SIZEOF:
return parse_sizeof_expression(parser); return parse_sizeof_expression(parser);
@@ -616,7 +561,7 @@ static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *parser) {
return null; return null;
} }
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_SIZE_OF); scc_ast_expr_t *expr = null;
// 尝试解析 sizeof(type-name) // 尝试解析 sizeof(type-name)
if (next->type == SCC_TOK_L_PAREN) { if (next->type == SCC_TOK_L_PAREN) {
@@ -624,17 +569,14 @@ static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *parser) {
scc_ast_type_t *type = scc_parse_type_name(parser); scc_ast_type_t *type = scc_parse_type_name(parser);
if (type) { if (type) {
// 消耗 ')' // 消耗 ')'
if (scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) { if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
expr->attr_of.type = type; SCC_ERROR(scc_parser_got_current_pos(parser),
"expected ')' after type-name in sizeof expression");
}
scc_ast_expr_sizeof_init(null, type);
return expr; return expr;
} else { } else {
// 不是有效的 sizeof(type-name),回退 TODO();
scc_parser_restore(parser);
// 释放 type
// TODO: scc_ast_type_drop(type);
}
} else {
scc_parser_restore(parser);
} }
} }
@@ -644,8 +586,9 @@ static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *parser) {
scc_free(expr); scc_free(expr);
parser_sync(parser); parser_sync(parser);
return null; return null;
} else {
scc_ast_expr_sizeof_init(operand, null);
} }
expr->attr_of.expr = operand;
return expr; return expr;
} }
@@ -777,7 +720,10 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
return left; return left;
scc_ast_expr_op_t op = map_token_to_unary_op(op_tok.type, false); scc_ast_expr_op_t op = map_token_to_unary_op(op_tok.type, false);
scc_lexer_tok_drop(&op_tok); scc_lexer_tok_drop(&op_tok);
left = create_unary_expr(parser, op, left); scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null);
scc_ast_expr_unary_init(expr, op, left);
left = expr;
break; break;
} }
default: default:
@@ -794,55 +740,51 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
if (!tok_ptr) if (!tok_ptr)
return null; return null;
scc_lexer_tok_t tok = {0};
scc_ast_expr_t *expr = null;
switch (tok_ptr->type) { switch (tok_ptr->type) {
case SCC_TOK_IDENT: { case SCC_TOK_IDENT: {
scc_lexer_tok_t ident; if (!scc_parser_next_consume(parser, &tok))
if (!scc_parser_next_consume(parser, &ident))
return null; return null;
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_IDENTIFIER); expr = scc_malloc(sizeof(scc_ast_expr_t));
expr->identifier.name = scc_cstring_as_cstr(&ident.lexeme); Assert(expr != null);
ident.lexeme.data = null; scc_ast_expr_identifier_init(expr, scc_cstring_as_cstr(&tok.lexeme));
scc_lexer_tok_drop(&ident);
return expr; return expr;
} }
case SCC_TOK_INT_LITERAL: { case SCC_TOK_INT_LITERAL: {
scc_lexer_tok_t lit; if (!scc_parser_next_consume(parser, &tok))
if (!scc_parser_next_consume(parser, &lit))
return null; return null;
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_INT_LITERAL); expr = scc_malloc(sizeof(scc_ast_expr_t));
expr->literal.lexme = scc_cstring_as_cstr(&lit.lexeme); Assert(expr != null);
lit.lexeme.data = null; // 转移所有权 scc_ast_expr_literal_int_init(expr, scc_cstring_as_cstr(&tok.lexeme),
scc_lexer_tok_drop(&lit); false);
return expr; return expr;
} }
case SCC_TOK_FLOAT_LITERAL: { case SCC_TOK_FLOAT_LITERAL: {
scc_lexer_tok_t lit; if (!scc_parser_next_consume(parser, &tok))
if (!scc_parser_next_consume(parser, &lit))
return null; return null;
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_FLOAT_LITERAL); expr = scc_malloc(sizeof(scc_ast_expr_t));
expr->literal.lexme = scc_cstring_as_cstr(&lit.lexeme); Assert(expr != null);
lit.lexeme.data = null; scc_ast_expr_literal_float_init(expr, scc_cstring_as_cstr(&tok.lexeme),
scc_lexer_tok_drop(&lit); false);
return expr; return expr;
} }
case SCC_TOK_CHAR_LITERAL: { case SCC_TOK_CHAR_LITERAL: {
scc_lexer_tok_t lit; if (!scc_parser_next_consume(parser, &tok))
if (!scc_parser_next_consume(parser, &lit))
return null; return null;
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_CHAR_LITERAL); expr = scc_malloc(sizeof(scc_ast_expr_t));
expr->literal.lexme = scc_cstring_as_cstr(&lit.lexeme); Assert(expr != null);
lit.lexeme.data = null; scc_ast_expr_literal_char_init(expr, scc_cstring_as_cstr(&tok.lexeme),
scc_lexer_tok_drop(&lit); false);
return expr; return expr;
} }
case SCC_TOK_STRING_LITERAL: { case SCC_TOK_STRING_LITERAL: {
scc_lexer_tok_t lit; if (!scc_parser_next_consume(parser, &tok))
if (!scc_parser_next_consume(parser, &lit))
return null; return null;
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_STRING_LITERAL); expr = scc_malloc(sizeof(scc_ast_expr_t));
expr->literal.lexme = scc_cstring_as_cstr(&lit.lexeme); Assert(expr != null);
lit.lexeme.data = null; scc_ast_expr_literal_string_init(expr, scc_cstring_as_cstr(&tok.lexeme),
scc_lexer_tok_drop(&lit); false);
return expr; return expr;
} }
case SCC_TOK_L_PAREN: case SCC_TOK_L_PAREN:
@@ -852,7 +794,7 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
} }
} }
// 处理括号表达式、类型转换、复合字面量(目前只实现括号表达式和类型转换) // 处理括号表达式、类型转换、复合字面量
static scc_ast_expr_t *parse_paren_expression(scc_parser_t *parser) { static scc_ast_expr_t *parse_paren_expression(scc_parser_t *parser) {
// 保存位置以便回退 // 保存位置以便回退
scc_parser_store(parser); scc_parser_store(parser);
@@ -869,9 +811,9 @@ static scc_ast_expr_t *parse_paren_expression(scc_parser_t *parser) {
// TODO: scc_ast_type_drop(type); // TODO: scc_ast_type_drop(type);
return null; return null;
} }
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_CAST); scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
expr->cast.type = type; Assert(expr != null);
expr->cast.expr = operand; scc_ast_expr_cast_init(expr, type, operand);
return expr; return expr;
} else { } else {
// 不是类型转换,回退并释放 type // 不是类型转换,回退并释放 type
@@ -915,11 +857,15 @@ scc_ast_expr_t *scc_parse_expression(scc_parser_t *parser) {
parser_sync(parser); parser_sync(parser);
return null; return null;
} }
left = create_binary_expr(parser, left, right, SCC_AST_OP_COMMA); scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null);
scc_ast_expr_binary_init(expr, SCC_AST_OP_COMMA, left, right);
left = expr;
} }
return left; return left;
} }
scc_ast_expr_t *scc_parser_constant_expression(scc_parser_t *parser) { scc_ast_expr_t *scc_parser_constant_expression(scc_parser_t *parser) {
// TODO check constant
return parse_conditional_expression(parser); return parse_conditional_expression(parser);
} }