feat(parser): 实现赋值表达式和常量表达式解析功能
- 添加 scc_parse_assignment_expression 函数用于解析赋值表达式 - 添加 scc_parser_constant_expression 函数用于解析常量表达式 - 修改 cast 表达式解析逻辑,修复类型转换解析问题 - 改进错误处理机制,使用 SCC_ERROR 替代 LOG_ERROR 并提供准确位置信息 - 移除未使用的变量声明,优化代码结构 refactor(ast): 调整类型定义中的 typedef 类型存储结构 - 将 scc_ast_type 中的 underlying 字段改为 decl 字段 - 更新相关初始化函数以适配新的字段名称 - 修复枚举类型初始化时缺失的 decl 字段设置 feat(ast): 添加类型转换、sizeof 和 alignof 表达式的初始化函数 - 实现 scc_ast_expr_cast_init 用于初始化类型转换表达式 - 实现 scc_ast_expr_sizeof_init 用于初始化 sizeof 表达式 - 实现 scc_ast_expr_alignof_init 用于初始化 alignof 表达式 - 完善表达式类型的支持 chore(parser): 增加语义分析回调接口和位置获取工具函数 - 添加 scc_parse_decl_sema、scc_parse_type_sema 等语义分析辅助函数 - 提供 scc_parser_got_current_pos 函数获取当前解析位置 - 增强错误报告的准确性 refactor(dump): 完善 AST 转储功能,支持 break 和 continue 语句 - 为 SCC_AST_STMT_BREAK 和 SCC_AST_STMT_CONTINUE 添加转储支持 - 优化转储函数的分支处理结构
This commit is contained in:
@@ -167,8 +167,6 @@ 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 *
|
||||
@@ -520,7 +518,7 @@ 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) {
|
||||
scc_ast_expr_t *scc_parse_assignment_expression(scc_parser_t *parser) {
|
||||
// 先解析左侧的 unary-expression(C 标准规定赋值左边必须是
|
||||
// unary-expression)
|
||||
scc_ast_expr_t *left = null;
|
||||
@@ -542,7 +540,7 @@ static scc_ast_expr_t *parse_assignment_expression(scc_parser_t *parser) {
|
||||
scc_lexer_tok_drop(&op_tok);
|
||||
|
||||
// 解析右侧(右结合:继续调用 parse_assignment_expression)
|
||||
scc_ast_expr_t *right = parse_assignment_expression(parser);
|
||||
scc_ast_expr_t *right = scc_parse_assignment_expression(parser);
|
||||
if (!right) {
|
||||
// 错误恢复
|
||||
parser_sync(parser);
|
||||
@@ -577,7 +575,8 @@ static scc_ast_expr_t *parse_conditional_expression(scc_parser_t *parser) {
|
||||
|
||||
// 消耗 ':'
|
||||
if (!scc_parser_consume_if(parser, SCC_TOK_COLON)) {
|
||||
LOG_ERROR("Expected ':' after '?'");
|
||||
SCC_ERROR(scc_parser_got_current_pos(parser),
|
||||
"Expected ':' after '?'");
|
||||
parser_sync(parser);
|
||||
return null;
|
||||
}
|
||||
@@ -600,6 +599,7 @@ static scc_ast_expr_t *parse_cast_expression(scc_parser_t *parser) {
|
||||
if (tok && tok->type == SCC_TOK_L_PAREN) {
|
||||
// 尝试解析类型名
|
||||
scc_parser_store(parser);
|
||||
scc_parser_next(parser);
|
||||
scc_ast_type_t *type = scc_parse_type_name(parser); // 需要外部实现
|
||||
if (type) {
|
||||
// 消耗了类型名后,下一个应该是 ')'
|
||||
@@ -618,13 +618,12 @@ static scc_ast_expr_t *parse_cast_expression(scc_parser_t *parser) {
|
||||
return expr;
|
||||
} else {
|
||||
// 不是类型转换,回退
|
||||
scc_parser_restore(parser);
|
||||
// 释放 type(假设 scc_parse_type_name 分配了)
|
||||
// TODO: scc_ast_type_drop(type);
|
||||
}
|
||||
} else {
|
||||
// 解析类型名失败,回退
|
||||
scc_parser_restore(parser);
|
||||
// 解析类型名失败,回退
|
||||
}
|
||||
}
|
||||
// 否则作为一元表达式
|
||||
@@ -679,7 +678,8 @@ static scc_ast_expr_t *parse_sizeof_expression(scc_parser_t *parser) {
|
||||
|
||||
const scc_lexer_tok_t *next = scc_parser_peek(parser);
|
||||
if (!next) {
|
||||
LOG_ERROR("Unexpected end after sizeof");
|
||||
SCC_ERROR(scc_parser_got_current_pos(parser),
|
||||
"Unexpected end after sizeof");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -741,7 +741,8 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
|
||||
return null;
|
||||
}
|
||||
if (!scc_parser_consume_if(parser, SCC_TOK_R_BRACKET)) {
|
||||
LOG_ERROR("Expected ']' after subscript");
|
||||
SCC_ERROR(scc_parser_got_current_pos(parser),
|
||||
"Expected ']' after subscript");
|
||||
parser_sync(parser);
|
||||
return null;
|
||||
}
|
||||
@@ -766,7 +767,8 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
|
||||
// 解析参数列表
|
||||
if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
|
||||
while (1) {
|
||||
scc_ast_expr_t *arg = parse_assignment_expression(parser);
|
||||
scc_ast_expr_t *arg =
|
||||
scc_parse_assignment_expression(parser);
|
||||
if (!arg) {
|
||||
parser_sync(parser);
|
||||
// 释放已解析的参数
|
||||
@@ -781,7 +783,8 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
|
||||
} else if (scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
|
||||
break;
|
||||
} else {
|
||||
LOG_ERROR("Expected ',' or ')' in function call");
|
||||
SCC_ERROR(scc_parser_got_current_pos(parser),
|
||||
"Expected ',' or ')' in function call");
|
||||
parser_sync(parser);
|
||||
// 释放资源
|
||||
scc_free(call);
|
||||
@@ -800,12 +803,14 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
|
||||
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_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 = expr_create(
|
||||
parser, op_tok.type == SCC_TOK_DOT ? SCC_AST_EXPR_MEMBER
|
||||
: SCC_AST_EXPR_PTR_MEMBER);
|
||||
@@ -944,7 +949,8 @@ static scc_ast_expr_t *parse_paren_expression(scc_parser_t *parser) {
|
||||
}
|
||||
|
||||
if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
|
||||
LOG_ERROR("Expected ')' after expression");
|
||||
SCC_ERROR(scc_parser_got_current_pos(parser),
|
||||
"Expected ')' after expression");
|
||||
parser_sync(parser);
|
||||
return null;
|
||||
}
|
||||
@@ -952,12 +958,12 @@ static scc_ast_expr_t *parse_paren_expression(scc_parser_t *parser) {
|
||||
}
|
||||
|
||||
scc_ast_expr_t *scc_parse_expression(scc_parser_t *parser) {
|
||||
scc_ast_expr_t *left = parse_assignment_expression(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 = parse_assignment_expression(parser);
|
||||
scc_ast_expr_t *right = scc_parse_assignment_expression(parser);
|
||||
if (!right) {
|
||||
parser_sync(parser);
|
||||
return null;
|
||||
@@ -966,3 +972,7 @@ scc_ast_expr_t *scc_parse_expression(scc_parser_t *parser) {
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
scc_ast_expr_t *scc_parser_constant_expression(scc_parser_t *parser) {
|
||||
return parse_conditional_expression(parser);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user