- 添加 scc_parse_assignment_expression 函数用于解析赋值表达式 - 添加 scc_parser_constant_expression 函数用于解析常量表达式 - 修改 cast 表达式解析逻辑,修复类型转换解析问题 - 改进错误处理机制,使用 SCC_ERROR 替代 LOG_ERROR 并提供准确位置信息 - 移除未使用的变量声明,优化代码结构 refactor(ast): 调整类型定义中的 typedef 类型存储结构 - 将 scc_ast_type 中的 underlying 字段改为 decl 字段 - 更新相关初始化函数以适配新的字段名称 - 修复枚举类型初始化时缺失的 decl 字段设置 feat(ast): 添加类型转换、sizeof 和 alignof 表达式的初始化函数 - 实现 scc_ast_expr_cast_init 用于初始化类型转换表达式 - 实现 scc_ast_expr_sizeof_init 用于初始化 sizeof 表达式 - 实现 scc_ast_expr_alignof_init 用于初始化 alignof 表达式 - 完善表达式类型的支持 chore(parser): 增加语义分析回调接口和位置获取工具函数 - 添加 scc_parse_decl_sema、scc_parse_type_sema 等语义分析辅助函数 - 提供 scc_parser_got_current_pos 函数获取当前解析位置 - 增强错误报告的准确性 refactor(dump): 完善 AST 转储功能,支持 break 和 continue 语句 - 为 SCC_AST_STMT_BREAK 和 SCC_AST_STMT_CONTINUE 添加转储支持 - 优化转储函数的分支处理结构
1456 lines
58 KiB
C
1456 lines
58 KiB
C
#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,
|
||
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);
|
||
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, 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);
|
||
}
|
||
|
||
{
|
||
// 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 表达式
|
||
// 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_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);
|
||
}
|
||
|
||
// 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(
|
||
¶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);
|
||
}
|
||
}
|
||
|
||
// 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(
|
||
¶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);
|
||
|
||
// 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);
|
||
|
||
// 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);
|
||
}
|
||
|
||
// 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_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);
|
||
|
||
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);
|
||
}
|
||
|
||
// 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(
|
||
¶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);
|
||
}
|
||
}
|
||
|
||
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},
|
||
};
|