Files
scc/libs/parser/src/parse_expr.c
zzy 2d1032c363 feat(ast): 添加LVALUE表达式类型支持并重构表达式创建逻辑
- 新增SCC_AST_EXPR_LVALUE表达式类型用于表示右值
- 重构表达式创建逻辑,移除旧的通用创建函数expr_create
- 使用新的初始化函数替代原有的表达式创建方式
- 更新AST转储功能以支持LVALUE表达式的输出
- 修改sizeof表达式解析逻辑,修复类型转换处理
- 优化各种表达式类型的解析和初始化过程
2026-03-12 21:58:00 +08:00

872 lines
28 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 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-expressionC 标准规定赋值左边必须是
// 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);
}