#include #include #include #include #include #include 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, cbool need_sema) { int res = 0; scc_sstream_t mem_stream; res = scc_sstream_init_by_buffer(&mem_stream, input, strlen(input), false, 16); Assert(res == 0); scc_lexer_t lexer; scc_lexer_init(&lexer, scc_sstream_to_ring(&mem_stream)); scc_lexer_tok_ring_t *tok_ring = scc_lexer_to_ring(&lexer, 64, false); scc_parser_t parser; 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); cbool not_eof = false; scc_ring_not_eof(*parser.ring, not_eof); if (not_eof == true) { // FIXME MAYBE free LOG_ERROR("Didn't consume all tokens"); return null; } scc_lexer_drop_ring(parser.ring); scc_parser_drop(&parser); scc_lexer_drop(&lexer); scc_sstream_drop(&mem_stream); return ret; } typedef void (*scc_tree_dump_output_t)(void *userdata, const char *fmt, ...); #define BUFFER_SIZE (4096) char expect_buffer[BUFFER_SIZE]; char output_buffer[BUFFER_SIZE]; static void dump2buffer(void *_buffer, const char *fmt, ...) { char *buffer = _buffer; va_list args; va_start(args, fmt); int res = scc_vsnprintf(buffer + strlen(buffer), BUFFER_SIZE - strlen(buffer) - 1, fmt, args); Assert(res > 0); va_end(args); } static void _scc_check_ast(scc_ast_node_t *expect_node_ptr, const char *str, 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); 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_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, \ false); \ TEST_CHECK(strcmp(output_buffer, expect_buffer) == 0); \ TEST_MSG("Expected: %s", expect_buffer); \ TEST_MSG("Produced: %s", output_buffer); \ } while (0); static void test_parser_unit(void) { // 1. 变量声明 int a; { scc_ast_decl_t int_decl; scc_ast_decl_val_init( &int_decl, (scc_ast_type_t *)&scc_ast_builtin_type_int, "a", null); SCC_CHECK_AST(&int_decl.base, "int a;", scc_parse_declaration); } // 2. 函数声明 int main(void) {} { // 构造函数类型:返回 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, &scc_ast_builtin_type_int, &func_params); // 构造复合语句块(空) scc_ast_stmt_t compound; scc_ast_stmt_compound_init(&compound, null); // 构造函数声明 scc_ast_decl_t func_decl; scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound); SCC_CHECK_AST(&func_decl.base, "int main(void) {}", scc_parse_declaration); } // 3. 翻译单元包含一个函数定义 { 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, &scc_ast_builtin_type_int, &func_params); scc_ast_stmt_t compound; scc_ast_stmt_compound_init(&compound, null); scc_ast_decl_t func_decl; scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound); // 构造翻译单元 scc_ast_decl_vec_t tu_decls; scc_vec_init(tu_decls); scc_vec_push(tu_decls, &func_decl); scc_ast_translation_unit_t tu; scc_ast_translation_unit_init(&tu, &tu_decls); SCC_CHECK_AST(&tu.base, "int main(void) {}", scc_parse_translation_unit); } // 4. 带返回语句的函数 int main(void) { return 65536; } { // 返回语句中的整数常量 scc_ast_expr_t ret_val; scc_ast_expr_literal_int_init(&ret_val, "65536", false); scc_ast_stmt_t ret_stmt; scc_ast_stmt_return_init(&ret_stmt, &ret_val); // 复合语句包含该返回语句 scc_ast_block_item_vec_t items; scc_vec_init(items); scc_vec_push(items, (scc_ast_node_t *)&ret_stmt); scc_ast_stmt_t compound; scc_ast_stmt_compound_init(&compound, &items); // items 被移动 // 函数类型 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, &scc_ast_builtin_type_int, &func_params); scc_ast_decl_t func_decl; scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound); scc_ast_decl_vec_t tu_decls; scc_vec_init(tu_decls); scc_vec_push(tu_decls, &func_decl); scc_ast_translation_unit_t tu; scc_ast_translation_unit_init(&tu, &tu_decls); SCC_CHECK_AST(&tu.base, "int main(void) { return 65536; }", scc_parse_translation_unit); } // 5. 多语句函数(复杂示例) { // 变量声明 int a; scc_ast_decl_t a_decl; scc_ast_decl_val_init(&a_decl, &scc_ast_builtin_type_int, "a", null); // 变量声明 int b; scc_ast_decl_t b_decl; scc_ast_decl_val_init(&b_decl, &scc_ast_builtin_type_int, "b", null); // 表达式 1 + 2 * 3 scc_ast_expr_t lit1, lit2, lit3, mul, add; scc_ast_expr_literal_int_init(&lit1, "1", false); scc_ast_expr_literal_int_init(&lit2, "2", false); scc_ast_expr_literal_int_init(&lit3, "3", false); scc_ast_expr_binary_init(&mul, SCC_AST_OP_MUL, &lit2, &lit3); scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &lit1, &mul); // 赋值 a = 1 + 2 * 3; scc_ast_expr_t a_ref1, assign1; scc_ast_expr_identifier_init(&a_ref1, "a"); scc_ast_expr_binary_init(&assign1, SCC_AST_OP_ASSIGN, &a_ref1, &add); scc_ast_stmt_t assign1_stmt; scc_ast_stmt_expr_init(&assign1_stmt, &assign1); // 赋值 b = 7; scc_ast_expr_t lit7; scc_ast_expr_literal_int_init(&lit7, "7", false); scc_ast_expr_t b_ref1, assign2; scc_ast_expr_identifier_init(&b_ref1, "b"); scc_ast_expr_binary_init(&assign2, SCC_AST_OP_ASSIGN, &b_ref1, &lit7); scc_ast_stmt_t assign2_stmt; scc_ast_stmt_expr_init(&assign2_stmt, &assign2); // 表达式 a - b + 1 scc_ast_expr_t a_ref2, b_ref2, sub, add2, lit1_2; scc_ast_expr_identifier_init(&a_ref2, "a"); scc_ast_expr_identifier_init(&b_ref2, "b"); scc_ast_expr_binary_init(&sub, SCC_AST_OP_SUB, &a_ref2, &b_ref2); scc_ast_expr_literal_int_init(&lit1_2, "1", false); scc_ast_expr_binary_init(&add2, SCC_AST_OP_ADD, &sub, &lit1_2); // 赋值 a = a - b + 1; scc_ast_expr_t a_ref3, assign3; scc_ast_expr_identifier_init(&a_ref3, "a"); scc_ast_expr_binary_init(&assign3, SCC_AST_OP_ASSIGN, &a_ref3, &add2); scc_ast_stmt_t assign3_stmt; scc_ast_stmt_expr_init(&assign3_stmt, &assign3); // return a; scc_ast_expr_t a_ref4; scc_ast_expr_identifier_init(&a_ref4, "a"); scc_ast_stmt_t ret_stmt; scc_ast_stmt_return_init(&ret_stmt, &a_ref4); // 复合语句块,按顺序放入 scc_ast_block_item_vec_t items; scc_vec_init(items); scc_vec_push(items, (scc_ast_node_t *)&a_decl); scc_vec_push(items, (scc_ast_node_t *)&b_decl); scc_vec_push(items, (scc_ast_node_t *)&assign1_stmt); scc_vec_push(items, (scc_ast_node_t *)&assign2_stmt); scc_vec_push(items, (scc_ast_node_t *)&assign3_stmt); scc_vec_push(items, (scc_ast_node_t *)&ret_stmt); scc_ast_stmt_t compound; scc_ast_stmt_compound_init(&compound, &items); // 函数类型 scc_ast_type_t func_type; scc_ast_type_function_init( &func_type, (scc_ast_type_t *)&scc_ast_builtin_type_int, null); scc_ast_decl_t func_decl; scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound); scc_ast_decl_vec_t tu_decls; scc_vec_init(tu_decls); scc_vec_push(tu_decls, &func_decl); scc_ast_translation_unit_t tu; scc_ast_translation_unit_init(&tu, &tu_decls); const char *input = "int main() {\n" " int a;\n" " int b;\n" " a = 1 + 2 * 3;\n" " b = 7;\n" " a = a - b + 1;\n" " return a;\n" "}\n"; SCC_CHECK_AST(&tu.base, input, scc_parse_translation_unit); } { // 整数字面量 10 scc_ast_expr_t lit10; scc_ast_expr_literal_int_init(&lit10, "10", false); // 变量声明 int x = 10; scc_ast_decl_t x_decl; scc_ast_decl_val_init( &x_decl, (scc_ast_type_t *)&scc_ast_builtin_type_int, "x", &lit10); // 表达式 x + 1 scc_ast_expr_t x_ref1, lit1, add; scc_ast_expr_identifier_init(&x_ref1, "x"); scc_ast_expr_literal_int_init(&lit1, "1", false); scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &x_ref1, &lit1); // 赋值 x = x + 1 scc_ast_expr_t x_ref2, assign; scc_ast_expr_identifier_init(&x_ref2, "x"); scc_ast_expr_binary_init(&assign, SCC_AST_OP_ASSIGN, &x_ref2, &add); // 表达式语句 scc_ast_stmt_t assign_stmt; scc_ast_stmt_expr_init(&assign_stmt, &assign); // return x scc_ast_expr_t x_ref3; scc_ast_expr_identifier_init(&x_ref3, "x"); scc_ast_stmt_t ret_stmt; scc_ast_stmt_return_init(&ret_stmt, &x_ref3); // 复合语句块 scc_ast_block_item_vec_t items; scc_vec_init(items); scc_vec_push(items, (scc_ast_node_t *)&x_decl); scc_vec_push(items, (scc_ast_node_t *)&assign_stmt); scc_vec_push(items, (scc_ast_node_t *)&ret_stmt); scc_ast_stmt_t compound; scc_ast_stmt_compound_init(&compound, &items); // 函数类型(返回 int,无参数) scc_ast_type_t func_type; scc_ast_type_function_init(&func_type, (scc_ast_type_t *)&scc_ast_builtin_type_int, null); // null 表示无参数 // 函数声明 int main() { ... } scc_ast_decl_t func_decl; scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound); // 翻译单元 scc_ast_decl_vec_t tu_decls; scc_vec_init(tu_decls); scc_vec_push(tu_decls, &func_decl); scc_ast_translation_unit_t tu; scc_ast_translation_unit_init(&tu, &tu_decls); // 输入源代码 const char *input = "int main() {\n" " int x = 10;\n" " x = x + 1;\n" " return x;\n" "}\n"; // 比较解析结果与期望 AST SCC_CHECK_AST(&tu.base, input, scc_parse_translation_unit); } { scc_ast_decl_vec_t params; scc_ast_decl_t param0; scc_ast_decl_param_init( ¶m0, (scc_ast_type_t *)&scc_ast_builtin_type_int, "a"); scc_ast_decl_t param1; scc_ast_decl_param_init( ¶m1, (scc_ast_type_t *)&scc_ast_builtin_type_int, "b"); scc_ast_decl_t param2; scc_ast_decl_param_init( ¶m2, (scc_ast_type_t *)&scc_ast_builtin_type_va_list, null); scc_ast_decl_t *params_array[] = {¶m0, ¶m1, ¶m2}; scc_vec_unsafe_from_array(params, params_array); scc_ast_type_t decl_func_type; scc_ast_type_function_init(&decl_func_type, (scc_ast_type_t *)&scc_ast_builtin_type_int, ¶ms); scc_ast_decl_t decl_func; scc_ast_decl_func_init(&decl_func, &decl_func_type, "add", null); SCC_CHECK_AST(&decl_func.base, "int add(int a, int b, ...);", scc_parse_declaration); } { scc_ast_decl_t typedef_decl; scc_ast_decl_typedef_init(&typedef_decl, "int32_t", &scc_ast_builtin_type_int); 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); } { // 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); 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(¶m1, &type_type, "a"); scc_ast_decl_t param2; scc_ast_decl_param_init(¶m2, &scc_ast_builtin_type_int, "b"); scc_ast_decl_t param3; scc_ast_decl_param_init(¶m3, &scc_ast_builtin_type_va_list, null); scc_ast_decl_t *params_array[] = {¶m1, ¶m2, ¶m3}; 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); } { // 1. 构造参数类型:volatile const char *restrict,并附加 register // 存储类 scc_ast_type_t char_type; _scc_ast_type_builtin_init(&char_type, SCC_AST_BUILTIN_TYPE_CHAR); char_type.quals.is_const = true; // const char_type.quals.is_volatile = true; // volatile scc_ast_type_t ptr_to_char; scc_ast_type_pointer_init(&ptr_to_char, &char_type); ptr_to_char.quals.is_restrict = true; // restrict 限定指针 ptr_to_char.quals.is_register = true; // register 存储类(作用于参数) // 2. 参数声明 scc_ast_decl_t param_decl; scc_ast_decl_param_init(¶m_decl, &ptr_to_char, "fmt"); // 3. 返回类型:void * scc_ast_type_t void_type; _scc_ast_type_builtin_init(&void_type, SCC_AST_BUILTIN_TYPE_VOID); scc_ast_type_t ptr_to_void; scc_ast_type_pointer_init(&ptr_to_void, &void_type); // 4. 参数列表 scc_ast_decl_vec_t params; scc_vec_init(params); scc_vec_push(params, ¶m_decl); // 5. 函数类型(包含 static 和 inline) scc_ast_type_t func_type; scc_ast_type_function_init(&func_type, &ptr_to_void, ¶ms); func_type.quals.is_static = true; func_type.quals.is_inline = true; // 6. 函数声明 scc_ast_decl_t decl; scc_ast_decl_func_init(&decl, &func_type, "call", null); // 7. 与解析结果比较 SCC_CHECK_AST_WITH_SEMA(&decl.base, "static inline void *call(volatile register " "const char *restrict fmt);", scc_parse_declaration); } { scc_ast_expr_t lvalue; scc_ast_expr_lvalue_init(&lvalue, &scc_ast_builtin_type_void); scc_ast_expr_t lhs1; scc_ast_expr_member_init(&lhs1, &lvalue, "data"); scc_ast_expr_t lhs2; scc_ast_expr_member_init(&lhs2, &lvalue, "size"); scc_ast_expr_t lhs3; scc_ast_expr_member_init(&lhs3, &lvalue, "cap"); scc_ast_expr_t rl0; scc_ast_expr_literal_int_init(&rl0, "0", false); scc_ast_type_t void_ptr; scc_ast_type_pointer_init(&void_ptr, &scc_ast_builtin_type_void); scc_ast_expr_t rhs1; scc_ast_expr_cast_init(&rhs1, &void_ptr, &rl0); scc_ast_expr_t rhs2; scc_ast_expr_literal_int_init(&rhs2, "0", false); scc_ast_expr_t rhs3; scc_ast_expr_literal_int_init(&rhs3, "0", false); scc_ast_expr_vec_t lhs_exprs; scc_ast_expr_t *lhs_array[] = {&lhs1, &lhs2, &lhs3}; scc_vec_unsafe_from_array(lhs_exprs, lhs_array); scc_ast_expr_vec_t rhs_exprs; scc_ast_expr_t *rhs_array[] = {&rhs1, &rhs2, &rhs3}; scc_vec_unsafe_from_array(rhs_exprs, rhs_array); scc_ast_expr_t expr; scc_ast_expr_compound_init(&expr, &lvalue, &lhs_exprs, &rhs_exprs); // FIXME use real records type SCC_CHECK_AST(&expr.base, "(void){.data = ((void *)0), .size = 0, .cap = 0}", scc_parse_expression); scc_ast_stmt_t stmt; scc_ast_stmt_return_init(&stmt, &expr); SCC_CHECK_AST(&stmt.base, "return (void){.data = (void *)0, .size = 0, .cap = 0};", scc_parse_statement); scc_ast_expr_t lhs4; scc_ast_expr_t lhs5; scc_ast_expr_member_init(&lhs4, &lvalue, "a"); scc_ast_expr_member_init(&lhs5, &lhs4, "b"); scc_ast_expr_t lhs6; scc_ast_expr_t lhs7; scc_ast_expr_member_init(&lhs6, &lvalue, "c"); scc_ast_expr_array_subscript_init(&lhs7, &lhs6, &rl0); scc_ast_expr_t *lhs_array_hard[] = {&lhs5, &lhs7}; scc_vec_unsafe_from_array(lhs_exprs, lhs_array_hard); scc_ast_expr_t *rhs_array_hard[] = {&rhs2, &rhs3}; scc_vec_unsafe_from_array(rhs_exprs, rhs_array_hard); scc_ast_expr_compound_init(&expr, &lvalue, &lhs_exprs, &rhs_exprs); SCC_CHECK_AST(&expr.base, "(void){.a.b = 0, .c[0] = 0}", scc_parse_expression); } { // 测试 struct S; 仅标记声明 { scc_ast_decl_t struct_decl; scc_ast_decl_vec_t empty_members; scc_vec_init(empty_members); scc_ast_decl_struct_init(&struct_decl, "S", &empty_members); SCC_CHECK_AST(&struct_decl.base, "struct S;", scc_parse_declaration); } // 测试 union U; 仅标记声明 { scc_ast_decl_t union_decl; scc_ast_decl_vec_t empty_members; scc_vec_init(empty_members); scc_ast_decl_union_init(&union_decl, "U", &empty_members); SCC_CHECK_AST(&union_decl.base, "union U;", scc_parse_declaration); } // 测试 enum E; 仅标记声明 { scc_ast_decl_t enum_decl; scc_ast_expr_vec_t empty_enumerators; scc_vec_init(empty_enumerators); scc_ast_decl_enum_init(&enum_decl, "E", &empty_enumerators); SCC_CHECK_AST(&enum_decl.base, "enum E;", scc_parse_declaration); } } { scc_ast_stmt_t continue_stmt; scc_ast_stmt_continue_init(&continue_stmt); scc_ast_stmt_t stmt; scc_ast_stmt_label_init(&stmt, "NEXT", &continue_stmt); SCC_CHECK_AST(&stmt.base, "NEXT: continue;", scc_parse_statement); scc_ast_expr_t str; scc_ast_expr_literal_string_init(&str, "\"ab\"", false); SCC_CHECK_AST(&str.base, "\"a\" \"b\"", scc_parse_expression); } { // 测试 int a = *(int*)b; { // 构造类型 int* scc_ast_type_t ptr_to_int; scc_ast_type_pointer_init( &ptr_to_int, (scc_ast_type_t *)&scc_ast_builtin_type_int); // 标识符 b scc_ast_expr_t b_expr; scc_ast_expr_identifier_init(&b_expr, "b"); // 类型转换 (int*)b scc_ast_expr_t cast_expr; scc_ast_expr_cast_init(&cast_expr, &ptr_to_int, &b_expr); // 解引用 *(int*)b scc_ast_expr_t deref_expr; scc_ast_expr_unary_init(&deref_expr, SCC_AST_OP_INDIRECTION, &cast_expr); // 声明 int a = *(int*)b; scc_ast_decl_t decl; scc_ast_decl_val_init(&decl, (scc_ast_type_t *)&scc_ast_builtin_type_int, "a", &deref_expr); SCC_CHECK_AST(&decl.base, "int a = *(int*)b;", scc_parse_declaration); } // 测试 int a, b; { scc_ast_decl_t decl_a, decl_b; scc_ast_decl_val_init(&decl_a, (scc_ast_type_t *)&scc_ast_builtin_type_int, "a", null); scc_ast_decl_val_init(&decl_b, (scc_ast_type_t *)&scc_ast_builtin_type_int, "b", null); scc_ast_decl_vec_t decl_vec; scc_vec_init(decl_vec); scc_vec_push(decl_vec, &decl_a); scc_vec_push(decl_vec, &decl_b); scc_ast_decl_t decl_list; scc_ast_decl_list_init(&decl_list, &decl_vec); // 假设存在该函数 SCC_CHECK_AST(&decl_list.base, "int a, b;", scc_parse_declaration); } // 测试 int a = 1, b = 2; { scc_ast_expr_t lit1, lit2; scc_ast_expr_literal_int_init(&lit1, "1", false); scc_ast_expr_literal_int_init(&lit2, "2", false); scc_ast_decl_t decl_a, decl_b; scc_ast_decl_val_init(&decl_a, (scc_ast_type_t *)&scc_ast_builtin_type_int, "a", &lit1); scc_ast_decl_val_init(&decl_b, (scc_ast_type_t *)&scc_ast_builtin_type_int, "b", &lit2); scc_ast_decl_vec_t decl_vec; scc_vec_init(decl_vec); scc_vec_push(decl_vec, &decl_a); scc_vec_push(decl_vec, &decl_b); scc_ast_decl_t decl_list; scc_ast_decl_list_init(&decl_list, &decl_vec); // 假设存在该函数 SCC_CHECK_AST(&decl_list.base, "int a = 1, b = 2;", scc_parse_declaration); } // 测试 "struct list_head *next, *prev;" { // 构造 struct list_head 类型(不完整) scc_ast_type_t struct_list_head; scc_ast_type_struct_init(&struct_list_head, "list_head", null); // 构造两个指针类型(分别用于 next 和 prev,指向同一结构体) scc_ast_type_t ptr_to_struct1, ptr_to_struct2; scc_ast_type_pointer_init(&ptr_to_struct1, &struct_list_head); scc_ast_type_pointer_init(&ptr_to_struct2, &struct_list_head); // 构造变量声明 next 和 prev scc_ast_decl_t next_decl, prev_decl; scc_ast_decl_val_init(&next_decl, &ptr_to_struct1, "next", null); scc_ast_decl_val_init(&prev_decl, &ptr_to_struct2, "prev", null); // 构造声明列表 scc_ast_decl_vec_t decl_vec; scc_vec_init(decl_vec); scc_vec_push(decl_vec, &next_decl); scc_vec_push(decl_vec, &prev_decl); scc_ast_decl_t decl_list; scc_ast_decl_list_init(&decl_list, &decl_vec); SCC_CHECK_AST(&decl_list.base, "struct list_head *next, *prev;", scc_parse_declaration); } // 测试 "typedef struct { int a; } struct_t, *struct_ptr_t;" { // 构造字段 int a; scc_ast_decl_t field_a; scc_ast_decl_val_init(&field_a, (scc_ast_type_t *)&scc_ast_builtin_type_int, "a", null); scc_ast_decl_vec_t fields; scc_vec_init(fields); scc_vec_push(fields, &field_a); // 构造匿名结构体定义声明 scc_ast_decl_t struct_def; scc_ast_decl_struct_init(&struct_def, null, &fields); // fields 被移动 // 构造匿名结构体类型 scc_ast_type_t anon_struct_type; scc_ast_type_struct_init(&anon_struct_type, null, &struct_def); // 构造指针类型指向该匿名结构体 scc_ast_type_t ptr_to_anon; scc_ast_type_pointer_init(&ptr_to_anon, &anon_struct_type); // 构造 typedef 声明 struct_t scc_ast_decl_t typedef_struct_t; scc_ast_decl_typedef_init(&typedef_struct_t, "struct_t", &anon_struct_type); // 构造 typedef 声明 struct_ptr_t scc_ast_decl_t typedef_struct_ptr_t; scc_ast_decl_typedef_init(&typedef_struct_ptr_t, "struct_ptr_t", &ptr_to_anon); // 构造声明列表 scc_ast_decl_vec_t typedef_vec; scc_vec_init(typedef_vec); scc_vec_push(typedef_vec, &typedef_struct_t); scc_vec_push(typedef_vec, &typedef_struct_ptr_t); scc_ast_decl_t decl_list; scc_ast_decl_list_init(&decl_list, &typedef_vec); SCC_CHECK_AST(&decl_list.base, "typedef struct { int a; } struct_t, *struct_ptr_t;", scc_parse_declaration); } "__scc_builtin_va_arg(ag, int)"; "__scc_builtin_va_arg(ag, long long)"; "typedef struct a;int a;struct a b;"; } { // 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(¶m1, &ptr_to_func, "bar"); scc_ast_decl_t param2; scc_ast_decl_param_init(¶m2, &typedef_func_type, "a"); scc_ast_decl_t param3; scc_ast_decl_param_init(¶m1, &scc_ast_builtin_type_va_list, null); scc_ast_decl_t *func_hard_array[] = {¶m1, ¶m2, ¶m3}; 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); } } static void test_parser_expression(void) { // 1. 基本表达式 { scc_ast_expr_t ident; scc_ast_expr_identifier_init(&ident, "x"); SCC_CHECK_AST(&ident.base, "x", scc_parse_expression); scc_ast_expr_t int_lit; scc_ast_expr_literal_int_init(&int_lit, "42", false); SCC_CHECK_AST(&int_lit.base, "42", scc_parse_expression); scc_ast_expr_t str_lit; scc_ast_expr_literal_string_init(&str_lit, "\"hello\"", false); SCC_CHECK_AST(&str_lit.base, "\"hello\"", scc_parse_expression); // 括号表达式(解析器应直接返回内部表达式) scc_ast_expr_t paren_ident; scc_ast_expr_identifier_init(&paren_ident, "y"); SCC_CHECK_AST(&paren_ident.base, "(y)", scc_parse_expression); } // 2. 后缀表达式 { // 数组下标 a[10] scc_ast_expr_t a, index, subscript; scc_ast_expr_identifier_init(&a, "a"); scc_ast_expr_literal_int_init(&index, "10", false); scc_ast_expr_array_subscript_init(&subscript, &a, &index); SCC_CHECK_AST(&subscript.base, "a[10]", scc_parse_expression); // 函数调用 f() scc_ast_expr_t f; scc_ast_expr_identifier_init(&f, "f"); scc_ast_expr_vec_t args; scc_vec_init(args); scc_ast_expr_t call; scc_ast_expr_t callee1; scc_ast_expr_identifier_init(&callee1, "f"); scc_ast_expr_call_init(&call, &callee1, &args); // 使用函数名,target 在语义分析时填充 SCC_CHECK_AST(&call.base, "f()", scc_parse_expression); // 函数调用带参数 f(1, x) scc_ast_expr_t arg1, arg2; scc_ast_expr_literal_int_init(&arg1, "1", false); scc_ast_expr_identifier_init(&arg2, "x"); scc_ast_expr_vec_t args2; scc_vec_init(args2); scc_vec_push(args2, &arg1); scc_vec_push(args2, &arg2); scc_ast_expr_t callee2; scc_ast_expr_identifier_init(&callee2, "f"); scc_ast_expr_t call2; scc_ast_expr_call_init(&call2, &callee2, &args2); SCC_CHECK_AST(&call2.base, "f(1, x)", scc_parse_expression); // 成员访问 . scc_ast_expr_t s, dot; scc_ast_expr_identifier_init(&s, "s"); scc_ast_expr_member_init(&dot, &s, "field"); SCC_CHECK_AST(&dot.base, "s.field", scc_parse_expression); // 指针成员访问 -> scc_ast_expr_t p, arrow; scc_ast_expr_identifier_init(&p, "p"); scc_ast_expr_ptr_member_init(&arrow, &p, "field"); SCC_CHECK_AST(&arrow.base, "p->field", scc_parse_expression); // 后缀 ++/-- scc_ast_expr_t x, post_inc, post_dec; scc_ast_expr_identifier_init(&x, "x"); scc_ast_expr_unary_init(&post_inc, SCC_AST_OP_POSTFIX_INCREMENT, &x); scc_ast_expr_unary_init(&post_dec, SCC_AST_OP_POSTFIX_DECREMENT, &x); SCC_CHECK_AST(&post_inc.base, "x++", scc_parse_expression); SCC_CHECK_AST(&post_dec.base, "x--", scc_parse_expression); } // 3. 一元表达式 { scc_ast_expr_t x; scc_ast_expr_identifier_init(&x, "x"); scc_ast_expr_t pre_inc; scc_ast_expr_unary_init(&pre_inc, SCC_AST_OP_PREFIX_INCREMENT, &x); SCC_CHECK_AST(&pre_inc.base, "++x", scc_parse_expression); scc_ast_expr_t pre_dec; scc_ast_expr_unary_init(&pre_dec, SCC_AST_OP_PREFIX_DECREMENT, &x); SCC_CHECK_AST(&pre_dec.base, "--x", scc_parse_expression); scc_ast_expr_t addr; scc_ast_expr_unary_init(&addr, SCC_AST_OP_ADDRESS_OF, &x); SCC_CHECK_AST(&addr.base, "&x", scc_parse_expression); scc_ast_expr_t deref; scc_ast_expr_unary_init(&deref, SCC_AST_OP_INDIRECTION, &x); SCC_CHECK_AST(&deref.base, "*x", scc_parse_expression); scc_ast_expr_t plus; scc_ast_expr_unary_init(&plus, SCC_AST_OP_UNARY_PLUS, &x); SCC_CHECK_AST(&plus.base, "+x", scc_parse_expression); scc_ast_expr_t minus; scc_ast_expr_unary_init(&minus, SCC_AST_OP_UNARY_MINUS, &x); SCC_CHECK_AST(&minus.base, "-x", scc_parse_expression); scc_ast_expr_t bit_not; scc_ast_expr_unary_init(&bit_not, SCC_AST_OP_BITWISE_NOT, &x); SCC_CHECK_AST(&bit_not.base, "~x", scc_parse_expression); scc_ast_expr_t log_not; scc_ast_expr_unary_init(&log_not, SCC_AST_OP_LOGICAL_NOT, &x); SCC_CHECK_AST(&log_not.base, "!x", scc_parse_expression); // sizeof 表达式 scc_ast_expr_t sizeof_x_expr; scc_ast_expr_sizeof_init(&sizeof_x_expr, null, &x); SCC_CHECK_AST(&sizeof_x_expr.base, "sizeof(x)", scc_parse_expression); scc_ast_expr_t sizeof_int_expr; scc_ast_expr_sizeof_init(&sizeof_int_expr, (scc_ast_type_t *)&scc_ast_builtin_type_int, null); SCC_CHECK_AST(&sizeof_int_expr.base, "sizeof(int)", scc_parse_expression); } // 4. 类型转换(示例: (int)x ) { 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. 二元运算符优先级 { scc_ast_expr_t a, b, c, d; scc_ast_expr_identifier_init(&a, "a"); scc_ast_expr_identifier_init(&b, "b"); scc_ast_expr_identifier_init(&c, "c"); scc_ast_expr_identifier_init(&d, "d"); // a * b + c scc_ast_expr_t mul, add; scc_ast_expr_binary_init(&mul, SCC_AST_OP_MUL, &a, &b); scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &mul, &c); SCC_CHECK_AST(&add.base, "a * b + c", scc_parse_expression); // a - b - c => (a - b) - c scc_ast_expr_t sub1, sub2; scc_ast_expr_binary_init(&sub1, SCC_AST_OP_SUB, &a, &b); scc_ast_expr_binary_init(&sub2, SCC_AST_OP_SUB, &sub1, &c); SCC_CHECK_AST(&sub2.base, "a - b - c", scc_parse_expression); // a << b scc_ast_expr_t shift; scc_ast_expr_binary_init(&shift, SCC_AST_OP_LEFT_SHIFT, &a, &b); SCC_CHECK_AST(&shift.base, "a << b", scc_parse_expression); // a < b scc_ast_expr_t lt; scc_ast_expr_binary_init(<, SCC_AST_OP_LESS, &a, &b); SCC_CHECK_AST(<.base, "a < b", scc_parse_expression); // a == b scc_ast_expr_t eq; scc_ast_expr_binary_init(&eq, SCC_AST_OP_EQUAL, &a, &b); SCC_CHECK_AST(&eq.base, "a == b", scc_parse_expression); // a & b ^ c | d scc_ast_expr_t bitand, bitxor, bitor; scc_ast_expr_binary_init(&bitand, SCC_AST_OP_BITWISE_AND, &a, &b); scc_ast_expr_binary_init(&bitxor, SCC_AST_OP_BITWISE_XOR, &bitand, &c); scc_ast_expr_binary_init(&bitor, SCC_AST_OP_BITWISE_OR, &bitxor, &d); SCC_CHECK_AST(&bitor.base, "a & b ^ c | d", scc_parse_expression); // a && b || c scc_ast_expr_t logand, logor; scc_ast_expr_binary_init(&logand, SCC_AST_OP_LOGICAL_AND, &a, &b); scc_ast_expr_binary_init(&logor, SCC_AST_OP_LOGICAL_OR, &logand, &c); SCC_CHECK_AST(&logor.base, "a && b || c", scc_parse_expression); } // 6. 三元运算符 { scc_ast_expr_t a, b, c; scc_ast_expr_identifier_init(&a, "a"); scc_ast_expr_identifier_init(&b, "b"); scc_ast_expr_identifier_init(&c, "c"); // a ? b : c scc_ast_expr_t cond1; scc_ast_expr_cond_init(&cond1, &a, &b, &c); SCC_CHECK_AST(&cond1.base, "a ? b : c", scc_parse_expression); // a ? b : c ? d : e => a ? b : (c ? d : e) scc_ast_expr_t d, e; scc_ast_expr_identifier_init(&d, "d"); scc_ast_expr_identifier_init(&e, "e"); scc_ast_expr_t inner, outer; scc_ast_expr_cond_init(&inner, &c, &d, &e); scc_ast_expr_cond_init(&outer, &a, &b, &inner); SCC_CHECK_AST(&outer.base, "a ? b : c ? d : e", scc_parse_expression); } // 7. 赋值运算符 { scc_ast_expr_t a, b, c; scc_ast_expr_identifier_init(&a, "a"); scc_ast_expr_identifier_init(&b, "b"); scc_ast_expr_identifier_init(&c, "c"); scc_ast_expr_t lit42; scc_ast_expr_literal_int_init(&lit42, "42", false); // a = b = c scc_ast_expr_t assign_inner, assign_outer; scc_ast_expr_binary_init(&assign_inner, SCC_AST_OP_ASSIGN, &b, &c); scc_ast_expr_binary_init(&assign_outer, SCC_AST_OP_ASSIGN, &a, &assign_inner); SCC_CHECK_AST(&assign_outer.base, "a = b = c", scc_parse_expression); // a = 42 scc_ast_expr_t assign1; scc_ast_expr_binary_init(&assign1, SCC_AST_OP_ASSIGN, &a, &lit42); SCC_CHECK_AST(&assign1.base, "a = 42", scc_parse_expression); // a = a - b + 42 scc_ast_expr_t sub, add, assign2; scc_ast_expr_binary_init(&sub, SCC_AST_OP_SUB, &a, &b); scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &sub, &lit42); scc_ast_expr_binary_init(&assign2, SCC_AST_OP_ASSIGN, &a, &add); SCC_CHECK_AST(&assign2.base, "a = a - b + 42", scc_parse_expression); // a += b scc_ast_expr_t add_assign; scc_ast_expr_binary_init(&add_assign, SCC_AST_OP_ASSIGN_ADD, &a, &b); SCC_CHECK_AST(&add_assign.base, "a += b", scc_parse_expression); } // 8. 逗号运算符 { scc_ast_expr_t a, b; scc_ast_expr_identifier_init(&a, "a"); scc_ast_expr_identifier_init(&b, "b"); scc_ast_expr_t comma; scc_ast_expr_binary_init(&comma, SCC_AST_OP_COMMA, &a, &b); SCC_CHECK_AST(&comma.base, "a, b", scc_parse_expression); } // 9. 混合优先级 { scc_ast_expr_t a, b, c, d; scc_ast_expr_identifier_init(&a, "a"); scc_ast_expr_identifier_init(&b, "b"); scc_ast_expr_identifier_init(&c, "c"); scc_ast_expr_identifier_init(&d, "d"); // a + b * c - d scc_ast_expr_t mul, add, sub; scc_ast_expr_binary_init(&mul, SCC_AST_OP_MUL, &b, &c); scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &a, &mul); scc_ast_expr_binary_init(&sub, SCC_AST_OP_SUB, &add, &d); SCC_CHECK_AST(&sub.base, "a + b * c - d", scc_parse_expression); // *p++ scc_ast_expr_t p, post_inc, deref; scc_ast_expr_identifier_init(&p, "p"); scc_ast_expr_unary_init(&post_inc, SCC_AST_OP_POSTFIX_INCREMENT, &p); scc_ast_expr_unary_init(&deref, SCC_AST_OP_INDIRECTION, &post_inc); SCC_CHECK_AST(&deref.base, "*p++", scc_parse_expression); } } static void test_parser_type(void) { { // 1. int { SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_int, "int", scc_parse_type_name); } // 2. int * { scc_ast_type_t ptr_to_int; scc_ast_type_pointer_init( &ptr_to_int, (scc_ast_type_t *)&scc_ast_builtin_type_int); SCC_CHECK_AST(&ptr_to_int.base, "int *", scc_parse_type_name); } // 3. int *[3] { scc_ast_type_t ptr_to_int; scc_ast_type_pointer_init( &ptr_to_int, (scc_ast_type_t *)&scc_ast_builtin_type_int); scc_ast_expr_t size_3; scc_ast_expr_literal_int_init(&size_3, "3", false); scc_ast_type_t array_of_ptr; scc_ast_type_array_init(&array_of_ptr, &ptr_to_int, &size_3); SCC_CHECK_AST(&array_of_ptr.base, "int *[3]", scc_parse_type_name); } // 4. int (*)[3] { scc_ast_expr_t size_3; scc_ast_expr_literal_int_init(&size_3, "3", false); scc_ast_type_t array_of_int; scc_ast_type_array_init(&array_of_int, (scc_ast_type_t *)&scc_ast_builtin_type_int, &size_3); scc_ast_type_t ptr_to_array; scc_ast_type_pointer_init(&ptr_to_array, &array_of_int); SCC_CHECK_AST(&ptr_to_array.base, "int (*)[3]", scc_parse_type_name); } // 5. int (*)[*] { 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 表示不定长数组 scc_ast_type_t ptr_to_array_var; scc_ast_type_pointer_init(&ptr_to_array_var, &array_of_int_var); SCC_CHECK_AST(&ptr_to_array_var.base, "int (*)[*]", scc_parse_type_name); } // 6. int *() { // 返回类型 int* scc_ast_type_t ptr_to_int; scc_ast_type_pointer_init( &ptr_to_int, (scc_ast_type_t *)&scc_ast_builtin_type_int); // 函数类型,返回 int*,无参数 scc_ast_type_t func_type; scc_ast_type_function_init(&func_type, &ptr_to_int, null); SCC_CHECK_AST(&func_type.base, "int *()", scc_parse_type_name); } // 7. int (*)(void) { // 函数类型,返回 int,无参数 scc_ast_type_t func_void; 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_void, (scc_ast_type_t *)&scc_ast_builtin_type_int, &func_params); scc_ast_type_t ptr_to_func; scc_ast_type_pointer_init(&ptr_to_func, &func_void); SCC_CHECK_AST(&ptr_to_func.base, "int (*)(void)", scc_parse_type_name); } // 8. int (*const [])(unsigned int, ...) { // --- 构造参数列表 --- // 第一个参数:unsigned int scc_ast_decl_t param_uint; scc_ast_decl_param_init( ¶m_uint, (scc_ast_type_t *)&scc_ast_builtin_type_unsigned_int, "u"); // 第二个参数:... 用内置 va_list 类型近似表示 scc_ast_type_t va_list_type; _scc_ast_type_builtin_init(&va_list_type, SCC_AST_BUILTIN_TYPE_VA_LIST); scc_ast_decl_t param_var; scc_ast_decl_param_init(¶m_var, &va_list_type, "..."); scc_ast_decl_vec_t params; scc_vec_init(params); scc_vec_push(params, ¶m_uint); scc_vec_push(params, ¶m_var); // --- 函数类型,返回 int --- scc_ast_type_t func_type; scc_ast_type_function_init( &func_type, (scc_ast_type_t *)&scc_ast_builtin_type_int, ¶ms); // params 被移动 // --- 指向函数的指针,带 const 限定 --- scc_ast_type_t ptr_to_func; scc_ast_type_pointer_init(&ptr_to_func, &func_type); ptr_to_func.quals.is_const = true; // 设置 const // --- 数组,元素为上述 const 指针,大小未指定 --- scc_ast_type_t array_of_ptr; scc_ast_type_array_init(&array_of_ptr, &ptr_to_func, null); SCC_CHECK_AST(&array_of_ptr.base, "int (*const [])(unsigned int, ...)", scc_parse_type_name); } } // 1. 基本内置类型及组合 { // int SCC_CHECK_AST(&scc_ast_builtin_type_int.base, "int", scc_parse_type_name); // char SCC_CHECK_AST(&scc_ast_builtin_type_char.base, "char", scc_parse_type_name); // long long SCC_CHECK_AST(&scc_ast_builtin_type_long_long.base, "long long", scc_parse_type_name); // long long SCC_CHECK_AST(&scc_ast_builtin_type_long_long.base, "long long int", scc_parse_type_name); // short SCC_CHECK_AST(&scc_ast_builtin_type_short.base, "short int", scc_parse_type_name); // unsigned int SCC_CHECK_AST(&scc_ast_builtin_type_unsigned_int.base, "unsigned int", scc_parse_type_name); // float SCC_CHECK_AST(&scc_ast_builtin_type_float.base, "float", scc_parse_type_name); // double SCC_CHECK_AST(&scc_ast_builtin_type_double.base, "double", scc_parse_type_name); // void SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_void, "void", scc_parse_type_name); // bool SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_bool, "bool", scc_parse_type_name); // long double SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_long_double, "long double", scc_parse_type_name); // _Complex double SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_complex_double, "double complex", scc_parse_type_name); } // 2. 带类型限定符的基本类型 (const, volatile) { // const int scc_ast_type_t const_int = scc_ast_builtin_type_int; const_int.quals.is_const = true; SCC_CHECK_AST(&const_int.base, "const int", scc_parse_type_name); // volatile unsigned long scc_ast_type_t volatile_ulong = scc_ast_builtin_type_unsigned_long; volatile_ulong.quals.is_volatile = true; SCC_CHECK_AST(&volatile_ulong.base, "volatile unsigned long", scc_parse_type_name); // const volatile char scc_ast_type_t const_volatile_char = scc_ast_builtin_type_char; const_volatile_char.quals.is_const = true; const_volatile_char.quals.is_volatile = true; SCC_CHECK_AST(&const_volatile_char.base, "const volatile char", scc_parse_type_name); } // 3. 指针类型 { // int * scc_ast_type_t ptr_to_int; scc_ast_type_pointer_init(&ptr_to_int, (scc_ast_type_t *)&scc_ast_builtin_type_int); SCC_CHECK_AST(&ptr_to_int.base, "int *", scc_parse_type_name); // int ** scc_ast_type_t ptr_to_ptr_to_int; scc_ast_type_pointer_init(&ptr_to_ptr_to_int, &ptr_to_int); SCC_CHECK_AST(&ptr_to_ptr_to_int.base, "int **", scc_parse_type_name); // int * const (const pointer to int) scc_ast_type_t const_ptr_to_int; scc_ast_type_pointer_init(&const_ptr_to_int, (scc_ast_type_t *)&scc_ast_builtin_type_int); const_ptr_to_int.quals.is_const = true; SCC_CHECK_AST(&const_ptr_to_int.base, "int * const", scc_parse_type_name); // const int * (pointer to const int) scc_ast_type_t const_int_type = scc_ast_builtin_type_int; const_int_type.quals.is_const = true; scc_ast_type_t ptr_to_const_int; scc_ast_type_pointer_init(&ptr_to_const_int, &const_int_type); SCC_CHECK_AST(&ptr_to_const_int.base, "const int *", scc_parse_type_name); // const int * const (const pointer to const int) scc_ast_type_t const_ptr_to_const_int; scc_ast_type_pointer_init(&const_ptr_to_const_int, &const_int_type); const_ptr_to_const_int.quals.is_const = true; SCC_CHECK_AST(&const_ptr_to_const_int.base, "const int * const", scc_parse_type_name); // volatile int * restrict scc_ast_type_t volatile_int = scc_ast_builtin_type_int; volatile_int.quals.is_volatile = true; scc_ast_type_t restrict_ptr_to_volatile_int; scc_ast_type_pointer_init(&restrict_ptr_to_volatile_int, &volatile_int); restrict_ptr_to_volatile_int.quals.is_restrict = true; SCC_CHECK_AST(&restrict_ptr_to_volatile_int.base, "volatile int * restrict", scc_parse_type_name); } // 4. 数组类型 { // 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); SCC_CHECK_AST(&array_of_5_int.base, "int [5]", scc_parse_type_name); // int [] (不完整类型) 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); SCC_CHECK_AST(&array_of_int_unknown.base, "int []", scc_parse_type_name); // // int [*] (变长数组原型中的不定长数组) // FIXME // 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 // // 表示。如果解析器需要区分,可能需要特殊处理。 这里暂时假设解析器对 // [*] // // 也生成 size=null 的数组节点。 // SCC_CHECK_AST(&array_of_int_var.base, "int [*]", scc_parse_type); // int [5][3] (二维数组) scc_ast_expr_t size_3; scc_ast_expr_literal_int_init(&size_3, "3", false); scc_ast_type_t inner_array; scc_ast_type_array_init( &inner_array, (scc_ast_type_t *)&scc_ast_builtin_type_int, &size_3); scc_ast_type_t outer_array; scc_ast_type_array_init(&outer_array, &inner_array, &size_5); SCC_CHECK_AST(&outer_array.base, "int [5][3]", scc_parse_type_name); // int (*)[5] (指向数组的指针) 已在前面测试,这里重复以保持完整性 scc_ast_type_t array_of_5_int2; scc_ast_type_array_init(&array_of_5_int2, (scc_ast_type_t *)&scc_ast_builtin_type_int, &size_5); scc_ast_type_t ptr_to_array; scc_ast_type_pointer_init(&ptr_to_array, &array_of_5_int2); SCC_CHECK_AST(&ptr_to_array.base, "int (*)[5]", scc_parse_type_name); // int *[5] (指针数组) scc_ast_type_t ptr_to_int2; scc_ast_type_pointer_init(&ptr_to_int2, (scc_ast_type_t *)&scc_ast_builtin_type_int); scc_ast_type_t array_of_5_ptr; scc_ast_type_array_init(&array_of_5_ptr, &ptr_to_int2, &size_5); SCC_CHECK_AST(&array_of_5_ptr.base, "int *[5]", scc_parse_type_name); // const int [5] (数组元素为const int) scc_ast_type_t const_int2 = scc_ast_builtin_type_int; const_int2.quals.is_const = true; scc_ast_type_t const_array; scc_ast_type_array_init(&const_array, &const_int2, &size_5); SCC_CHECK_AST(&const_array.base, "const int [5]", scc_parse_type_name); } // 5. 函数类型 { // int (void) scc_ast_type_t func_void; 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_void, (scc_ast_type_t *)&scc_ast_builtin_type_int, &func_params); SCC_CHECK_AST(&func_void.base, "int (void)", scc_parse_type_name); // // int () (无参数声明,非原型) // // // 在C中,空括号表示未指定参数,但AST中可能仍然用空参数列表表示。这里假设与 // // (void) 相同。 // SCC_CHECK_AST(&func_void.base, "int ()", scc_parse_type); // int (int, float) scc_ast_decl_t param1, param2; scc_ast_decl_param_init( ¶m1, (scc_ast_type_t *)&scc_ast_builtin_type_int, null); scc_ast_decl_param_init( ¶m2, (scc_ast_type_t *)&scc_ast_builtin_type_float, null); scc_ast_decl_vec_t params; scc_vec_init(params); scc_vec_push(params, ¶m1); scc_vec_push(params, ¶m2); scc_ast_type_t func_with_params; scc_ast_type_function_init(&func_with_params, (scc_ast_type_t *)&scc_ast_builtin_type_int, ¶ms); SCC_CHECK_AST(&func_with_params.base, "int (int, float)", scc_parse_type_name); // int (int, ...) (可变参数) scc_ast_decl_t param_int, param_var; scc_ast_decl_param_init( ¶m_int, (scc_ast_type_t *)&scc_ast_builtin_type_int, null); scc_ast_type_t va_list_type; _scc_ast_type_builtin_init(&va_list_type, SCC_AST_BUILTIN_TYPE_VA_LIST); scc_ast_decl_param_init(¶m_var, &va_list_type, null); scc_ast_decl_vec_t params_var; scc_vec_init(params_var); scc_vec_push(params_var, ¶m_int); scc_vec_push(params_var, ¶m_var); scc_ast_type_t func_varargs; scc_ast_type_function_init(&func_varargs, (scc_ast_type_t *)&scc_ast_builtin_type_int, ¶ms_var); SCC_CHECK_AST(&func_varargs.base, "int (int, ...)", scc_parse_type_name); // int (*)(int) (函数指针) scc_ast_decl_t param; scc_ast_decl_param_init( ¶m, (scc_ast_type_t *)&scc_ast_builtin_type_int, null); scc_ast_decl_vec_t params2; scc_vec_init(params2); scc_vec_push(params2, ¶m); scc_ast_type_t func_type; scc_ast_type_function_init( &func_type, (scc_ast_type_t *)&scc_ast_builtin_type_int, ¶ms2); scc_ast_type_t ptr_to_func; scc_ast_type_pointer_init(&ptr_to_func, &func_type); SCC_CHECK_AST(&ptr_to_func.base, "int (*)(int)", scc_parse_type_name); } // 6. 函数指针和复杂声明符 { // int (*foo)(void) // 这里应解析为类型名,但包含标识符?我们的解析函数是scc_parse_type,它应该解析类型名,不应包含标识符。 // 所以跳过带标识符的,只测试抽象声明符。 // 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_CHECK_AST(&ptr_to_func.base, "int (*(*)(void))[5]", scc_parse_type_name); // int (*(*)[5])(void) (指向数组的指针,数组元素为函数指针) // 1) 函数类型:返回 int,无参数 scc_ast_type_t func_type2; scc_ast_decl_vec_t func_params2; scc_vec_unsafe_from_array(func_params2, array); scc_ast_type_function_init(&func_type2, (scc_ast_type_t *)&scc_ast_builtin_type_int, &func_params2); // 2) 指针指向该函数 scc_ast_type_t ptr_to_func2; scc_ast_type_pointer_init(&ptr_to_func2, &func_type2); // 3) 数组,元素为上述指针 scc_ast_type_t array_of_ptr_to_func; scc_ast_type_array_init(&array_of_ptr_to_func, &ptr_to_func2, &size_5); // 4) 指针指向该数组 scc_ast_type_t ptr_to_array_of_ptr; scc_ast_type_pointer_init(&ptr_to_array_of_ptr, &array_of_ptr_to_func); SCC_CHECK_AST(&ptr_to_array_of_ptr.base, "int (*(*)[5])(void)", scc_parse_type_name); } // 7. 结构体/联合/枚举类型(标记和定义) { // struct S (不完整类型) scc_ast_type_t struct_tag; scc_ast_type_struct_init(&struct_tag, "S", null); // name="S", members=null SCC_CHECK_AST(&struct_tag.base, "struct S", scc_parse_type_name); // 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_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_name); scc_vec_init(fields); scc_vec_push(fields, &field); 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_name); // union U (不完整类型) scc_ast_type_t union_tag; scc_ast_type_union_init(&union_tag, "U", null); SCC_CHECK_AST(&union_tag.base, "union U", scc_parse_type_name); // 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); scc_ast_decl_val_init( &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_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_name); 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_name); // enum E (不完整类型) scc_ast_type_t enum_tag; scc_ast_type_enum_init(&enum_tag, "E", null); SCC_CHECK_AST(&enum_tag.base, "enum E", scc_parse_type_name); // enum { RED, GREEN, BLUE } (匿名枚举定义) scc_ast_expr_t red, green, blue; scc_ast_expr_identifier_init(&red, "RED"); scc_ast_expr_identifier_init(&green, "GREEN"); scc_ast_expr_identifier_init(&blue, "BLUE"); scc_ast_expr_vec_t enumerators; 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); 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_name); 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_parse_type_name); } // 8. typedef 类型 { // 假设存在 typedef int myint; 但类型解析时,遇到 myint // 应得到对应的类型节点。 为了测试,我们直接构造一个 typedef 类型节点。 // scc_ast_type_t myint_type; // scc_ast_type_typedef_init(&myint_type, "myint", // (scc_ast_type_t // *)&scc_ast_builtin_type_int); // SCC_CHECK_AST(&myint_type.base, "myint", scc_parse_type); // // myint * (指针指向 typedef 类型) // scc_ast_type_t ptr_to_myint; // scc_ast_type_pointer_init(&ptr_to_myint, &myint_type); // SCC_CHECK_AST(&ptr_to_myint.base, "myint *", scc_parse_type); } // 9. 混合复杂类型 { // const int * volatile (*)[10] // 步骤: // 1) const int scc_ast_type_t const_int = scc_ast_builtin_type_int; const_int.quals.is_const = true; // 2) 指针指向 const int (普通指针) scc_ast_type_t ptr_to_const_int; scc_ast_type_pointer_init(&ptr_to_const_int, &const_int); // 该指针本身是 volatile 限定?语法上 "const int * volatile" 表示指针是 // volatile 的,指向 const int。 ptr_to_const_int.quals.is_volatile = true; // 3) 数组,元素为上述指针,大小为10 scc_ast_expr_t size_10; scc_ast_expr_literal_int_init(&size_10, "10", false); scc_ast_type_t array_of_ptr; scc_ast_type_array_init(&array_of_ptr, &ptr_to_const_int, &size_10); // 4) 指针指向该数组 scc_ast_type_t ptr_to_array; scc_ast_type_pointer_init(&ptr_to_array, &array_of_ptr); SCC_CHECK_AST(&ptr_to_array.base, "const int * volatile (*)[10]", scc_parse_type_name); // 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); // 3) 指针指向该函数 scc_ast_type_t ptr_to_func_ret_float; scc_ast_type_pointer_init(&ptr_to_func_ret_float, &func_ret_float); // 4) 外层函数类型,返回上述指针,参数为 (int, ...) scc_ast_decl_t param_int, param_var; scc_ast_decl_param_init( ¶m_int, (scc_ast_type_t *)&scc_ast_builtin_type_int, null); scc_ast_type_t va_list_type; _scc_ast_type_builtin_init(&va_list_type, SCC_AST_BUILTIN_TYPE_VA_LIST); scc_ast_decl_param_init(¶m_var, &va_list_type, null); scc_ast_decl_vec_t params_outer; scc_vec_init(params_outer); scc_vec_push(params_outer, ¶m_int); scc_vec_push(params_outer, ¶m_var); scc_ast_type_t outer_func; scc_ast_type_function_init(&outer_func, &ptr_to_func_ret_float, ¶ms_outer); // 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, "float (*(*)(int, ...))()", scc_parse_type_name); } } TEST_LIST = { {"parser_unit", test_parser_unit}, {"parser_expression", test_parser_expression}, {"parser_type", test_parser_type}, // {"parser_statement", test_parser_statement}, // {"parser_declaration", test_parser_declaration}, // {"parser_translation_unit", test_parser_translation_unit}, {null, null}, };