Files
scc/libs/parser/tests/test_parser_unit.c
zzy 30ac2de73b feat(parser): 添加语义分析回调清理函数并完善资源管理
添加了 scc_sema_drop 函数用于清理语义分析回调结构,
并在主程序中正确初始化和释放语义分析回调,
确保资源得到适当管理。

同时修复了AST转储中的缩进问题,在函数调用括号前添加正确的缩进,
并修正了测试代码中的结构体字段初始化顺序。
2026-03-11 22:07:52 +08:00

1276 lines
50 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <assert.h>
#include <scc_lexer.h>
#include <scc_parser.h>
#include <string.h>
#include <utest/acutest.h>
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);
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);
scc_vsnprintf(buffer + strlen(buffer), BUFFER_SIZE - strlen(buffer) - 1,
fmt, args);
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_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); \
} 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(
&param0, (scc_ast_type_t *)&scc_ast_builtin_type_int, "a");
scc_ast_decl_t param1;
scc_ast_decl_param_init(
&param1, (scc_ast_type_t *)&scc_ast_builtin_type_int, "b");
scc_ast_decl_t param2;
scc_ast_decl_param_init(
&param2, (scc_ast_type_t *)&scc_ast_builtin_type_va_list, null);
scc_ast_decl_t *params_array[] = {&param0, &param1, &param2};
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,
&params);
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_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) {
// 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 表达式
// 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(&lt, SCC_AST_OP_LESS, &a, &b);
SCC_CHECK_AST(&lt.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);
}
// 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);
}
// 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);
}
// 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);
}
// 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);
}
// 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);
}
// 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);
}
// 8. int (*const [])(unsigned int, ...)
{
// --- 构造参数列表 ---
// 第一个参数unsigned int
scc_ast_decl_t param_uint;
scc_ast_decl_param_init(
&param_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(&param_var, &va_list_type, "...");
scc_ast_decl_vec_t params;
scc_vec_init(params);
scc_vec_push(params, &param_uint);
scc_vec_push(params, &param_var);
// --- 函数类型,返回 int ---
scc_ast_type_t func_type;
scc_ast_type_function_init(
&func_type, (scc_ast_type_t *)&scc_ast_builtin_type_int,
&params); // 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);
}
}
// 1. 基本内置类型及组合
{
// int
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_int, "int",
_scc_parse_type);
// char
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_char, "char",
_scc_parse_type);
// long long
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_long_long,
"long long", _scc_parse_type);
// unsigned int
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_unsigned_int,
"unsigned int", _scc_parse_type);
// float
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_float, "float",
_scc_parse_type);
// double
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_double, "double",
_scc_parse_type);
// void
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_void, "void",
_scc_parse_type);
// bool
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_bool, "bool",
_scc_parse_type);
// long double
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_long_double,
"long double", _scc_parse_type);
// _Complex double
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_complex_double,
"complex double", _scc_parse_type);
}
// 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);
// 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);
// 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);
}
// 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);
// 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);
// 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);
// 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);
// 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);
// 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);
}
// 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);
// 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);
// // 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);
// 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);
// 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);
// 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);
}
// 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);
// // 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(
&param1, (scc_ast_type_t *)&scc_ast_builtin_type_int, null);
scc_ast_decl_param_init(
&param2, (scc_ast_type_t *)&scc_ast_builtin_type_float, null);
scc_ast_decl_vec_t params;
scc_vec_init(params);
scc_vec_push(params, &param1);
scc_vec_push(params, &param2);
scc_ast_type_t func_with_params;
scc_ast_type_function_init(&func_with_params,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
&params);
SCC_CHECK_AST(&func_with_params.base, "int (int, float)",
_scc_parse_type);
// int (int, ...) (可变参数)
scc_ast_decl_t param_int, param_var;
scc_ast_decl_param_init(
&param_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(&param_var, &va_list_type, null);
scc_ast_decl_vec_t params_var;
scc_vec_init(params_var);
scc_vec_push(params_var, &param_int);
scc_vec_push(params_var, &param_var);
scc_ast_type_t func_varargs;
scc_ast_type_function_init(&func_varargs,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
&params_var);
SCC_CHECK_AST(&func_varargs.base, "int (int, ...)", _scc_parse_type);
// int (*)(int) (函数指针)
scc_ast_decl_t param;
scc_ast_decl_param_init(
&param, (scc_ast_type_t *)&scc_ast_builtin_type_int, null);
scc_ast_decl_vec_t params2;
scc_vec_init(params2);
scc_vec_push(params2, &param);
scc_ast_type_t func_type;
scc_ast_type_function_init(
&func_type, (scc_ast_type_t *)&scc_ast_builtin_type_int, &params2);
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);
}
// 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);
// 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);
}
// 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);
// 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);
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);
// 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);
// 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);
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_CHECK_AST(&enum_tag.base, "enum E", _scc_parse_type);
// 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_vec_init(enumerators);
scc_vec_push(enumerators, &red);
scc_vec_push(enumerators, &green);
scc_vec_push(enumerators, &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);
}
// 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);
// 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(
&param_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(&param_var, &va_list_type, null);
scc_ast_decl_vec_t params_outer;
scc_vec_init(params_outer);
scc_vec_push(params_outer, &param_int);
scc_vec_push(params_outer, &param_var);
scc_ast_type_t outer_func;
scc_ast_type_function_init(&outer_func, &ptr_to_func_ret_float,
&params_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);
}
}
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},
};