- 添加 SCC_AST_DECL_LIST 节点类型用于表示声明列表 - 实现 scc_ast_decl_list_init 函数来初始化声明列表节点 - 重构 scc_parse_declaration 函数以支持逗号分隔的多个变量声明 - 分离类型说明符解析到独立的 scc_parse_declaration_specifiers 函数 - 支持 typedef 和多变量声明如 'int a, b;' 和 'int a = 1, b = 2;' - 在 ast_dump 中添加对声明列表节点的打印支持 refactor(ast): 统一使用 scc_vec_foreach 宏替换手动循环 - 将 ast_dump.c 中的多个手动索引循环改为使用 scc_vec_foreach - 提高代码可读性和安全性 - 避免索引越界错误 fix(parser): 修复语义分析中结构体符号表冲突 - 为结构体、联合体和枚举符号名添加前缀避免命名冲突 - 使用 '$S_'、'$U_'、'$E_' 前缀分别标识结构体、联合体和枚举 refactor(log): 统一终止处理方式 - 将 log_exit 替换为 log_abort 以更准确反映行为 - 更新相关依赖模块的实现 style(parser): 移除未使用的参数和清理代码 - 在 argparse.c 中添加 (void) 参数注释处理未使用的参数 - 清理 parse_expr.c 中未使用的函数声明 - 优化 parse_type.c 中的错误处理流程
120 lines
4.2 KiB
C
120 lines
4.2 KiB
C
#ifndef __SCC_TREE_DUMP_H__
|
|
#define __SCC_TREE_DUMP_H__
|
|
|
|
#include <scc_core.h>
|
|
|
|
#define SCC_TREE_DUMP_VERTICAL "| "
|
|
#define SCC_TREE_DUMP_BRANCH "|-"
|
|
#define SCC_TREE_DUMP_LAST_BRANCH "`-"
|
|
#define SCC_TREE_DUMP_SPACE " "
|
|
|
|
#define SCC_TREE_DUMP_NODE_COLOR ANSI_FG_BLUE
|
|
#define SCC_TREE_DUMP_VALUE_COLOR ANSI_FG_GREEN
|
|
#define SCC_TREE_DUMP_BRANCH_COLOR ANSI_FG_YELLOW
|
|
#define SCC_TREE_DUMP_RESET_COLOR ANSI_NONE
|
|
|
|
// #define ANSI_FMT
|
|
|
|
typedef SCC_VEC(cbool) scc_ast_dump_stack_t;
|
|
|
|
typedef void (*scc_tree_dump_output_t)(void *userdata, const char *fmt, ...);
|
|
|
|
typedef struct {
|
|
scc_ast_dump_stack_t stack; ///< 每层是否为最后子节点
|
|
cbool use_color; ///< 是否使用颜色输出
|
|
|
|
const char *vertical;
|
|
const char *branch;
|
|
const char *last_branch;
|
|
const char *space;
|
|
|
|
const char *node_color; ///< 节点类型颜色
|
|
const char *value_color; ///< 值颜色
|
|
const char *branch_color; ///< 分支符号颜色
|
|
const char *reset_color; ///< 重置颜色
|
|
|
|
scc_tree_dump_output_t output_func;
|
|
void *output_userdata;
|
|
} scc_tree_dump_ctx_t;
|
|
|
|
static inline void scc_tree_dump_ctx_init(scc_tree_dump_ctx_t *ctx,
|
|
cbool use_color,
|
|
scc_tree_dump_output_t output_func,
|
|
void *output_userdata) {
|
|
ctx->use_color = use_color;
|
|
scc_vec_init(ctx->stack);
|
|
|
|
ctx->vertical = SCC_TREE_DUMP_VERTICAL;
|
|
ctx->branch = SCC_TREE_DUMP_BRANCH;
|
|
ctx->last_branch = SCC_TREE_DUMP_LAST_BRANCH;
|
|
ctx->space = SCC_TREE_DUMP_SPACE;
|
|
|
|
ctx->node_color = use_color ? SCC_TREE_DUMP_NODE_COLOR : "";
|
|
ctx->value_color = use_color ? SCC_TREE_DUMP_VALUE_COLOR : "";
|
|
ctx->branch_color = use_color ? SCC_TREE_DUMP_BRANCH_COLOR : "";
|
|
ctx->reset_color = use_color ? SCC_TREE_DUMP_RESET_COLOR : "";
|
|
|
|
ctx->output_func = output_func;
|
|
ctx->output_userdata = output_userdata;
|
|
}
|
|
|
|
#define scc_tree_dump_printf(ctx, fmt, ...) \
|
|
(ctx)->output_func((ctx)->output_userdata, fmt, ##__VA_ARGS__)
|
|
|
|
static inline void scc_tree_dump_ctx_drop(scc_tree_dump_ctx_t *ctx) {
|
|
scc_vec_free(ctx->stack);
|
|
}
|
|
|
|
// 打印缩进
|
|
static inline void scc_tree_print_indent(scc_tree_dump_ctx_t *ctx) {
|
|
scc_vec_foreach(ctx->stack, i) {
|
|
cbool last_child = scc_vec_at(ctx->stack, i);
|
|
const char *data = null;
|
|
if (i + 1 == scc_vec_size(ctx->stack)) {
|
|
// 最后一层打印分支符号
|
|
data = last_child ? ctx->last_branch : ctx->branch;
|
|
} else {
|
|
data = last_child ? ctx->space : ctx->vertical;
|
|
}
|
|
Assert(data != null);
|
|
if (ctx->use_color) {
|
|
ctx->output_func(ctx->output_userdata, "%s%s%s", ctx->branch_color,
|
|
data, ctx->reset_color);
|
|
} else {
|
|
ctx->output_func(ctx->output_userdata, "%s", data);
|
|
}
|
|
}
|
|
}
|
|
|
|
#define SCC_TREE_DUMP_PRINT_COLORED(ctx, color, before_str, fmt, after_str, \
|
|
...) \
|
|
(ctx)->output_func((ctx)->output_userdata, \
|
|
before_str "%s" fmt "%s" after_str, \
|
|
(ctx)->use_color ? color : "", ##__VA_ARGS__, \
|
|
(ctx)->use_color ? ANSI_NONE : "");
|
|
|
|
#define SCC_TREE_DUMP_PRINT_AROUND(ctx, color, around_str, fmt, ...) \
|
|
SCC_TREE_DUMP_PRINT_COLORED(ctx, color, around_str, fmt, around_str, \
|
|
##__VA_ARGS__)
|
|
|
|
#define SCC_TREE_DUMP_PRINT_PURE(ctx, color, fmt, ...) \
|
|
SCC_TREE_DUMP_PRINT_COLORED(ctx, color, "", fmt, "", ##__VA_ARGS__)
|
|
|
|
// 推入新的层级到栈中
|
|
static inline void scc_tree_dump_push_level(scc_tree_dump_ctx_t *ctx,
|
|
cbool is_last_child) {
|
|
scc_vec_push(ctx->stack, is_last_child);
|
|
}
|
|
|
|
// 弹出当前层级
|
|
static inline void scc_tree_dump_pop_level(scc_tree_dump_ctx_t *ctx) {
|
|
(void)scc_vec_pop(ctx->stack);
|
|
}
|
|
|
|
// 获取当前层级深度
|
|
static inline usize scc_tree_dump_depth(scc_tree_dump_ctx_t *ctx) {
|
|
return scc_vec_size(ctx->stack);
|
|
}
|
|
|
|
#endif /* __SCC_TREE_DUMP_H__ */
|