feat(ast): 添加AST定义和dump工具头文件
新增libs/ast模块的基础定义文件,包括: - AST节点类型枚举定义,涵盖声明、语句、表达式、类型等各类节点 - AST操作符枚举,定义所有二元、一元、逻辑、算术等操作符 - AST节点结构体定义,包含表达式、语句、声明、类型等具体实现 - AST dump工具接口,支持树形结构输出和颜色显示 - 语义分析回调函数类型定义,为后续语义分析提供基础
This commit is contained in:
85
libs/parser/src/parser.c
Normal file
85
libs/parser/src/parser.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* @file parser.c
|
||||
* @brief 新的解析器实现
|
||||
*/
|
||||
|
||||
#include "parser.h"
|
||||
#include <log.h>
|
||||
|
||||
static void dummy_sema_callback(void *context, scc_ast_node_type_t node_type,
|
||||
void *node) {
|
||||
(void)context;
|
||||
(void)node_type;
|
||||
(void)node;
|
||||
return;
|
||||
}
|
||||
|
||||
#define ASSIGN_PTR_OR_DEFAULT(assigned_val, value, default) \
|
||||
assigned_val = value ? value : default
|
||||
|
||||
void scc_parser_init(scc_parser_t *parser, scc_lexer_stream_t *lexer,
|
||||
scc_sema_callbacks_t *callbacks) {
|
||||
Assert(parser != null && lexer != null);
|
||||
parser->lex_stream = lexer;
|
||||
parser->has_error = false;
|
||||
parser->translation_unit = null;
|
||||
if (callbacks) {
|
||||
ASSIGN_PTR_OR_DEFAULT(parser->sema_callbacks.on_decl,
|
||||
callbacks->on_decl, dummy_sema_callback);
|
||||
ASSIGN_PTR_OR_DEFAULT(parser->sema_callbacks.on_stmt,
|
||||
callbacks->on_stmt, dummy_sema_callback);
|
||||
ASSIGN_PTR_OR_DEFAULT(parser->sema_callbacks.on_expr,
|
||||
callbacks->on_expr, dummy_sema_callback);
|
||||
ASSIGN_PTR_OR_DEFAULT(parser->sema_callbacks.on_type,
|
||||
callbacks->on_type, dummy_sema_callback);
|
||||
parser->sema_callbacks.context = callbacks->context;
|
||||
} else {
|
||||
parser->sema_callbacks.on_decl = dummy_sema_callback;
|
||||
parser->sema_callbacks.on_stmt = dummy_sema_callback;
|
||||
parser->sema_callbacks.on_expr = dummy_sema_callback;
|
||||
parser->sema_callbacks.on_type = dummy_sema_callback;
|
||||
parser->sema_callbacks.context = dummy_sema_callback;
|
||||
}
|
||||
// // ONLY FOR INIT TYPE
|
||||
// parser->current_token.type = SCC_TOK_UNKNOWN;
|
||||
}
|
||||
|
||||
void scc_parser_drop(scc_parser_t *parser) {
|
||||
// TODO: 释放 AST 内存
|
||||
(void)parser;
|
||||
}
|
||||
|
||||
scc_ast_translation_unit_t *scc_parse_translation_unit(scc_parser_t *parser) {
|
||||
scc_ast_translation_unit_t *unit =
|
||||
scc_malloc(sizeof(scc_ast_translation_unit_t));
|
||||
if (!unit)
|
||||
return null;
|
||||
unit->base.type = SCC_AST_TRANSLATION_UNIT;
|
||||
scc_vec_init(unit->declarations);
|
||||
|
||||
/**
|
||||
* Program := (Declaration | Definition)*
|
||||
* same as
|
||||
* Program := Declaration* Definition*
|
||||
*/
|
||||
do {
|
||||
scc_ast_decl_t *decl = scc_parse_declaration(parser);
|
||||
if (decl != null) {
|
||||
scc_vec_push(unit->declarations, decl);
|
||||
} else {
|
||||
break;
|
||||
// MAYBE return or next
|
||||
}
|
||||
} while (!scc_lexer_tok_match(scc_lexer_stream_current(parser->lex_stream),
|
||||
SCC_TOK_EOF) &&
|
||||
!parser->has_error);
|
||||
|
||||
if (parser->has_error) {
|
||||
// TODO: 清理
|
||||
scc_free(unit);
|
||||
return null;
|
||||
}
|
||||
|
||||
Assert(unit->base.type == SCC_AST_TRANSLATION_UNIT);
|
||||
return unit;
|
||||
}
|
||||
Reference in New Issue
Block a user