- 在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调用
980 lines
33 KiB
C
980 lines
33 KiB
C
/*
|
||
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-expression(C 标准规定赋值左边必须是
|
||
// 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;
|
||
}
|