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:
zzy
2026-03-12 14:57:35 +08:00
parent 30ac2de73b
commit b00a42a539
18 changed files with 592 additions and 197 deletions

View File

@@ -7,7 +7,8 @@
typedef scc_ast_node_t *(*scc_parse_node_func)(scc_parser_t *parser);
static scc_ast_node_t *process_input(const char *input,
scc_parse_node_func parse_func) {
scc_parse_node_func parse_func,
cbool need_sema) {
int res = 0;
scc_sstream_t mem_stream;
res = scc_sstream_init_by_buffer(&mem_stream, input, strlen(input), false,
@@ -20,7 +21,13 @@ static scc_ast_node_t *process_input(const char *input,
scc_lexer_tok_ring_t *tok_ring = scc_lexer_to_ring(&lexer, 64, false);
scc_parser_t parser;
scc_parser_init(&parser, tok_ring, null);
if (need_sema) {
scc_sema_callbacks_t sema_callbacks;
scc_sema_init(&sema_callbacks);
scc_parser_init(&parser, tok_ring, &sema_callbacks);
} else {
scc_parser_init(&parser, tok_ring, null);
}
scc_ast_node_t *ret = parse_func(&parser);
@@ -55,8 +62,8 @@ static void dump2buffer(void *_buffer, const char *fmt, ...) {
}
static void _scc_check_ast(scc_ast_node_t *expect_node_ptr, const char *str,
scc_parse_node_func parse_func) {
scc_ast_node_t *output_node_ptr = process_input(str, parse_func);
scc_parse_node_func parse_func, cbool need_sema) {
scc_ast_node_t *output_node_ptr = process_input(str, parse_func, need_sema);
scc_tree_dump_ctx_t ctx;
expect_buffer[0] = '\n', expect_buffer[1] = '\0';
scc_tree_dump_ctx_init(&ctx, true, dump2buffer, expect_buffer);
@@ -68,9 +75,19 @@ static void _scc_check_ast(scc_ast_node_t *expect_node_ptr, const char *str,
scc_tree_dump_ctx_drop(&ctx);
}
#define SCC_CHECK_AST_WITH_SEMA(expect_node_ptr, str, parse_func) \
do { \
_scc_check_ast(expect_node_ptr, str, (scc_parse_node_func)parse_func, \
true); \
TEST_CHECK(strcmp(output_buffer, expect_buffer) == 0); \
TEST_MSG("Expected: %s", expect_buffer); \
TEST_MSG("Produced: %s", output_buffer); \
} while (0);
#define SCC_CHECK_AST(expect_node_ptr, str, parse_func) \
do { \
_scc_check_ast(expect_node_ptr, str, (scc_parse_node_func)parse_func); \
_scc_check_ast(expect_node_ptr, str, (scc_parse_node_func)parse_func, \
false); \
TEST_CHECK(strcmp(output_buffer, expect_buffer) == 0); \
TEST_MSG("Expected: %s", expect_buffer); \
TEST_MSG("Produced: %s", output_buffer); \
@@ -370,8 +387,38 @@ static void test_parser_unit(void) {
scc_ast_decl_t typedef_decl;
scc_ast_decl_typedef_init(&typedef_decl, "int32_t",
&scc_ast_builtin_type_int);
SCC_CHECK_AST(&typedef_decl.base, "typedef int int32_t;",
scc_parse_declaration);
scc_ast_type_t typedef_type;
scc_ast_type_typedef_init(&typedef_type, "int32_t", &typedef_decl);
scc_ast_decl_t i32a_decl;
scc_ast_decl_val_init(&i32a_decl, &typedef_type, "a", null);
scc_ast_node_t *array[] = {&typedef_decl.base, &i32a_decl.base};
scc_ast_stmt_t stmt;
scc_ast_block_item_vec_t items;
scc_vec_unsafe_from_array(items, array);
scc_ast_stmt_compound_init(&stmt, &items);
SCC_CHECK_AST_WITH_SEMA(&stmt.base, "{typedef int int32_t;int32_t a;}",
scc_parse_statement);
scc_ast_type_t void_ptr;
scc_ast_type_pointer_init(&void_ptr, &scc_ast_builtin_type_void);
scc_ast_decl_t void_ptr_decl;
scc_ast_decl_typedef_init(&void_ptr_decl, "void_ptr", &void_ptr);
scc_ast_type_t void_ptr_type;
scc_ast_type_typedef_init(&void_ptr_type, "void_ptr", &void_ptr_decl);
scc_ast_decl_t void_ptr_a_decl;
scc_ast_decl_val_init(&void_ptr_a_decl, &void_ptr_type, "a", null);
scc_ast_node_t *array2[] = {&void_ptr_decl.base, &void_ptr_a_decl.base};
scc_vec_unsafe_from_array(items, array2);
scc_ast_stmt_compound_init(&stmt, &items);
SCC_CHECK_AST_WITH_SEMA(&stmt.base,
"{typedef void* void_ptr; void_ptr a;}",
scc_parse_statement);
SCC_CHECK_AST_WITH_SEMA(&void_ptr_decl.base, "typedef void *void_ptr;",
scc_parse_declaration);
}
{
@@ -387,6 +434,145 @@ static void test_parser_unit(void) {
scc_ast_decl_struct_init(&struct_def, null, &fields);
SCC_CHECK_AST(&struct_def.base, "struct { int x; };",
scc_parse_declaration);
scc_ast_type_t struct_type;
scc_ast_type_struct_init(&struct_type, null, &struct_def);
scc_ast_type_t typedef_type;
scc_ast_type_typedef_init(&typedef_type, "struct_t", &struct_def);
scc_ast_decl_t typedef_decl;
scc_ast_decl_typedef_init(&typedef_decl, "struct_t", &struct_type);
SCC_CHECK_AST_WITH_SEMA(&typedef_decl.base,
"typedef struct { int x; } struct_t;",
scc_parse_declaration);
scc_ast_decl_t typedef_impl_decl;
scc_ast_decl_val_init(&typedef_impl_decl, &typedef_type, "a", null);
scc_ast_node_t *array[] = {&typedef_decl.base, &typedef_impl_decl.base};
scc_ast_stmt_t stmt;
scc_ast_block_item_vec_t items;
scc_vec_unsafe_from_array(items, array);
scc_ast_stmt_compound_init(&stmt, &items);
SCC_CHECK_AST_WITH_SEMA(
&stmt.base, "{typedef struct { int x; } struct_t; struct_t a;}",
scc_parse_statement);
}
{
scc_ast_decl_t type_decl;
scc_ast_decl_typedef_init(&type_decl, "size_t",
&scc_ast_builtin_type_long_long);
scc_ast_type_t type_type;
scc_ast_type_typedef_init(&type_type, "size_t", &type_decl);
scc_ast_decl_t param1;
scc_ast_decl_param_init(&param1, &type_type, "a");
scc_ast_decl_t param2;
scc_ast_decl_param_init(&param2, &scc_ast_builtin_type_int, "b");
scc_ast_decl_t param3;
scc_ast_decl_param_init(&param3, &scc_ast_builtin_type_va_list, null);
scc_ast_decl_t *params_array[] = {&param1, &param2, &param3};
scc_ast_decl_vec_t func_params;
scc_vec_unsafe_from_array(func_params, params_array);
scc_ast_type_t func_type;
scc_ast_type_t return_type;
scc_ast_type_pointer_init(&return_type, &scc_ast_builtin_type_void);
scc_ast_type_function_init(&func_type, &return_type, &func_params);
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "func", null);
scc_ast_decl_t *decls_array[] = {&type_decl, &func_decl};
scc_ast_translation_unit_t tu;
scc_ast_decl_vec_t decls;
scc_vec_unsafe_from_array(decls, decls_array);
scc_ast_translation_unit_init(&tu, &decls);
SCC_CHECK_AST_WITH_SEMA(&tu.base,
"typedef long long size_t;"
"void *func(size_t a, int b, ...);",
scc_parse_translation_unit);
scc_ast_type_t type_func_ptr_type;
scc_ast_type_pointer_init(&type_func_ptr_type, &func_type);
scc_ast_decl_t type_func_ptr_decl;
scc_ast_decl_typedef_init(&type_func_ptr_decl, "func_t",
&type_func_ptr_type);
scc_ast_decl_t *decls_array2[] = {&type_decl, &type_func_ptr_decl};
scc_vec_unsafe_from_array(decls, decls_array2);
scc_ast_translation_unit_init(&tu, &decls);
SCC_CHECK_AST_WITH_SEMA(
&tu.base,
"typedef long long size_t;"
"typedef void *(*func_t)(size_t a, int b, ...);",
scc_parse_translation_unit);
}
{
// int (*(*)(void))[5] (指向函数的指针,该函数返回指向数组的指针)
// 步骤:
// 1) 数组类型int [5]
scc_ast_expr_t size_5;
scc_ast_expr_literal_int_init(&size_5, "5", false);
scc_ast_type_t array_of_5_int;
scc_ast_type_array_init(&array_of_5_int,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
&size_5);
// 2) 函数类型:返回指向数组的指针,无参数
scc_ast_type_t ptr_to_array;
scc_ast_type_pointer_init(&ptr_to_array, &array_of_5_int);
scc_ast_type_t func_type;
scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &scc_ast_builtin_type_void, null);
scc_ast_decl_t *array[] = {&void_decl};
scc_vec_unsafe_from_array(func_params, array);
scc_ast_type_function_init(&func_type, &ptr_to_array,
&func_params); // 无参数
// 3) 指向该函数的指针
scc_ast_type_t ptr_to_func;
scc_ast_type_pointer_init(&ptr_to_func, &func_type);
scc_ast_decl_t ptr_to_func_decl;
scc_ast_decl_val_init(&ptr_to_func_decl, &ptr_to_func, "foo", null);
SCC_CHECK_AST(&ptr_to_func_decl.base, "int (*(*foo)(void))[5];",
scc_parse_declaration);
scc_ast_decl_t typedef_func_decl;
scc_ast_decl_typedef_init(&typedef_func_decl, "func_t", &ptr_to_func);
scc_ast_type_t typedef_func_type;
scc_ast_type_typedef_init(&typedef_func_type, "func_t",
&typedef_func_decl);
scc_ast_decl_t func_hard_decl;
scc_ast_type_t func_hard_type;
scc_ast_decl_t param1;
scc_ast_decl_param_init(&param1, &ptr_to_func, "bar");
scc_ast_decl_t param2;
scc_ast_decl_param_init(&param2, &typedef_func_type, "a");
scc_ast_decl_t param3;
scc_ast_decl_param_init(&param1, &scc_ast_builtin_type_va_list, null);
scc_ast_decl_t *func_hard_array[] = {&param1, &param2, &param3};
scc_ast_decl_vec_t func_hard_params;
scc_vec_unsafe_from_array(func_hard_params, func_hard_array);
scc_ast_type_function_init(&func_hard_type, &ptr_to_array,
&func_hard_params);
scc_ast_decl_func_init(&func_hard_decl, &func_hard_type, "bar", null);
scc_ast_decl_vec_t decls;
scc_ast_decl_t *decls_array[] = {
&typedef_func_decl,
&func_hard_decl,
};
scc_vec_unsafe_from_array(decls, decls_array);
scc_ast_translation_unit_t tu;
scc_ast_translation_unit_init(&tu, &decls);
// SCC_CHECK_AST_WITH_SEMA(
// &tu.base,
// "typedef int (*(*func_t)(void))[5];"
// "int (*(*(bar)(int(*(*foo)(void))[5], func_t a,
// ...))(void))[5];", scc_parse_translation_unit);
}
}
@@ -513,18 +699,12 @@ static void test_parser_expression(void) {
// 4. 类型转换(示例: (int)x
{
// scc_ast_type_t
// int_type; // 使用内置类型全局变量即可,但类型转换需要一个类型节点
// //
// 我们可以直接使用全局内置类型的地址,但类型转换节点需要一个类型节点,直接引用全局即可
// // TODO
// scc_ast_expr_t x;
// scc_ast_expr_identifier_init(&x, "x");
// scc_ast_expr_t cast;
// scc_ast_expr_cast_init(&cast,
// (scc_ast_type_t *)&scc_ast_builtin_type_int,
// &x);
// SCC_CHECK_AST(&cast.base, "(int)x", scc_parse_expression);
scc_ast_expr_t x;
scc_ast_expr_identifier_init(&x, "x");
scc_ast_expr_t cast;
scc_ast_expr_cast_init(&cast,
(scc_ast_type_t *)&scc_ast_builtin_type_int, &x);
SCC_CHECK_AST(&cast.base, "(int)x", scc_parse_expression);
}
// 5. 二元运算符优先级
@@ -1168,10 +1348,8 @@ static void test_parser_type(void) {
scc_ast_expr_identifier_init(&green, "GREEN");
scc_ast_expr_identifier_init(&blue, "BLUE");
scc_ast_expr_vec_t enumerators;
scc_vec_init(enumerators);
scc_vec_push(enumerators, &red);
scc_vec_push(enumerators, &green);
scc_vec_push(enumerators, &blue);
scc_ast_expr_t *array[] = {&red, &green, &blue};
scc_vec_unsafe_from_array(enumerators, array);
scc_ast_decl_t enum_def;
scc_ast_decl_enum_init(&enum_def, null, &enumerators);
@@ -1179,9 +1357,11 @@ static void test_parser_type(void) {
scc_ast_type_enum_init(&enum_type, null, &enum_def);
SCC_CHECK_AST(&enum_type.base, "enum { RED, GREEN, BLUE }",
_scc_parse_type);
scc_vec_unsafe_from_array(enumerators, array);
scc_ast_decl_enum_init(&enum_def, "E", &enumerators);
scc_ast_type_enum_init(&enum_type, "E", &enum_def);
SCC_CHECK_AST(&enum_type.base, "enum E { RED, GREEN, BLUE }",
SCC_CHECK_AST(&enum_type.base, "enum E { RED, GREEN, BLUE, }",
_scc_parse_type);
}