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

@@ -132,39 +132,10 @@ typedef enum {
PREC_PRIMARY = 17, // 最高优先级
} 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,
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 *
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,
int min_prec) {
@@ -442,7 +374,10 @@ static scc_ast_expr_t *parse_expression_with_precedence(scc_parser_t *parser,
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;
}
@@ -476,16 +411,19 @@ scc_ast_expr_t *scc_parse_assignment_expression(scc_parser_t *parser) {
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;
}
// 条件表达式(右结合)
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);
if (!cond)
if (!cond_expr)
return null;
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;
if (!scc_parser_next_consume(parser, &q_tok))
return cond;
return cond_expr;
scc_lexer_tok_drop(&q_tok);
// 解析中间表达式(可以是任何表达式,包括逗号)
@@ -518,9 +456,12 @@ static scc_ast_expr_t *parse_conditional_expression(scc_parser_t *parser) {
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
@@ -543,9 +484,9 @@ static scc_ast_expr_t *parse_cast_expression(scc_parser_t *parser) {
// TODO: 需要 scc_ast_type_drop(type);
return null;
}
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_CAST);
expr->cast.type = type;
expr->cast.expr = 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 {
// 不是类型转换,回退
@@ -591,7 +532,11 @@ static scc_ast_expr_t *parse_unary_expression(scc_parser_t *parser) {
parser_sync(parser);
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:
return parse_sizeof_expression(parser);
@@ -616,7 +561,7 @@ static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *parser) {
return null;
}
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_SIZE_OF);
scc_ast_expr_t *expr = null;
// 尝试解析 sizeof(type-name)
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);
if (type) {
// 消耗 ')'
if (scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
expr->attr_of.type = type;
return expr;
} else {
// 不是有效的 sizeof(type-name),回退
scc_parser_restore(parser);
// 释放 type
// TODO: scc_ast_type_drop(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_parser_restore(parser);
TODO();
}
}
@@ -644,8 +586,9 @@ static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *parser) {
scc_free(expr);
parser_sync(parser);
return null;
} else {
scc_ast_expr_sizeof_init(operand, null);
}
expr->attr_of.expr = operand;
return expr;
}
@@ -777,7 +720,10 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
return left;
scc_ast_expr_op_t op = map_token_to_unary_op(op_tok.type, false);
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;
}
default:
@@ -794,55 +740,51 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
if (!tok_ptr)
return null;
scc_lexer_tok_t tok = {0};
scc_ast_expr_t *expr = null;
switch (tok_ptr->type) {
case SCC_TOK_IDENT: {
scc_lexer_tok_t ident;
if (!scc_parser_next_consume(parser, &ident))
if (!scc_parser_next_consume(parser, &tok))
return null;
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_IDENTIFIER);
expr->identifier.name = scc_cstring_as_cstr(&ident.lexeme);
ident.lexeme.data = null;
scc_lexer_tok_drop(&ident);
expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null);
scc_ast_expr_identifier_init(expr, scc_cstring_as_cstr(&tok.lexeme));
return expr;
}
case SCC_TOK_INT_LITERAL: {
scc_lexer_tok_t lit;
if (!scc_parser_next_consume(parser, &lit))
if (!scc_parser_next_consume(parser, &tok))
return null;
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_INT_LITERAL);
expr->literal.lexme = scc_cstring_as_cstr(&lit.lexeme);
lit.lexeme.data = null; // 转移所有权
scc_lexer_tok_drop(&lit);
expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null);
scc_ast_expr_literal_int_init(expr, scc_cstring_as_cstr(&tok.lexeme),
false);
return expr;
}
case SCC_TOK_FLOAT_LITERAL: {
scc_lexer_tok_t lit;
if (!scc_parser_next_consume(parser, &lit))
if (!scc_parser_next_consume(parser, &tok))
return null;
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_FLOAT_LITERAL);
expr->literal.lexme = scc_cstring_as_cstr(&lit.lexeme);
lit.lexeme.data = null;
scc_lexer_tok_drop(&lit);
expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null);
scc_ast_expr_literal_float_init(expr, scc_cstring_as_cstr(&tok.lexeme),
false);
return expr;
}
case SCC_TOK_CHAR_LITERAL: {
scc_lexer_tok_t lit;
if (!scc_parser_next_consume(parser, &lit))
if (!scc_parser_next_consume(parser, &tok))
return null;
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_CHAR_LITERAL);
expr->literal.lexme = scc_cstring_as_cstr(&lit.lexeme);
lit.lexeme.data = null;
scc_lexer_tok_drop(&lit);
expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null);
scc_ast_expr_literal_char_init(expr, scc_cstring_as_cstr(&tok.lexeme),
false);
return expr;
}
case SCC_TOK_STRING_LITERAL: {
scc_lexer_tok_t lit;
if (!scc_parser_next_consume(parser, &lit))
if (!scc_parser_next_consume(parser, &tok))
return null;
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_STRING_LITERAL);
expr->literal.lexme = scc_cstring_as_cstr(&lit.lexeme);
lit.lexeme.data = null;
scc_lexer_tok_drop(&lit);
expr = scc_malloc(sizeof(scc_ast_expr_t));
Assert(expr != null);
scc_ast_expr_literal_string_init(expr, scc_cstring_as_cstr(&tok.lexeme),
false);
return expr;
}
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) {
// 保存位置以便回退
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);
return null;
}
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_CAST);
expr->cast.type = type;
expr->cast.expr = 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
@@ -915,11 +857,15 @@ scc_ast_expr_t *scc_parse_expression(scc_parser_t *parser) {
parser_sync(parser);
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;
}
scc_ast_expr_t *scc_parser_constant_expression(scc_parser_t *parser) {
// TODO check constant
return parse_conditional_expression(parser);
}