Files
scc/libs/parser/tests/test_parser_unit.c
zzy eb969cdbf7 feat(parser): 添加声明列表支持并重构解析逻辑
- 添加 SCC_AST_DECL_LIST 节点类型用于表示声明列表
- 实现 scc_ast_decl_list_init 函数来初始化声明列表节点
- 重构 scc_parse_declaration 函数以支持逗号分隔的多个变量声明
- 分离类型说明符解析到独立的 scc_parse_declaration_specifiers 函数
- 支持 typedef 和多变量声明如 'int a, b;' 和 'int a = 1, b = 2;'
- 在 ast_dump 中添加对声明列表节点的打印支持

refactor(ast): 统一使用 scc_vec_foreach 宏替换手动循环

- 将 ast_dump.c 中的多个手动索引循环改为使用 scc_vec_foreach
- 提高代码可读性和安全性
- 避免索引越界错误

fix(parser): 修复语义分析中结构体符号表冲突

- 为结构体、联合体和枚举符号名添加前缀避免命名冲突
- 使用 '$S_'、'$U_'、'$E_' 前缀分别标识结构体、联合体和枚举

refactor(log): 统一终止处理方式

- 将 log_exit 替换为 log_abort 以更准确反映行为
- 更新相关依赖模块的实现

style(parser): 移除未使用的参数和清理代码

- 在 argparse.c 中添加 (void) 参数注释处理未使用的参数
- 清理 parse_expr.c 中未使用的函数声明
- 优化 parse_type.c 中的错误处理流程
2026-03-14 14:04:24 +08:00

1712 lines
67 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 <stdio.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);
int res = scc_vsnprintf(buffer + strlen(buffer),
BUFFER_SIZE - strlen(buffer) - 1, fmt, args);
Assert(res > 0);
va_end(args);
}
static void _scc_check_ast(scc_ast_node_t *expect_node_ptr, const char *str,
scc_parse_node_func parse_func, cbool need_sema) {
scc_ast_node_t *output_node_ptr = process_input(str, parse_func, need_sema);
scc_tree_dump_ctx_t ctx;
expect_buffer[0] = '\n', expect_buffer[1] = '\0';
scc_tree_dump_ctx_init(&ctx, true, dump2buffer, expect_buffer);
scc_ast_dump_node(&ctx, expect_node_ptr);
scc_tree_dump_ctx_drop(&ctx);
output_buffer[0] = '\n', output_buffer[1] = '\0';
scc_tree_dump_ctx_init(&ctx, true, dump2buffer, output_buffer);
scc_ast_dump_node(&ctx, output_node_ptr);
scc_tree_dump_ctx_drop(&ctx);
}
#define SCC_CHECK_AST_WITH_SEMA(expect_node_ptr, str, parse_func) \
do { \
_scc_check_ast(expect_node_ptr, str, (scc_parse_node_func)parse_func, \
true); \
TEST_CHECK(strcmp(output_buffer, expect_buffer) == 0); \
TEST_MSG("Expected: %s", expect_buffer); \
TEST_MSG("Produced: %s", output_buffer); \
} while (0);
#define SCC_CHECK_AST(expect_node_ptr, str, parse_func) \
do { \
_scc_check_ast(expect_node_ptr, str, (scc_parse_node_func)parse_func, \
false); \
TEST_CHECK(strcmp(output_buffer, expect_buffer) == 0); \
TEST_MSG("Expected: %s", expect_buffer); \
TEST_MSG("Produced: %s", output_buffer); \
} while (0);
static void test_parser_unit(void) {
// 1. 变量声明 int a;
{
scc_ast_decl_t int_decl;
scc_ast_decl_val_init(
&int_decl, (scc_ast_type_t *)&scc_ast_builtin_type_int, "a", null);
SCC_CHECK_AST(&int_decl.base, "int a;", scc_parse_declaration);
}
// 2. 函数声明 int main(void) {}
{
// 构造函数类型:返回 int参数为空
scc_ast_type_t func_type;
scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &scc_ast_builtin_type_void, null);
scc_ast_decl_t *array[] = {&void_decl};
scc_vec_unsafe_from_array(func_params, array);
scc_ast_type_function_init(&func_type, &scc_ast_builtin_type_int,
&func_params);
// 构造复合语句块(空)
scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, null);
// 构造函数声明
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound);
SCC_CHECK_AST(&func_decl.base, "int main(void) {}",
scc_parse_declaration);
}
// 3. 翻译单元包含一个函数定义
{
scc_ast_type_t func_type;
scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &scc_ast_builtin_type_void, null);
scc_ast_decl_t *array[] = {&void_decl};
scc_vec_unsafe_from_array(func_params, array);
scc_ast_type_function_init(&func_type, &scc_ast_builtin_type_int,
&func_params);
scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, null);
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound);
// 构造翻译单元
scc_ast_decl_vec_t tu_decls;
scc_vec_init(tu_decls);
scc_vec_push(tu_decls, &func_decl);
scc_ast_translation_unit_t tu;
scc_ast_translation_unit_init(&tu, &tu_decls);
SCC_CHECK_AST(&tu.base, "int main(void) {}",
scc_parse_translation_unit);
}
// 4. 带返回语句的函数 int main(void) { return 65536; }
{
// 返回语句中的整数常量
scc_ast_expr_t ret_val;
scc_ast_expr_literal_int_init(&ret_val, "65536", false);
scc_ast_stmt_t ret_stmt;
scc_ast_stmt_return_init(&ret_stmt, &ret_val);
// 复合语句包含该返回语句
scc_ast_block_item_vec_t items;
scc_vec_init(items);
scc_vec_push(items, (scc_ast_node_t *)&ret_stmt);
scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, &items); // items 被移动
// 函数类型
scc_ast_type_t func_type;
scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &scc_ast_builtin_type_void, null);
scc_ast_decl_t *array[] = {&void_decl};
scc_vec_unsafe_from_array(func_params, array);
scc_ast_type_function_init(&func_type, &scc_ast_builtin_type_int,
&func_params);
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound);
scc_ast_decl_vec_t tu_decls;
scc_vec_init(tu_decls);
scc_vec_push(tu_decls, &func_decl);
scc_ast_translation_unit_t tu;
scc_ast_translation_unit_init(&tu, &tu_decls);
SCC_CHECK_AST(&tu.base, "int main(void) { return 65536; }",
scc_parse_translation_unit);
}
// 5. 多语句函数(复杂示例)
{
// 变量声明 int a;
scc_ast_decl_t a_decl;
scc_ast_decl_val_init(&a_decl, &scc_ast_builtin_type_int, "a", null);
// 变量声明 int b;
scc_ast_decl_t b_decl;
scc_ast_decl_val_init(&b_decl, &scc_ast_builtin_type_int, "b", null);
// 表达式 1 + 2 * 3
scc_ast_expr_t lit1, lit2, lit3, mul, add;
scc_ast_expr_literal_int_init(&lit1, "1", false);
scc_ast_expr_literal_int_init(&lit2, "2", false);
scc_ast_expr_literal_int_init(&lit3, "3", false);
scc_ast_expr_binary_init(&mul, SCC_AST_OP_MUL, &lit2, &lit3);
scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &lit1, &mul);
// 赋值 a = 1 + 2 * 3;
scc_ast_expr_t a_ref1, assign1;
scc_ast_expr_identifier_init(&a_ref1, "a");
scc_ast_expr_binary_init(&assign1, SCC_AST_OP_ASSIGN, &a_ref1, &add);
scc_ast_stmt_t assign1_stmt;
scc_ast_stmt_expr_init(&assign1_stmt, &assign1);
// 赋值 b = 7;
scc_ast_expr_t lit7;
scc_ast_expr_literal_int_init(&lit7, "7", false);
scc_ast_expr_t b_ref1, assign2;
scc_ast_expr_identifier_init(&b_ref1, "b");
scc_ast_expr_binary_init(&assign2, SCC_AST_OP_ASSIGN, &b_ref1, &lit7);
scc_ast_stmt_t assign2_stmt;
scc_ast_stmt_expr_init(&assign2_stmt, &assign2);
// 表达式 a - b + 1
scc_ast_expr_t a_ref2, b_ref2, sub, add2, lit1_2;
scc_ast_expr_identifier_init(&a_ref2, "a");
scc_ast_expr_identifier_init(&b_ref2, "b");
scc_ast_expr_binary_init(&sub, SCC_AST_OP_SUB, &a_ref2, &b_ref2);
scc_ast_expr_literal_int_init(&lit1_2, "1", false);
scc_ast_expr_binary_init(&add2, SCC_AST_OP_ADD, &sub, &lit1_2);
// 赋值 a = a - b + 1;
scc_ast_expr_t a_ref3, assign3;
scc_ast_expr_identifier_init(&a_ref3, "a");
scc_ast_expr_binary_init(&assign3, SCC_AST_OP_ASSIGN, &a_ref3, &add2);
scc_ast_stmt_t assign3_stmt;
scc_ast_stmt_expr_init(&assign3_stmt, &assign3);
// return a;
scc_ast_expr_t a_ref4;
scc_ast_expr_identifier_init(&a_ref4, "a");
scc_ast_stmt_t ret_stmt;
scc_ast_stmt_return_init(&ret_stmt, &a_ref4);
// 复合语句块,按顺序放入
scc_ast_block_item_vec_t items;
scc_vec_init(items);
scc_vec_push(items, (scc_ast_node_t *)&a_decl);
scc_vec_push(items, (scc_ast_node_t *)&b_decl);
scc_vec_push(items, (scc_ast_node_t *)&assign1_stmt);
scc_vec_push(items, (scc_ast_node_t *)&assign2_stmt);
scc_vec_push(items, (scc_ast_node_t *)&assign3_stmt);
scc_vec_push(items, (scc_ast_node_t *)&ret_stmt);
scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, &items);
// 函数类型
scc_ast_type_t func_type;
scc_ast_type_function_init(
&func_type, (scc_ast_type_t *)&scc_ast_builtin_type_int, null);
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound);
scc_ast_decl_vec_t tu_decls;
scc_vec_init(tu_decls);
scc_vec_push(tu_decls, &func_decl);
scc_ast_translation_unit_t tu;
scc_ast_translation_unit_init(&tu, &tu_decls);
const char *input = "int main() {\n"
" int a;\n"
" int b;\n"
" a = 1 + 2 * 3;\n"
" b = 7;\n"
" a = a - b + 1;\n"
" return a;\n"
"}\n";
SCC_CHECK_AST(&tu.base, input, scc_parse_translation_unit);
}
{
// 整数字面量 10
scc_ast_expr_t lit10;
scc_ast_expr_literal_int_init(&lit10, "10", false);
// 变量声明 int x = 10;
scc_ast_decl_t x_decl;
scc_ast_decl_val_init(
&x_decl, (scc_ast_type_t *)&scc_ast_builtin_type_int, "x", &lit10);
// 表达式 x + 1
scc_ast_expr_t x_ref1, lit1, add;
scc_ast_expr_identifier_init(&x_ref1, "x");
scc_ast_expr_literal_int_init(&lit1, "1", false);
scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &x_ref1, &lit1);
// 赋值 x = x + 1
scc_ast_expr_t x_ref2, assign;
scc_ast_expr_identifier_init(&x_ref2, "x");
scc_ast_expr_binary_init(&assign, SCC_AST_OP_ASSIGN, &x_ref2, &add);
// 表达式语句
scc_ast_stmt_t assign_stmt;
scc_ast_stmt_expr_init(&assign_stmt, &assign);
// return x
scc_ast_expr_t x_ref3;
scc_ast_expr_identifier_init(&x_ref3, "x");
scc_ast_stmt_t ret_stmt;
scc_ast_stmt_return_init(&ret_stmt, &x_ref3);
// 复合语句块
scc_ast_block_item_vec_t items;
scc_vec_init(items);
scc_vec_push(items, (scc_ast_node_t *)&x_decl);
scc_vec_push(items, (scc_ast_node_t *)&assign_stmt);
scc_vec_push(items, (scc_ast_node_t *)&ret_stmt);
scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, &items);
// 函数类型(返回 int无参数
scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
null); // null 表示无参数
// 函数声明 int main() { ... }
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "main", &compound);
// 翻译单元
scc_ast_decl_vec_t tu_decls;
scc_vec_init(tu_decls);
scc_vec_push(tu_decls, &func_decl);
scc_ast_translation_unit_t tu;
scc_ast_translation_unit_init(&tu, &tu_decls);
// 输入源代码
const char *input = "int main() {\n"
" int x = 10;\n"
" x = x + 1;\n"
" return x;\n"
"}\n";
// 比较解析结果与期望 AST
SCC_CHECK_AST(&tu.base, input, scc_parse_translation_unit);
}
{
scc_ast_decl_vec_t params;
scc_ast_decl_t param0;
scc_ast_decl_param_init(
&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_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(&param1, &type_type, "a");
scc_ast_decl_t param2;
scc_ast_decl_param_init(&param2, &scc_ast_builtin_type_int, "b");
scc_ast_decl_t param3;
scc_ast_decl_param_init(&param3, &scc_ast_builtin_type_va_list, null);
scc_ast_decl_t *params_array[] = {&param1, &param2, &param3};
scc_ast_decl_vec_t func_params;
scc_vec_unsafe_from_array(func_params, params_array);
scc_ast_type_t func_type;
scc_ast_type_t return_type;
scc_ast_type_pointer_init(&return_type, &scc_ast_builtin_type_void);
scc_ast_type_function_init(&func_type, &return_type, &func_params);
scc_ast_decl_t func_decl;
scc_ast_decl_func_init(&func_decl, &func_type, "func", null);
scc_ast_decl_t *decls_array[] = {&type_decl, &func_decl};
scc_ast_translation_unit_t tu;
scc_ast_decl_vec_t decls;
scc_vec_unsafe_from_array(decls, decls_array);
scc_ast_translation_unit_init(&tu, &decls);
SCC_CHECK_AST_WITH_SEMA(&tu.base,
"typedef long long size_t;"
"void *func(size_t a, int b, ...);",
scc_parse_translation_unit);
scc_ast_type_t type_func_ptr_type;
scc_ast_type_pointer_init(&type_func_ptr_type, &func_type);
scc_ast_decl_t type_func_ptr_decl;
scc_ast_decl_typedef_init(&type_func_ptr_decl, "func_t",
&type_func_ptr_type);
scc_ast_decl_t *decls_array2[] = {&type_decl, &type_func_ptr_decl};
scc_vec_unsafe_from_array(decls, decls_array2);
scc_ast_translation_unit_init(&tu, &decls);
SCC_CHECK_AST_WITH_SEMA(
&tu.base,
"typedef long long size_t;"
"typedef void *(*func_t)(size_t a, int b, ...);",
scc_parse_translation_unit);
}
{
// 1. 构造参数类型volatile const char *restrict并附加 register
// 存储类
scc_ast_type_t char_type;
_scc_ast_type_builtin_init(&char_type, SCC_AST_BUILTIN_TYPE_CHAR);
char_type.quals.is_const = true; // const
char_type.quals.is_volatile = true; // volatile
scc_ast_type_t ptr_to_char;
scc_ast_type_pointer_init(&ptr_to_char, &char_type);
ptr_to_char.quals.is_restrict = true; // restrict 限定指针
ptr_to_char.quals.is_register = true; // register 存储类(作用于参数)
// 2. 参数声明
scc_ast_decl_t param_decl;
scc_ast_decl_param_init(&param_decl, &ptr_to_char, "fmt");
// 3. 返回类型void *
scc_ast_type_t void_type;
_scc_ast_type_builtin_init(&void_type, SCC_AST_BUILTIN_TYPE_VOID);
scc_ast_type_t ptr_to_void;
scc_ast_type_pointer_init(&ptr_to_void, &void_type);
// 4. 参数列表
scc_ast_decl_vec_t params;
scc_vec_init(params);
scc_vec_push(params, &param_decl);
// 5. 函数类型(包含 static 和 inline
scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type, &ptr_to_void, &params);
func_type.quals.is_static = true;
func_type.quals.is_inline = true;
// 6. 函数声明
scc_ast_decl_t decl;
scc_ast_decl_func_init(&decl, &func_type, "call", NULL);
// 7. 与解析结果比较
SCC_CHECK_AST_WITH_SEMA(&decl.base,
"static inline void *call(volatile register "
"const char *restrict fmt);",
scc_parse_declaration);
}
{
scc_ast_expr_t lvalue;
scc_ast_expr_lvalue_init(&lvalue, &scc_ast_builtin_type_void);
scc_ast_expr_t lhs1;
scc_ast_expr_member_init(&lhs1, &lvalue, "data");
scc_ast_expr_t lhs2;
scc_ast_expr_member_init(&lhs2, &lvalue, "size");
scc_ast_expr_t lhs3;
scc_ast_expr_member_init(&lhs3, &lvalue, "cap");
scc_ast_expr_t rl0;
scc_ast_expr_literal_int_init(&rl0, "0", false);
scc_ast_type_t void_ptr;
scc_ast_type_pointer_init(&void_ptr, &scc_ast_builtin_type_void);
scc_ast_expr_t rhs1;
scc_ast_expr_cast_init(&rhs1, &void_ptr, &rl0);
scc_ast_expr_t rhs2;
scc_ast_expr_literal_int_init(&rhs2, "0", false);
scc_ast_expr_t rhs3;
scc_ast_expr_literal_int_init(&rhs3, "0", false);
scc_ast_expr_vec_t lhs_exprs;
scc_ast_expr_t *lhs_array[] = {&lhs1, &lhs2, &lhs3};
scc_vec_unsafe_from_array(lhs_exprs, lhs_array);
scc_ast_expr_vec_t rhs_exprs;
scc_ast_expr_t *rhs_array[] = {&rhs1, &rhs2, &rhs3};
scc_vec_unsafe_from_array(rhs_exprs, rhs_array);
scc_ast_expr_t expr;
scc_ast_expr_compound_init(&expr, &lvalue, &lhs_exprs, &rhs_exprs);
// FIXME use real records type
SCC_CHECK_AST(&expr.base,
"(void){.data = ((void *)0), .size = 0, .cap = 0}",
scc_parse_expression);
scc_ast_stmt_t stmt;
scc_ast_stmt_return_init(&stmt, &expr);
SCC_CHECK_AST(&stmt.base,
"return (void){.data = (void *)0, .size = 0, .cap = 0};",
scc_parse_statement);
scc_ast_expr_t lhs4;
scc_ast_expr_t lhs5;
scc_ast_expr_member_init(&lhs4, &lvalue, "a");
scc_ast_expr_member_init(&lhs5, &lhs4, "b");
scc_ast_expr_t lhs6;
scc_ast_expr_t lhs7;
scc_ast_expr_member_init(&lhs6, &lvalue, "c");
scc_ast_expr_array_subscript_init(&lhs7, &lhs6, &rl0);
scc_ast_expr_t *lhs_array_hard[] = {&lhs5, &lhs7};
scc_vec_unsafe_from_array(lhs_exprs, lhs_array_hard);
scc_ast_expr_t *rhs_array_hard[] = {&rhs2, &rhs3};
scc_vec_unsafe_from_array(rhs_exprs, rhs_array_hard);
scc_ast_expr_compound_init(&expr, &lvalue, &lhs_exprs, &rhs_exprs);
SCC_CHECK_AST(&expr.base, "(void){.a.b = 0, .c[0] = 0}",
scc_parse_expression);
}
{
// 测试 struct S; 仅标记声明
{
scc_ast_decl_t struct_decl;
scc_ast_decl_vec_t empty_members;
scc_vec_init(empty_members);
scc_ast_decl_struct_init(&struct_decl, "S", &empty_members);
SCC_CHECK_AST(&struct_decl.base, "struct S;",
scc_parse_declaration);
}
// 测试 union U; 仅标记声明
{
scc_ast_decl_t union_decl;
scc_ast_decl_vec_t empty_members;
scc_vec_init(empty_members);
scc_ast_decl_union_init(&union_decl, "U", &empty_members);
SCC_CHECK_AST(&union_decl.base, "union U;", scc_parse_declaration);
}
// 测试 enum E; 仅标记声明
{
scc_ast_decl_t enum_decl;
scc_ast_expr_vec_t empty_enumerators;
scc_vec_init(empty_enumerators);
scc_ast_decl_enum_init(&enum_decl, "E", &empty_enumerators);
SCC_CHECK_AST(&enum_decl.base, "enum E;", scc_parse_declaration);
}
}
{
scc_ast_stmt_t continue_stmt;
scc_ast_stmt_continue_init(&continue_stmt);
scc_ast_stmt_t stmt;
scc_ast_stmt_label_init(&stmt, "NEXT", &continue_stmt);
SCC_CHECK_AST(&stmt.base, "NEXT: continue;", scc_parse_statement);
scc_ast_expr_t str;
scc_ast_expr_literal_string_init(&str, "\"ab\"", false);
SCC_CHECK_AST(&str.base, "\"a\" \"b\"", scc_parse_expression);
}
{
// 测试 int a = *(int*)b;
{
// 构造类型 int*
scc_ast_type_t ptr_to_int;
scc_ast_type_pointer_init(
&ptr_to_int, (scc_ast_type_t *)&scc_ast_builtin_type_int);
// 标识符 b
scc_ast_expr_t b_expr;
scc_ast_expr_identifier_init(&b_expr, "b");
// 类型转换 (int*)b
scc_ast_expr_t cast_expr;
scc_ast_expr_cast_init(&cast_expr, &ptr_to_int, &b_expr);
// 解引用 *(int*)b
scc_ast_expr_t deref_expr;
scc_ast_expr_unary_init(&deref_expr, SCC_AST_OP_INDIRECTION,
&cast_expr);
// 声明 int a = *(int*)b;
scc_ast_decl_t decl;
scc_ast_decl_val_init(&decl,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
"a", &deref_expr);
SCC_CHECK_AST(&decl.base, "int a = *(int*)b;",
scc_parse_declaration);
}
// 测试 int a, b;
{
scc_ast_decl_t decl_a, decl_b;
scc_ast_decl_val_init(&decl_a,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
"a", null);
scc_ast_decl_val_init(&decl_b,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
"b", null);
scc_ast_decl_vec_t decl_vec;
scc_vec_init(decl_vec);
scc_vec_push(decl_vec, &decl_a);
scc_vec_push(decl_vec, &decl_b);
scc_ast_decl_t decl_list;
scc_ast_decl_list_init(&decl_list, &decl_vec); // 假设存在该函数
SCC_CHECK_AST(&decl_list.base, "int a, b;", scc_parse_declaration);
}
// 测试 int a = 1, b = 2;
{
scc_ast_expr_t lit1, lit2;
scc_ast_expr_literal_int_init(&lit1, "1", false);
scc_ast_expr_literal_int_init(&lit2, "2", false);
scc_ast_decl_t decl_a, decl_b;
scc_ast_decl_val_init(&decl_a,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
"a", &lit1);
scc_ast_decl_val_init(&decl_b,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
"b", &lit2);
scc_ast_decl_vec_t decl_vec;
scc_vec_init(decl_vec);
scc_vec_push(decl_vec, &decl_a);
scc_vec_push(decl_vec, &decl_b);
scc_ast_decl_t decl_list;
scc_ast_decl_list_init(&decl_list, &decl_vec); // 假设存在该函数
SCC_CHECK_AST(&decl_list.base, "int a = 1, b = 2;",
scc_parse_declaration);
}
"struct list_head *next, *prev;";
"typedef struct { int a; } struct_t, *struct_ptr_t;";
"__scc_builtin_va_arg(ag, int)";
"__scc_builtin_va_arg(ag, long long)";
"typedef struct a;int a;struct a b;";
}
{
// int (*(*)(void))[5] (指向函数的指针,该函数返回指向数组的指针)
// 步骤:
// 1) 数组类型int [5]
scc_ast_expr_t size_5;
scc_ast_expr_literal_int_init(&size_5, "5", false);
scc_ast_type_t array_of_5_int;
scc_ast_type_array_init(&array_of_5_int,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
&size_5);
// 2) 函数类型:返回指向数组的指针,无参数
scc_ast_type_t ptr_to_array;
scc_ast_type_pointer_init(&ptr_to_array, &array_of_5_int);
scc_ast_type_t func_type;
scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &scc_ast_builtin_type_void, null);
scc_ast_decl_t *array[] = {&void_decl};
scc_vec_unsafe_from_array(func_params, array);
scc_ast_type_function_init(&func_type, &ptr_to_array,
&func_params); // 无参数
// 3) 指向该函数的指针
scc_ast_type_t ptr_to_func;
scc_ast_type_pointer_init(&ptr_to_func, &func_type);
scc_ast_decl_t ptr_to_func_decl;
scc_ast_decl_val_init(&ptr_to_func_decl, &ptr_to_func, "foo", null);
SCC_CHECK_AST(&ptr_to_func_decl.base, "int (*(*foo)(void))[5];",
scc_parse_declaration);
scc_ast_decl_t typedef_func_decl;
scc_ast_decl_typedef_init(&typedef_func_decl, "func_t", &ptr_to_func);
scc_ast_type_t typedef_func_type;
scc_ast_type_typedef_init(&typedef_func_type, "func_t",
&typedef_func_decl);
scc_ast_decl_t func_hard_decl;
scc_ast_type_t func_hard_type;
scc_ast_decl_t param1;
scc_ast_decl_param_init(&param1, &ptr_to_func, "bar");
scc_ast_decl_t param2;
scc_ast_decl_param_init(&param2, &typedef_func_type, "a");
scc_ast_decl_t param3;
scc_ast_decl_param_init(&param1, &scc_ast_builtin_type_va_list, null);
scc_ast_decl_t *func_hard_array[] = {&param1, &param2, &param3};
scc_ast_decl_vec_t func_hard_params;
scc_vec_unsafe_from_array(func_hard_params, func_hard_array);
scc_ast_type_function_init(&func_hard_type, &ptr_to_array,
&func_hard_params);
scc_ast_decl_func_init(&func_hard_decl, &func_hard_type, "bar", null);
scc_ast_decl_vec_t decls;
scc_ast_decl_t *decls_array[] = {
&typedef_func_decl,
&func_hard_decl,
};
scc_vec_unsafe_from_array(decls, decls_array);
scc_ast_translation_unit_t tu;
scc_ast_translation_unit_init(&tu, &decls);
// SCC_CHECK_AST_WITH_SEMA(
// &tu.base,
// "typedef int (*(*func_t)(void))[5];"
// "int (*(*(bar)(int(*(*foo)(void))[5], func_t a,
// ...))(void))[5];", scc_parse_translation_unit);
}
}
static void test_parser_expression(void) {
// 1. 基本表达式
{
scc_ast_expr_t ident;
scc_ast_expr_identifier_init(&ident, "x");
SCC_CHECK_AST(&ident.base, "x", scc_parse_expression);
scc_ast_expr_t int_lit;
scc_ast_expr_literal_int_init(&int_lit, "42", false);
SCC_CHECK_AST(&int_lit.base, "42", scc_parse_expression);
scc_ast_expr_t str_lit;
scc_ast_expr_literal_string_init(&str_lit, "\"hello\"", false);
SCC_CHECK_AST(&str_lit.base, "\"hello\"", scc_parse_expression);
// 括号表达式(解析器应直接返回内部表达式)
scc_ast_expr_t paren_ident;
scc_ast_expr_identifier_init(&paren_ident, "y");
SCC_CHECK_AST(&paren_ident.base, "(y)", scc_parse_expression);
}
// 2. 后缀表达式
{
// 数组下标 a[10]
scc_ast_expr_t a, index, subscript;
scc_ast_expr_identifier_init(&a, "a");
scc_ast_expr_literal_int_init(&index, "10", false);
scc_ast_expr_array_subscript_init(&subscript, &a, &index);
SCC_CHECK_AST(&subscript.base, "a[10]", scc_parse_expression);
// 函数调用 f()
scc_ast_expr_t f;
scc_ast_expr_identifier_init(&f, "f");
scc_ast_expr_vec_t args;
scc_vec_init(args);
scc_ast_expr_t call;
scc_ast_expr_t callee1;
scc_ast_expr_identifier_init(&callee1, "f");
scc_ast_expr_call_init(&call, &callee1,
&args); // 使用函数名target 在语义分析时填充
SCC_CHECK_AST(&call.base, "f()", scc_parse_expression);
// 函数调用带参数 f(1, x)
scc_ast_expr_t arg1, arg2;
scc_ast_expr_literal_int_init(&arg1, "1", false);
scc_ast_expr_identifier_init(&arg2, "x");
scc_ast_expr_vec_t args2;
scc_vec_init(args2);
scc_vec_push(args2, &arg1);
scc_vec_push(args2, &arg2);
scc_ast_expr_t callee2;
scc_ast_expr_identifier_init(&callee2, "f");
scc_ast_expr_t call2;
scc_ast_expr_call_init(&call2, &callee2, &args2);
SCC_CHECK_AST(&call2.base, "f(1, x)", scc_parse_expression);
// 成员访问 .
scc_ast_expr_t s, dot;
scc_ast_expr_identifier_init(&s, "s");
scc_ast_expr_member_init(&dot, &s, "field");
SCC_CHECK_AST(&dot.base, "s.field", scc_parse_expression);
// 指针成员访问 ->
scc_ast_expr_t p, arrow;
scc_ast_expr_identifier_init(&p, "p");
scc_ast_expr_ptr_member_init(&arrow, &p, "field");
SCC_CHECK_AST(&arrow.base, "p->field", scc_parse_expression);
// 后缀 ++/--
scc_ast_expr_t x, post_inc, post_dec;
scc_ast_expr_identifier_init(&x, "x");
scc_ast_expr_unary_init(&post_inc, SCC_AST_OP_POSTFIX_INCREMENT, &x);
scc_ast_expr_unary_init(&post_dec, SCC_AST_OP_POSTFIX_DECREMENT, &x);
SCC_CHECK_AST(&post_inc.base, "x++", scc_parse_expression);
SCC_CHECK_AST(&post_dec.base, "x--", scc_parse_expression);
}
// 3. 一元表达式
{
scc_ast_expr_t x;
scc_ast_expr_identifier_init(&x, "x");
scc_ast_expr_t pre_inc;
scc_ast_expr_unary_init(&pre_inc, SCC_AST_OP_PREFIX_INCREMENT, &x);
SCC_CHECK_AST(&pre_inc.base, "++x", scc_parse_expression);
scc_ast_expr_t pre_dec;
scc_ast_expr_unary_init(&pre_dec, SCC_AST_OP_PREFIX_DECREMENT, &x);
SCC_CHECK_AST(&pre_dec.base, "--x", scc_parse_expression);
scc_ast_expr_t addr;
scc_ast_expr_unary_init(&addr, SCC_AST_OP_ADDRESS_OF, &x);
SCC_CHECK_AST(&addr.base, "&x", scc_parse_expression);
scc_ast_expr_t deref;
scc_ast_expr_unary_init(&deref, SCC_AST_OP_INDIRECTION, &x);
SCC_CHECK_AST(&deref.base, "*x", scc_parse_expression);
scc_ast_expr_t plus;
scc_ast_expr_unary_init(&plus, SCC_AST_OP_UNARY_PLUS, &x);
SCC_CHECK_AST(&plus.base, "+x", scc_parse_expression);
scc_ast_expr_t minus;
scc_ast_expr_unary_init(&minus, SCC_AST_OP_UNARY_MINUS, &x);
SCC_CHECK_AST(&minus.base, "-x", scc_parse_expression);
scc_ast_expr_t bit_not;
scc_ast_expr_unary_init(&bit_not, SCC_AST_OP_BITWISE_NOT, &x);
SCC_CHECK_AST(&bit_not.base, "~x", scc_parse_expression);
scc_ast_expr_t log_not;
scc_ast_expr_unary_init(&log_not, SCC_AST_OP_LOGICAL_NOT, &x);
SCC_CHECK_AST(&log_not.base, "!x", scc_parse_expression);
// sizeof 表达式
scc_ast_expr_t sizeof_x_expr;
scc_ast_expr_sizeof_init(&sizeof_x_expr, null, &x);
SCC_CHECK_AST(&sizeof_x_expr.base, "sizeof(x)", scc_parse_expression);
scc_ast_expr_t sizeof_int_expr;
scc_ast_expr_sizeof_init(&sizeof_int_expr,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
null);
SCC_CHECK_AST(&sizeof_int_expr.base, "sizeof(int)",
scc_parse_expression);
}
// 4. 类型转换(示例: (int)x
{
scc_ast_expr_t x;
scc_ast_expr_identifier_init(&x, "x");
scc_ast_expr_t cast;
scc_ast_expr_cast_init(&cast,
(scc_ast_type_t *)&scc_ast_builtin_type_int, &x);
SCC_CHECK_AST(&cast.base, "(int)x", scc_parse_expression);
}
// 5. 二元运算符优先级
{
scc_ast_expr_t a, b, c, d;
scc_ast_expr_identifier_init(&a, "a");
scc_ast_expr_identifier_init(&b, "b");
scc_ast_expr_identifier_init(&c, "c");
scc_ast_expr_identifier_init(&d, "d");
// a * b + c
scc_ast_expr_t mul, add;
scc_ast_expr_binary_init(&mul, SCC_AST_OP_MUL, &a, &b);
scc_ast_expr_binary_init(&add, SCC_AST_OP_ADD, &mul, &c);
SCC_CHECK_AST(&add.base, "a * b + c", scc_parse_expression);
// a - b - c => (a - b) - c
scc_ast_expr_t sub1, sub2;
scc_ast_expr_binary_init(&sub1, SCC_AST_OP_SUB, &a, &b);
scc_ast_expr_binary_init(&sub2, SCC_AST_OP_SUB, &sub1, &c);
SCC_CHECK_AST(&sub2.base, "a - b - c", scc_parse_expression);
// a << b
scc_ast_expr_t shift;
scc_ast_expr_binary_init(&shift, SCC_AST_OP_LEFT_SHIFT, &a, &b);
SCC_CHECK_AST(&shift.base, "a << b", scc_parse_expression);
// a < b
scc_ast_expr_t lt;
scc_ast_expr_binary_init(&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_name);
}
// 2. int *
{
scc_ast_type_t ptr_to_int;
scc_ast_type_pointer_init(
&ptr_to_int, (scc_ast_type_t *)&scc_ast_builtin_type_int);
SCC_CHECK_AST(&ptr_to_int.base, "int *", scc_parse_type_name);
}
// 3. int *[3]
{
scc_ast_type_t ptr_to_int;
scc_ast_type_pointer_init(
&ptr_to_int, (scc_ast_type_t *)&scc_ast_builtin_type_int);
scc_ast_expr_t size_3;
scc_ast_expr_literal_int_init(&size_3, "3", false);
scc_ast_type_t array_of_ptr;
scc_ast_type_array_init(&array_of_ptr, &ptr_to_int, &size_3);
SCC_CHECK_AST(&array_of_ptr.base, "int *[3]", scc_parse_type_name);
}
// 4. int (*)[3]
{
scc_ast_expr_t size_3;
scc_ast_expr_literal_int_init(&size_3, "3", false);
scc_ast_type_t array_of_int;
scc_ast_type_array_init(&array_of_int,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
&size_3);
scc_ast_type_t ptr_to_array;
scc_ast_type_pointer_init(&ptr_to_array, &array_of_int);
SCC_CHECK_AST(&ptr_to_array.base, "int (*)[3]",
scc_parse_type_name);
}
// 5. int (*)[*]
{
scc_ast_type_t array_of_int_var;
scc_ast_type_array_init(&array_of_int_var,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
null); // null 表示不定长数组
scc_ast_type_t ptr_to_array_var;
scc_ast_type_pointer_init(&ptr_to_array_var, &array_of_int_var);
SCC_CHECK_AST(&ptr_to_array_var.base, "int (*)[*]",
scc_parse_type_name);
}
// 6. int *()
{
// 返回类型 int*
scc_ast_type_t ptr_to_int;
scc_ast_type_pointer_init(
&ptr_to_int, (scc_ast_type_t *)&scc_ast_builtin_type_int);
// 函数类型,返回 int*,无参数
scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type, &ptr_to_int, null);
SCC_CHECK_AST(&func_type.base, "int *()", scc_parse_type_name);
}
// 7. int (*)(void)
{
// 函数类型,返回 int无参数
scc_ast_type_t func_void;
scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &scc_ast_builtin_type_void,
null);
scc_ast_decl_t *array[] = {&void_decl};
scc_vec_unsafe_from_array(func_params, array);
scc_ast_type_function_init(
&func_void, (scc_ast_type_t *)&scc_ast_builtin_type_int,
&func_params);
scc_ast_type_t ptr_to_func;
scc_ast_type_pointer_init(&ptr_to_func, &func_void);
SCC_CHECK_AST(&ptr_to_func.base, "int (*)(void)",
scc_parse_type_name);
}
// 8. int (*const [])(unsigned int, ...)
{
// --- 构造参数列表 ---
// 第一个参数unsigned int
scc_ast_decl_t param_uint;
scc_ast_decl_param_init(
&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_name);
}
}
// 1. 基本内置类型及组合
{
// int
SCC_CHECK_AST(&scc_ast_builtin_type_int.base, "int",
scc_parse_type_name);
// char
SCC_CHECK_AST(&scc_ast_builtin_type_char.base, "char",
scc_parse_type_name);
// long long
SCC_CHECK_AST(&scc_ast_builtin_type_long_long.base, "long long",
scc_parse_type_name);
// long long
SCC_CHECK_AST(&scc_ast_builtin_type_long_long.base, "long long int",
scc_parse_type_name);
// short
SCC_CHECK_AST(&scc_ast_builtin_type_short.base, "short int",
scc_parse_type_name);
// unsigned int
SCC_CHECK_AST(&scc_ast_builtin_type_unsigned_int.base, "unsigned int",
scc_parse_type_name);
// float
SCC_CHECK_AST(&scc_ast_builtin_type_float.base, "float",
scc_parse_type_name);
// double
SCC_CHECK_AST(&scc_ast_builtin_type_double.base, "double",
scc_parse_type_name);
// void
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_void, "void",
scc_parse_type_name);
// bool
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_bool, "bool",
scc_parse_type_name);
// long double
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_long_double,
"long double", scc_parse_type_name);
// _Complex double
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_complex_double,
"double complex", scc_parse_type_name);
}
// 2. 带类型限定符的基本类型 (const, volatile)
{
// const int
scc_ast_type_t const_int = scc_ast_builtin_type_int;
const_int.quals.is_const = true;
SCC_CHECK_AST(&const_int.base, "const int", scc_parse_type_name);
// volatile unsigned long
scc_ast_type_t volatile_ulong = scc_ast_builtin_type_unsigned_long;
volatile_ulong.quals.is_volatile = true;
SCC_CHECK_AST(&volatile_ulong.base, "volatile unsigned long",
scc_parse_type_name);
// const volatile char
scc_ast_type_t const_volatile_char = scc_ast_builtin_type_char;
const_volatile_char.quals.is_const = true;
const_volatile_char.quals.is_volatile = true;
SCC_CHECK_AST(&const_volatile_char.base, "const volatile char",
scc_parse_type_name);
}
// 3. 指针类型
{
// int *
scc_ast_type_t ptr_to_int;
scc_ast_type_pointer_init(&ptr_to_int,
(scc_ast_type_t *)&scc_ast_builtin_type_int);
SCC_CHECK_AST(&ptr_to_int.base, "int *", scc_parse_type_name);
// int **
scc_ast_type_t ptr_to_ptr_to_int;
scc_ast_type_pointer_init(&ptr_to_ptr_to_int, &ptr_to_int);
SCC_CHECK_AST(&ptr_to_ptr_to_int.base, "int **", scc_parse_type_name);
// int * const (const pointer to int)
scc_ast_type_t const_ptr_to_int;
scc_ast_type_pointer_init(&const_ptr_to_int,
(scc_ast_type_t *)&scc_ast_builtin_type_int);
const_ptr_to_int.quals.is_const = true;
SCC_CHECK_AST(&const_ptr_to_int.base, "int * const",
scc_parse_type_name);
// const int * (pointer to const int)
scc_ast_type_t const_int_type = scc_ast_builtin_type_int;
const_int_type.quals.is_const = true;
scc_ast_type_t ptr_to_const_int;
scc_ast_type_pointer_init(&ptr_to_const_int, &const_int_type);
SCC_CHECK_AST(&ptr_to_const_int.base, "const int *",
scc_parse_type_name);
// const int * const (const pointer to const int)
scc_ast_type_t const_ptr_to_const_int;
scc_ast_type_pointer_init(&const_ptr_to_const_int, &const_int_type);
const_ptr_to_const_int.quals.is_const = true;
SCC_CHECK_AST(&const_ptr_to_const_int.base, "const int * const",
scc_parse_type_name);
// volatile int * restrict
scc_ast_type_t volatile_int = scc_ast_builtin_type_int;
volatile_int.quals.is_volatile = true;
scc_ast_type_t restrict_ptr_to_volatile_int;
scc_ast_type_pointer_init(&restrict_ptr_to_volatile_int, &volatile_int);
restrict_ptr_to_volatile_int.quals.is_restrict = true;
SCC_CHECK_AST(&restrict_ptr_to_volatile_int.base,
"volatile int * restrict", scc_parse_type_name);
}
// 4. 数组类型
{
// int [5]
scc_ast_expr_t size_5;
scc_ast_expr_literal_int_init(&size_5, "5", false);
scc_ast_type_t array_of_5_int;
scc_ast_type_array_init(&array_of_5_int,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
&size_5);
SCC_CHECK_AST(&array_of_5_int.base, "int [5]", scc_parse_type_name);
// int [] (不完整类型)
scc_ast_type_t array_of_int_unknown;
scc_ast_type_array_init(&array_of_int_unknown,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
null);
SCC_CHECK_AST(&array_of_int_unknown.base, "int []",
scc_parse_type_name);
// // int [*] (变长数组原型中的不定长数组)
// FIXME
// scc_ast_type_t array_of_int_var;
// scc_ast_type_array_init(&array_of_int_var,
// (scc_ast_type_t *)&scc_ast_builtin_type_int,
// null);
// // 注意:[*] 与 [] 在AST中目前无法区分都使用 size=null
// // 表示。如果解析器需要区分,可能需要特殊处理。 这里暂时假设解析器对
// [*]
// // 也生成 size=null 的数组节点。
// SCC_CHECK_AST(&array_of_int_var.base, "int [*]", scc_parse_type);
// int [5][3] (二维数组)
scc_ast_expr_t size_3;
scc_ast_expr_literal_int_init(&size_3, "3", false);
scc_ast_type_t inner_array;
scc_ast_type_array_init(
&inner_array, (scc_ast_type_t *)&scc_ast_builtin_type_int, &size_3);
scc_ast_type_t outer_array;
scc_ast_type_array_init(&outer_array, &inner_array, &size_5);
SCC_CHECK_AST(&outer_array.base, "int [5][3]", scc_parse_type_name);
// int (*)[5] (指向数组的指针) 已在前面测试,这里重复以保持完整性
scc_ast_type_t array_of_5_int2;
scc_ast_type_array_init(&array_of_5_int2,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
&size_5);
scc_ast_type_t ptr_to_array;
scc_ast_type_pointer_init(&ptr_to_array, &array_of_5_int2);
SCC_CHECK_AST(&ptr_to_array.base, "int (*)[5]", scc_parse_type_name);
// int *[5] (指针数组)
scc_ast_type_t ptr_to_int2;
scc_ast_type_pointer_init(&ptr_to_int2,
(scc_ast_type_t *)&scc_ast_builtin_type_int);
scc_ast_type_t array_of_5_ptr;
scc_ast_type_array_init(&array_of_5_ptr, &ptr_to_int2, &size_5);
SCC_CHECK_AST(&array_of_5_ptr.base, "int *[5]", scc_parse_type_name);
// const int [5] (数组元素为const int)
scc_ast_type_t const_int2 = scc_ast_builtin_type_int;
const_int2.quals.is_const = true;
scc_ast_type_t const_array;
scc_ast_type_array_init(&const_array, &const_int2, &size_5);
SCC_CHECK_AST(&const_array.base, "const int [5]", scc_parse_type_name);
}
// 5. 函数类型
{
// int (void)
scc_ast_type_t func_void;
scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &scc_ast_builtin_type_void, null);
scc_ast_decl_t *array[] = {&void_decl};
scc_vec_unsafe_from_array(func_params, array);
scc_ast_type_function_init(&func_void,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
&func_params);
SCC_CHECK_AST(&func_void.base, "int (void)", scc_parse_type_name);
// // int () (无参数声明,非原型)
// //
// 在C中空括号表示未指定参数但AST中可能仍然用空参数列表表示。这里假设与
// // (void) 相同。
// SCC_CHECK_AST(&func_void.base, "int ()", scc_parse_type);
// int (int, float)
scc_ast_decl_t param1, param2;
scc_ast_decl_param_init(
&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_name);
// 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_name);
// 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_name);
}
// 6. 函数指针和复杂声明符
{
// int (*foo)(void)
// 这里应解析为类型名但包含标识符我们的解析函数是scc_parse_type它应该解析类型名不应包含标识符。
// 所以跳过带标识符的,只测试抽象声明符。
// int (*(*)(void))[5] (指向函数的指针,该函数返回指向数组的指针)
// 步骤:
// 1) 数组类型int [5]
scc_ast_expr_t size_5;
scc_ast_expr_literal_int_init(&size_5, "5", false);
scc_ast_type_t array_of_5_int;
scc_ast_type_array_init(&array_of_5_int,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
&size_5);
// 2) 函数类型:返回指向数组的指针,无参数
scc_ast_type_t ptr_to_array;
scc_ast_type_pointer_init(&ptr_to_array, &array_of_5_int);
scc_ast_type_t func_type;
scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &scc_ast_builtin_type_void, null);
scc_ast_decl_t *array[] = {&void_decl};
scc_vec_unsafe_from_array(func_params, array);
scc_ast_type_function_init(&func_type, &ptr_to_array,
&func_params); // 无参数
// 3) 指向该函数的指针
scc_ast_type_t ptr_to_func;
scc_ast_type_pointer_init(&ptr_to_func, &func_type);
SCC_CHECK_AST(&ptr_to_func.base, "int (*(*)(void))[5]",
scc_parse_type_name);
// int (*(*)[5])(void) (指向数组的指针,数组元素为函数指针)
// 1) 函数类型:返回 int无参数
scc_ast_type_t func_type2;
scc_ast_decl_vec_t func_params2;
scc_vec_unsafe_from_array(func_params2, array);
scc_ast_type_function_init(&func_type2,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
&func_params2);
// 2) 指针指向该函数
scc_ast_type_t ptr_to_func2;
scc_ast_type_pointer_init(&ptr_to_func2, &func_type2);
// 3) 数组,元素为上述指针
scc_ast_type_t array_of_ptr_to_func;
scc_ast_type_array_init(&array_of_ptr_to_func, &ptr_to_func2, &size_5);
// 4) 指针指向该数组
scc_ast_type_t ptr_to_array_of_ptr;
scc_ast_type_pointer_init(&ptr_to_array_of_ptr, &array_of_ptr_to_func);
SCC_CHECK_AST(&ptr_to_array_of_ptr.base, "int (*(*)[5])(void)",
scc_parse_type_name);
}
// 7. 结构体/联合/枚举类型(标记和定义)
{
// struct S (不完整类型)
scc_ast_type_t struct_tag;
scc_ast_type_struct_init(&struct_tag, "S",
null); // name="S", members=null
SCC_CHECK_AST(&struct_tag.base, "struct S", scc_parse_type_name);
// struct { int x; } (匿名结构体定义)
scc_ast_decl_t field;
scc_ast_decl_val_init(
&field, (scc_ast_type_t *)&scc_ast_builtin_type_int, "x", null);
scc_ast_decl_vec_t fields;
scc_vec_init(fields);
scc_vec_push(fields, &field);
scc_ast_decl_t struct_def;
scc_ast_decl_struct_init(&struct_def, null, &fields);
scc_ast_type_t struct_type;
scc_ast_type_struct_init(&struct_type, null, &struct_def);
SCC_CHECK_AST(&struct_type.base, "struct { int x; }",
scc_parse_type_name);
scc_vec_init(fields);
scc_vec_push(fields, &field);
scc_ast_decl_struct_init(&struct_def, "A", &fields);
scc_ast_type_struct_init(&struct_type, "A", &struct_def);
SCC_CHECK_AST(&struct_type.base, "struct A { int x; }",
scc_parse_type_name);
// union U (不完整类型)
scc_ast_type_t union_tag;
scc_ast_type_union_init(&union_tag, "U", null);
SCC_CHECK_AST(&union_tag.base, "union U", scc_parse_type_name);
// union { int a; float b; } (匿名联合定义)
scc_ast_decl_t field_a, field_b;
scc_ast_decl_val_init(
&field_a, (scc_ast_type_t *)&scc_ast_builtin_type_int, "a", null);
scc_ast_decl_val_init(
&field_b, (scc_ast_type_t *)&scc_ast_builtin_type_float, "b", null);
scc_ast_decl_vec_t fields_union;
scc_vec_init(fields_union);
scc_vec_push(fields_union, &field_a);
scc_vec_push(fields_union, &field_b);
scc_ast_decl_t union_def;
scc_ast_decl_union_init(&union_def, null, &fields_union);
scc_ast_type_t union_type;
scc_ast_type_union_init(&union_type, null, &union_def);
SCC_CHECK_AST(&union_type.base, "union { int a; float b; }",
scc_parse_type_name);
scc_ast_decl_union_init(&union_def, "Union", &fields_union);
scc_ast_type_union_init(&union_type, "Union", &union_def);
SCC_CHECK_AST(&union_type.base, "union Union { int a; float b; }",
scc_parse_type_name);
// enum E (不完整类型)
scc_ast_type_t enum_tag;
scc_ast_type_enum_init(&enum_tag, "E", null);
SCC_CHECK_AST(&enum_tag.base, "enum E", scc_parse_type_name);
// enum { RED, GREEN, BLUE } (匿名枚举定义)
scc_ast_expr_t red, green, blue;
scc_ast_expr_identifier_init(&red, "RED");
scc_ast_expr_identifier_init(&green, "GREEN");
scc_ast_expr_identifier_init(&blue, "BLUE");
scc_ast_expr_vec_t enumerators;
scc_ast_expr_t *array[] = {&red, &green, &blue};
scc_vec_unsafe_from_array(enumerators, array);
scc_ast_decl_t enum_def;
scc_ast_decl_enum_init(&enum_def, null, &enumerators);
scc_ast_type_t enum_type;
scc_ast_type_enum_init(&enum_type, null, &enum_def);
SCC_CHECK_AST(&enum_type.base, "enum { RED, GREEN, BLUE }",
scc_parse_type_name);
scc_vec_unsafe_from_array(enumerators, array);
scc_ast_decl_enum_init(&enum_def, "E", &enumerators);
scc_ast_type_enum_init(&enum_type, "E", &enum_def);
SCC_CHECK_AST(&enum_type.base, "enum E { RED, GREEN, BLUE, }",
scc_parse_type_name);
}
// 8. typedef 类型
{
// 假设存在 typedef int myint; 但类型解析时,遇到 myint
// 应得到对应的类型节点。 为了测试,我们直接构造一个 typedef 类型节点。
// scc_ast_type_t myint_type;
// scc_ast_type_typedef_init(&myint_type, "myint",
// (scc_ast_type_t
// *)&scc_ast_builtin_type_int);
// SCC_CHECK_AST(&myint_type.base, "myint", scc_parse_type);
// // myint * (指针指向 typedef 类型)
// scc_ast_type_t ptr_to_myint;
// scc_ast_type_pointer_init(&ptr_to_myint, &myint_type);
// SCC_CHECK_AST(&ptr_to_myint.base, "myint *", scc_parse_type);
}
// 9. 混合复杂类型
{
// const int * volatile (*)[10]
// 步骤:
// 1) const int
scc_ast_type_t const_int = scc_ast_builtin_type_int;
const_int.quals.is_const = true;
// 2) 指针指向 const int (普通指针)
scc_ast_type_t ptr_to_const_int;
scc_ast_type_pointer_init(&ptr_to_const_int, &const_int);
// 该指针本身是 volatile 限定?语法上 "const int * volatile" 表示指针是
// volatile 的,指向 const int。
ptr_to_const_int.quals.is_volatile = true;
// 3) 数组元素为上述指针大小为10
scc_ast_expr_t size_10;
scc_ast_expr_literal_int_init(&size_10, "10", false);
scc_ast_type_t array_of_ptr;
scc_ast_type_array_init(&array_of_ptr, &ptr_to_const_int, &size_10);
// 4) 指针指向该数组
scc_ast_type_t ptr_to_array;
scc_ast_type_pointer_init(&ptr_to_array, &array_of_ptr);
SCC_CHECK_AST(&ptr_to_array.base, "const int * volatile (*)[10]",
scc_parse_type_name);
// float (*(*)(int, ...))()
// 1) float 类型作为内部函数返回类型
// 2) 构建返回 float 的函数类型,无参数(或者参数为空)
scc_ast_type_t func_ret_float;
scc_ast_type_function_init(
&func_ret_float, (scc_ast_type_t *)&scc_ast_builtin_type_float,
null);
// 3) 指针指向该函数
scc_ast_type_t ptr_to_func_ret_float;
scc_ast_type_pointer_init(&ptr_to_func_ret_float, &func_ret_float);
// 4) 外层函数类型,返回上述指针,参数为 (int, ...)
scc_ast_decl_t param_int, param_var;
scc_ast_decl_param_init(
&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_name);
}
}
TEST_LIST = {
{"parser_unit", test_parser_unit},
{"parser_expression", test_parser_expression},
{"parser_type", test_parser_type},
// {"parser_statement", test_parser_statement},
// {"parser_declaration", test_parser_declaration},
// {"parser_translation_unit", test_parser_translation_unit},
{null, null},
};