feat(parser): 完善类型解析和表达式解析功能
完善了scc_parse_type函数以正确解析基本类型,修复了条件表达式解析逻辑, 实现了for循环中声明和表达式的混合处理,并添加了对赋值语句和复杂表达式的支持。 fix(parser): 修复内存泄漏和解析器状态管理问题 修复了当tok参数为null时的内存泄漏问题,在标签语句解析中正确处理解析器状态回退, 并改进了表达式和声明的错误处理机制。 test(parser): 更新单元测试以验证修复的功能 更新了返回语句的测试值,添加了包含变量声明、赋值语句和复杂表达式的综合测试用例, 验证了赋值运算符的右结合性和复杂表达式的解析正确性。
This commit is contained in:
@@ -175,30 +175,13 @@ scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) {
|
||||
* declarator = initializer
|
||||
*/
|
||||
cbool ok;
|
||||
const scc_lexer_tok_t *tok_ptr = scc_parser_next(parser);
|
||||
scc_lexer_tok_t tok;
|
||||
if (tok_ptr == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
scc_ast_type_t *type = scc_malloc(sizeof(scc_ast_type_t));
|
||||
scc_ast_type_t *type = scc_parse_type(parser);
|
||||
if (type == null) {
|
||||
LOG_FATAL("out of memory");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (tok_ptr->type != SCC_TOK_INT) {
|
||||
// TODO back it
|
||||
scc_parser_reset(parser);
|
||||
return null;
|
||||
} else {
|
||||
type->base.type = SCC_AST_TYPE_BUILTIN;
|
||||
type->base.loc = tok_ptr->loc;
|
||||
type->builtin.type = SCC_AST_BUILTIN_TYPE_INT;
|
||||
type->builtin.quals = (scc_ast_decl_specifier_t){0};
|
||||
}
|
||||
|
||||
scc_parser_commit(parser);
|
||||
ok = scc_parser_next_consume(parser, &tok);
|
||||
if (ok == false) {
|
||||
return null;
|
||||
@@ -231,7 +214,7 @@ scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) {
|
||||
decl->base.type = SCC_AST_DECL_VAR;
|
||||
decl->var.type = type;
|
||||
decl->var.name = scc_cstring_as_cstr(&tok.lexeme);
|
||||
decl->var.init = null; // scc_parse_expression(parser);
|
||||
decl->var.init = scc_parse_expression(parser);
|
||||
goto RETURN;
|
||||
}
|
||||
// TODO
|
||||
@@ -255,7 +238,7 @@ scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) {
|
||||
return null;
|
||||
}
|
||||
|
||||
tok_ptr = scc_parser_peek(parser);
|
||||
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
|
||||
if (tok_ptr == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -525,9 +525,6 @@ static scc_ast_expr_t *parse_assignment_expression(scc_parser_t *parser) {
|
||||
// unary-expression)
|
||||
scc_ast_expr_t *left = null;
|
||||
left = parse_conditional_expression(parser);
|
||||
if (left)
|
||||
return left;
|
||||
left = parse_unary_expression(parser);
|
||||
if (!left)
|
||||
return null;
|
||||
|
||||
|
||||
@@ -260,6 +260,12 @@ static scc_ast_stmt_t *parse_for_statement(scc_parser_t *parser) {
|
||||
|
||||
// TODO use decl or expr
|
||||
stmt->for_stmt.init = (scc_ast_type_t *)scc_parse_expression(parser);
|
||||
if (stmt->for_stmt.init == null) {
|
||||
stmt->for_stmt.init = (scc_ast_type_t *)scc_parse_declaration(parser);
|
||||
}
|
||||
if (stmt->for_stmt.init == null) {
|
||||
LOG_ERROR("Expected expression or declaration in for statement.");
|
||||
}
|
||||
|
||||
if (!scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) {
|
||||
LOG_ERROR("Expected semicolon in for statement.");
|
||||
@@ -348,8 +354,10 @@ scc_ast_stmt_t *scc_parse_statement(scc_parser_t *parser) {
|
||||
default : statement
|
||||
*/
|
||||
case SCC_TOK_IDENT:
|
||||
scc_parser_next(parser);
|
||||
tok_ref = scc_parser_next(parser);
|
||||
if (tok_ref == null || tok_ref->type != SCC_TOK_COLON) {
|
||||
scc_parser_reset(parser);
|
||||
break;
|
||||
}
|
||||
stmt = parse_label_statement(parser);
|
||||
|
||||
@@ -235,8 +235,22 @@ cbool scc_parse_is_storage_class_start(scc_parser_t *parser) {
|
||||
}
|
||||
}
|
||||
scc_ast_type_t *scc_parse_type(scc_parser_t *parser) {
|
||||
TODO();
|
||||
return null;
|
||||
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
|
||||
scc_ast_type_t *ret = null;
|
||||
if (tok_ptr->type == SCC_TOK_INT) {
|
||||
scc_lexer_tok_t tok;
|
||||
scc_parser_next_consume(parser, &tok);
|
||||
ret = scc_malloc(sizeof(scc_ast_type_t));
|
||||
if (ret == null) {
|
||||
LOG_FATAL("memory alloc failed");
|
||||
return ret;
|
||||
}
|
||||
ret->base.type = SCC_AST_TYPE_BUILTIN;
|
||||
ret->base.loc = tok_ptr->loc;
|
||||
ret->builtin.type = SCC_AST_BUILTIN_TYPE_INT;
|
||||
scc_lexer_tok_drop(&tok);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// // 前向声明辅助函数
|
||||
|
||||
Reference in New Issue
Block a user