refactor(ast): 调整AST结构体和枚举类型的声明表示方式

将结构体、联合和枚举类型的字段表示从向量改为声明指针,
允许name和decl字段为null,更新相关初始化函数的断言检查,
使结构更加灵活并支持不完整类型定义。

BREAKING CHANGE: 修改了scc_ast_type结构体中record和enumeration
子类型的字段表示方法,从fields向量改为decl指针。
This commit is contained in:
zzy
2026-03-11 21:53:19 +08:00
parent ce5414f2eb
commit e6511c508c
12 changed files with 338 additions and 116 deletions

View File

@@ -28,6 +28,7 @@ static scc_ast_node_t *process_input(const char *input,
scc_ring_not_eof(*parser.ring, not_eof);
if (not_eof == true) {
// FIXME MAYBE free
LOG_ERROR("Didn't consume all tokens");
return null;
}
@@ -53,19 +54,23 @@ static void dump2buffer(void *_buffer, const char *fmt, ...) {
va_end(args);
}
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_tree_dump_ctx_t ctx;
expect_buffer[0] = '\n', expect_buffer[1] = '\0';
scc_tree_dump_ctx_init(&ctx, true, dump2buffer, expect_buffer);
scc_ast_dump_node(&ctx, expect_node_ptr);
scc_tree_dump_ctx_drop(&ctx);
output_buffer[0] = '\n', output_buffer[1] = '\0';
scc_tree_dump_ctx_init(&ctx, true, dump2buffer, output_buffer);
scc_ast_dump_node(&ctx, output_node_ptr);
scc_tree_dump_ctx_drop(&ctx);
}
#define SCC_CHECK_AST(expect_node_ptr, str, parse_func) \
do { \
scc_ast_node_t *output_node_ptr = \
process_input(str, (scc_parse_node_func)parse_func); \
scc_tree_dump_ctx_t ctx; \
expect_buffer[0] = '\n', expect_buffer[1] = '\0'; \
scc_tree_dump_ctx_init(&ctx, true, dump2buffer, expect_buffer); \
scc_ast_dump_node(&ctx, expect_node_ptr); \
scc_tree_dump_ctx_drop(&ctx); \
output_buffer[0] = '\n', output_buffer[1] = '\0'; \
scc_tree_dump_ctx_init(&ctx, true, dump2buffer, output_buffer); \
scc_ast_dump_node(&ctx, output_node_ptr); \
scc_tree_dump_ctx_drop(&ctx); \
_scc_check_ast(expect_node_ptr, str, (scc_parse_node_func)parse_func); \
TEST_CHECK(strcmp(output_buffer, expect_buffer) == 0); \
TEST_MSG("Expected: %s", expect_buffer); \
TEST_MSG("Produced: %s", output_buffer); \
@@ -368,6 +373,21 @@ static void test_parser_unit(void) {
SCC_CHECK_AST(&typedef_decl.base, "typedef int int32_t;",
scc_parse_declaration);
}
{
// struct { int x; } (匿名结构体定义)
scc_ast_decl_t field;
scc_ast_decl_val_init(
&field, (scc_ast_type_t *)&scc_ast_builtin_type_int, "x", null);
scc_ast_decl_vec_t fields;
scc_vec_init(fields);
scc_vec_push(fields, &field);
scc_ast_decl_t struct_def;
scc_ast_decl_struct_init(&struct_def, null, &fields);
SCC_CHECK_AST(&struct_def.base, "struct { int x; };",
scc_parse_declaration);
}
}
static void test_parser_expression(void) {
@@ -696,7 +716,7 @@ static void test_parser_type(void) {
scc_ast_type_t array_of_int_var;
scc_ast_type_array_init(&array_of_int_var,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
NULL); // NULL 表示不定长数组
null); // null 表示不定长数组
scc_ast_type_t ptr_to_array_var;
scc_ast_type_pointer_init(&ptr_to_array_var, &array_of_int_var);
@@ -713,7 +733,7 @@ static void test_parser_type(void) {
// 函数类型,返回 int*,无参数
scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type, &ptr_to_int, NULL);
scc_ast_type_function_init(&func_type, &ptr_to_int, null);
SCC_CHECK_AST(&func_type.base, "int *()", _scc_parse_type);
}
@@ -770,7 +790,7 @@ static void test_parser_type(void) {
// --- 数组,元素为上述 const 指针,大小未指定 ---
scc_ast_type_t array_of_ptr;
scc_ast_type_array_init(&array_of_ptr, &ptr_to_func, NULL);
scc_ast_type_array_init(&array_of_ptr, &ptr_to_func, null);
SCC_CHECK_AST(&array_of_ptr.base,
"int (*const [])(unsigned int, ...)",
@@ -901,7 +921,7 @@ static void test_parser_type(void) {
scc_ast_type_t array_of_int_unknown;
scc_ast_type_array_init(&array_of_int_unknown,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
NULL);
null);
SCC_CHECK_AST(&array_of_int_unknown.base, "int []", _scc_parse_type);
// // int [*] (变长数组原型中的不定长数组)
@@ -909,11 +929,11 @@ static void test_parser_type(void) {
// scc_ast_type_t array_of_int_var;
// scc_ast_type_array_init(&array_of_int_var,
// (scc_ast_type_t *)&scc_ast_builtin_type_int,
// NULL);
// // 注意:[*] 与 [] 在AST中目前无法区分都使用 size=NULL
// null);
// // 注意:[*] 与 [] 在AST中目前无法区分都使用 size=null
// // 表示。如果解析器需要区分,可能需要特殊处理。 这里暂时假设解析器对
// [*]
// // 也生成 size=NULL 的数组节点。
// // 也生成 size=null 的数组节点。
// SCC_CHECK_AST(&array_of_int_var.base, "int [*]", scc_parse_type);
// int [5][3] (二维数组)
@@ -1087,46 +1107,57 @@ static void test_parser_type(void) {
// struct S (不完整类型)
scc_ast_type_t struct_tag;
scc_ast_type_struct_init(&struct_tag, "S",
NULL); // name="S", members=NULL
null); // name="S", members=null
SCC_CHECK_AST(&struct_tag.base, "struct S", _scc_parse_type);
// struct { int x; } (匿名结构体定义)
scc_ast_decl_t field;
scc_ast_decl_val_init(
&field, (scc_ast_type_t *)&scc_ast_builtin_type_int, "x", NULL);
&field, (scc_ast_type_t *)&scc_ast_builtin_type_int, "x", null);
scc_ast_decl_vec_t fields;
scc_vec_init(fields);
scc_vec_push(fields, &field);
scc_ast_type_t struct_def;
scc_ast_type_struct_init(&struct_def, NULL,
&fields); // name=NULL, members=fields
SCC_CHECK_AST(&struct_def.base, "struct { int x; }", _scc_parse_type);
scc_ast_decl_t struct_def;
scc_ast_decl_struct_init(&struct_def, null, &fields);
scc_ast_type_t struct_type;
scc_ast_type_struct_init(&struct_type, null, &struct_def);
SCC_CHECK_AST(&struct_type.base, "struct { int x; }", _scc_parse_type);
scc_ast_decl_struct_init(&struct_def, "A", &fields);
scc_ast_type_struct_init(&struct_type, "A", &struct_def);
SCC_CHECK_AST(&struct_type.base, "struct A { int x; }",
_scc_parse_type);
// union U (不完整类型)
scc_ast_type_t union_tag;
scc_ast_type_union_init(&union_tag, "U", NULL);
scc_ast_type_union_init(&union_tag, "U", null);
SCC_CHECK_AST(&union_tag.base, "union U", _scc_parse_type);
// union { int a; float b; } (匿名联合定义)
scc_ast_decl_t field_a, field_b;
scc_ast_decl_val_init(
&field_a, (scc_ast_type_t *)&scc_ast_builtin_type_int, "a", NULL);
&field_a, (scc_ast_type_t *)&scc_ast_builtin_type_int, "a", null);
scc_ast_decl_val_init(
&field_b, (scc_ast_type_t *)&scc_ast_builtin_type_float, "b", NULL);
&field_b, (scc_ast_type_t *)&scc_ast_builtin_type_float, "b", null);
scc_ast_decl_vec_t fields_union;
scc_vec_init(fields_union);
scc_vec_push(fields_union, &field_a);
scc_vec_push(fields_union, &field_b);
scc_ast_type_t union_def;
scc_ast_type_union_init(&union_def, NULL, &fields_union);
SCC_CHECK_AST(&union_def.base, "union { int a; float b; }",
scc_ast_decl_t union_def;
scc_ast_decl_union_init(&union_def, null, &fields_union);
scc_ast_type_t union_type;
scc_ast_type_union_init(&union_type, null, &union_def);
SCC_CHECK_AST(&union_type.base, "union { int a; float b; }",
_scc_parse_type);
scc_ast_decl_union_init(&union_def, "Union", &fields_union);
scc_ast_type_union_init(&union_type, "Union", &union_def);
SCC_CHECK_AST(&union_type.base, "union Union { int a; float b; }",
_scc_parse_type);
// enum E (不完整类型)
scc_ast_type_t enum_tag;
scc_ast_type_enum_init(&enum_tag, "E", NULL);
scc_ast_type_enum_init(&enum_tag, "E", null);
SCC_CHECK_AST(&enum_tag.base, "enum E", _scc_parse_type);
// enum { RED, GREEN, BLUE } (匿名枚举定义)
@@ -1140,9 +1171,15 @@ static void test_parser_type(void) {
scc_vec_push(enumerators, &green);
scc_vec_push(enumerators, &blue);
scc_ast_type_t enum_def;
scc_ast_type_enum_init(&enum_def, NULL, &enumerators);
SCC_CHECK_AST(&enum_def.base, "enum { RED, GREEN, BLUE }",
scc_ast_decl_t enum_def;
scc_ast_decl_enum_init(&enum_def, null, &enumerators);
scc_ast_type_t enum_type;
scc_ast_type_enum_init(&enum_type, null, &enum_def);
SCC_CHECK_AST(&enum_type.base, "enum { RED, GREEN, BLUE }",
_scc_parse_type);
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_parse_type);
}
@@ -1189,13 +1226,13 @@ static void test_parser_type(void) {
SCC_CHECK_AST(&ptr_to_array.base, "const int * volatile (*)[10]",
_scc_parse_type);
// int (*(*)(int, ...))(float)
// float (*(*)(int, ...))()
// 1) float 类型作为内部函数返回类型
// 2) 构建返回 float 的函数类型,无参数(或者参数为空)
scc_ast_type_t func_ret_float;
scc_ast_type_function_init(
&func_ret_float, (scc_ast_type_t *)&scc_ast_builtin_type_float,
NULL);
null);
// 3) 指针指向该函数
scc_ast_type_t ptr_to_func_ret_float;
@@ -1220,7 +1257,7 @@ static void test_parser_type(void) {
// 5) 指针指向外层函数
scc_ast_type_t ptr_to_outer_func;
scc_ast_type_pointer_init(&ptr_to_outer_func, &outer_func);
SCC_CHECK_AST(&ptr_to_outer_func.base, "int (*(*)(int, ...))(float)",
SCC_CHECK_AST(&ptr_to_outer_func.base, "float (*(*)(int, ...))()",
_scc_parse_type);
}
}
@@ -1233,4 +1270,4 @@ TEST_LIST = {
// {"parser_declaration", test_parser_declaration},
// {"parser_translation_unit", test_parser_translation_unit},
{null, null},
};
};