refactor(ast): 调整AST结构体和枚举类型的声明表示方式
将结构体、联合和枚举类型的字段表示从向量改为声明指针, 允许name和decl字段为null,更新相关初始化函数的断言检查, 使结构更加灵活并支持不完整类型定义。 BREAKING CHANGE: 修改了scc_ast_type结构体中record和enumeration 子类型的字段表示方法,从fields向量改为decl指针。
This commit is contained in:
@@ -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},
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user