/* A.2.1 Expressions (6.5.1) primary-expression: identifier constant string-literal ( expression ) (6.5.2) postfix-expression: primary-expression postfix-expression [ expression ] postfix-expression ( argument-expression-list(opt) ) postfix-expression . identifier postfix-expression -> identifier postfix-expression ++ postfix-expression -- ( type-name ) { initializer-list } ( type-name ) { initializer-list , } (6.5.2) argument-expression-list: assignment-expression argument-expression-list , assignment-expression (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 & * + - ~ ! (6.5.4) cast-expression: unary-expression ( type-name ) cast-expression (6.5.5) multiplicative-expression: cast-expression multiplicative-expression * cast-expression multiplicative-expression / cast-expression multiplicative-expression % cast-expression (6.5.6) additive-expression: multiplicative-expression additive-expression + multiplicative-expression additive-expression - multiplicative-expression (6.5.7) shift-expression: additive-expression shift-expression << additive-expression shift-expression >> additive-expression (6.5.8) relational-expression: shift-expression relational-expression < shift-expression relational-expression > shift-expression relational-expression <= shift-expression relational-expression >= shift-expression (6.5.9) equality-expression: relational-expression equality-expression == relational-expression equality-expression != relational-expression (6.5.10) AND-expression: equality-expression AND-expression & equality-expression (6.5.11) exclusive-OR-expression: AND-expression exclusive-OR-expression ^ AND-expression (6.5.12) inclusive-OR-expression: exclusive-OR-expression inclusive-OR-expression | exclusive-OR-expression (6.5.13) logical-AND-expression: inclusive-OR-expression logical-AND-expression && inclusive-OR-expression (6.5.14) logical-OR-expression: logical-AND-expression logical-OR-expression || logical-AND-expression (6.5.15) conditional-expression: logical-OR-expression logical-OR-expression ? expression : conditional-expression (6.5.16) assignment-expression: conditional-expression unary-expression assignment-operator assignment-expression (6.5.16) assignment-operator: one of = *= /= %= += -= <<= >>= &= ^= |= (6.5.17) expression: assignment-expression expression , assignment-expression (6.6) constant-expression: conditional-expression */ #include #include /** * @brief 运算符优先级定义 */ typedef enum { PREC_NONE = 0, // 无优先级 PREC_COMMA = 1, // , PREC_ASSIGNMENT = 2, // = += -= *= /= %= &= ^= |= <<= >>= PREC_CONDITIONAL = 3, // ?: PREC_LOGICAL_OR = 4, // || PREC_LOGICAL_AND = 5, // && PREC_BITWISE_OR = 6, // | PREC_BITWISE_XOR = 7, // ^ PREC_BITWISE_AND = 8, // & PREC_EQUALITY = 9, // == != PREC_RELATIONAL = 10, // < > <= >= PREC_SHIFT = 11, // << >> PREC_ADDITIVE = 12, // + - PREC_MULTIPLICATIVE = 13, // * / % PREC_CAST = 14, // 类型转换 PREC_UNARY = 15, // ++ -- + - * & ~ ! sizeof PREC_POSTFIX = 16, // [] () . -> ++ -- PREC_PRIMARY = 17, // 最高优先级 } scc_precedence_t; /* ---------------------------- 函数前向声明 ---------------------------- */ static scc_ast_expr_t *parse_expression_with_precedence(scc_parser_t *parser, int min_prec); // 特殊结构:独立解析(右结合、条件、一元、后缀、基本) static scc_ast_expr_t * parse_conditional_expression(scc_parser_t *parser); // 右结合 static scc_ast_expr_t *parse_cast_expression(scc_parser_t *parser); // 类型转换 static scc_ast_expr_t * parse_unary_expression(scc_parser_t *parser); // 一元运算符 static scc_ast_expr_t * parse_postfix_expression(scc_parser_t *parser); // 后缀运算符 static scc_ast_expr_t * parse_primary_expression(scc_parser_t *parser); // 基本表达式 // 特殊结构的内部辅助函数 static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *parser); static scc_ast_expr_t * parse_paren_expression(scc_parser_t *parser); // 处理括号的三种情况 /* ---------------------------- 工具函数 ---------------------------- */ // 获取 token 的优先级(用于二元运算符) static int get_token_precedence(scc_tok_type_t type) { switch (type) { case SCC_TOK_COMMA: return PREC_COMMA; // 赋值运算符(右结合,但优先级相同,统一处理) case SCC_TOK_ASSIGN: case SCC_TOK_ASSIGN_ADD: case SCC_TOK_ASSIGN_SUB: case SCC_TOK_ASSIGN_MUL: case SCC_TOK_ASSIGN_DIV: case SCC_TOK_ASSIGN_MOD: case SCC_TOK_ASSIGN_AND: case SCC_TOK_ASSIGN_OR: case SCC_TOK_ASSIGN_XOR: case SCC_TOK_ASSIGN_L_SH: case SCC_TOK_ASSIGN_R_SH: return PREC_ASSIGNMENT; case SCC_TOK_COND: return PREC_CONDITIONAL; case SCC_TOK_OR_OR: return PREC_LOGICAL_OR; case SCC_TOK_AND_AND: return PREC_LOGICAL_AND; case SCC_TOK_OR: return PREC_BITWISE_OR; case SCC_TOK_XOR: return PREC_BITWISE_XOR; case SCC_TOK_AND: return PREC_BITWISE_AND; case SCC_TOK_EQ: case SCC_TOK_NEQ: return PREC_EQUALITY; case SCC_TOK_LT: case SCC_TOK_GT: case SCC_TOK_LE: case SCC_TOK_GE: return PREC_RELATIONAL; case SCC_TOK_L_SH: case SCC_TOK_R_SH: return PREC_SHIFT; case SCC_TOK_ADD: case SCC_TOK_SUB: return PREC_ADDITIVE; case SCC_TOK_MUL: case SCC_TOK_DIV: case SCC_TOK_MOD: return PREC_MULTIPLICATIVE; default: return PREC_NONE; } } // 判断 token 是否为二元运算符 static cbool is_binary_operator(scc_tok_type_t type) { return get_token_precedence(type) > PREC_NONE; } // 将 token 类型映射为二元操作符(用于 AST) static scc_ast_expr_op_t map_token_to_binary_op(scc_tok_type_t type) { switch (type) { case SCC_TOK_ADD: return SCC_AST_OP_ADD; case SCC_TOK_SUB: return SCC_AST_OP_SUB; case SCC_TOK_MUL: return SCC_AST_OP_MUL; case SCC_TOK_DIV: return SCC_AST_OP_DIV; case SCC_TOK_MOD: return SCC_AST_OP_MOD; case SCC_TOK_L_SH: return SCC_AST_OP_LEFT_SHIFT; case SCC_TOK_R_SH: return SCC_AST_OP_RIGHT_SHIFT; case SCC_TOK_LT: return SCC_AST_OP_LESS; case SCC_TOK_GT: return SCC_AST_OP_GREATER; case SCC_TOK_LE: return SCC_AST_OP_LESS_EQUAL; case SCC_TOK_GE: return SCC_AST_OP_GREATER_EQUAL; case SCC_TOK_EQ: return SCC_AST_OP_EQUAL; case SCC_TOK_NEQ: return SCC_AST_OP_NOT_EQUAL; case SCC_TOK_AND: return SCC_AST_OP_BITWISE_AND; case SCC_TOK_XOR: return SCC_AST_OP_BITWISE_XOR; case SCC_TOK_OR: return SCC_AST_OP_BITWISE_OR; case SCC_TOK_AND_AND: return SCC_AST_OP_LOGICAL_AND; case SCC_TOK_OR_OR: return SCC_AST_OP_LOGICAL_OR; case SCC_TOK_COMMA: return SCC_AST_OP_COMMA; default: return SCC_AST_OP_NONE; } } // 将 token 类型映射为一元操作符 static scc_ast_expr_op_t map_token_to_unary_op(scc_tok_type_t type, cbool is_prefix) { if (is_prefix) { switch (type) { case SCC_TOK_ADD: return SCC_AST_OP_UNARY_PLUS; case SCC_TOK_SUB: return SCC_AST_OP_UNARY_MINUS; case SCC_TOK_AND: return SCC_AST_OP_ADDRESS_OF; case SCC_TOK_MUL: return SCC_AST_OP_INDIRECTION; case SCC_TOK_BIT_NOT: return SCC_AST_OP_BITWISE_NOT; case SCC_TOK_NOT: return SCC_AST_OP_LOGICAL_NOT; case SCC_TOK_ADD_ADD: return SCC_AST_OP_PREFIX_INCREMENT; case SCC_TOK_SUB_SUB: return SCC_AST_OP_PREFIX_DECREMENT; default: return SCC_AST_OP_NONE; } } else { switch (type) { case SCC_TOK_ADD_ADD: return SCC_AST_OP_POSTFIX_INCREMENT; case SCC_TOK_SUB_SUB: return SCC_AST_OP_POSTFIX_DECREMENT; default: return SCC_AST_OP_NONE; } } } // 将 token 类型映射为赋值操作符 static scc_ast_expr_op_t map_token_to_assign_op(scc_tok_type_t type) { switch (type) { case SCC_TOK_ASSIGN: return SCC_AST_OP_ASSIGN; case SCC_TOK_ASSIGN_ADD: return SCC_AST_OP_ASSIGN_ADD; case SCC_TOK_ASSIGN_SUB: return SCC_AST_OP_ASSIGN_SUB; case SCC_TOK_ASSIGN_MUL: return SCC_AST_OP_ASSIGN_MUL; case SCC_TOK_ASSIGN_DIV: return SCC_AST_OP_ASSIGN_DIV; case SCC_TOK_ASSIGN_MOD: return SCC_AST_OP_ASSIGN_MOD; case SCC_TOK_ASSIGN_AND: return SCC_AST_OP_ASSIGN_AND; case SCC_TOK_ASSIGN_OR: return SCC_AST_OP_ASSIGN_OR; case SCC_TOK_ASSIGN_XOR: return SCC_AST_OP_ASSIGN_XOR; case SCC_TOK_ASSIGN_L_SH: return SCC_AST_OP_ASSIGN_LSHIFT; case SCC_TOK_ASSIGN_R_SH: return SCC_AST_OP_ASSIGN_RSHIFT; default: return SCC_AST_OP_NONE; } } /* ---------------------------- 错误恢复辅助 ---------------------------- */ // 跳过直到遇到同步 token(分号、右括号、逗号、EOF) static void parser_sync(scc_parser_t *parser) { const scc_lexer_tok_t *tok_ptr; while ((tok_ptr = scc_parser_peek(parser)) != null) { scc_tok_type_t type = tok_ptr->type; if (type == SCC_TOK_SEMICOLON || type == SCC_TOK_R_PAREN || type == SCC_TOK_R_BRACE || type == SCC_TOK_COMMA || type == SCC_TOK_EOF) { break; } // 消耗并丢弃当前 token scc_lexer_tok_t discard; if (scc_parser_next_consume(parser, &discard)) { scc_lexer_tok_drop(&discard); } } } /* ---------------------------- 通用二元解析器 ---------------------------- */ static scc_ast_expr_t *parse_expression_with_precedence(scc_parser_t *parser, int min_prec) { // 从最底层(cast-expression)开始 scc_ast_expr_t *left = parse_cast_expression(parser); if (!left) return null; while (1) { const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); if (!tok_ptr) break; int prec = get_token_precedence(tok_ptr->type); // 只处理优先级 >= min_prec 的普通二元运算符 if (prec < min_prec || !is_binary_operator(tok_ptr->type)) break; // 消费运算符 scc_lexer_tok_t op_tok; if (!scc_parser_next_consume(parser, &op_tok)) break; scc_ast_expr_op_t op = map_token_to_binary_op(op_tok.type); scc_lexer_tok_drop(&op_tok); // 解析右操作数(优先级 +1,确保左结合) scc_ast_expr_t *right = parse_expression_with_precedence(parser, prec + 1); if (!right) { parser_sync(parser); return null; } 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; } // 赋值表达式(右结合) scc_ast_expr_t *scc_parse_assignment_expression(scc_parser_t *parser) { // 先解析左侧的 unary-expression(C 标准规定赋值左边必须是 // unary-expression) scc_ast_expr_t *left = null; left = parse_conditional_expression(parser); if (!left) return null; const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); if (!tok_ptr) return left; int prec = get_token_precedence(tok_ptr->type); if (prec == PREC_ASSIGNMENT && is_binary_operator(tok_ptr->type)) { // 消费赋值运算符 scc_lexer_tok_t op_tok; if (!scc_parser_next_consume(parser, &op_tok)) return left; scc_ast_expr_op_t op = map_token_to_assign_op(op_tok.type); scc_lexer_tok_drop(&op_tok); // 解析右侧(右结合:继续调用 parse_assignment_expression) scc_ast_expr_t *right = scc_parse_assignment_expression(parser); if (!right) { // 错误恢复 parser_sync(parser); return null; } 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_expr = parse_expression_with_precedence(parser, PREC_LOGICAL_OR); if (!cond_expr) return null; const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); if (tok_ptr && tok_ptr->type == SCC_TOK_COND) { // 消耗 '?' scc_lexer_tok_t q_tok; if (!scc_parser_next_consume(parser, &q_tok)) return cond_expr; scc_lexer_tok_drop(&q_tok); // 解析中间表达式(可以是任何表达式,包括逗号) scc_ast_expr_t *then_expr = scc_parse_expression(parser); if (!then_expr) { parser_sync(parser); return null; } // 消耗 ':' if (!scc_parser_consume_if(parser, SCC_TOK_COLON)) { SCC_ERROR(scc_parser_got_current_pos(parser), "Expected ':' after '?'"); parser_sync(parser); return null; } // 解析 else 部分(右结合,再次调用 parse_conditional_expression) scc_ast_expr_t *else_expr = parse_conditional_expression(parser); if (!else_expr) { parser_sync(parser); return null; } 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_expr; } // 类型转换表达式 (type-name) cast-expression static scc_ast_expr_t *parse_cast_expression(scc_parser_t *parser) { const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); scc_ast_type_t *type = null; if (tok_ptr && tok_ptr->type == SCC_TOK_L_PAREN) { // 尝试解析类型名 scc_parser_store(parser); scc_parser_next(parser); type = scc_parse_type_name(parser); // 需要外部实现 if (type) { // 消耗了类型名后,下一个应该是 ')' if (scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) { // 是类型转换,解析后面的 cast-expression(注意 cast-expression // 可以嵌套) scc_ast_expr_t *operand = parse_cast_expression(parser); if (!operand) { // 释放 type // TODO: 需要 scc_ast_type_drop(type); return null; } 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_parse_type_name 分配了) // TODO: scc_ast_type_drop(type); scc_parser_restore(parser); } } else { scc_parser_restore(parser); // 解析类型名失败,回退 } } // 否则作为一元表达式 return parse_unary_expression(parser); } // 一元表达式 static scc_ast_expr_t *parse_unary_expression(scc_parser_t *parser) { const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); if (!tok_ptr) return null; // 处理一元运算符 switch (tok_ptr->type) { case SCC_TOK_ADD_ADD: // ++x case SCC_TOK_SUB_SUB: // --x case SCC_TOK_AND: // &x case SCC_TOK_MUL: // *x case SCC_TOK_ADD: // +x case SCC_TOK_SUB: // -x case SCC_TOK_BIT_NOT: // ~x case SCC_TOK_NOT: // !x { scc_lexer_tok_t op_tok; if (!scc_parser_next_consume(parser, &op_tok)) return null; scc_ast_expr_op_t op = map_token_to_unary_op(op_tok.type, true); scc_lexer_tok_drop(&op_tok); // 一元运算符右结合,递归调用 parse_unary_expression scc_ast_expr_t *operand = parse_unary_expression(parser); if (!operand) { parser_sync(parser); return null; } 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); default: return parse_postfix_expression(parser); } } // sizeof 表达式(特殊处理两种形式) static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *parser) { scc_lexer_tok_t tok_ptr; if (!scc_parser_next_consume(parser, &tok_ptr) || tok_ptr.type != SCC_TOK_SIZEOF) { return null; } scc_lexer_tok_drop(&tok_ptr); const scc_lexer_tok_t *next = scc_parser_peek(parser); if (!next) { SCC_ERROR(scc_parser_got_current_pos(parser), "Unexpected end after sizeof"); return null; } scc_ast_expr_t *expr = null; // 尝试解析 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 { TODO(); } } // 否则作为 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); } return expr; } // 后缀表达式 static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) { scc_ast_expr_t *left = parse_primary_expression(parser); const scc_lexer_tok_t *tok_ptr = null; if (!left) { tok_ptr = scc_parser_peek(parser); if (!(tok_ptr && tok_ptr->type == SCC_TOK_L_PAREN)) { return null; } scc_parser_store(parser); scc_parser_next(parser); scc_ast_type_t *type = scc_parse_type_name(parser); if (!type) { scc_parser_restore(parser); return null; } scc_parser_commit(parser); if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) { SCC_ERROR(scc_parser_got_current_pos(parser), "Expected ')'"); } if (!scc_parser_consume_if(parser, SCC_TOK_L_BRACKET)) { SCC_ERROR(scc_parser_got_current_pos(parser), "Expected '{"); } scc_ast_expr_t *expr = scc_malloc(sizeof(scc_ast_expr_t)); scc_ast_expr_lvalue_init(expr, type); return scc_parse_initializer(parser, expr); } while (1) { tok_ptr = scc_parser_peek(parser); if (!tok_ptr) break; switch (tok_ptr->type) { case SCC_TOK_L_BRACKET: // left[expr] { if (!scc_parser_next_consume(parser, null)) return left; scc_ast_expr_t *index = scc_parse_expression(parser); if (!index) { parser_sync(parser); return null; } if (!scc_parser_consume_if(parser, SCC_TOK_R_BRACKET)) { SCC_ERROR(scc_parser_got_current_pos(parser), "Expected ']' after subscript"); parser_sync(parser); return null; } scc_ast_expr_t *subscript = scc_malloc(sizeof(scc_ast_expr_t)); Assert(subscript != null); scc_ast_expr_array_subscript_init(subscript, left, index); left = subscript; break; } case SCC_TOK_L_PAREN: // left(args) { if (!scc_parser_next_consume(parser, null)) return left; scc_ast_expr_vec_t args; scc_vec_init(args); while (1) { if (scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) break; scc_ast_expr_t *arg = scc_parse_assignment_expression(parser); if (!arg) { parser_sync(parser); break; } scc_vec_push(args, arg); if (scc_parser_consume_if(parser, SCC_TOK_COMMA)) { continue; } else if (scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) break; else { SCC_ERROR(scc_parser_got_current_pos(parser), "Expected ',' or ')' in function call"); // 释放已解析的参数 // TODO: 释放 args 中的表达式 parser_sync(parser); return null; } } scc_ast_expr_t *call = scc_malloc(sizeof(scc_ast_expr_t)); Assert(call != null); scc_ast_expr_call_init(call, left, &args); left = call; break; } case SCC_TOK_DOT: case SCC_TOK_DEREF: { scc_lexer_tok_t op_tok; if (!scc_parser_next_consume(parser, &op_tok)) return left; scc_lexer_tok_t ident_tok; if (!scc_parser_next_consume(parser, &ident_tok) || ident_tok.type != SCC_TOK_IDENT) { SCC_ERROR(scc_parser_got_current_pos(parser), "Expected identifier after member access"); scc_lexer_tok_drop(&op_tok); parser_sync(parser); return null; } const char *name = scc_cstring_as_cstr(&ident_tok.lexeme); scc_ast_expr_t *member = scc_malloc(sizeof(scc_ast_expr_t)); Assert(member != null); if (op_tok.type == SCC_TOK_DOT) { scc_ast_expr_member_init(member, left, name); } else { scc_ast_expr_ptr_member_init(member, left, name); } scc_lexer_tok_drop(&op_tok); left = member; break; } case SCC_TOK_ADD_ADD: // left++ case SCC_TOK_SUB_SUB: // left-- { scc_lexer_tok_t op_tok; if (!scc_parser_next_consume(parser, &op_tok)) return left; scc_ast_expr_op_t op = map_token_to_unary_op(op_tok.type, false); scc_lexer_tok_drop(&op_tok); 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: goto done; } } done: return left; } // 基本表达式 static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) { const scc_lexer_tok_t *tok_ptr = scc_parser_peek(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: { if (!scc_parser_next_consume(parser, &tok)) return null; 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: { if (!scc_parser_next_consume(parser, &tok)) return null; 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: { if (!scc_parser_next_consume(parser, &tok)) return null; 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: { if (!scc_parser_next_consume(parser, &tok)) return null; 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: { if (!scc_parser_next_consume(parser, &tok)) return null; 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: return parse_paren_expression(parser); 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) { // 释放 type // TODO: scc_ast_type_drop(type); return null; } 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) return null; while (scc_parser_consume_if(parser, SCC_TOK_COMMA)) { scc_ast_expr_t *right = scc_parse_assignment_expression(parser); if (!right) { parser_sync(parser); return null; } 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); }