- 新增SCC_AST_EXPR_LVALUE表达式类型用于表示右值 - 重构表达式创建逻辑,移除旧的通用创建函数expr_create - 使用新的初始化函数替代原有的表达式创建方式 - 更新AST转储功能以支持LVALUE表达式的输出 - 修改sizeof表达式解析逻辑,修复类型转换处理 - 优化各种表达式类型的解析和初始化过程
872 lines
28 KiB
C
872 lines
28 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 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);
|
||
}
|