|
|
|
|
@@ -132,39 +132,10 @@ typedef enum {
|
|
|
|
|
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_conditional_expression(scc_parser_t *parser); // 右结合
|
|
|
|
|
@@ -371,45 +342,6 @@ static void parser_sync(scc_parser_t *parser) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 等)
|
|
|
|
|
|
|
|
|
|
/* ---------------------------- 通用二元解析器 ---------------------------- */
|
|
|
|
|
static scc_ast_expr_t *parse_expression_with_precedence(scc_parser_t *parser,
|
|
|
|
|
int min_prec) {
|
|
|
|
|
@@ -442,7 +374,10 @@ static scc_ast_expr_t *parse_expression_with_precedence(scc_parser_t *parser,
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
left = create_binary_expr(parser, left, right, op);
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
@@ -476,16 +411,19 @@ scc_ast_expr_t *scc_parse_assignment_expression(scc_parser_t *parser) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
left = create_binary_expr(parser, left, right, op);
|
|
|
|
|
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 =
|
|
|
|
|
scc_ast_expr_t *cond_expr =
|
|
|
|
|
parse_expression_with_precedence(parser, PREC_LOGICAL_OR);
|
|
|
|
|
if (!cond)
|
|
|
|
|
if (!cond_expr)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
|
|
|
|
|
@@ -493,7 +431,7 @@ static scc_ast_expr_t *parse_conditional_expression(scc_parser_t *parser) {
|
|
|
|
|
// 消耗 '?'
|
|
|
|
|
scc_lexer_tok_t q_tok;
|
|
|
|
|
if (!scc_parser_next_consume(parser, &q_tok))
|
|
|
|
|
return cond;
|
|
|
|
|
return cond_expr;
|
|
|
|
|
scc_lexer_tok_drop(&q_tok);
|
|
|
|
|
|
|
|
|
|
// 解析中间表达式(可以是任何表达式,包括逗号)
|
|
|
|
|
@@ -518,9 +456,12 @@ static scc_ast_expr_t *parse_conditional_expression(scc_parser_t *parser) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cond = create_conditional_expr(parser, cond, then_expr, else_expr);
|
|
|
|
|
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;
|
|
|
|
|
return cond_expr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 类型转换表达式 (type-name) cast-expression
|
|
|
|
|
@@ -543,9 +484,9 @@ static scc_ast_expr_t *parse_cast_expression(scc_parser_t *parser) {
|
|
|
|
|
// 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;
|
|
|
|
|
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 {
|
|
|
|
|
// 不是类型转换,回退
|
|
|
|
|
@@ -591,7 +532,11 @@ static scc_ast_expr_t *parse_unary_expression(scc_parser_t *parser) {
|
|
|
|
|
parser_sync(parser);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
return create_unary_expr(parser, op, operand);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
@@ -616,7 +561,7 @@ static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *parser) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_SIZE_OF);
|
|
|
|
|
scc_ast_expr_t *expr = null;
|
|
|
|
|
|
|
|
|
|
// 尝试解析 sizeof(type-name)
|
|
|
|
|
if (next->type == SCC_TOK_L_PAREN) {
|
|
|
|
|
@@ -624,17 +569,14 @@ static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *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;
|
|
|
|
|
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 {
|
|
|
|
|
// 不是有效的 sizeof(type-name),回退
|
|
|
|
|
scc_parser_restore(parser);
|
|
|
|
|
// 释放 type
|
|
|
|
|
// TODO: scc_ast_type_drop(type);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
scc_parser_restore(parser);
|
|
|
|
|
TODO();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -644,8 +586,9 @@ static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *parser) {
|
|
|
|
|
scc_free(expr);
|
|
|
|
|
parser_sync(parser);
|
|
|
|
|
return null;
|
|
|
|
|
} else {
|
|
|
|
|
scc_ast_expr_sizeof_init(operand, null);
|
|
|
|
|
}
|
|
|
|
|
expr->attr_of.expr = operand;
|
|
|
|
|
return expr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -777,7 +720,10 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
|
|
|
|
|
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);
|
|
|
|
|
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:
|
|
|
|
|
@@ -794,55 +740,51 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *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: {
|
|
|
|
|
scc_lexer_tok_t ident;
|
|
|
|
|
if (!scc_parser_next_consume(parser, &ident))
|
|
|
|
|
if (!scc_parser_next_consume(parser, &tok))
|
|
|
|
|
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);
|
|
|
|
|
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: {
|
|
|
|
|
scc_lexer_tok_t lit;
|
|
|
|
|
if (!scc_parser_next_consume(parser, &lit))
|
|
|
|
|
if (!scc_parser_next_consume(parser, &tok))
|
|
|
|
|
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);
|
|
|
|
|
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: {
|
|
|
|
|
scc_lexer_tok_t lit;
|
|
|
|
|
if (!scc_parser_next_consume(parser, &lit))
|
|
|
|
|
if (!scc_parser_next_consume(parser, &tok))
|
|
|
|
|
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);
|
|
|
|
|
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: {
|
|
|
|
|
scc_lexer_tok_t lit;
|
|
|
|
|
if (!scc_parser_next_consume(parser, &lit))
|
|
|
|
|
if (!scc_parser_next_consume(parser, &tok))
|
|
|
|
|
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);
|
|
|
|
|
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: {
|
|
|
|
|
scc_lexer_tok_t lit;
|
|
|
|
|
if (!scc_parser_next_consume(parser, &lit))
|
|
|
|
|
if (!scc_parser_next_consume(parser, &tok))
|
|
|
|
|
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);
|
|
|
|
|
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:
|
|
|
|
|
@@ -852,7 +794,7 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理括号表达式、类型转换、复合字面量(目前只实现括号表达式和类型转换)
|
|
|
|
|
// 处理括号表达式、类型转换、复合字面量
|
|
|
|
|
static scc_ast_expr_t *parse_paren_expression(scc_parser_t *parser) {
|
|
|
|
|
// 保存位置以便回退
|
|
|
|
|
scc_parser_store(parser);
|
|
|
|
|
@@ -869,9 +811,9 @@ static scc_ast_expr_t *parse_paren_expression(scc_parser_t *parser) {
|
|
|
|
|
// 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;
|
|
|
|
|
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
|
|
|
|
|
@@ -915,11 +857,15 @@ scc_ast_expr_t *scc_parse_expression(scc_parser_t *parser) {
|
|
|
|
|
parser_sync(parser);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
left = create_binary_expr(parser, left, right, SCC_AST_OP_COMMA);
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|