Files
scc/libs/parser/src/parse_decl.c
zzy 742bede02f feat(ast): 修改函数调用表达式的结构定义
在AST定义中将函数调用表达式的name字段替换为callee字段,
以支持更复杂的函数调用场景。同时更新了相关的初始化函数、
转储函数和解析逻辑,使函数调用表达式能够正确处理callee节点。

BREAKING CHANGE: 函数调用表达式的结构发生了改变,从使用name字符串
改为使用callee表达式节点。
2026-03-10 14:33:32 +08:00

262 lines
7.7 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-declaratoropt [ 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_type_t *type = scc_parse_type(parser);
if (type == null) {
return null;
}
ok = scc_parser_next_consume(parser, &tok);
if (ok == false) {
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)) {
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;
}
}
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,
decl->base.type, decl);
}
return decl;
}