feat(ast): 添加AST定义和dump工具头文件
新增libs/ast模块的基础定义文件,包括: - AST节点类型枚举定义,涵盖声明、语句、表达式、类型等各类节点 - AST操作符枚举,定义所有二元、一元、逻辑、算术等操作符 - AST节点结构体定义,包含表达式、语句、声明、类型等具体实现 - AST dump工具接口,支持树形结构输出和颜色显示 - 语义分析回调函数类型定义,为后续语义分析提供基础
This commit is contained in:
918
libs/parser/src/parse_expr.c
Normal file
918
libs/parser/src/parse_expr.c
Normal file
@@ -0,0 +1,918 @@
|
||||
/**
|
||||
* @file parse_expr.c
|
||||
* @author your name (you@domain.com)
|
||||
* @brief Pratt Parser表达式解析器
|
||||
* @version 0.1
|
||||
* @date 2026-01-09
|
||||
*
|
||||
* @copyright Copyright (c) 2026
|
||||
*
|
||||
*/
|
||||
#include <parser.h>
|
||||
|
||||
/*
|
||||
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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief 从token映射到AST操作符
|
||||
* @param tok_type 词法token类型
|
||||
* @param is_unary 是否为一元操作符上下文
|
||||
* @return AST操作符类型
|
||||
*/
|
||||
static scc_ast_expr_op_t scc_ast_token_to_operator(scc_tok_type_t tok_type,
|
||||
cbool is_unary) {
|
||||
switch (tok_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_XOR:
|
||||
return SCC_AST_OP_ASSIGN_XOR;
|
||||
case SCC_TOK_ASSIGN_OR:
|
||||
return SCC_AST_OP_ASSIGN_OR;
|
||||
case SCC_TOK_ASSIGN_L_SH:
|
||||
return SCC_AST_OP_ASSIGN_LSHIFT;
|
||||
case SCC_TOK_ASSIGN_R_SH:
|
||||
return SCC_AST_OP_ASSIGN_RSHIFT;
|
||||
|
||||
/* 逻辑操作符 */
|
||||
case SCC_TOK_OR_OR:
|
||||
return SCC_AST_OP_LOGICAL_OR;
|
||||
case SCC_TOK_AND_AND:
|
||||
return SCC_AST_OP_LOGICAL_AND;
|
||||
|
||||
/* 位操作符 */
|
||||
case SCC_TOK_OR:
|
||||
return SCC_AST_OP_BITWISE_OR;
|
||||
case SCC_TOK_XOR:
|
||||
return SCC_AST_OP_BITWISE_XOR;
|
||||
case SCC_TOK_AND:
|
||||
return is_unary ? SCC_AST_OP_ADDRESS_OF : SCC_AST_OP_BITWISE_AND;
|
||||
|
||||
/* 相等性操作符 */
|
||||
case SCC_TOK_EQ:
|
||||
return SCC_AST_OP_EQUAL;
|
||||
case SCC_TOK_NEQ:
|
||||
return SCC_AST_OP_NOT_EQUAL;
|
||||
|
||||
/* 关系操作符 */
|
||||
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_L_SH:
|
||||
return SCC_AST_OP_LEFT_SHIFT;
|
||||
case SCC_TOK_R_SH:
|
||||
return SCC_AST_OP_RIGHT_SHIFT;
|
||||
|
||||
/* 算术操作符 */
|
||||
case SCC_TOK_ADD:
|
||||
return is_unary ? SCC_AST_OP_UNARY_PLUS : SCC_AST_OP_ADD;
|
||||
case SCC_TOK_SUB:
|
||||
return is_unary ? SCC_AST_OP_UNARY_MINUS : SCC_AST_OP_SUB;
|
||||
case SCC_TOK_MUL:
|
||||
return is_unary ? SCC_AST_OP_INDIRECTION : 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_NOT:
|
||||
return SCC_AST_OP_LOGICAL_NOT;
|
||||
case SCC_TOK_BIT_NOT:
|
||||
return SCC_AST_OP_BITWISE_NOT;
|
||||
case SCC_TOK_ADD_ADD:
|
||||
return is_unary ? SCC_AST_OP_PREFIX_INCREMENT
|
||||
: SCC_AST_OP_POSTFIX_INCREMENT;
|
||||
case SCC_TOK_SUB_SUB:
|
||||
return is_unary ? SCC_AST_OP_PREFIX_DECREMENT
|
||||
: SCC_AST_OP_POSTFIX_DECREMENT;
|
||||
|
||||
default:
|
||||
return SCC_AST_OP_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* @brief 获取二元运算符优先级
|
||||
*/
|
||||
static scc_precedence_t get_binary_precedence(scc_tok_type_t op) {
|
||||
switch (op) {
|
||||
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_XOR:
|
||||
case SCC_TOK_ASSIGN_OR:
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 检查是否是赋值运算符
|
||||
*/
|
||||
static cbool is_assignment_operator(scc_tok_type_t op) {
|
||||
switch (op) {
|
||||
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_XOR:
|
||||
case SCC_TOK_ASSIGN_OR:
|
||||
case SCC_TOK_ASSIGN_L_SH:
|
||||
case SCC_TOK_ASSIGN_R_SH:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 检查是否是二元运算符
|
||||
*/
|
||||
static cbool is_binary_operator(scc_tok_type_t op) {
|
||||
return get_binary_precedence(op) != PREC_NONE;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 解析基本表达式
|
||||
*
|
||||
* (6.5.1) primary-expression:
|
||||
* identifier
|
||||
* constant
|
||||
* string-literal
|
||||
* ( expression )
|
||||
*/
|
||||
static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
|
||||
const scc_lexer_tok_t *tok = scc_lexer_stream_current(parser->lex_stream);
|
||||
|
||||
switch (tok->type) {
|
||||
case SCC_TOK_IDENT: {
|
||||
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_IDENTIFIER);
|
||||
if (!expr)
|
||||
return null;
|
||||
expr->identifier.name = tok->value.cstr.data;
|
||||
scc_lexer_stream_consume(parser->lex_stream);
|
||||
|
||||
// 调用语义回调
|
||||
if (parser->sema_callbacks.on_expr) {
|
||||
parser->sema_callbacks.on_expr(parser->sema_callbacks.context,
|
||||
expr->base.type, expr);
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
case SCC_TOK_INT_LITERAL:
|
||||
case SCC_TOK_FLOAT_LITERAL:
|
||||
case SCC_TOK_CHAR_LITERAL: {
|
||||
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_INT_LITERAL);
|
||||
if (!expr)
|
||||
return null;
|
||||
expr->literal.value = tok->value;
|
||||
scc_lexer_stream_consume(parser->lex_stream);
|
||||
|
||||
if (parser->sema_callbacks.on_expr) {
|
||||
parser->sema_callbacks.on_expr(parser->sema_callbacks.context,
|
||||
expr->base.type, expr);
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
case SCC_TOK_STRING_LITERAL: {
|
||||
scc_ast_expr_t *expr = expr_create(parser, SCC_AST_EXPR_STRING_LITERAL);
|
||||
if (!expr)
|
||||
return null;
|
||||
expr->literal.value = tok->value;
|
||||
scc_lexer_stream_consume(parser->lex_stream);
|
||||
|
||||
if (parser->sema_callbacks.on_expr) {
|
||||
parser->sema_callbacks.on_expr(parser->sema_callbacks.context,
|
||||
expr->base.type, expr);
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
case SCC_TOK_L_PAREN: {
|
||||
TODO();
|
||||
// // 保存当前位置,用于区分类型转换和括号表达式
|
||||
// usize save_pos = parser->lex_stream->curr_pos;
|
||||
|
||||
// // 跳过 '('
|
||||
// scc_lexer_stream_consume(parser->lex_stream);
|
||||
|
||||
// // 尝试解析类型转换
|
||||
// if (parser_is_type_start(parser)) {
|
||||
// scc_ast_type_t *type = scc_parse_type_name(parser);
|
||||
// if (type && parser_consume_if(parser, SCC_TOK_R_PAREN)) {
|
||||
// // 成功解析类型转换
|
||||
// scc_ast_expr_t *cast = expr_create(parser,
|
||||
// SCC_AST_EXPR_CAST); if (!cast) {
|
||||
// scc_free(type);
|
||||
// return null;
|
||||
// }
|
||||
// cast->cast.type = type;
|
||||
// cast->cast.expr = scc_parse_expression(parser, 0); //
|
||||
// 递归解析
|
||||
|
||||
// if (parser->sema_callbacks.on_expr) {
|
||||
// parser->sema_callbacks.on_expr(
|
||||
// parser->sema_callbacks.context, cast->node_type,
|
||||
// cast);
|
||||
// }
|
||||
// return cast;
|
||||
// }
|
||||
// // 解析失败,清理
|
||||
// if (type)
|
||||
// scc_free(type);
|
||||
// }
|
||||
|
||||
// // 不是类型转换,恢复为括号表达式
|
||||
// parser->lex_stream->curr_pos = save_pos;
|
||||
// scc_lexer_stream_consume(parser->lex_stream); // 跳过 '('
|
||||
|
||||
// scc_ast_expr_t *expr = scc_parse_expression(parser, 0);
|
||||
// if (!expr) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// if (!parser_consume_if(parser, SCC_TOK_R_PAREN)) {
|
||||
// PARSER_ERROR(parser, "expected ')' after expression");
|
||||
// scc_free(expr);
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// 括号表达式不需要特殊节点,直接返回内部表达式
|
||||
// return expr;
|
||||
}
|
||||
|
||||
default:
|
||||
LOG_ERROR("expected primary expression, got %s",
|
||||
scc_get_tok_name(tok->type));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 解析后缀表达式
|
||||
*
|
||||
* (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 , }
|
||||
*/
|
||||
static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser,
|
||||
scc_ast_expr_t *lhs) {
|
||||
scc_ast_expr_t *expr = lhs;
|
||||
|
||||
while (true) {
|
||||
const scc_lexer_tok_t *tok =
|
||||
scc_lexer_stream_current(parser->lex_stream);
|
||||
|
||||
switch (tok->type) {
|
||||
case SCC_TOK_L_BRACKET: { // 数组下标
|
||||
scc_lexer_stream_consume(parser->lex_stream); // 跳过 '['
|
||||
|
||||
scc_ast_expr_t *subscript =
|
||||
expr_create(parser, SCC_AST_EXPR_ARRAY_SUBSCRIPT);
|
||||
if (!subscript) {
|
||||
scc_free(expr);
|
||||
return null;
|
||||
}
|
||||
|
||||
subscript->subscript.array = expr;
|
||||
subscript->subscript.index = scc_parse_expression(parser);
|
||||
|
||||
if (!subscript->subscript.index) {
|
||||
scc_free(subscript);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_R_BRACKET)) {
|
||||
LOG_ERROR("expected ']' after array index");
|
||||
scc_free(subscript);
|
||||
return null;
|
||||
}
|
||||
|
||||
expr = subscript;
|
||||
break;
|
||||
}
|
||||
|
||||
case SCC_TOK_L_PAREN: { // 函数调用
|
||||
scc_lexer_stream_consume(parser->lex_stream); // 跳过 '('
|
||||
|
||||
scc_ast_expr_t *call = expr_create(parser, SCC_AST_EXPR_CALL);
|
||||
if (!call) {
|
||||
scc_free(expr);
|
||||
return null;
|
||||
}
|
||||
|
||||
call->call.callee = expr;
|
||||
scc_vec_init(call->call.args);
|
||||
|
||||
// 解析参数列表
|
||||
if (!scc_parse_is(parser->lex_stream, SCC_TOK_R_PAREN)) {
|
||||
do {
|
||||
scc_ast_expr_t *arg = scc_parse_expression(parser);
|
||||
if (!arg) {
|
||||
// 清理已解析的参数
|
||||
scc_vec_foreach(call->call.args, i) {
|
||||
scc_free(scc_vec_at(call->call.args, i));
|
||||
}
|
||||
scc_vec_free(call->call.args);
|
||||
scc_free(call);
|
||||
return null;
|
||||
}
|
||||
scc_vec_push(call->call.args, arg);
|
||||
|
||||
if (!scc_parse_consume_if(parser->lex_stream,
|
||||
SCC_TOK_COMMA)) {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_R_PAREN)) {
|
||||
LOG_ERROR("expected ')' after argument list");
|
||||
// 清理
|
||||
scc_vec_foreach(call->call.args, i) {
|
||||
scc_free(scc_vec_at(call->call.args, i));
|
||||
}
|
||||
scc_vec_free(call->call.args);
|
||||
scc_free(call);
|
||||
return null;
|
||||
}
|
||||
|
||||
expr = call;
|
||||
break;
|
||||
}
|
||||
|
||||
case SCC_TOK_DOT: { // 成员访问
|
||||
scc_lexer_stream_consume(parser->lex_stream); // 跳过 '.'
|
||||
|
||||
scc_ast_expr_t *member = expr_create(parser, SCC_AST_EXPR_MEMBER);
|
||||
if (!member) {
|
||||
scc_free(expr);
|
||||
return null;
|
||||
}
|
||||
|
||||
member->member.base = expr;
|
||||
|
||||
if (!scc_parse_is(parser->lex_stream, SCC_TOK_IDENT)) {
|
||||
LOG_ERROR("expected identifier after '.'");
|
||||
scc_free(member);
|
||||
return null;
|
||||
}
|
||||
|
||||
member->member.member_name = tok->value.cstr.data;
|
||||
scc_lexer_stream_consume(parser->lex_stream); // 跳过标识符
|
||||
|
||||
expr = member;
|
||||
break;
|
||||
}
|
||||
|
||||
case SCC_TOK_DEREF: { // 指针成员访问 ->
|
||||
scc_lexer_stream_consume(parser->lex_stream); // 跳过 '->'
|
||||
|
||||
scc_ast_expr_t *ptr_member =
|
||||
expr_create(parser, SCC_AST_EXPR_PTR_MEMBER);
|
||||
if (!ptr_member) {
|
||||
scc_free(expr);
|
||||
return null;
|
||||
}
|
||||
|
||||
ptr_member->ptr_member.base = expr;
|
||||
|
||||
if (!scc_parse_is(parser->lex_stream, SCC_TOK_IDENT)) {
|
||||
LOG_ERROR("expected identifier after '->'");
|
||||
scc_free(ptr_member);
|
||||
return null;
|
||||
}
|
||||
|
||||
ptr_member->ptr_member.member_name = tok->value.cstr.data;
|
||||
scc_lexer_stream_consume(parser->lex_stream); // 跳过标识符
|
||||
|
||||
expr = ptr_member;
|
||||
break;
|
||||
}
|
||||
|
||||
case SCC_TOK_ADD_ADD: // 后缀++
|
||||
case SCC_TOK_SUB_SUB: { // 后缀--
|
||||
// 跳过操作符
|
||||
scc_lexer_stream_consume(parser->lex_stream);
|
||||
|
||||
scc_ast_expr_t *unary = expr_create(parser, SCC_AST_EXPR_UNARY);
|
||||
if (!unary) {
|
||||
scc_free(expr);
|
||||
return null;
|
||||
}
|
||||
|
||||
unary->unary.op = scc_ast_token_to_operator(tok->type, false);
|
||||
unary->unary.operand = expr;
|
||||
|
||||
expr = unary;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// 不是后缀操作符,返回当前表达式
|
||||
return expr;
|
||||
}
|
||||
|
||||
// 调用语义回调
|
||||
// if (parser->sema_callbacks.on_expr) {
|
||||
// parser->sema_callbacks.on_expr(parser->sema_callbacks.context,
|
||||
// expr->base.type, expr);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 解析一元表达式
|
||||
*
|
||||
* (6.5.3) unary-expression:
|
||||
* postfix-expression
|
||||
* ++ unary-expression
|
||||
* -- unary-expression
|
||||
* unary-operator cast-expression
|
||||
* sizeof unary-expression
|
||||
* sizeof ( type-name )
|
||||
*/
|
||||
static scc_ast_expr_t *parse_unary_expression(scc_parser_t *parser) {
|
||||
const scc_lexer_tok_t *tok = scc_lexer_stream_current(parser->lex_stream);
|
||||
|
||||
switch (tok->type) {
|
||||
case SCC_TOK_ADD_ADD: // 前缀++
|
||||
case SCC_TOK_SUB_SUB: { // 前缀--
|
||||
scc_lexer_stream_consume(parser->lex_stream); // 跳过操作符
|
||||
|
||||
scc_ast_expr_t *unary = expr_create(parser, SCC_AST_EXPR_UNARY);
|
||||
if (!unary)
|
||||
return null;
|
||||
|
||||
unary->unary.op = scc_ast_token_to_operator(tok->type, true);
|
||||
unary->unary.operand = parse_unary_expression(parser);
|
||||
|
||||
if (!unary->unary.operand) {
|
||||
scc_free(unary);
|
||||
return null;
|
||||
}
|
||||
|
||||
// if (parser->sema_callbacks.on_expr) {
|
||||
// parser->sema_callbacks.on_expr(parser->sema_callbacks.context,
|
||||
// unary->node_type, unary);
|
||||
// }
|
||||
return unary;
|
||||
}
|
||||
|
||||
case SCC_TOK_ADD: // +
|
||||
case SCC_TOK_SUB: // -
|
||||
case SCC_TOK_MUL: // *
|
||||
case SCC_TOK_AND: // &
|
||||
case SCC_TOK_NOT: // !
|
||||
case SCC_TOK_BIT_NOT: { // ~
|
||||
// 跳过操作符
|
||||
scc_lexer_stream_consume(parser->lex_stream);
|
||||
|
||||
scc_ast_expr_t *unary = expr_create(parser, SCC_AST_EXPR_UNARY);
|
||||
if (!unary)
|
||||
return null;
|
||||
|
||||
unary->unary.op = scc_ast_token_to_operator(tok->type, true);
|
||||
unary->unary.operand = parse_unary_expression(parser);
|
||||
|
||||
if (!unary->unary.operand) {
|
||||
scc_free(unary);
|
||||
return null;
|
||||
}
|
||||
|
||||
// if (parser->sema_callbacks.on_expr) {
|
||||
// parser->sema_callbacks.on_expr(parser->sema_callbacks.context,
|
||||
// unary->node_type, unary);
|
||||
// }
|
||||
return unary;
|
||||
}
|
||||
|
||||
case SCC_TOK_SIZEOF: { // sizeof
|
||||
// scc_lexer_stream_consume(parser->lex_stream); // 跳过 'sizeof'
|
||||
|
||||
// scc_ast_expr_t *size_of = expr_create(parser, SCC_AST_EXPR_SIZE_OF);
|
||||
// if (!size_of)
|
||||
// return null;
|
||||
|
||||
// size_of->size_align.is_size_of = true;
|
||||
|
||||
// // 检查是否是 sizeof(type) 或 sizeof expr
|
||||
// if (scc_parse_consume_if(parser->lex_stream, SCC_TOK_L_PAREN)) {
|
||||
// // 检查是否是类型
|
||||
// // if (parser_is_type_start(parser)) {
|
||||
// // size_of->size_align.type = scc_parse_type_name(parser);
|
||||
// // if (!size_of->size_align.type) {
|
||||
// // scc_free(size_of);
|
||||
// // return null;
|
||||
// // }
|
||||
// // } else {
|
||||
// size_of->size_align.expr = scc_parse_expression(parser);
|
||||
// if (!size_of->size_align.expr) {
|
||||
// scc_free(size_of);
|
||||
// return null;
|
||||
// }
|
||||
// // }
|
||||
|
||||
// if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_R_PAREN)) {
|
||||
// LOG_ERROR("expected ')' after sizeof");
|
||||
// // if (size_of->size_align.type)
|
||||
// // scc_free(size_of->size_align.type);
|
||||
// // if (size_of->size_align.expr)
|
||||
// // scc_free(size_of->size_align.expr);
|
||||
// // scc_free(size_of);
|
||||
// // return null;
|
||||
// }
|
||||
// } else {
|
||||
// size_of->size_align.expr = parse_unary_expression(parser);
|
||||
// if (!size_of->size_align.expr) {
|
||||
// scc_free(size_of);
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // if (parser->sema_callbacks.on_expr) {
|
||||
// // parser->sema_callbacks.on_expr(parser->sema_callbacks.context,
|
||||
// // size_of->node_type, size_of);
|
||||
// // }
|
||||
// return size_of;
|
||||
}
|
||||
|
||||
default:
|
||||
// 不是一元操作符,解析基本表达式
|
||||
scc_ast_expr_t *primary = parse_primary_expression(parser);
|
||||
if (!primary)
|
||||
return null;
|
||||
|
||||
// 应用后缀操作符
|
||||
return parse_postfix_expression(parser, primary);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 解析强制转换表达式
|
||||
*
|
||||
* (6.5.4) cast-expression:
|
||||
* unary-expression
|
||||
* ( type-name ) cast-expression
|
||||
*/
|
||||
static scc_ast_expr_t *parse_cast_expression(scc_parser_t *parser) {
|
||||
// 检查是否是类型转换
|
||||
// if (parser_is_cast_expression(parser)) {
|
||||
// // 我们已经知道是 ( type-name ) 格式
|
||||
// scc_lexer_stream_consume(parser->lex_stream); // 跳过 '('
|
||||
|
||||
// scc_ast_type_t *type = scc_parse_type_name(parser);
|
||||
// if (!type) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// if (!parser_consume_if(parser, SCC_TOK_R_PAREN)) {
|
||||
// PARSER_ERROR(parser, "expected ')' after type name");
|
||||
// scc_free(type);
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// scc_ast_expr_t *cast = expr_create(parser, SCC_AST_EXPR_CAST);
|
||||
// if (!cast) {
|
||||
// scc_free(type);
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// cast->cast.type = type;
|
||||
// cast->cast.expr = parse_cast_expression(parser); // 递归解析
|
||||
|
||||
// if (!cast->cast.expr) {
|
||||
// scc_free(cast);
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// if (parser->sema_callbacks.on_expr) {
|
||||
// parser->sema_callbacks.on_expr(parser->sema_callbacks.context,
|
||||
// cast->node_type, cast);
|
||||
// }
|
||||
// return cast;
|
||||
// }
|
||||
|
||||
// 不是类型转换,解析一元表达式
|
||||
return parse_unary_expression(parser);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pratt Parser核心:解析表达式
|
||||
* @param parser 解析器
|
||||
* @param min_prec 最小优先级
|
||||
* @return 表达式AST节点
|
||||
*/
|
||||
static scc_ast_expr_t *
|
||||
parse_expression_with_precedence(scc_parser_t *parser,
|
||||
scc_precedence_t min_prec) {
|
||||
// 解析左侧表达式(一元表达式或基本表达式)
|
||||
scc_ast_expr_t *lhs = parse_cast_expression(parser);
|
||||
if (!lhs) {
|
||||
return null;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
const scc_lexer_tok_t *tok =
|
||||
scc_lexer_stream_current(parser->lex_stream);
|
||||
scc_tok_type_t op = tok->type;
|
||||
scc_precedence_t prec = get_binary_precedence(op);
|
||||
|
||||
// 检查是否达到最小优先级或不是二元运算符
|
||||
if (prec < min_prec || prec == PREC_NONE) {
|
||||
break;
|
||||
}
|
||||
|
||||
// 特殊处理条件表达式 ?:
|
||||
if (op == SCC_TOK_COND) {
|
||||
scc_lexer_stream_consume(parser->lex_stream); // 跳过 '?'
|
||||
|
||||
scc_ast_expr_t *cond_expr = expr_create(parser, SCC_AST_EXPR_COND);
|
||||
if (!cond_expr) {
|
||||
scc_free(lhs);
|
||||
return null;
|
||||
}
|
||||
|
||||
cond_expr->cond.cond = lhs;
|
||||
|
||||
// 解析then表达式
|
||||
cond_expr->cond.then_expr =
|
||||
parse_expression_with_precedence(parser, PREC_NONE);
|
||||
if (!cond_expr->cond.then_expr) {
|
||||
scc_free(cond_expr);
|
||||
scc_free(lhs);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 期望 ':'
|
||||
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_COLON)) {
|
||||
LOG_ERROR("expected ':' in conditional expression");
|
||||
scc_free(cond_expr);
|
||||
scc_free(lhs);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 解析else表达式(条件表达式,右结合)
|
||||
cond_expr->cond.else_expr =
|
||||
parse_expression_with_precedence(parser, PREC_CONDITIONAL - 1);
|
||||
if (!cond_expr->cond.else_expr) {
|
||||
scc_free(cond_expr);
|
||||
scc_free(lhs);
|
||||
return null;
|
||||
}
|
||||
|
||||
lhs = cond_expr;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 对于赋值运算符,右侧优先级需要减1(右结合性)
|
||||
scc_precedence_t next_min_prec;
|
||||
if (is_assignment_operator(op)) {
|
||||
next_min_prec = (scc_precedence_t)(prec - 1); // 右结合
|
||||
} else {
|
||||
next_min_prec = (scc_precedence_t)(prec + 1); // 左结合
|
||||
}
|
||||
|
||||
scc_lexer_stream_consume(parser->lex_stream); // 跳过操作符
|
||||
|
||||
// 解析右侧表达式
|
||||
scc_ast_expr_t *rhs =
|
||||
parse_expression_with_precedence(parser, next_min_prec);
|
||||
if (!rhs) {
|
||||
scc_free(lhs);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 创建二元表达式节点
|
||||
scc_ast_expr_t *binary = expr_create(parser, SCC_AST_EXPR_BINARY);
|
||||
if (!binary) {
|
||||
scc_free(lhs);
|
||||
scc_free(rhs);
|
||||
return null;
|
||||
}
|
||||
|
||||
binary->binary.op = scc_ast_token_to_operator(op, false);
|
||||
binary->binary.lhs = lhs;
|
||||
binary->binary.rhs = rhs;
|
||||
|
||||
lhs = binary;
|
||||
}
|
||||
|
||||
// if (parser->sema_callbacks.on_expr) {
|
||||
// parser->sema_callbacks.on_expr(parser->sema_callbacks.context,
|
||||
// binary->node_type, binary);
|
||||
// }
|
||||
return lhs;
|
||||
}
|
||||
|
||||
scc_ast_expr_t *scc_parse_expression(scc_parser_t *parser) {
|
||||
return parse_expression_with_precedence(parser, PREC_NONE);
|
||||
}
|
||||
Reference in New Issue
Block a user