feat(ast): 添加AST定义和dump工具头文件
新增libs/ast模块的基础定义文件,包括: - AST节点类型枚举定义,涵盖声明、语句、表达式、类型等各类节点 - AST操作符枚举,定义所有二元、一元、逻辑、算术等操作符 - AST节点结构体定义,包含表达式、语句、声明、类型等具体实现 - AST dump工具接口,支持树形结构输出和颜色显示 - 语义分析回调函数类型定义,为后续语义分析提供基础
This commit is contained in:
250
libs/parser/src/parse_decl.c
Normal file
250
libs/parser/src/parse_decl.c
Normal file
@@ -0,0 +1,250 @@
|
||||
#include <parser.h>
|
||||
|
||||
/*
|
||||
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
|
||||
*/
|
||||
|
||||
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
|
||||
*/
|
||||
if (!scc_parse_is_declaration_start(parser, 0)) {
|
||||
return null;
|
||||
}
|
||||
scc_ast_type_t *type = scc_parse_type(parser);
|
||||
if (type == null) {
|
||||
LOG_ERROR("Failed to parse type");
|
||||
return null;
|
||||
}
|
||||
|
||||
const scc_lexer_tok_t *tok = scc_lexer_stream_current(parser->lex_stream);
|
||||
if (!scc_lexer_tok_match(tok, SCC_TOK_IDENT)) {
|
||||
LOG_ERROR("Expected identifier, got %s", scc_get_tok_name(tok->type));
|
||||
return null;
|
||||
}
|
||||
|
||||
scc_lexer_stream_consume(parser->lex_stream);
|
||||
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_parse_consume_if(parser->lex_stream, SCC_TOK_L_PAREN)) {
|
||||
// TODO
|
||||
if (scc_parse_consume_if(parser->lex_stream, SCC_TOK_SEMICOLON)) {
|
||||
decl->base.type = SCC_AST_DECL_VAR;
|
||||
decl->var.type = type;
|
||||
decl->var.name = tok->value.cstr.data;
|
||||
decl->var.init = null;
|
||||
return decl;
|
||||
} else if (scc_parse_consume_if(parser->lex_stream, SCC_TOK_ASSIGN)) {
|
||||
decl->base.type = SCC_AST_DECL_VAR;
|
||||
decl->var.type = type;
|
||||
decl->var.name = tok->value.cstr.data;
|
||||
decl->var.init = scc_parse_expression(parser);
|
||||
return decl;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// function decl
|
||||
decl->base.type = SCC_AST_DECL_FUNC;
|
||||
decl->func.name = tok->value.cstr.data;
|
||||
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
|
||||
decl->func.type->function.is_variadic = false;
|
||||
|
||||
// TODO param type
|
||||
scc_parse_consume_if(parser->lex_stream, SCC_TOK_VOID);
|
||||
|
||||
if (!scc_parse_consume_if(parser->lex_stream, SCC_TOK_R_PAREN)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!scc_parse_is(parser->lex_stream, SCC_TOK_L_BRACE)) {
|
||||
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 decl;
|
||||
}
|
||||
Reference in New Issue
Block a user