Files
scc/libs/parser/src/parse_expr.c
zzy 1fceeca011 feat(parser): 启用parser和ast模块并重构解析器结构
- 在cbuild.toml中启用parser和ast依赖项
- 将AST内置类型枚举重命名为SCC_AST_BUILTIN_TYPE_*前缀格式
- 修复ast_def.h中的类型字段命名,将builtin改为type
- 添加逗号操作符支持到表达式操作符枚举中
- 更新字面量表达式的lexeme字段为const char*指针和owned标志
- 重构解析器头文件结构,分离为parser.h、parser_utils.h、scc_sema.h等
- 实现新的解析器工具函数,包括预览、消费、回溯等功能
- 更新声明解析逻辑,使用新的解析器接口进行token处理
- 添加符号表语义分析功能框架
- 修复词法分析器中token移动时的空指针检查
- 统一使用scc_tree_dump_printf替代直接的scc_printf调用
2026-03-09 15:25:12 +08:00

980 lines
33 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
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 <parser_utils.h>
#include <scc_parser.h>
/**
* @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 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_assignment_expression(scc_parser_t *parser); // 右结合
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;
while ((tok = scc_parser_peek(parser)) != null) {
scc_tok_type_t type = tok->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 *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 等)
/* ---------------------------- 通用二元解析器 ---------------------------- */
/**
* 解析左结合的二元表达式
* @param parser 解析器
* @param parse_sub 解析下一级(优先级更低)的函数
* @param this_prec 当前层的优先级
* @return 表达式节点
*/
static scc_ast_expr_t *parse_binary_expression(scc_parser_t *parser,
parse_sub_expr_func parse_sub,
int this_prec) {
scc_ast_expr_t *left = parse_sub(parser);
if (!left) {
// 左侧解析失败,尝试同步后返回 null
parser_sync(parser);
return null;
}
while (1) {
const scc_lexer_tok_t *tok = scc_parser_peek(parser);
if (!tok)
break;
int prec = get_token_precedence(tok->type);
if (prec < this_prec)
break;
// 必须是二元运算符(但赋值和条件除外,它们已在高层处理,这里不会出现)
if (!is_binary_operator(tok->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);
// 解析右侧(注意左结合:传入
// this_prec+1确保优先级相同的不再结合避免右结合
scc_ast_expr_t *right =
parse_binary_expression(parser, parse_sub, this_prec + 1);
if (!right) {
// 右侧解析失败,尝试恢复
parser_sync(parser);
// 释放已构建的 left这里 left 可能已被使用,简单的做法是向上返回
// null
return null;
}
left = create_binary_expr(parser, left, right, op);
if (!left)
return null;
}
return left;
}
static scc_ast_expr_t *parse_multiplicative_expression(scc_parser_t *parser) {
return parse_binary_expression(parser, parse_cast_expression,
PREC_MULTIPLICATIVE);
}
static scc_ast_expr_t *parse_additive_expression(scc_parser_t *parser) {
return parse_binary_expression(parser, parse_multiplicative_expression,
PREC_ADDITIVE);
}
static scc_ast_expr_t *parse_shift_expression(scc_parser_t *parser) {
return parse_binary_expression(parser, parse_additive_expression,
PREC_SHIFT);
}
static scc_ast_expr_t *parse_relational_expression(scc_parser_t *parser) {
return parse_binary_expression(parser, parse_shift_expression,
PREC_RELATIONAL);
}
static scc_ast_expr_t *parse_equality_expression(scc_parser_t *parser) {
return parse_binary_expression(parser, parse_relational_expression,
PREC_EQUALITY);
}
static scc_ast_expr_t *parse_bitwise_and_expression(scc_parser_t *parser) {
return parse_binary_expression(parser, parse_equality_expression,
PREC_BITWISE_AND);
}
static scc_ast_expr_t *parse_bitwise_xor_expression(scc_parser_t *parser) {
return parse_binary_expression(parser, parse_bitwise_and_expression,
PREC_BITWISE_XOR);
}
static scc_ast_expr_t *parse_bitwise_or_expression(scc_parser_t *parser) {
return parse_binary_expression(parser, parse_bitwise_xor_expression,
PREC_BITWISE_OR);
}
static scc_ast_expr_t *parse_logical_and_expression(scc_parser_t *parser) {
return parse_binary_expression(parser, parse_bitwise_or_expression,
PREC_LOGICAL_AND);
}
static scc_ast_expr_t *parse_logical_or_expression(scc_parser_t *parser) {
return parse_binary_expression(parser, parse_logical_and_expression,
PREC_LOGICAL_OR);
}
// 赋值表达式(右结合)
static scc_ast_expr_t *parse_assignment_expression(scc_parser_t *parser) {
// 先解析左侧的 unary-expressionC 标准规定赋值左边必须是
// unary-expression
scc_ast_expr_t *left = null;
left = parse_conditional_expression(parser);
if (left)
return left;
left = parse_unary_expression(parser);
if (!left)
return null;
const scc_lexer_tok_t *tok = scc_parser_peek(parser);
if (!tok)
return left;
int prec = get_token_precedence(tok->type);
if (prec == PREC_ASSIGNMENT && is_binary_operator(tok->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 = parse_assignment_expression(parser);
if (!right) {
// 错误恢复
parser_sync(parser);
return null;
}
left = create_binary_expr(parser, left, right, op);
}
return left;
}
// 条件表达式(右结合)
static scc_ast_expr_t *parse_conditional_expression(scc_parser_t *parser) {
scc_ast_expr_t *cond = parse_logical_or_expression(parser);
if (!cond)
return null;
const scc_lexer_tok_t *tok = scc_parser_peek(parser);
if (tok && tok->type == SCC_TOK_COND) {
// 消耗 '?'
scc_lexer_tok_t q_tok;
if (!scc_parser_next_consume(parser, &q_tok))
return cond;
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)) {
LOG_ERROR("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;
}
cond = create_conditional_expr(parser, cond, then_expr, else_expr);
}
return cond;
}
// 类型转换表达式 (type-name) cast-expression
static scc_ast_expr_t *parse_cast_expression(scc_parser_t *parser) {
const scc_lexer_tok_t *tok = scc_parser_peek(parser);
if (tok && tok->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)) {
// 是类型转换,解析后面的 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 = expr_create(parser, SCC_AST_EXPR_CAST);
expr->cast.type = type;
expr->cast.expr = operand;
return expr;
} else {
// 不是类型转换,回退
scc_parser_restore(parser);
// 释放 type假设 scc_parse_type_name 分配了)
// TODO: scc_ast_type_drop(type);
}
} 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 = scc_parser_peek(parser);
if (!tok)
return null;
// 处理一元运算符
switch (tok->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;
}
return create_unary_expr(parser, op, operand);
}
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;
if (!scc_parser_next_consume(parser, &tok) || tok.type != SCC_TOK_SIZEOF) {
return null;
}
scc_lexer_tok_drop(&tok);
const scc_lexer_tok_t *next = scc_parser_peek(parser);
if (!next) {
LOG_ERROR("Unexpected end after sizeof");
return null;
}
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_SIZE_OF);
// 尝试解析 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)) {
expr->attr_of.type = type;
return expr;
} else {
// 不是有效的 sizeof(type-name),回退
scc_parser_restore(parser);
// 释放 type
// TODO: scc_ast_type_drop(type);
}
} else {
scc_parser_restore(parser);
}
}
// 否则作为 sizeof unary-expression
scc_ast_expr_t *operand = parse_unary_expression(parser);
if (!operand) {
scc_free(expr);
parser_sync(parser);
return null;
}
expr->attr_of.expr = operand;
return expr;
}
// 后缀表达式
static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
scc_ast_expr_t *left = parse_primary_expression(parser);
if (!left)
return null;
while (1) {
const scc_lexer_tok_t *tok = scc_parser_peek(parser);
if (!tok)
break;
switch (tok->type) {
case SCC_TOK_L_BRACKET: // left[expr]
{
scc_lexer_tok_t lb;
if (!scc_parser_next_consume(parser, &lb))
return left;
scc_lexer_tok_drop(&lb);
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)) {
LOG_ERROR("Expected ']' after subscript");
parser_sync(parser);
return null;
}
scc_ast_expr_t *subscript =
expr_create(parser, SCC_AST_EXPR_ARRAY_SUBSCRIPT);
subscript->subscript.array = left;
subscript->subscript.index = index;
left = subscript;
break;
}
case SCC_TOK_L_PAREN: // left(args)
{
scc_lexer_tok_t lp;
if (!scc_parser_next_consume(parser, &lp))
return left;
scc_lexer_tok_drop(&lp);
scc_ast_expr_t *call = expr_create(parser, SCC_AST_EXPR_CALL);
call->call.callee = left;
scc_vec_init(call->call.args);
// 解析参数列表
if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
while (1) {
scc_ast_expr_t *arg = parse_assignment_expression(parser);
if (!arg) {
parser_sync(parser);
// 释放已解析的参数
// TODO: 释放 call->call.args 中的表达式
scc_free(call);
return null;
}
scc_vec_push(call->call.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 {
LOG_ERROR("Expected ',' or ')' in function call");
parser_sync(parser);
// 释放资源
scc_free(call);
return null;
}
}
}
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) {
LOG_ERROR("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_lexer_tok_drop(&ident_tok);
scc_ast_expr_t *member = expr_create(
parser, op_tok.type == SCC_TOK_DOT ? SCC_AST_EXPR_MEMBER
: SCC_AST_EXPR_PTR_MEMBER);
if (op_tok.type == SCC_TOK_DOT) {
member->member.base = left;
member->member.member_name = name;
} else {
member->ptr_member.base = left;
member->ptr_member.member_name = 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);
left = create_unary_expr(parser, op, left);
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 = scc_parser_peek(parser);
if (!tok)
return null;
switch (tok->type) {
case SCC_TOK_IDENT: {
scc_lexer_tok_t ident;
if (!scc_parser_next_consume(parser, &ident))
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);
return expr;
}
case SCC_TOK_INT_LITERAL: {
scc_lexer_tok_t lit;
if (!scc_parser_next_consume(parser, &lit))
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);
return expr;
}
case SCC_TOK_FLOAT_LITERAL: {
scc_lexer_tok_t lit;
if (!scc_parser_next_consume(parser, &lit))
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);
return expr;
}
case SCC_TOK_CHAR_LITERAL: {
scc_lexer_tok_t lit;
if (!scc_parser_next_consume(parser, &lit))
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);
return expr;
}
case SCC_TOK_STRING_LITERAL: {
scc_lexer_tok_t lit;
if (!scc_parser_next_consume(parser, &lit))
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);
return expr;
}
case SCC_TOK_L_PAREN:
return parse_paren_expression(parser);
default:
LOG_ERROR("Unexpected token in primary expression: %s",
scc_get_tok_name(tok->type));
parser_sync(parser);
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 = expr_create(parser, SCC_AST_EXPR_CAST);
expr->cast.type = type;
expr->cast.expr = 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)) {
LOG_ERROR("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 = parse_assignment_expression(parser);
if (!left)
return null;
while (scc_parser_consume_if(parser, SCC_TOK_COMMA)) {
scc_ast_expr_t *right = parse_assignment_expression(parser);
if (!right) {
parser_sync(parser);
return null;
}
left = create_binary_expr(parser, left, right, SCC_AST_OP_COMMA);
}
return left;
}