#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) { 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; 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); Assert(!not_eof == true); 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); scc_vsnprintf(buffer + strlen(buffer), BUFFER_SIZE - strlen(buffer) - 1, fmt, args); va_end(args); } #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); \ 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_type_function_init(&func_type, &scc_ast_builtin_type_int, null); // 无参数,非可变参数 // 构造复合语句块(空) 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_type_function_init(&func_type, &scc_ast_builtin_type_int, null); 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_type_function_init(&func_type, &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); 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); } } 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_call_init(&call, "f", &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 call2; scc_ast_expr_call_init(&call2, "f", &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 表达式 // TODO // scc_ast_expr_t sizeof_expr; // scc_ast_expr_sizeof_expr_init(&sizeof_expr, &x); // SCC_CHECK_AST(&sizeof_expr.base, "sizeof x", scc_parse_expression); } // 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); } // 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); } } TEST_LIST = { {"parser_unit", test_parser_unit}, {"parser_expression", test_parser_expression}, {null, null}, };