- 添加 va_list、bool、signed/unsigned 各种整数类型等内置类型 - 重新排列内置类型枚举顺序,增加 UNKNOWN 类型 - 为复合字面量、指针类型、数组类型添加初始化函数 - 添加结构体、联合体、枚举、typedef 类型的初始化函数 - 更新类型转储功能以支持新的内置类型显示 refactor(parser): 优化类型解析和声明处理逻辑 - 修改类型解析函数返回类型为通用 AST 节点 - 重构声明解析逻辑,支持变量和函数声明的不同处理路径 - 更新语法分析规则中的空格标记处理 - 简化表达式解析中的错误处理流程 fix(ast): 修复参数声明和类型转储相关问题 - 修正参数声明初始化函数中对 name 参数可为空的处理 - 修复类型转储中修饰符显示和指针类型显示问题 - 更新 AST 转储中空值检查使用正确的 null 比较
227 lines
6.6 KiB
C
227 lines
6.6 KiB
C
/*
|
|
A.2.2 Declarations
|
|
|
|
(6.7) declaration:
|
|
declaration-specifiers init-declarator-list(opt) ;
|
|
(6.7) declaration-specifiers:
|
|
storage-class-specifier declaration-specifiers(opt)
|
|
type-specifier declaration-specifiers(opt)
|
|
type-qualifier declaration-specifiers(opt)
|
|
function-specifier declaration-specifiers(opt)
|
|
(6.7) init-declarator-list:
|
|
init-declarator
|
|
init-declarator-list , init-declarator
|
|
(6.7) init-declarator:
|
|
declarator
|
|
declarator = initializer
|
|
(6.7.1) storage-class-specifier:
|
|
typedef
|
|
extern
|
|
static
|
|
auto
|
|
register
|
|
(6.7.2) type-specifier:
|
|
void
|
|
char
|
|
short
|
|
int
|
|
long
|
|
float
|
|
double
|
|
signed
|
|
unsigned
|
|
_Bool
|
|
_Complex
|
|
struct-or-union-specifier
|
|
enum-specifier
|
|
typedef-name
|
|
(6.7.2.1) struct-or-union-specifier:
|
|
struct-or-union identifier(opt) { struct-declaration-list }
|
|
struct-or-union identifier
|
|
(6.7.2.1) struct-or-union:
|
|
struct
|
|
union
|
|
(6.7.2.1) struct-declaration-list:
|
|
struct-declaration
|
|
struct-declaration-list struct-declaration
|
|
(6.7.2.1) struct-declaration:
|
|
specifier-qualifier-list struct-declarator-list ;
|
|
(6.7.2.1) specifier-qualifier-list:
|
|
type-specifier specifier-qualifier-list(opt)
|
|
type-qualifier specifier-qualifier-list(opt)
|
|
(6.7.2.1) struct-declarator-list:
|
|
struct-declarator
|
|
struct-declarator-list , struct-declarator
|
|
(6.7.2.1) struct-declarator:
|
|
declarator
|
|
declarator(opt) : constant-expression
|
|
(6.7.2.2) enum-specifier:
|
|
enum identifier(opt) { enumerator-list }
|
|
enum identifier(opt) { enumerator-list , }
|
|
enum identifier
|
|
(6.7.2.2) enumerator-list:
|
|
enumerator
|
|
enumerator-list , enumerator
|
|
(6.7.2.2) enumerator:
|
|
enumeration-constant
|
|
enumeration-constant = constant-expression
|
|
(6.7.3) type-qualifier:
|
|
const
|
|
restrict
|
|
volatile
|
|
(6.7.4) function-specifier:
|
|
inline
|
|
(6.7.5) declarator:
|
|
pointer(opt) direct-declarator
|
|
(6.7.5) direct-declarator:
|
|
identifier
|
|
( declarator )
|
|
direct-declarator [ type-qualifier-list(opt)
|
|
assignment-expression(opt) ]
|
|
direct-declarator [ static type-qualifier-list(opt)
|
|
assignment-expression ]
|
|
direct-declarator [ type-qualifier-list static
|
|
assignment-expression ]
|
|
direct-declarator [ type-qualifier-list(opt) * ]
|
|
direct-declarator ( parameter-type-list )
|
|
direct-declarator ( identifier-list(opt) )
|
|
(6.7.5) pointer:
|
|
* type-qualifier-list(opt)
|
|
* type-qualifier-list(opt) pointer
|
|
(6.7.5) type-qualifier-list:
|
|
type-qualifier
|
|
type-qualifier-list type-qualifier
|
|
(6.7.5) parameter-type-list:
|
|
parameter-list
|
|
parameter-list , ...
|
|
(6.7.5) parameter-list:
|
|
parameter-declaration
|
|
parameter-list , parameter-declaration
|
|
(6.7.5) parameter-declaration:
|
|
declaration-specifiers declarator
|
|
declaration-specifiers abstract-declarator(opt)
|
|
(6.7.5) identifier-list:
|
|
identifier
|
|
identifier-list , identifier
|
|
(6.7.6) type-name:
|
|
specifier-qualifier-list abstract-declarator(opt)
|
|
(6.7.6) abstract-declarator:
|
|
pointer
|
|
pointer(opt) direct-abstract-declarator
|
|
(6.7.6) direct-abstract-declarator:
|
|
( abstract-declarator )
|
|
direct-abstract-declarator(opt) [ type-qualifier-list (opt)
|
|
assignment-expression(opt) ]
|
|
direct-abstract-declarator(opt) [ static type-qualifier-list(opt)
|
|
assignment-expression ]
|
|
direct-abstract-declarator(opt) [ type-qualifier-list static
|
|
assignment-expression ]
|
|
direct-abstract-declarator(opt) [ * ]
|
|
direct-abstract-declarator(opt) ( parameter-type-list(opt) )
|
|
(6.7.7) typedef-name:
|
|
identifier
|
|
(6.7.8) initializer:
|
|
assignment-expression
|
|
{ initializer-list }
|
|
{ initializer-list , }
|
|
(6.7.8) initializer-list:
|
|
designation(opt) initializer
|
|
initializer-list , designation(opt) initializer
|
|
(6.7.8) designation:
|
|
designator-list =
|
|
(6.7.8) designator-list:
|
|
designator
|
|
designator-list designator
|
|
(6.7.8) designator:
|
|
[ constant-expression ]
|
|
. identifier
|
|
|
|
A.2.4 External definitions
|
|
|
|
(6.9) translation-unit:
|
|
external-declaration
|
|
translation-unit external-declaration
|
|
(6.9) external-declaration:
|
|
function-definition
|
|
declaration
|
|
(6.9.1) function-definition:
|
|
declaration-specifiers declarator declaration-list(opt) compound-statement
|
|
(6.9.1) declaration-list:
|
|
declaration
|
|
declaration-list declaration
|
|
*/
|
|
|
|
#include <parser_utils.h>
|
|
#include <scc_parser.h>
|
|
|
|
scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) {
|
|
/**
|
|
* ISO/IEC 9899:TC3
|
|
* 6.7 Declarations
|
|
* Syntax
|
|
*
|
|
* declaration:
|
|
* declaration-specifiers init-declarator-list(opt) ;
|
|
* declaration-specifiers:
|
|
* storage-class-specifier declaration-specifiers(opt)
|
|
* type-specifier declaration-specifiers(opt)
|
|
* type-qualifier declaration-specifiers(opt)
|
|
* function-specifier declaration-specifiers(opt)
|
|
* init-declarator-list:
|
|
* init-declarator
|
|
* init-declarator-list , init-declarator
|
|
* init-declarator:
|
|
* declarator
|
|
* declarator = initializer
|
|
*/
|
|
cbool ok;
|
|
scc_lexer_tok_t tok;
|
|
|
|
scc_ast_node_t *type_or_decl = _scc_parse_type(parser);
|
|
scc_ast_decl_t *decl = null;
|
|
if (type_or_decl == null) {
|
|
return null;
|
|
}
|
|
|
|
if (SCC_AST_IS_A(scc_ast_type_t, type_or_decl)) {
|
|
LOG_WARN("declaration dose not declare anything");
|
|
return null;
|
|
} 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->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();
|
|
}
|
|
|
|
RETURN:
|
|
if (decl) {
|
|
parser->sema_callbacks.on_decl(parser->sema_callbacks.context,
|
|
decl->base.type, decl);
|
|
}
|
|
return decl;
|
|
}
|