新增libs/ast模块的基础定义文件,包括: - AST节点类型枚举定义,涵盖声明、语句、表达式、类型等各类节点 - AST操作符枚举,定义所有二元、一元、逻辑、算术等操作符 - AST节点结构体定义,包含表达式、语句、声明、类型等具体实现 - AST dump工具接口,支持树形结构输出和颜色显示 - 语义分析回调函数类型定义,为后续语义分析提供基础
86 lines
2.7 KiB
C
86 lines
2.7 KiB
C
/**
|
|
* @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;
|
|
}
|