feat(ast): 添加完整的内置类型支持并重构类型定义

- 添加 va_list、bool、signed/unsigned 各种整数类型等内置类型
- 重新排列内置类型枚举顺序,增加 UNKNOWN 类型
- 为复合字面量、指针类型、数组类型添加初始化函数
- 添加结构体、联合体、枚举、typedef 类型的初始化函数
- 更新类型转储功能以支持新的内置类型显示

refactor(parser): 优化类型解析和声明处理逻辑

- 修改类型解析函数返回类型为通用 AST 节点
- 重构声明解析逻辑,支持变量和函数声明的不同处理路径
- 更新语法分析规则中的空格标记处理
- 简化表达式解析中的错误处理流程

fix(ast): 修复参数声明和类型转储相关问题

- 修正参数声明初始化函数中对 name 参数可为空的处理
- 修复类型转储中修饰符显示和指针类型显示问题
- 更新 AST 转储中空值检查使用正确的 null 比较
This commit is contained in:
zzy
2026-03-11 16:51:52 +08:00
parent 742bede02f
commit ce5414f2eb
14 changed files with 1717 additions and 1136 deletions

View File

@@ -48,6 +48,7 @@ static inline void scc_parser_restore(scc_parser_t *parser) {
_scc_ring_probe(*parser->ring) = parser->checkpoint;
}
// tok can null it will be safty free
static inline cbool scc_parser_next_consume(scc_parser_t *parser,
scc_lexer_tok_t *tok) {
cbool ok = false;

View File

@@ -66,10 +66,8 @@ scc_ast_expr_t *scc_parse_expression(scc_parser_t *parser);
* @param parser 解析器实例
* @return 类型 AST 节点
*/
scc_ast_type_t *scc_parse_type(scc_parser_t *parser);
scc_ast_node_t *_scc_parse_type(scc_parser_t *parser);
static inline scc_ast_type_t *scc_parse_type_name(scc_parser_t *parser) {
return null; // TODO
}
scc_ast_type_t *scc_parse_type_name(scc_parser_t *parser);
#endif /* __SCC_PARSER_H__ */

View File

@@ -57,7 +57,7 @@ A.2.2 Declarations
declarator(opt) : constant-expression
(6.7.2.2) enum-specifier:
enum identifier(opt) { enumerator-list }
enum identifier(opt) { enumerator-list ,}
enum identifier(opt) { enumerator-list , }
enum identifier
(6.7.2.2) enumerator-list:
enumerator
@@ -82,7 +82,7 @@ A.2.2 Declarations
assignment-expression ]
direct-declarator [ type-qualifier-list static
assignment-expression ]
direct-declarator [ type-qualifier-list(opt) *]
direct-declarator [ type-qualifier-list(opt) * ]
direct-declarator ( parameter-type-list )
direct-declarator ( identifier-list(opt) )
(6.7.5) pointer:
@@ -112,9 +112,9 @@ A.2.2 Declarations
( abstract-declarator )
direct-abstract-declarator(opt) [ type-qualifier-list (opt)
assignment-expression(opt) ]
direct-abstract-declarator(opt) [static type-qualifier-list(opt)
direct-abstract-declarator(opt) [ static type-qualifier-list(opt)
assignment-expression ]
direct-abstract-declaratoropt [ type-qualifier-list static
direct-abstract-declarator(opt) [ type-qualifier-list static
assignment-expression ]
direct-abstract-declarator(opt) [ * ]
direct-abstract-declarator(opt) ( parameter-type-list(opt) )
@@ -177,81 +177,46 @@ scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) {
cbool ok;
scc_lexer_tok_t tok;
scc_ast_type_t *type = scc_parse_type(parser);
if (type == null) {
scc_ast_node_t *type_or_decl = _scc_parse_type(parser);
scc_ast_decl_t *decl = null;
if (type_or_decl == null) {
return null;
}
ok = scc_parser_next_consume(parser, &tok);
if (ok == false) {
if (SCC_AST_IS_A(scc_ast_type_t, type_or_decl)) {
LOG_WARN("declaration dose not declare anything");
return null;
}
scc_ast_decl_t *decl = scc_malloc(sizeof(scc_ast_decl_t));
/*
(6.7.5) declarator:
pointeropt direct-declarator
(6.7.5) direct-declarator:
identifier
( declarator )
direct-declarator [ type-qualifier-listopt assignment-expressionopt ]
direct-declarator [static type-qualifier-listopt assignment-expression ]
direct-declarator [ type-qualifier-list static assignment-expression ]
direct-declarator [ type-qualifier-listopt *]
direct-declarator ( parameter-type-list )
direct-declarator ( identifier-listopt )
*/
if (!scc_parser_consume_if(parser, SCC_TOK_L_PAREN)) {
if (scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) {
scc_ast_decl_val_init(decl, type, scc_cstring_as_cstr(&tok.lexeme),
null);
goto RETURN;
} else if (scc_parser_consume_if(parser, SCC_TOK_ASSIGN)) {
scc_ast_expr_t *init = scc_parse_expression(parser);
scc_ast_decl_val_init(decl, type, scc_cstring_as_cstr(&tok.lexeme),
init);
if (!scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) {
LOG_ERROR("expect semicolon");
}
goto RETURN;
}
// TODO
return null;
}
// function decl
decl->base.type = SCC_AST_DECL_FUNC;
decl->name = scc_cstring_as_cstr(&tok.lexeme);
decl->func.type = scc_malloc(sizeof(scc_ast_type_t));
decl->func.type->base.type = SCC_AST_TYPE_FUNCTION;
scc_vec_init(decl->func.type->function.param_types);
decl->func.type->function.return_type = type;
// TODO param type
scc_parser_consume_if(parser, SCC_TOK_VOID);
if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
} else if (SCC_AST_IS_A(scc_ast_decl_t, type_or_decl)) {
decl = SCC_AST_CAST_TO(scc_ast_decl_t, type_or_decl);
} else {
LOG_ERROR("invalid declaration");
return null;
}
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
if (tok_ptr == null) {
return null;
}
if (tok_ptr->type != SCC_TOK_L_BRACE) {
if (tok_ptr->type == SCC_TOK_SEMICOLON) {
decl->func.body = null;
} else {
return null;
if (tok_ptr->type == SCC_TOK_SEMICOLON) {
scc_parser_next_consume(parser, null);
goto RETURN;
} else if (tok_ptr->type == SCC_TOK_ASSIGN) {
scc_parser_next_consume(parser, null);
scc_ast_expr_t *init = scc_parse_expression(parser);
decl->var.init = init;
if (!scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) {
LOG_ERROR("expect semicolon");
}
goto RETURN;
} else if (tok_ptr->type == SCC_TOK_L_BRACE) {
scc_ast_stmt_t *body = scc_parse_statement(parser);
Assert(decl->base.type == SCC_AST_DECL_FUNC);
decl->func.body = body;
Assert(decl->func.type != null);
Assert(decl->func.type->base.type == SCC_AST_TYPE_FUNCTION);
Assert(decl->func.body != null);
Assert(decl->func.body->base.type == SCC_AST_STMT_COMPOUND);
} else {
UNREACHABLE();
}
decl->func.body = scc_parse_statement(parser);
Assert(decl->func.type != null);
Assert(decl->func.type->base.type == SCC_AST_TYPE_FUNCTION);
Assert(decl->func.body != null);
Assert(decl->func.body->base.type == SCC_AST_STMT_COMPOUND);
RETURN:
if (decl) {
parser->sema_callbacks.on_decl(parser->sema_callbacks.context,

View File

@@ -897,8 +897,6 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
case SCC_TOK_L_PAREN:
return parse_paren_expression(parser);
default:
LOG_ERROR("Unexpected token in primary expression: %s",
scc_get_tok_name(tok->type));
parser_sync(parser);
return null;
}

File diff suppressed because it is too large Load Diff

View File

@@ -26,7 +26,10 @@ static scc_ast_node_t *process_input(const char *input,
cbool not_eof = false;
scc_ring_not_eof(*parser.ring, not_eof);
Assert(!not_eof == true);
if (not_eof == true) {
// FIXME MAYBE free
return null;
}
scc_lexer_drop_ring(parser.ring);
scc_parser_drop(&parser);
@@ -81,9 +84,13 @@ static void test_parser_unit(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,
null); // 无参数,非可变参数
&func_params);
// 构造复合语句块(空)
scc_ast_stmt_t compound;
scc_ast_stmt_compound_init(&compound, null);
@@ -99,7 +106,13 @@ static void test_parser_unit(void) {
// 3. 翻译单元包含一个函数定义
{
scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type, &scc_ast_builtin_type_int, null);
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);
@@ -138,7 +151,13 @@ static void test_parser_unit(void) {
// 函数类型
scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type, &scc_ast_builtin_type_int, null);
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);
@@ -318,6 +337,37 @@ static void test_parser_unit(void) {
// 比较解析结果与期望 AST
SCC_CHECK_AST(&tu.base, input, scc_parse_translation_unit);
}
{
scc_ast_decl_vec_t params;
scc_ast_decl_t param0;
scc_ast_decl_param_init(
&param0, (scc_ast_type_t *)&scc_ast_builtin_type_int, "a");
scc_ast_decl_t param1;
scc_ast_decl_param_init(
&param1, (scc_ast_type_t *)&scc_ast_builtin_type_int, "b");
scc_ast_decl_t param2;
scc_ast_decl_param_init(
&param2, (scc_ast_type_t *)&scc_ast_builtin_type_va_list, null);
scc_ast_decl_t *params_array[] = {&param0, &param1, &param2};
scc_vec_unsafe_from_array(params, params_array);
scc_ast_type_t decl_func_type;
scc_ast_type_function_init(&decl_func_type,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
&params);
scc_ast_decl_t decl_func;
scc_ast_decl_func_init(&decl_func, &decl_func_type, "add", null);
SCC_CHECK_AST(&decl_func.base, "int add(int a, int b, ...);",
scc_parse_declaration);
}
{
scc_ast_decl_t typedef_decl;
scc_ast_decl_typedef_init(&typedef_decl, "int32_t",
&scc_ast_builtin_type_int);
SCC_CHECK_AST(&typedef_decl.base, "typedef int int32_t;",
scc_parse_declaration);
}
}
static void test_parser_expression(void) {
@@ -596,8 +646,591 @@ static void test_parser_expression(void) {
}
}
static void test_parser_type(void) {
{
// 1. int
{
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_int, "int",
_scc_parse_type);
}
// 2. int *
{
scc_ast_type_t ptr_to_int;
scc_ast_type_pointer_init(
&ptr_to_int, (scc_ast_type_t *)&scc_ast_builtin_type_int);
SCC_CHECK_AST(&ptr_to_int.base, "int *", _scc_parse_type);
}
// 3. int *[3]
{
scc_ast_type_t ptr_to_int;
scc_ast_type_pointer_init(
&ptr_to_int, (scc_ast_type_t *)&scc_ast_builtin_type_int);
scc_ast_expr_t size_3;
scc_ast_expr_literal_int_init(&size_3, "3", false);
scc_ast_type_t array_of_ptr;
scc_ast_type_array_init(&array_of_ptr, &ptr_to_int, &size_3);
SCC_CHECK_AST(&array_of_ptr.base, "int *[3]", _scc_parse_type);
}
// 4. int (*)[3]
{
scc_ast_expr_t size_3;
scc_ast_expr_literal_int_init(&size_3, "3", false);
scc_ast_type_t array_of_int;
scc_ast_type_array_init(&array_of_int,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
&size_3);
scc_ast_type_t ptr_to_array;
scc_ast_type_pointer_init(&ptr_to_array, &array_of_int);
SCC_CHECK_AST(&ptr_to_array.base, "int (*)[3]", _scc_parse_type);
}
// 5. int (*)[*]
{
scc_ast_type_t array_of_int_var;
scc_ast_type_array_init(&array_of_int_var,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
NULL); // NULL 表示不定长数组
scc_ast_type_t ptr_to_array_var;
scc_ast_type_pointer_init(&ptr_to_array_var, &array_of_int_var);
SCC_CHECK_AST(&ptr_to_array_var.base, "int (*)[*]",
_scc_parse_type);
}
// 6. int *()
{
// 返回类型 int*
scc_ast_type_t ptr_to_int;
scc_ast_type_pointer_init(
&ptr_to_int, (scc_ast_type_t *)&scc_ast_builtin_type_int);
// 函数类型,返回 int*,无参数
scc_ast_type_t func_type;
scc_ast_type_function_init(&func_type, &ptr_to_int, NULL);
SCC_CHECK_AST(&func_type.base, "int *()", _scc_parse_type);
}
// 7. int (*)(void)
{
// 函数类型,返回 int无参数
scc_ast_type_t func_void;
scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &scc_ast_builtin_type_void,
null);
scc_ast_decl_t *array[] = {&void_decl};
scc_vec_unsafe_from_array(func_params, array);
scc_ast_type_function_init(
&func_void, (scc_ast_type_t *)&scc_ast_builtin_type_int,
&func_params);
scc_ast_type_t ptr_to_func;
scc_ast_type_pointer_init(&ptr_to_func, &func_void);
SCC_CHECK_AST(&ptr_to_func.base, "int (*)(void)", _scc_parse_type);
}
// 8. int (*const [])(unsigned int, ...)
{
// --- 构造参数列表 ---
// 第一个参数unsigned int
scc_ast_decl_t param_uint;
scc_ast_decl_param_init(
&param_uint,
(scc_ast_type_t *)&scc_ast_builtin_type_unsigned_int, "u");
// 第二个参数:... 用内置 va_list 类型近似表示
scc_ast_type_t va_list_type;
_scc_ast_type_builtin_init(&va_list_type,
SCC_AST_BUILTIN_TYPE_VA_LIST);
scc_ast_decl_t param_var;
scc_ast_decl_param_init(&param_var, &va_list_type, "...");
scc_ast_decl_vec_t params;
scc_vec_init(params);
scc_vec_push(params, &param_uint);
scc_vec_push(params, &param_var);
// --- 函数类型,返回 int ---
scc_ast_type_t func_type;
scc_ast_type_function_init(
&func_type, (scc_ast_type_t *)&scc_ast_builtin_type_int,
&params); // params 被移动
// --- 指向函数的指针,带 const 限定 ---
scc_ast_type_t ptr_to_func;
scc_ast_type_pointer_init(&ptr_to_func, &func_type);
ptr_to_func.quals.is_const = true; // 设置 const
// --- 数组,元素为上述 const 指针,大小未指定 ---
scc_ast_type_t array_of_ptr;
scc_ast_type_array_init(&array_of_ptr, &ptr_to_func, NULL);
SCC_CHECK_AST(&array_of_ptr.base,
"int (*const [])(unsigned int, ...)",
_scc_parse_type);
}
}
// 1. 基本内置类型及组合
{
// int
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_int, "int",
_scc_parse_type);
// char
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_char, "char",
_scc_parse_type);
// long long
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_long_long,
"long long", _scc_parse_type);
// unsigned int
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_unsigned_int,
"unsigned int", _scc_parse_type);
// float
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_float, "float",
_scc_parse_type);
// double
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_double, "double",
_scc_parse_type);
// void
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_void, "void",
_scc_parse_type);
// bool
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_bool, "bool",
_scc_parse_type);
// long double
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_long_double,
"long double", _scc_parse_type);
// _Complex double
SCC_CHECK_AST((scc_ast_node_t *)&scc_ast_builtin_type_complex_double,
"complex double", _scc_parse_type);
}
// 2. 带类型限定符的基本类型 (const, volatile)
{
// const int
scc_ast_type_t const_int = scc_ast_builtin_type_int;
const_int.quals.is_const = true;
SCC_CHECK_AST(&const_int.base, "const int", _scc_parse_type);
// volatile unsigned long
scc_ast_type_t volatile_ulong = scc_ast_builtin_type_unsigned_long;
volatile_ulong.quals.is_volatile = true;
SCC_CHECK_AST(&volatile_ulong.base, "volatile unsigned long",
_scc_parse_type);
// const volatile char
scc_ast_type_t const_volatile_char = scc_ast_builtin_type_char;
const_volatile_char.quals.is_const = true;
const_volatile_char.quals.is_volatile = true;
SCC_CHECK_AST(&const_volatile_char.base, "const volatile char",
_scc_parse_type);
}
// 3. 指针类型
{
// int *
scc_ast_type_t ptr_to_int;
scc_ast_type_pointer_init(&ptr_to_int,
(scc_ast_type_t *)&scc_ast_builtin_type_int);
SCC_CHECK_AST(&ptr_to_int.base, "int *", _scc_parse_type);
// int **
scc_ast_type_t ptr_to_ptr_to_int;
scc_ast_type_pointer_init(&ptr_to_ptr_to_int, &ptr_to_int);
SCC_CHECK_AST(&ptr_to_ptr_to_int.base, "int **", _scc_parse_type);
// int * const (const pointer to int)
scc_ast_type_t const_ptr_to_int;
scc_ast_type_pointer_init(&const_ptr_to_int,
(scc_ast_type_t *)&scc_ast_builtin_type_int);
const_ptr_to_int.quals.is_const = true;
SCC_CHECK_AST(&const_ptr_to_int.base, "int * const", _scc_parse_type);
// const int * (pointer to const int)
scc_ast_type_t const_int_type = scc_ast_builtin_type_int;
const_int_type.quals.is_const = true;
scc_ast_type_t ptr_to_const_int;
scc_ast_type_pointer_init(&ptr_to_const_int, &const_int_type);
SCC_CHECK_AST(&ptr_to_const_int.base, "const int *", _scc_parse_type);
// const int * const (const pointer to const int)
scc_ast_type_t const_ptr_to_const_int;
scc_ast_type_pointer_init(&const_ptr_to_const_int, &const_int_type);
const_ptr_to_const_int.quals.is_const = true;
SCC_CHECK_AST(&const_ptr_to_const_int.base, "const int * const",
_scc_parse_type);
// volatile int * restrict
scc_ast_type_t volatile_int = scc_ast_builtin_type_int;
volatile_int.quals.is_volatile = true;
scc_ast_type_t restrict_ptr_to_volatile_int;
scc_ast_type_pointer_init(&restrict_ptr_to_volatile_int, &volatile_int);
restrict_ptr_to_volatile_int.quals.is_restrict = true;
SCC_CHECK_AST(&restrict_ptr_to_volatile_int.base,
"volatile int * restrict", _scc_parse_type);
}
// 4. 数组类型
{
// int [5]
scc_ast_expr_t size_5;
scc_ast_expr_literal_int_init(&size_5, "5", false);
scc_ast_type_t array_of_5_int;
scc_ast_type_array_init(&array_of_5_int,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
&size_5);
SCC_CHECK_AST(&array_of_5_int.base, "int [5]", _scc_parse_type);
// int [] (不完整类型)
scc_ast_type_t array_of_int_unknown;
scc_ast_type_array_init(&array_of_int_unknown,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
NULL);
SCC_CHECK_AST(&array_of_int_unknown.base, "int []", _scc_parse_type);
// // int [*] (变长数组原型中的不定长数组)
// FIXME
// scc_ast_type_t array_of_int_var;
// scc_ast_type_array_init(&array_of_int_var,
// (scc_ast_type_t *)&scc_ast_builtin_type_int,
// NULL);
// // 注意:[*] 与 [] 在AST中目前无法区分都使用 size=NULL
// // 表示。如果解析器需要区分,可能需要特殊处理。 这里暂时假设解析器对
// [*]
// // 也生成 size=NULL 的数组节点。
// SCC_CHECK_AST(&array_of_int_var.base, "int [*]", scc_parse_type);
// int [5][3] (二维数组)
scc_ast_expr_t size_3;
scc_ast_expr_literal_int_init(&size_3, "3", false);
scc_ast_type_t inner_array;
scc_ast_type_array_init(
&inner_array, (scc_ast_type_t *)&scc_ast_builtin_type_int, &size_3);
scc_ast_type_t outer_array;
scc_ast_type_array_init(&outer_array, &inner_array, &size_5);
SCC_CHECK_AST(&outer_array.base, "int [5][3]", _scc_parse_type);
// int (*)[5] (指向数组的指针) 已在前面测试,这里重复以保持完整性
scc_ast_type_t array_of_5_int2;
scc_ast_type_array_init(&array_of_5_int2,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
&size_5);
scc_ast_type_t ptr_to_array;
scc_ast_type_pointer_init(&ptr_to_array, &array_of_5_int2);
SCC_CHECK_AST(&ptr_to_array.base, "int (*)[5]", _scc_parse_type);
// int *[5] (指针数组)
scc_ast_type_t ptr_to_int2;
scc_ast_type_pointer_init(&ptr_to_int2,
(scc_ast_type_t *)&scc_ast_builtin_type_int);
scc_ast_type_t array_of_5_ptr;
scc_ast_type_array_init(&array_of_5_ptr, &ptr_to_int2, &size_5);
SCC_CHECK_AST(&array_of_5_ptr.base, "int *[5]", _scc_parse_type);
// const int [5] (数组元素为const int)
scc_ast_type_t const_int2 = scc_ast_builtin_type_int;
const_int2.quals.is_const = true;
scc_ast_type_t const_array;
scc_ast_type_array_init(&const_array, &const_int2, &size_5);
SCC_CHECK_AST(&const_array.base, "const int [5]", _scc_parse_type);
}
// 5. 函数类型
{
// int (void)
scc_ast_type_t func_void;
scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &scc_ast_builtin_type_void, null);
scc_ast_decl_t *array[] = {&void_decl};
scc_vec_unsafe_from_array(func_params, array);
scc_ast_type_function_init(&func_void,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
&func_params);
SCC_CHECK_AST(&func_void.base, "int (void)", _scc_parse_type);
// // int () (无参数声明,非原型)
// //
// 在C中空括号表示未指定参数但AST中可能仍然用空参数列表表示。这里假设与
// // (void) 相同。
// SCC_CHECK_AST(&func_void.base, "int ()", scc_parse_type);
// int (int, float)
scc_ast_decl_t param1, param2;
scc_ast_decl_param_init(
&param1, (scc_ast_type_t *)&scc_ast_builtin_type_int, null);
scc_ast_decl_param_init(
&param2, (scc_ast_type_t *)&scc_ast_builtin_type_float, null);
scc_ast_decl_vec_t params;
scc_vec_init(params);
scc_vec_push(params, &param1);
scc_vec_push(params, &param2);
scc_ast_type_t func_with_params;
scc_ast_type_function_init(&func_with_params,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
&params);
SCC_CHECK_AST(&func_with_params.base, "int (int, float)",
_scc_parse_type);
// int (int, ...) (可变参数)
scc_ast_decl_t param_int, param_var;
scc_ast_decl_param_init(
&param_int, (scc_ast_type_t *)&scc_ast_builtin_type_int, null);
scc_ast_type_t va_list_type;
_scc_ast_type_builtin_init(&va_list_type, SCC_AST_BUILTIN_TYPE_VA_LIST);
scc_ast_decl_param_init(&param_var, &va_list_type, null);
scc_ast_decl_vec_t params_var;
scc_vec_init(params_var);
scc_vec_push(params_var, &param_int);
scc_vec_push(params_var, &param_var);
scc_ast_type_t func_varargs;
scc_ast_type_function_init(&func_varargs,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
&params_var);
SCC_CHECK_AST(&func_varargs.base, "int (int, ...)", _scc_parse_type);
// int (*)(int) (函数指针)
scc_ast_decl_t param;
scc_ast_decl_param_init(
&param, (scc_ast_type_t *)&scc_ast_builtin_type_int, null);
scc_ast_decl_vec_t params2;
scc_vec_init(params2);
scc_vec_push(params2, &param);
scc_ast_type_t func_type;
scc_ast_type_function_init(
&func_type, (scc_ast_type_t *)&scc_ast_builtin_type_int, &params2);
scc_ast_type_t ptr_to_func;
scc_ast_type_pointer_init(&ptr_to_func, &func_type);
SCC_CHECK_AST(&ptr_to_func.base, "int (*)(int)", _scc_parse_type);
}
// 6. 函数指针和复杂声明符
{
// int (*foo)(void)
// 这里应解析为类型名但包含标识符我们的解析函数是scc_parse_type它应该解析类型名不应包含标识符。
// 所以跳过带标识符的,只测试抽象声明符。
// int (*(*)(void))[5] (指向函数的指针,该函数返回指向数组的指针)
// 步骤:
// 1) 数组类型int [5]
scc_ast_expr_t size_5;
scc_ast_expr_literal_int_init(&size_5, "5", false);
scc_ast_type_t array_of_5_int;
scc_ast_type_array_init(&array_of_5_int,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
&size_5);
// 2) 函数类型:返回指向数组的指针,无参数
scc_ast_type_t ptr_to_array;
scc_ast_type_pointer_init(&ptr_to_array, &array_of_5_int);
scc_ast_type_t func_type;
scc_ast_decl_vec_t func_params;
scc_ast_decl_t void_decl;
scc_ast_decl_param_init(&void_decl, &scc_ast_builtin_type_void, null);
scc_ast_decl_t *array[] = {&void_decl};
scc_vec_unsafe_from_array(func_params, array);
scc_ast_type_function_init(&func_type, &ptr_to_array,
&func_params); // 无参数
// 3) 指向该函数的指针
scc_ast_type_t ptr_to_func;
scc_ast_type_pointer_init(&ptr_to_func, &func_type);
SCC_CHECK_AST(&ptr_to_func.base, "int (*(*)(void))[5]",
_scc_parse_type);
// int (*(*)[5])(void) (指向数组的指针,数组元素为函数指针)
// 1) 函数类型:返回 int无参数
scc_ast_type_t func_type2;
scc_ast_decl_vec_t func_params2;
scc_vec_unsafe_from_array(func_params2, array);
scc_ast_type_function_init(&func_type2,
(scc_ast_type_t *)&scc_ast_builtin_type_int,
&func_params2);
// 2) 指针指向该函数
scc_ast_type_t ptr_to_func2;
scc_ast_type_pointer_init(&ptr_to_func2, &func_type2);
// 3) 数组,元素为上述指针
scc_ast_type_t array_of_ptr_to_func;
scc_ast_type_array_init(&array_of_ptr_to_func, &ptr_to_func2, &size_5);
// 4) 指针指向该数组
scc_ast_type_t ptr_to_array_of_ptr;
scc_ast_type_pointer_init(&ptr_to_array_of_ptr, &array_of_ptr_to_func);
SCC_CHECK_AST(&ptr_to_array_of_ptr.base, "int (*(*)[5])(void)",
_scc_parse_type);
}
// 7. 结构体/联合/枚举类型(标记和定义)
{
// struct S (不完整类型)
scc_ast_type_t struct_tag;
scc_ast_type_struct_init(&struct_tag, "S",
NULL); // name="S", members=NULL
SCC_CHECK_AST(&struct_tag.base, "struct S", _scc_parse_type);
// struct { int x; } (匿名结构体定义)
scc_ast_decl_t field;
scc_ast_decl_val_init(
&field, (scc_ast_type_t *)&scc_ast_builtin_type_int, "x", NULL);
scc_ast_decl_vec_t fields;
scc_vec_init(fields);
scc_vec_push(fields, &field);
scc_ast_type_t struct_def;
scc_ast_type_struct_init(&struct_def, NULL,
&fields); // name=NULL, members=fields
SCC_CHECK_AST(&struct_def.base, "struct { 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_type_t union_def;
scc_ast_type_union_init(&union_def, NULL, &fields_union);
SCC_CHECK_AST(&union_def.base, "union { int a; float b; }",
_scc_parse_type);
// enum E (不完整类型)
scc_ast_type_t enum_tag;
scc_ast_type_enum_init(&enum_tag, "E", NULL);
SCC_CHECK_AST(&enum_tag.base, "enum E", _scc_parse_type);
// enum { RED, GREEN, BLUE } (匿名枚举定义)
scc_ast_expr_t red, green, blue;
scc_ast_expr_identifier_init(&red, "RED");
scc_ast_expr_identifier_init(&green, "GREEN");
scc_ast_expr_identifier_init(&blue, "BLUE");
scc_ast_expr_vec_t enumerators;
scc_vec_init(enumerators);
scc_vec_push(enumerators, &red);
scc_vec_push(enumerators, &green);
scc_vec_push(enumerators, &blue);
scc_ast_type_t enum_def;
scc_ast_type_enum_init(&enum_def, NULL, &enumerators);
SCC_CHECK_AST(&enum_def.base, "enum { 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);
// int (*(*)(int, ...))(float)
// 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, "int (*(*)(int, ...))(float)",
_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},
};