feat(ast): 添加AST定义和dump工具头文件

新增libs/ast模块的基础定义文件,包括:
- AST节点类型枚举定义,涵盖声明、语句、表达式、类型等各类节点
- AST操作符枚举,定义所有二元、一元、逻辑、算术等操作符
- AST节点结构体定义,包含表达式、语句、声明、类型等具体实现
- AST dump工具接口,支持树形结构输出和颜色显示
- 语义分析回调函数类型定义,为后续语义分析提供基础
This commit is contained in:
zzy
2026-01-28 15:44:59 +08:00
parent e1cd8c5206
commit 79ee7a657a
13 changed files with 4181 additions and 0 deletions

9
libs/ast/cbuild.toml Normal file
View File

@@ -0,0 +1,9 @@
[package]
name = "scc_ast"
version = "0.1.0"
authors = []
description = ""
# dependencies = []
# features = {}
# default_features = []

442
libs/ast/include/ast_def.h Normal file
View File

@@ -0,0 +1,442 @@
#ifndef __SCC_AST_DEF_H__
#define __SCC_AST_DEF_H__
#include <scc_core.h>
/**
* @brief AST 节点类型枚举
*/
typedef enum {
// 声明
scc_ast_decl_t_BEGIN, // 声明开始
SCC_AST_DECL_VAR, // 变量声明
SCC_AST_DECL_FUNC, // 函数声明
SCC_AST_DECL_PARAM, // 参数声明
SCC_AST_DECL_STRUCT, // 结构体声明
SCC_AST_DECL_UNION, // 联合声明
SCC_AST_DECL_ENUM, // 枚举声明
SCC_AST_DECL_TYPEDEF, // typedef 声明
scc_ast_decl_t_END, // 声明结束
// 语句
scc_ast_stmt_t_BEGIN, // 语句开始
SCC_AST_STMT_COMPOUND, // 复合语句 { ... }
SCC_AST_STMT_EXPR, // 表达式语句
SCC_AST_STMT_IF, // if 语句
SCC_AST_STMT_WHILE, // while 语句
SCC_AST_STMT_DO_WHILE, // do-while 语句
SCC_AST_STMT_FOR, // for 语句
SCC_AST_STMT_SWITCH, // switch 语句
SCC_AST_STMT_CASE, // case 语句
SCC_AST_STMT_DEFAULT, // default 语句
SCC_AST_STMT_BREAK, // break 语句
SCC_AST_STMT_CONTINUE, // continue 语句
SCC_AST_STMT_RETURN, // return 语句
SCC_AST_STMT_GOTO, // goto 语句
SCC_AST_STMT_LABEL, // 标签语句
scc_ast_stmt_t_END, // 结束语句
// 表达式
scc_ast_expr_t_BEGIN, // 表达式开始
SCC_AST_EXPR_BINARY, // 二元运算
SCC_AST_EXPR_UNARY, // 一元运算
SCC_AST_EXPR_COND, // 条件表达式 ?:
SCC_AST_EXPR_CALL, // 函数调用
SCC_AST_EXPR_ARRAY_SUBSCRIPT, // 数组下标
SCC_AST_EXPR_MEMBER, // 成员访问 .
SCC_AST_EXPR_PTR_MEMBER, // 指针成员访问 ->
SCC_AST_EXPR_CAST, // 类型转换
SCC_AST_EXPR_SIZE_OF, // sizeof
SCC_AST_EXPR_ALIGN_OF, // _Alignof
SCC_AST_EXPR_COMPOUND_LITERAL, // 复合字面量
// 字面量
SCC_AST_EXPR_INT_LITERAL, // 整数字面量
SCC_AST_EXPR_FLOAT_LITERAL, // 浮点字面量
SCC_AST_EXPR_CHAR_LITERAL, // 字符字面量
SCC_AST_EXPR_STRING_LITERAL, // 字符串字面量
// 标识符
SCC_AST_EXPR_IDENTIFIER, // 标识符
scc_ast_expr_t_END, // 表达式结束
// 类型
scc_ast_type_t_BEGIN, // 类型开始
SCC_AST_TYPE_BUILTIN, // 内置类型
SCC_AST_TYPE_POINTER, // 指针类型
SCC_AST_TYPE_ARRAY, // 数组类型
SCC_AST_TYPE_FUNCTION, // 函数类型
SCC_AST_TYPE_STRUCT, // 结构体类型
SCC_AST_TYPE_UNION, // 联合类型
SCC_AST_TYPE_ENUM, // 枚举类型
SCC_AST_TYPE_TYPEDEF, // typedef 类型
scc_ast_type_t_END, // 类型结束
// 其他
scc_ast_translation_unit_t_BEGIN,
SCC_AST_TRANSLATION_UNIT, // 翻译单元(根节点)
scc_ast_translation_unit_t_END,
} scc_ast_node_type_t;
typedef struct {
scc_ast_node_type_t type;
scc_pos_t loc;
} scc_ast_node_t;
#define SCC_AST_CAST_TO(kind, expr) \
((kind *)(Assert(((scc_ast_node_t *)expr)->type > kind##_BEGIN && \
((scc_ast_node_t *)expr)->type < kind##_END), \
(expr)))
#define SCC_AST_IS_A(kind, expr) \
((expr) && (((scc_ast_node_t *)expr)->type > kind##_BEGIN && \
((scc_ast_node_t *)expr)->type < kind##_END))
/**
* @brief 内置类型枚举
*/
typedef enum {
TYPE_VOID,
TYPE_CHAR,
TYPE_SHORT,
TYPE_INT,
TYPE_LONG,
TYPE_LONG_LONG,
TYPE_FLOAT,
TYPE_DOUBLE,
TYPE_LONG_DOUBLE,
TYPE_BOOL,
TYPE_COMPLEX_FLOAT,
TYPE_COMPLEX_DOUBLE,
TYPE_COMPLEX_LONG_DOUBLE,
} scc_ast_builtin_type_t;
/**
* @brief 限定符
*/
typedef struct {
// storage-class-specifier
cbool is_typedef;
cbool is_extern;
cbool is_static;
cbool is_auto;
cbool is_register;
// type-qualifier
cbool is_const;
cbool is_volatile;
cbool is_restrict;
cbool is_atomic;
// function-specifier
cbool is_inline;
} scc_ast_decl_specifier_t;
// 前向声明
typedef struct scc_ast_type scc_ast_type_t;
typedef struct scc_ast_expr scc_ast_expr_t;
typedef struct scc_ast_stmt scc_ast_stmt_t;
typedef struct scc_ast_decl scc_ast_decl_t;
typedef SCC_VEC(scc_ast_type_t *) scc_ast_type_vec_t;
typedef SCC_VEC(scc_ast_expr_t *) scc_ast_expr_vec_t;
typedef SCC_VEC(scc_ast_stmt_t *) scc_ast_stmt_vec_t;
typedef SCC_VEC(scc_ast_decl_t *) scc_ast_decl_vec_t;
// 通过指针实现泛型
typedef SCC_VEC(scc_ast_node_type_t *) scc_ast_block_item_vec_t;
/**
* @brief 类型表示
*/
struct scc_ast_type {
scc_ast_node_t base;
union {
struct {
scc_ast_builtin_type_t builtin;
scc_ast_decl_specifier_t quals;
} builtin;
struct {
scc_ast_type_t *pointee;
scc_ast_decl_specifier_t quals;
} pointer;
struct {
scc_ast_type_t *element;
scc_ast_expr_t *size; // 可为 null <=> 不定长数组
} array;
struct {
scc_ast_type_t *return_type;
scc_ast_type_vec_t param_types;
cbool is_variadic;
} function;
struct {
const char *name;
scc_ast_decl_vec_t fields; // 结构体/联合字段
} record;
struct {
const char *name;
scc_ast_expr_vec_t enumerators; // 枚举项
} enumeration;
struct {
const char *name;
scc_ast_type_t *underlying;
} typedef_type;
};
};
/**
* @brief AST 操作符枚举
* 这个枚举定义了所有在AST中使用的操作符与词法token分离
*/
typedef enum scc_ast_expr_op {
/* 无操作符 */
SCC_AST_OP_NONE = 0,
/* 赋值操作符 */
SCC_AST_OP_ASSIGN, // =
SCC_AST_OP_ASSIGN_ADD, // +=
SCC_AST_OP_ASSIGN_SUB, // -=
SCC_AST_OP_ASSIGN_MUL, // *=
SCC_AST_OP_ASSIGN_DIV, // /=
SCC_AST_OP_ASSIGN_MOD, // %=
SCC_AST_OP_ASSIGN_AND, // &=
SCC_AST_OP_ASSIGN_XOR, // ^=
SCC_AST_OP_ASSIGN_OR, // |=
SCC_AST_OP_ASSIGN_LSHIFT, // <<=
SCC_AST_OP_ASSIGN_RSHIFT, // >>=
/* 条件操作符 */
SCC_AST_OP_CONDITIONAL, // ?:
/* 逻辑操作符 */
SCC_AST_OP_LOGICAL_OR, // ||
SCC_AST_OP_LOGICAL_AND, // &&
/* 位操作符 */
SCC_AST_OP_BITWISE_OR, // |
SCC_AST_OP_BITWISE_XOR, // ^
SCC_AST_OP_BITWISE_AND, // &
/* 相等性操作符 */
SCC_AST_OP_EQUAL, // ==
SCC_AST_OP_NOT_EQUAL, // !=
/* 关系操作符 */
SCC_AST_OP_LESS, // <
SCC_AST_OP_GREATER, // >
SCC_AST_OP_LESS_EQUAL, // <=
SCC_AST_OP_GREATER_EQUAL, // >=
/* 移位操作符 */
SCC_AST_OP_LEFT_SHIFT, // <<
SCC_AST_OP_RIGHT_SHIFT, // >>
/* 算术操作符 */
SCC_AST_OP_ADD, // +
SCC_AST_OP_SUB, // -
SCC_AST_OP_MUL, // *
SCC_AST_OP_DIV, // /
SCC_AST_OP_MOD, // %
/* 一元操作符 */
SCC_AST_OP_UNARY_PLUS, // + (一元)
SCC_AST_OP_UNARY_MINUS, // - (一元)
SCC_AST_OP_ADDRESS_OF, // &
SCC_AST_OP_INDIRECTION, // *
SCC_AST_OP_BITWISE_NOT, // ~
SCC_AST_OP_LOGICAL_NOT, // !
SCC_AST_OP_PREFIX_INCREMENT, // ++ (前缀)
SCC_AST_OP_PREFIX_DECREMENT, // -- (前缀)
SCC_AST_OP_POSTFIX_INCREMENT, // ++ (后缀)
SCC_AST_OP_POSTFIX_DECREMENT, // -- (后缀)
/* 成员访问 */
SCC_AST_OP_MEMBER_ACCESS, // .
SCC_AST_OP_PTR_MEMBER_ACCESS, // ->
} scc_ast_expr_op_t;
/**
* @brief 表达式节点
*/
struct scc_ast_expr {
scc_ast_node_t base;
union {
// 二元运算
struct {
scc_ast_expr_op_t op;
scc_ast_expr_t *lhs;
scc_ast_expr_t *rhs;
} binary;
// 一元运算
struct {
scc_ast_expr_op_t op;
scc_ast_expr_t *operand;
} unary;
// 条件表达式
struct {
scc_ast_expr_t *cond;
scc_ast_expr_t *then_expr;
scc_ast_expr_t *else_expr;
} cond;
// 函数调用
struct {
scc_ast_expr_t *callee;
scc_ast_expr_vec_t args;
} call;
// 数组下标
struct {
scc_ast_expr_t *array;
scc_ast_expr_t *index;
} subscript;
// 成员访问
struct {
scc_ast_expr_t *base;
const char *member_name;
} member;
// 指针成员访问
struct {
scc_ast_expr_t *base;
const char *member_name;
} ptr_member;
// 类型转换
struct {
scc_ast_type_t *type;
scc_ast_expr_t *expr;
} cast;
// sizeof / _Alignof / ...
union {
scc_ast_type_t *type;
scc_ast_expr_t *expr;
} attr_of;
// 复合字面量
struct {
scc_ast_type_t *type;
scc_ast_expr_vec_t init_list;
} compound_literal;
// 字面量
struct {
scc_cvalue_t value;
} literal;
// 标识符
struct {
const char *name;
} identifier;
};
};
/**
* @brief 语句节点
*/
struct scc_ast_stmt {
scc_ast_node_t base;
union {
// 复合语句
struct {
scc_ast_block_item_vec_t block_items; // decl or stmt
} compound;
// 表达式语句
struct {
scc_ast_expr_t *expr;
} expr;
// if 语句
struct {
scc_ast_expr_t *cond;
scc_ast_stmt_t *then_stmt;
scc_ast_stmt_t *opt_else_stmt; // stmt or null
} if_stmt;
// while 语句
struct {
scc_ast_expr_t *cond;
scc_ast_stmt_t *body;
} while_stmt;
// do-while 语句
struct {
scc_ast_stmt_t *body;
scc_ast_expr_t *cond;
} do_while_stmt;
// for 语句
struct {
scc_ast_type_t *init; // expr or decl or null
scc_ast_expr_t *cond; // 可为 null
scc_ast_expr_t *iter; // 可为 null
scc_ast_stmt_t *body;
} for_stmt;
// switch 语句
struct {
scc_ast_expr_t *cond;
scc_ast_stmt_t *body;
} switch_stmt;
// case 语句
struct {
scc_ast_expr_t *expr;
scc_ast_stmt_t *stmt;
} case_stmt;
// default 语句
struct {
scc_ast_stmt_t *stmt;
} default_stmt;
// break/continue
struct {
// 无额外字段
} jump;
// return 语句
struct {
scc_ast_expr_t *expr; // 可为 NULL
} return_stmt;
// goto 语句
struct {
const char *label;
} goto_stmt;
// 标签语句
struct {
const char *label;
scc_ast_stmt_t *stmt;
} label_stmt;
};
};
/**
* @brief 声明节点
*/
struct scc_ast_decl {
scc_ast_node_t base;
union {
// 变量声明
struct {
const char *name;
scc_ast_type_t *type;
scc_ast_expr_t *init; // 可为 NULL
} var;
// 函数声明
struct {
const char *name;
scc_ast_type_t *type; // 函数类型
scc_ast_stmt_t *body; // 可为 NULL只有声明 or
} func;
// 参数声明
struct {
const char *name;
scc_ast_type_t *type;
} param;
// 结构体/联合声明
struct {
const char *name;
scc_ast_decl_vec_t fields;
} record;
// 枚举声明
struct {
const char *name;
scc_ast_expr_vec_t enumerators;
} enumeration;
// typedef 声明
struct {
const char *name;
scc_ast_type_t *type;
} typedef_decl;
};
};
/**
* @brief 翻译单元节点(根节点)
*/
typedef struct scc_ast_translation_unit {
scc_ast_node_t base;
scc_ast_decl_vec_t declarations;
} scc_ast_translation_unit_t;
#endif /* __SCC_AST_DEF_H__ */

View File

@@ -0,0 +1,37 @@
/**
* @file ast_dump.h
* @brief AST dump 工具,支持多种输出格式(插件化设计)
*/
#ifndef __SCC_AST_DUMP_H__
#define __SCC_AST_DUMP_H__
#include "ast_def.h"
typedef SCC_VEC(u8) scc_ast_dump_stack_t;
/**
* @brief AST dump 上下文结构
*/
typedef struct {
int depth; ///< 当前深度
cbool *is_last_child; ///< 每层是否为最后子节点
cbool use_color; ///< 是否使用颜色输出
size_t max_depth; ///< 分配的最大深度
const char *node_color; ///< 节点类型颜色
const char *value_color; ///< 值颜色
const char *branch_color; ///< 分支符号颜色
const char *reset_color; ///< 重置颜色
} scc_ast_dump_ctx_t;
/**
* @brief 以指定格式 dump AST
*
* @param node AST 节点(可以是任意类型的节点)
* @param ctx dump 上下文
*/
void scc_ast_dump_node(scc_ast_node_t *node, scc_ast_dump_ctx_t *ctx);
void scc_ast_dump_ctx_init(scc_ast_dump_ctx_t *ctx, cbool use_color);
void scc_ast_dump_ctx_drop(scc_ast_dump_ctx_t *ctx);
#endif /* __SCC_AST_DUMP_H__ */

View File

@@ -0,0 +1,23 @@
#ifndef __SCC_AST_H__
#define __SCC_AST_H__
#include "ast_def.h"
/**
* @brief 语义分析回调函数类型
*/
typedef void (*scc_sema_callback_t)(void *context,
scc_ast_node_type_t node_type, void *node);
/**
* @brief 语义分析回调集合
*/
typedef struct scc_sema_callbacks {
scc_sema_callback_t on_decl;
scc_sema_callback_t on_stmt;
scc_sema_callback_t on_expr;
scc_sema_callback_t on_type;
void *context;
} scc_sema_callbacks_t;
#endif /* __SCC_AST_H__ */

803
libs/ast/src/ast_dump.c Normal file
View File

@@ -0,0 +1,803 @@
/**
* @file ast_dump.c
* @brief AST dump 实现
*/
#include <ast_dump.h>
#define VERTICAL "| "
#define BRANCH "|-"
#define LAST_BRANCH "`-"
#define SPACE " "
// 默认颜色配置
#define DEFAULT_NODE_COLOR ANSI_FG_BLUE
#define DEFAULT_VALUE_COLOR ANSI_FG_GREEN
#define DEFAULT_BRANCH_COLOR ANSI_FG_YELLOW
#define DEFAULT_RESET_COLOR ANSI_NONE
// 通用宏定义
#define PRINT_COLORED(ctx, color_field, fmt, ...) \
do { \
if (ctx->use_color) { \
scc_printf("%s" fmt "%s", ctx->color_field, ##__VA_ARGS__, \
ctx->reset_color); \
} else { \
scc_printf(fmt, ##__VA_ARGS__); \
} \
} while (0)
#define PRINT_VALUE(ctx, fmt, ...) \
PRINT_COLORED(ctx, value_color, fmt, ##__VA_ARGS__)
#define PRINT_NODE_TYPE(ctx, node) \
PRINT_COLORED(ctx, node_color, "%s", get_node_type_str(node->type))
#define PRINT_QUOTED_VALUE(ctx, value) \
do { \
PRINT_VALUE(ctx, "'%s'", value); \
} while (0)
// 扩展上下文深度
static void ensure_context_depth(scc_ast_dump_ctx_t *ctx, int new_depth) {
if ((size_t)new_depth >= ctx->max_depth) {
size_t old_size = ctx->max_depth * sizeof(cbool);
ctx->max_depth = new_depth + 16; // 预分配更多空间
ctx->is_last_child = (cbool *)scc_realloc(
ctx->is_last_child, ctx->max_depth * sizeof(cbool));
scc_memset((char *)ctx->is_last_child + old_size, 0,
ctx->max_depth * sizeof(cbool) - old_size);
}
}
// 打印缩进
static void print_indent(scc_ast_dump_ctx_t *ctx) {
for (int i = 0; i < ctx->depth; i++) {
if (i == ctx->depth - 1) {
// 最后一层打印分支符号
if (ctx->use_color) {
scc_printf("%s%s%s", ctx->branch_color,
ctx->is_last_child[i] ? LAST_BRANCH : BRANCH,
ctx->reset_color);
} else {
scc_printf("%s", ctx->is_last_child[i] ? LAST_BRANCH : BRANCH);
}
} else {
// 中间层根据是否是最后一个子节点决定是否打印垂直线
if (ctx->use_color) {
scc_printf("%s%s%s", ctx->branch_color,
ctx->is_last_child[i] ? SPACE : VERTICAL,
ctx->reset_color);
} else {
scc_printf("%s", ctx->is_last_child[i] ? SPACE : VERTICAL);
}
}
}
}
// 获取节点类型的字符串表示
static const char *get_node_type_str(scc_ast_node_type_t type) {
switch (type) {
// 声明类型
case SCC_AST_DECL_VAR:
return "VarDecl";
case SCC_AST_DECL_FUNC:
return "FuncDecl";
case SCC_AST_DECL_PARAM:
return "ParamDecl";
case SCC_AST_DECL_STRUCT:
return "StructDecl";
case SCC_AST_DECL_UNION:
return "UnionDecl";
case SCC_AST_DECL_ENUM:
return "EnumDecl";
case SCC_AST_DECL_TYPEDEF:
return "TypedefDecl";
// 语句类型
case SCC_AST_STMT_COMPOUND:
return "CompoundStmt";
case SCC_AST_STMT_EXPR:
return "ExprStmt";
case SCC_AST_STMT_IF:
return "IfStmt";
case SCC_AST_STMT_WHILE:
return "WhileStmt";
case SCC_AST_STMT_DO_WHILE:
return "DoStmt";
case SCC_AST_STMT_FOR:
return "ForStmt";
case SCC_AST_STMT_SWITCH:
return "SwitchStmt";
case SCC_AST_STMT_CASE:
return "CaseStmt";
case SCC_AST_STMT_DEFAULT:
return "DefaultStmt";
case SCC_AST_STMT_BREAK:
return "BreakStmt";
case SCC_AST_STMT_CONTINUE:
return "ContinueStmt";
case SCC_AST_STMT_RETURN:
return "ReturnStmt";
case SCC_AST_STMT_GOTO:
return "GotoStmt";
case SCC_AST_STMT_LABEL:
return "LabelStmt";
// 表达式类型
case SCC_AST_EXPR_BINARY:
return "BinaryOperator";
case SCC_AST_EXPR_UNARY:
return "UnaryOperator";
case SCC_AST_EXPR_COND:
return "ConditionalOperator";
case SCC_AST_EXPR_CALL:
return "CallExpr";
case SCC_AST_EXPR_ARRAY_SUBSCRIPT:
return "ArraySubscriptExpr";
case SCC_AST_EXPR_MEMBER:
return "MemberExpr";
case SCC_AST_EXPR_PTR_MEMBER:
return "PtrMemberExpr";
case SCC_AST_EXPR_CAST:
return "CastExpr";
case SCC_AST_EXPR_SIZE_OF:
return "SizeOfExpr";
case SCC_AST_EXPR_ALIGN_OF:
return "AlignOfExpr";
case SCC_AST_EXPR_COMPOUND_LITERAL:
return "CompoundLiteralExpr";
case SCC_AST_EXPR_INT_LITERAL:
return "IntegerLiteral";
case SCC_AST_EXPR_FLOAT_LITERAL:
return "FloatingLiteral";
case SCC_AST_EXPR_CHAR_LITERAL:
return "CharacterLiteral";
case SCC_AST_EXPR_STRING_LITERAL:
return "StringLiteral";
case SCC_AST_EXPR_IDENTIFIER:
return "DeclRefExpr";
// 类型类型
case SCC_AST_TYPE_BUILTIN:
return "BuiltinType";
case SCC_AST_TYPE_POINTER:
return "PointerType";
case SCC_AST_TYPE_ARRAY:
return "ArrayType";
case SCC_AST_TYPE_FUNCTION:
return "FunctionType";
case SCC_AST_TYPE_STRUCT:
return "RecordType";
case SCC_AST_TYPE_UNION:
return "RecordType";
case SCC_AST_TYPE_ENUM:
return "EnumType";
case SCC_AST_TYPE_TYPEDEF:
return "TypedefType";
// 根节点
case SCC_AST_TRANSLATION_UNIT:
return "TranslationUnitDecl";
default:
return "UnknownNode";
}
}
// 获取内置类型名称
static const char *get_builtin_type_str(scc_ast_builtin_type_t type) {
switch (type) {
case TYPE_VOID:
return "void";
case TYPE_CHAR:
return "char";
case TYPE_SHORT:
return "short";
case TYPE_INT:
return "int";
case TYPE_LONG:
return "long";
case TYPE_LONG_LONG:
return "long long";
case TYPE_FLOAT:
return "float";
case TYPE_DOUBLE:
return "double";
case TYPE_LONG_DOUBLE:
return "long double";
case TYPE_BOOL:
return "_Bool";
case TYPE_COMPLEX_FLOAT:
return "float _Complex";
case TYPE_COMPLEX_DOUBLE:
return "double _Complex";
case TYPE_COMPLEX_LONG_DOUBLE:
return "long double _Complex";
default:
return "<unknown>";
}
}
// 获取操作符字符串
static const char *get_op_str(scc_ast_expr_op_t op) {
switch (op) {
case SCC_AST_OP_ASSIGN:
return "=";
case SCC_AST_OP_ASSIGN_ADD:
return "+=";
case SCC_AST_OP_ASSIGN_SUB:
return "-=";
case SCC_AST_OP_ASSIGN_MUL:
return "*=";
case SCC_AST_OP_ASSIGN_DIV:
return "/=";
case SCC_AST_OP_ASSIGN_MOD:
return "%=";
case SCC_AST_OP_ASSIGN_AND:
return "&=";
case SCC_AST_OP_ASSIGN_XOR:
return "^=";
case SCC_AST_OP_ASSIGN_OR:
return "|=";
case SCC_AST_OP_ASSIGN_LSHIFT:
return "<<=";
case SCC_AST_OP_ASSIGN_RSHIFT:
return ">>=";
case SCC_AST_OP_CONDITIONAL:
return "? :";
case SCC_AST_OP_LOGICAL_OR:
return "||";
case SCC_AST_OP_LOGICAL_AND:
return "&&";
case SCC_AST_OP_BITWISE_OR:
return "|";
case SCC_AST_OP_BITWISE_XOR:
return "^";
case SCC_AST_OP_BITWISE_AND:
return "&";
case SCC_AST_OP_EQUAL:
return "==";
case SCC_AST_OP_NOT_EQUAL:
return "!=";
case SCC_AST_OP_LESS:
return "<";
case SCC_AST_OP_GREATER:
return ">";
case SCC_AST_OP_LESS_EQUAL:
return "<=";
case SCC_AST_OP_GREATER_EQUAL:
return ">=";
case SCC_AST_OP_LEFT_SHIFT:
return "<<";
case SCC_AST_OP_RIGHT_SHIFT:
return ">>";
case SCC_AST_OP_ADD:
return "+";
case SCC_AST_OP_SUB:
return "-";
case SCC_AST_OP_MUL:
return "*";
case SCC_AST_OP_DIV:
return "/";
case SCC_AST_OP_MOD:
return "%";
case SCC_AST_OP_UNARY_PLUS:
return "+";
case SCC_AST_OP_UNARY_MINUS:
return "-";
case SCC_AST_OP_ADDRESS_OF:
return "&";
case SCC_AST_OP_INDIRECTION:
return "*";
case SCC_AST_OP_BITWISE_NOT:
return "~";
case SCC_AST_OP_LOGICAL_NOT:
return "!";
case SCC_AST_OP_PREFIX_INCREMENT:
return "++";
case SCC_AST_OP_PREFIX_DECREMENT:
return "--";
case SCC_AST_OP_POSTFIX_INCREMENT:
return "++";
case SCC_AST_OP_POSTFIX_DECREMENT:
return "--";
case SCC_AST_OP_MEMBER_ACCESS:
return ".";
case SCC_AST_OP_PTR_MEMBER_ACCESS:
return "->";
default:
return "<op>";
}
}
// 通用的开始节点打印函数
static inline void start_node_dump(scc_ast_node_t *node,
scc_ast_dump_ctx_t *ctx) {
print_indent(ctx);
PRINT_NODE_TYPE(ctx, node);
}
// 通用的结束节点打印函数
static inline void end_node_dump(scc_ast_dump_ctx_t *ctx) { scc_printf("\n"); }
// 通用的递归转储辅助函数
static inline void dump_child_node(scc_ast_node_t *child,
scc_ast_dump_ctx_t *ctx, cbool is_last) {
if (!child)
return;
ctx->depth++;
ensure_context_depth(ctx, ctx->depth);
ctx->is_last_child[ctx->depth - 1] = is_last;
scc_ast_dump_node(child, ctx);
ctx->depth--;
}
// 用于构建复合类型名称的宏
#define BUILD_TYPE_NAME(ctx, prefix, name) \
do { \
if (ctx->use_color) { \
scc_printf("%s'%s%s%s'%s", ctx->value_color, prefix, name, \
ctx->reset_color, ctx->reset_color); \
} else { \
scc_printf("'%s%s'", prefix, name); \
} \
} while (0)
// 递归转储类型
static void dump_type_impl(scc_ast_type_t *type, scc_ast_dump_ctx_t *ctx) {
if (!type)
return;
start_node_dump(&type->base, ctx);
// 根据类型输出特定信息
switch (type->base.type) {
case SCC_AST_TYPE_BUILTIN:
PRINT_QUOTED_VALUE(ctx, get_builtin_type_str(type->builtin.builtin));
break;
case SCC_AST_TYPE_POINTER:
if (type->pointer.pointee &&
type->pointer.pointee->base.type == SCC_AST_TYPE_BUILTIN) {
const char *base_type =
get_builtin_type_str(type->pointer.pointee->builtin.builtin);
if (ctx->use_color) {
scc_printf("%s'%s *'%s", ctx->value_color, base_type,
ctx->reset_color);
} else {
scc_printf("'%s *'", base_type);
}
} else {
PRINT_QUOTED_VALUE(ctx, "pointer");
}
break;
case SCC_AST_TYPE_ARRAY:
PRINT_QUOTED_VALUE(ctx, "array");
break;
case SCC_AST_TYPE_FUNCTION:
PRINT_QUOTED_VALUE(ctx, "function");
break;
case SCC_AST_TYPE_STRUCT:
if (type->record.name) {
BUILD_TYPE_NAME(ctx, "struct ", type->record.name);
} else {
PRINT_QUOTED_VALUE(ctx, "anonymous struct");
}
break;
case SCC_AST_TYPE_UNION:
if (type->record.name) {
BUILD_TYPE_NAME(ctx, "union ", type->record.name);
} else {
PRINT_QUOTED_VALUE(ctx, "anonymous union");
}
break;
case SCC_AST_TYPE_ENUM:
if (type->enumeration.name) {
BUILD_TYPE_NAME(ctx, "enum ", type->enumeration.name);
} else {
PRINT_QUOTED_VALUE(ctx, "anonymous enum");
}
break;
case SCC_AST_TYPE_TYPEDEF:
PRINT_QUOTED_VALUE(ctx, type->typedef_type.name);
break;
default:
break;
}
end_node_dump(ctx);
// 递归转储子节点
switch (type->base.type) {
case SCC_AST_TYPE_POINTER:
dump_child_node((scc_ast_node_t *)type->pointer.pointee, ctx, true);
break;
case SCC_AST_TYPE_ARRAY:
dump_child_node((scc_ast_node_t *)type->array.element, ctx,
type->array.size == NULL);
if (type->array.size) {
dump_child_node((scc_ast_node_t *)type->array.size, ctx, true);
}
break;
default:
break;
}
}
// 递归转储表达式
static void dump_expr_impl(scc_ast_expr_t *expr, scc_ast_dump_ctx_t *ctx) {
if (!expr)
return;
start_node_dump(&expr->base, ctx);
// 根据表达式类型输出特定信息
switch (expr->base.type) {
case SCC_AST_EXPR_BINARY:
PRINT_QUOTED_VALUE(ctx, get_op_str(expr->binary.op));
break;
case SCC_AST_EXPR_UNARY:
PRINT_QUOTED_VALUE(ctx, get_op_str(expr->unary.op));
break;
case SCC_AST_EXPR_INT_LITERAL:
PRINT_VALUE(ctx, " %lld", expr->literal.value.i);
break;
case SCC_AST_EXPR_FLOAT_LITERAL:
PRINT_VALUE(ctx, " %f", expr->literal.value.f);
break;
case SCC_AST_EXPR_CHAR_LITERAL:
PRINT_VALUE(ctx, " '%c'", (char)expr->literal.value.ch);
break;
case SCC_AST_EXPR_STRING_LITERAL:
PRINT_VALUE(ctx, " \"%s\"", expr->literal.value.cstr.data);
break;
case SCC_AST_EXPR_IDENTIFIER:
if (expr->identifier.name) {
PRINT_QUOTED_VALUE(ctx, expr->identifier.name);
}
break;
case SCC_AST_EXPR_SIZE_OF:
case SCC_AST_EXPR_ALIGN_OF:
PRINT_QUOTED_VALUE(ctx, (expr->base.type == SCC_AST_EXPR_SIZE_OF)
? "sizeof"
: "alignof");
break;
default:
break;
}
end_node_dump(ctx);
// 使用辅助函数处理子节点转储
switch (expr->base.type) {
case SCC_AST_EXPR_BINARY:
dump_child_node((scc_ast_node_t *)expr->binary.lhs, ctx, false);
dump_child_node((scc_ast_node_t *)expr->binary.rhs, ctx, true);
break;
case SCC_AST_EXPR_UNARY:
dump_child_node((scc_ast_node_t *)expr->unary.operand, ctx, true);
break;
case SCC_AST_EXPR_COND:
dump_child_node((scc_ast_node_t *)expr->cond.cond, ctx, false);
dump_child_node((scc_ast_node_t *)expr->cond.then_expr, ctx, false);
dump_child_node((scc_ast_node_t *)expr->cond.else_expr, ctx, true);
break;
case SCC_AST_EXPR_CALL:
dump_child_node((scc_ast_node_t *)expr->call.callee, ctx, false);
// 转储参数
for (size_t i = 0; i < expr->call.args.size; i++) {
dump_child_node((scc_ast_node_t *)expr->call.args.data[i], ctx,
i == expr->call.args.size - 1);
}
break;
case SCC_AST_EXPR_ARRAY_SUBSCRIPT:
dump_child_node((scc_ast_node_t *)expr->subscript.array, ctx, false);
dump_child_node((scc_ast_node_t *)expr->subscript.index, ctx, true);
break;
case SCC_AST_EXPR_MEMBER:
case SCC_AST_EXPR_PTR_MEMBER:
dump_child_node((scc_ast_node_t *)expr->member.base, ctx, false);
// 打印成员访问信息
print_indent(ctx);
PRINT_COLORED(ctx, node_color, "Member [\"%s\"]",
expr->member.member_name);
scc_printf("\n");
break;
case SCC_AST_EXPR_CAST:
dump_child_node((scc_ast_node_t *)expr->cast.type, ctx, false);
dump_child_node((scc_ast_node_t *)expr->cast.expr, ctx, true);
break;
case SCC_AST_EXPR_SIZE_OF:
case SCC_AST_EXPR_ALIGN_OF:
if (expr->attr_of.expr) {
dump_child_node((scc_ast_node_t *)expr->attr_of.expr, ctx, true);
} else if (expr->attr_of.type) {
dump_child_node((scc_ast_node_t *)expr->attr_of.type, ctx, true);
}
break;
case SCC_AST_EXPR_COMPOUND_LITERAL:
dump_child_node((scc_ast_node_t *)expr->compound_literal.type, ctx,
false);
// 初始化列表
for (size_t i = 0; i < expr->compound_literal.init_list.size; i++) {
dump_child_node(
(scc_ast_node_t *)expr->compound_literal.init_list.data[i], ctx,
i == expr->compound_literal.init_list.size - 1);
}
break;
default:
break;
}
}
// 递归转储语句
static void dump_stmt_impl(scc_ast_stmt_t *stmt, scc_ast_dump_ctx_t *ctx) {
if (!stmt)
return;
start_node_dump(&stmt->base, ctx);
// 根据语句类型输出特定信息
switch (stmt->base.type) {
case SCC_AST_STMT_IF:
scc_printf("\n"); // if语句总是换行显示子节点
dump_child_node((scc_ast_node_t *)stmt->if_stmt.cond, ctx, false);
dump_child_node((scc_ast_node_t *)stmt->if_stmt.then_stmt, ctx,
!stmt->if_stmt.opt_else_stmt);
if (stmt->if_stmt.opt_else_stmt) {
dump_child_node((scc_ast_node_t *)stmt->if_stmt.opt_else_stmt, ctx,
true);
}
return;
case SCC_AST_STMT_WHILE:
scc_printf("\n"); // 循环和switch语句换行显示子节点
dump_child_node((scc_ast_node_t *)stmt->while_stmt.cond, ctx, false);
dump_child_node((scc_ast_node_t *)stmt->while_stmt.body, ctx, true);
return;
case SCC_AST_STMT_DO_WHILE:
scc_printf("\n"); // 循环和switch语句换行显示子节点
dump_child_node((scc_ast_node_t *)stmt->do_while_stmt.body, ctx, false);
dump_child_node((scc_ast_node_t *)stmt->do_while_stmt.cond, ctx, true);
return;
case SCC_AST_STMT_SWITCH:
scc_printf("\n"); // 循环和switch语句换行显示子节点
dump_child_node((scc_ast_node_t *)stmt->switch_stmt.cond, ctx, false);
dump_child_node((scc_ast_node_t *)stmt->switch_stmt.body, ctx, true);
return;
case SCC_AST_STMT_FOR:
scc_printf("\n"); // for语句换行显示子节点
if (stmt->for_stmt.init) {
dump_child_node((scc_ast_node_t *)stmt->for_stmt.init, ctx, false);
}
if (stmt->for_stmt.cond) {
dump_child_node((scc_ast_node_t *)stmt->for_stmt.cond, ctx, false);
}
if (stmt->for_stmt.iter) {
dump_child_node((scc_ast_node_t *)stmt->for_stmt.iter, ctx, false);
}
dump_child_node((scc_ast_node_t *)stmt->for_stmt.body, ctx, true);
return;
case SCC_AST_STMT_RETURN:
if (stmt->return_stmt.expr) {
scc_printf("\n");
dump_child_node((scc_ast_node_t *)stmt->return_stmt.expr, ctx,
true);
return;
}
break;
case SCC_AST_STMT_GOTO:
if (stmt->goto_stmt.label) {
PRINT_VALUE(ctx, " Label: %s", stmt->goto_stmt.label);
}
break;
case SCC_AST_STMT_LABEL:
if (stmt->label_stmt.label) {
PRINT_VALUE(ctx, " %s", stmt->label_stmt.label);
}
break;
default:
break;
}
end_node_dump(ctx);
// 递归转储其他子节点
switch (stmt->base.type) {
case SCC_AST_STMT_COMPOUND:
for (size_t i = 0; i < stmt->compound.block_items.size; i++) {
scc_ast_node_t *item =
(scc_ast_node_t *)stmt->compound.block_items.data[i];
dump_child_node(item, ctx,
i == stmt->compound.block_items.size - 1);
}
break;
case SCC_AST_STMT_EXPR:
if (stmt->expr.expr) {
dump_child_node((scc_ast_node_t *)stmt->expr.expr, ctx, true);
}
break;
case SCC_AST_STMT_CASE:
dump_child_node((scc_ast_node_t *)stmt->case_stmt.expr, ctx, false);
dump_child_node((scc_ast_node_t *)stmt->case_stmt.stmt, ctx, true);
break;
case SCC_AST_STMT_DEFAULT:
dump_child_node((scc_ast_node_t *)stmt->default_stmt.stmt, ctx, true);
break;
default:
break;
}
}
// 递归转储声明
static void dump_decl_impl(scc_ast_decl_t *decl, scc_ast_dump_ctx_t *ctx) {
if (!decl)
return;
start_node_dump(&decl->base, ctx);
// 根据声明类型输出特定信息
switch (decl->base.type) {
case SCC_AST_DECL_VAR:
if (decl->var.name) {
PRINT_QUOTED_VALUE(ctx, decl->var.name);
}
break;
case SCC_AST_DECL_FUNC:
if (decl->func.name) {
PRINT_QUOTED_VALUE(ctx, decl->func.name);
}
break;
case SCC_AST_DECL_PARAM:
if (decl->param.name) {
PRINT_QUOTED_VALUE(ctx, decl->param.name);
}
break;
case SCC_AST_DECL_STRUCT:
if (decl->record.name) {
PRINT_QUOTED_VALUE(ctx, decl->record.name);
}
break;
case SCC_AST_DECL_UNION:
if (decl->record.name) {
PRINT_QUOTED_VALUE(ctx, decl->record.name);
}
break;
case SCC_AST_DECL_ENUM:
if (decl->enumeration.name) {
PRINT_QUOTED_VALUE(ctx, decl->enumeration.name);
}
break;
case SCC_AST_DECL_TYPEDEF:
if (decl->typedef_decl.name) {
PRINT_QUOTED_VALUE(ctx, decl->typedef_decl.name);
}
break;
default:
break;
}
end_node_dump(ctx);
// 递归转储子节点
switch (decl->base.type) {
case SCC_AST_DECL_VAR:
if (decl->var.type) {
dump_child_node((scc_ast_node_t *)decl->var.type, ctx,
decl->var.init == NULL);
if (decl->var.init) {
dump_child_node((scc_ast_node_t *)decl->var.init, ctx, true);
}
}
break;
case SCC_AST_DECL_FUNC:
if (decl->func.type) {
dump_child_node((scc_ast_node_t *)decl->func.type, ctx,
decl->func.body == NULL);
if (decl->func.body) {
dump_child_node((scc_ast_node_t *)decl->func.body, ctx, true);
}
}
break;
case SCC_AST_DECL_PARAM:
if (decl->param.type) {
dump_child_node((scc_ast_node_t *)decl->param.type, ctx, true);
}
break;
case SCC_AST_DECL_STRUCT:
case SCC_AST_DECL_UNION:
for (size_t i = 0; i < decl->record.fields.size; i++) {
dump_child_node((scc_ast_node_t *)decl->record.fields.data[i], ctx,
i == decl->record.fields.size - 1);
}
break;
case SCC_AST_DECL_ENUM:
for (size_t i = 0; i < decl->enumeration.enumerators.size; i++) {
dump_child_node(
(scc_ast_node_t *)decl->enumeration.enumerators.data[i], ctx,
i == decl->enumeration.enumerators.size - 1);
}
break;
case SCC_AST_DECL_TYPEDEF:
if (decl->typedef_decl.type) {
dump_child_node((scc_ast_node_t *)decl->typedef_decl.type, ctx,
true);
}
break;
default:
break;
}
}
// 递归转储翻译单元
static void dump_unit_impl(scc_ast_translation_unit_t *unit,
scc_ast_dump_ctx_t *ctx) {
if (!unit)
return;
start_node_dump(&unit->base, ctx);
scc_printf("\n");
for (size_t i = 0; i < unit->declarations.size; i++) {
dump_child_node((scc_ast_node_t *)unit->declarations.data[i], ctx,
i == unit->declarations.size - 1);
}
}
// 实现上下文管理函数
void scc_ast_dump_ctx_init(scc_ast_dump_ctx_t *ctx, cbool use_color) {
scc_memset(ctx, 0, sizeof(*ctx));
ctx->use_color = use_color;
ctx->node_color = use_color ? DEFAULT_NODE_COLOR : "";
ctx->value_color = use_color ? DEFAULT_VALUE_COLOR : "";
ctx->branch_color = use_color ? DEFAULT_BRANCH_COLOR : "";
ctx->reset_color = use_color ? DEFAULT_RESET_COLOR : "";
ensure_context_depth(ctx, 0);
ctx->is_last_child[0] = true;
}
void scc_ast_dump_ctx_drop(scc_ast_dump_ctx_t *ctx) {
if (ctx->is_last_child) {
scc_free(ctx->is_last_child);
ctx->is_last_child = NULL;
}
}
void scc_ast_dump_node(scc_ast_node_t *node, scc_ast_dump_ctx_t *ctx) {
if (!node)
return;
if (SCC_AST_IS_A(scc_ast_expr_t, node)) {
dump_expr_impl(SCC_AST_CAST_TO(scc_ast_expr_t, node), ctx);
} else if (SCC_AST_IS_A(scc_ast_stmt_t, node)) {
dump_stmt_impl(SCC_AST_CAST_TO(scc_ast_stmt_t, node), ctx);
} else if (SCC_AST_IS_A(scc_ast_decl_t, node)) {
dump_decl_impl(SCC_AST_CAST_TO(scc_ast_decl_t, node), ctx);
} else if (SCC_AST_IS_A(scc_ast_type_t, node)) {
dump_type_impl(SCC_AST_CAST_TO(scc_ast_type_t, node), ctx);
} else if (SCC_AST_IS_A(scc_ast_translation_unit_t, node)) {
dump_unit_impl(SCC_AST_CAST_TO(scc_ast_translation_unit_t, node), ctx);
}
}

View File

@@ -0,0 +1,10 @@
#include <stdio.h>
void test_example() {
printf("Test passed!\n");
}
int main() {
test_example();
return 0;
}