【2025-11-16】现有代码上传
This commit is contained in:
325
ast.h
Normal file
325
ast.h
Normal file
@@ -0,0 +1,325 @@
|
||||
#ifndef MINI_C_AST_H
|
||||
#define MINI_C_AST_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
/*──────────────────────────────
|
||||
* 0. 语义分析辅助
|
||||
*─────────────────────────────*/
|
||||
|
||||
// 在 type.h 中定义具体的 Type 类
|
||||
struct Type;
|
||||
|
||||
// 用于记录 AST 节点在源文件中的行、列位置
|
||||
struct SourceLoc {
|
||||
int line = 0;
|
||||
int col = 0;
|
||||
};
|
||||
|
||||
/*──────────────────────────────
|
||||
* 1. 词法‑语法层枚举
|
||||
*─────────────────────────────*/
|
||||
//——单目运算符——
|
||||
enum UnaryOp : int {
|
||||
op_address, op_deref, op_unary_plus, op_neg,
|
||||
op_bitnot, op_not
|
||||
};
|
||||
|
||||
//——赋值运算符(含复合)——
|
||||
enum AssignOp : int {
|
||||
op_assign, op_mul_assign, op_div_assign, op_mod_assign,
|
||||
op_add_assign, op_sub_assign, op_shl_assign, op_shr_assign,
|
||||
op_and_assign, op_xor_assign, op_or_assign
|
||||
};
|
||||
|
||||
//——额外二元运算符——
|
||||
enum BinaryOp : int {
|
||||
// ASCII 运算符直接用字面字符
|
||||
SHL = 256, SHR,
|
||||
LE, GE, EQ, NE
|
||||
};
|
||||
|
||||
//——存储类别说明符——
|
||||
enum StorageClass : int {
|
||||
SC_TYPEDEF, SC_EXTERN, SC_STATIC, SC_AUTO, SC_REGISTER
|
||||
};
|
||||
|
||||
//——基本类型说明符——
|
||||
enum TypeSpecifier : int {
|
||||
TS_VOID, TS_CHAR, TS_SHORT, TS_INT, TS_LONG,
|
||||
TS_FLOAT, TS_DOUBLE, TS_SIGNED, TS_UNSIGNED,
|
||||
TS_BOOL, TS_COMPLEX, TS_IMAGINARY,
|
||||
TS_TYPE_NAME // typedef‑alias
|
||||
};
|
||||
|
||||
//——struct / union——
|
||||
enum StructUnionKind : int { SU_STRUCT, SU_UNION };
|
||||
|
||||
//——限定符 / 函数特性——
|
||||
enum TypeQualifier : int { TQ_CONST, TQ_RESTRICT, TQ_VOLATILE };
|
||||
enum FuncSpecifier : int { FS_INLINE };
|
||||
|
||||
/*──────────────────────────────
|
||||
* 2. AST 结点与标签
|
||||
*─────────────────────────────*/
|
||||
enum class ASTTag : std::uint16_t {
|
||||
/*── 基本 / 运算类 ──*/
|
||||
ID, CONST, STRING,
|
||||
UNARY, BINARY, LOGIC_AND, LOGIC_OR,
|
||||
COND, ASSIGN,
|
||||
ARRAY_REF, STRUCT_REF, FUNC_CALL,
|
||||
SIZEOF_EXPR, CAST_EXPR, COMPOUND_LITERAL,
|
||||
EXPR_LIST, ARG_LIST,
|
||||
PRE_INC, PRE_DEC, // ← 新增
|
||||
POST_INC, POST_DEC, // ← 新增
|
||||
/*── 声明 & 类型 ──*/
|
||||
SPECIFIER, SPEC_LIST, DECLARATION, INIT_DECL, INIT_DECL_LIST,
|
||||
DECL_SPEC_LIST, DECLARATOR, POINTER_DECL,
|
||||
ARRAY_DECL, FUNC_DECL, OLD_FUNC_DECL,
|
||||
PARAM_DECL, PARAM_LIST, PARAM_LIST_ELIPS,
|
||||
ID_LIST, TYPE_NAME_NODE,
|
||||
ABS_DECL, ABS_ARRAY, ABS_ARRAY_CHILD,
|
||||
ABS_FUNC, ABS_FUNC_CHILD,
|
||||
POINTER, POINTER_CHAIN,
|
||||
TQ_LIST,
|
||||
|
||||
/*── struct / enum ──*/
|
||||
SU_SPEC, STRUCT_DECL, STRUCT_DECL_LIST,
|
||||
STRUCT_DECLARATOR, STRUCT_DECLARATOR_LIST,
|
||||
BITFIELD,
|
||||
ENUM_SPEC, ENUM_LIST, ENUM_CONST,
|
||||
|
||||
SPECQ_LIST,
|
||||
|
||||
/*── 初始化 / 设计化初始化 ──*/
|
||||
INIT_EXPR, INIT_LIST_NODE, INIT_ITEM_LIST,
|
||||
DESIGNATOR_LIST, DESIGNATED_INIT,
|
||||
ARRAY_DESIGNATOR, FIELD_DESIGNATOR,
|
||||
|
||||
/*── 语句 ──*/
|
||||
LABELED_ID_STMT, CASE_STMT, DEFAULT_STMT,
|
||||
COMPOUND_STMT, BLOCK_ITEM_LIST, BLOCK_DECL, BLOCK_STMT,
|
||||
EXPR_STMT,
|
||||
IF_STMT, SWITCH_STMT,
|
||||
WHILE_STMT, DO_WHILE_STMT,
|
||||
FOR_STMT, FOR_DECL_STMT,
|
||||
GOTO_STMT, CONTINUE_STMT, BREAK_STMT, RETURN_STMT,
|
||||
|
||||
/*── 顶层 ──*/
|
||||
TRANSL_UNIT, DECL_STMT, FUNCTION_DEF, DECL_LIST
|
||||
};
|
||||
|
||||
struct ASTNode {
|
||||
ASTTag tag;
|
||||
std::string text; // 标识符
|
||||
std::int64_t ival{}; // 数值或枚举值
|
||||
bool flag{};
|
||||
SourceLoc loc{}; // 源代码行列信息
|
||||
Type* type{}; // 语义分析后填充的类型指针
|
||||
std::vector<ASTNode*> kids; // 子节点(按动作顺序)
|
||||
explicit ASTNode(ASTTag t, SourceLoc loc_ = SourceLoc{})
|
||||
: tag(t), loc(loc_) {}
|
||||
};
|
||||
|
||||
/* 方便在别处直接引用整棵语法树 */
|
||||
extern ASTNode *ast_root;
|
||||
|
||||
/*──────────────────────────────
|
||||
* 3. 表达式构造函数
|
||||
*─────────────────────────────*/
|
||||
ASTNode* new_id_node (const char* name, SourceLoc loc);
|
||||
ASTNode* new_const_node(const char* literal, SourceLoc loc);
|
||||
ASTNode* new_string_node(const char* literal, SourceLoc loc);
|
||||
|
||||
ASTNode* new_array_ref_node(ASTNode* array, ASTNode* index, SourceLoc loc);
|
||||
ASTNode* new_func_call_node(ASTNode* callee, ASTNode* arg_list, SourceLoc loc);
|
||||
ASTNode* new_struct_ref_node(ASTNode* base, const char* field, bool is_ptr_op, SourceLoc loc);
|
||||
|
||||
ASTNode* new_post_inc_node(ASTNode* expr, SourceLoc loc);
|
||||
ASTNode* new_post_dec_node(ASTNode* expr, SourceLoc loc);
|
||||
ASTNode* new_pre_inc_node(ASTNode* expr, SourceLoc loc);
|
||||
ASTNode* new_pre_dec_node(ASTNode* expr, SourceLoc loc);
|
||||
ASTNode* new_compound_literal_node(ASTNode* type_name, ASTNode* init_list, SourceLoc loc);
|
||||
|
||||
ASTNode* new_arg_list(ASTNode* first_arg, SourceLoc loc);
|
||||
ASTNode* append_arg_list(ASTNode* list, ASTNode* arg, SourceLoc loc);
|
||||
|
||||
ASTNode* new_unary_op_node(int op, ASTNode* operand, SourceLoc loc);
|
||||
ASTNode* new_sizeof_node(ASTNode* target, bool is_type_name, SourceLoc loc);
|
||||
ASTNode* new_cast_node(ASTNode* type_name, ASTNode* expr, SourceLoc loc);
|
||||
ASTNode* new_binop_node (int op, ASTNode* lhs, ASTNode* rhs, SourceLoc loc); // op 可为字符或 BinaryOp
|
||||
ASTNode* new_logical_and_node(ASTNode* lhs, ASTNode* rhs, SourceLoc loc);
|
||||
ASTNode* new_logical_or_node(ASTNode* lhs, ASTNode* rhs, SourceLoc loc);
|
||||
ASTNode* new_conditional_node(ASTNode* cond, ASTNode* then_expr, ASTNode* else_expr, SourceLoc loc);
|
||||
ASTNode* new_assign_node (ASTNode* lhs, int op, ASTNode* rhs, SourceLoc loc);
|
||||
|
||||
ASTNode* new_expr_list(ASTNode* left, ASTNode* right, SourceLoc loc);
|
||||
|
||||
/*──────────────────────────────
|
||||
* 4. 声明 & 类型系统
|
||||
*─────────────────────────────*/
|
||||
ASTNode* new_declaration(ASTNode* spec_list, ASTNode* init_list, SourceLoc loc);
|
||||
ASTNode* new_spec_list(int spec, SourceLoc loc); // 建立首节点
|
||||
ASTNode* append_spec_list(ASTNode* list, int spec, SourceLoc loc); // 追加
|
||||
|
||||
ASTNode* new_init_list(ASTNode* init_decl, SourceLoc loc);
|
||||
ASTNode* append_init_list(ASTNode* list, ASTNode* init_decl, SourceLoc loc);
|
||||
ASTNode* new_init_decl(ASTNode* declarator, ASTNode* initializer, SourceLoc loc);
|
||||
|
||||
ASTNode* new_struct_su_node(StructUnionKind su, const char* id, ASTNode* decl_list, SourceLoc loc);
|
||||
ASTNode* new_sdecl_list(ASTNode* sdecl, SourceLoc loc);
|
||||
ASTNode* append_sdecl_list(ASTNode* list, ASTNode* sdecl, SourceLoc loc);
|
||||
ASTNode* new_struct_decl(ASTNode* specq_list, ASTNode* sdecl_list, SourceLoc loc);
|
||||
|
||||
ASTNode* new_specq_list(int spec_or_qual, SourceLoc loc);
|
||||
ASTNode* append_specq_list(ASTNode* list, int spec_or_qual, SourceLoc loc);
|
||||
|
||||
ASTNode* new_sdeclarator_list(ASTNode* sdecltor, SourceLoc loc);
|
||||
ASTNode* append_sdeclarator_list(ASTNode* list, ASTNode* sdecltor, SourceLoc loc);
|
||||
|
||||
ASTNode* new_bitfield_node(ASTNode* declarator /*nullable*/,
|
||||
ASTNode* width_expr, SourceLoc loc);
|
||||
|
||||
ASTNode* new_enum_node(const char* id /*nullable*/, ASTNode* enumerator_list, SourceLoc loc);
|
||||
ASTNode* new_enum_list(ASTNode* enumerator, SourceLoc loc);
|
||||
ASTNode* append_enum_list(ASTNode* list, ASTNode* enumerator, SourceLoc loc);
|
||||
ASTNode* new_enum_const(const char* id, ASTNode* value_expr /*nullable*/, SourceLoc loc);
|
||||
|
||||
ASTNode* new_tq_list(int tq, SourceLoc loc);
|
||||
ASTNode* append_tq_list(ASTNode* list, int tq, SourceLoc loc);
|
||||
|
||||
ASTNode* new_declarator_node(ASTNode* pointer /*nullable*/, ASTNode* direct_decl, SourceLoc loc);
|
||||
ASTNode* new_decl_ident(const char* id, SourceLoc loc);
|
||||
ASTNode* new_array_decl(ASTNode* decl, ASTNode* tq_list /*nullable*/,
|
||||
ASTNode* size_expr /*nullable*/,
|
||||
bool is_static /*nullable*/,
|
||||
bool is_star /*nullable*/, SourceLoc loc);
|
||||
ASTNode* new_func_decl(ASTNode* decl, ASTNode* param_type_list /*nullable*/, SourceLoc loc);
|
||||
ASTNode* new_oldstyle_func_decl(ASTNode* decl, ASTNode* id_list, SourceLoc loc);
|
||||
|
||||
ASTNode* new_pointer(ASTNode* tq_list /*nullable*/, SourceLoc loc);
|
||||
ASTNode* prepend_pointer(ASTNode* tq_list /*nullable*/, ASTNode* existing, SourceLoc loc);
|
||||
|
||||
ASTNode* new_param_list(ASTNode* param_decl, SourceLoc loc);
|
||||
ASTNode* append_param_list(ASTNode* list, ASTNode* param_decl, SourceLoc loc);
|
||||
ASTNode* new_param_list_ellipsis(ASTNode* list, SourceLoc loc);
|
||||
ASTNode* new_param_decl(ASTNode* decl_spec, ASTNode* declarator /*nullable*/, SourceLoc loc);
|
||||
|
||||
ASTNode* new_id_list(const char* id, SourceLoc loc);
|
||||
ASTNode* append_id_list(ASTNode* list, const char* id, SourceLoc loc);
|
||||
|
||||
ASTNode* new_type_name(ASTNode* specq_list, ASTNode* abs_decl /*nullable*/, SourceLoc loc);
|
||||
|
||||
ASTNode* new_abs_decl(ASTNode* pointer /*nullable*/, ASTNode* direct_abs_decl /*nullable*/, SourceLoc loc);
|
||||
ASTNode* new_abs_array(ASTNode* size_expr /*nullable*/, bool is_star /*nullable*/, SourceLoc loc);
|
||||
ASTNode* new_abs_array_child(ASTNode* parent, ASTNode* size_expr /*nullable*/, bool is_star /*nullable*/, SourceLoc loc);
|
||||
ASTNode* new_abs_func(ASTNode* param_type_list /*nullable*/, SourceLoc loc);
|
||||
ASTNode* new_abs_func_child(ASTNode* parent, ASTNode* param_type_list /*nullable*/, SourceLoc loc);
|
||||
|
||||
/*──────────────────────────────
|
||||
* 5. 初始化 & 设计化初始化
|
||||
*─────────────────────────────*/
|
||||
ASTNode* new_init_expr(ASTNode* expr, SourceLoc loc);
|
||||
ASTNode* new_init_list_node(ASTNode* init_item_list, SourceLoc loc);
|
||||
ASTNode* new_init_item_list(ASTNode* initializer, SourceLoc loc);
|
||||
ASTNode* append_init_item(ASTNode* list, ASTNode* initializer, SourceLoc loc);
|
||||
|
||||
ASTNode* new_designated_init(ASTNode* designator_list, ASTNode* initializer, SourceLoc loc);
|
||||
ASTNode* new_designator_list(ASTNode* designator, SourceLoc loc);
|
||||
ASTNode* append_designator_list(ASTNode* list, ASTNode* designator, SourceLoc loc);
|
||||
ASTNode* new_array_designator(ASTNode* const_expr, SourceLoc loc);
|
||||
ASTNode* new_field_designator(const char* field, SourceLoc loc);
|
||||
|
||||
/*──────────────────────────────
|
||||
* 6. 语句
|
||||
*─────────────────────────────*/
|
||||
ASTNode* new_labeled_stmt_id(const char* id, ASTNode* stmt, SourceLoc loc);
|
||||
ASTNode* new_case_stmt(ASTNode* const_expr, ASTNode* stmt, SourceLoc loc);
|
||||
ASTNode* new_default_stmt(ASTNode* stmt, SourceLoc loc);
|
||||
|
||||
ASTNode* new_compound_stmt(ASTNode* block_item_list /*nullable*/, SourceLoc loc);
|
||||
ASTNode* new_block_item_list(ASTNode* item, SourceLoc loc);
|
||||
ASTNode* append_block_item_list(ASTNode* list, ASTNode* item, SourceLoc loc);
|
||||
ASTNode* new_block_decl(ASTNode* decl, SourceLoc loc);
|
||||
ASTNode* new_block_stmt(ASTNode* stmt, SourceLoc loc);
|
||||
|
||||
ASTNode* new_expr_stmt(ASTNode* expr /*nullable*/, SourceLoc loc);
|
||||
|
||||
ASTNode* new_if_stmt(ASTNode* cond, ASTNode* then_stmt, ASTNode* else_stmt /*nullable*/, SourceLoc loc);
|
||||
ASTNode* new_switch_stmt(ASTNode* expr, ASTNode* stmt, SourceLoc loc);
|
||||
|
||||
ASTNode* new_while_stmt(ASTNode* cond, ASTNode* body, SourceLoc loc);
|
||||
ASTNode* new_do_while_stmt(ASTNode* body, ASTNode* cond, SourceLoc loc);
|
||||
ASTNode* new_for_stmt(ASTNode* init, ASTNode* cond, ASTNode* iter /*nullable*/, ASTNode* body, SourceLoc loc);
|
||||
ASTNode* new_for_decl_stmt(ASTNode* decl, ASTNode* cond_expr_stmt,
|
||||
ASTNode* iter_expr /*nullable*/, ASTNode* body, SourceLoc loc);
|
||||
|
||||
ASTNode* new_goto_stmt(const char* id, SourceLoc loc);
|
||||
ASTNode* new_continue_stmt(SourceLoc loc);
|
||||
ASTNode* new_break_stmt(SourceLoc loc);
|
||||
ASTNode* new_return_stmt (ASTNode* expr /*nullable*/, SourceLoc loc);
|
||||
|
||||
/*──────────────────────────────
|
||||
* 7. 翻译单元 / 顶层
|
||||
*─────────────────────────────*/
|
||||
ASTNode* new_translation_unit(ASTNode* prev, ASTNode* ext_decl, SourceLoc loc);
|
||||
ASTNode* new_decl_stmt (ASTNode* declaration, SourceLoc loc);
|
||||
ASTNode* new_function_def (ASTNode* decl_spec, ASTNode* declarator,
|
||||
ASTNode* decl_list /*nullable*/, ASTNode* compound_stmt,
|
||||
SourceLoc loc);
|
||||
|
||||
ASTNode* new_declaration_list(ASTNode* decl, SourceLoc loc);
|
||||
ASTNode* append_declaration_list(ASTNode* list, ASTNode* decl, SourceLoc loc);
|
||||
|
||||
// ★ 放在初始化区域旁边
|
||||
ASTNode* append_designated_init(ASTNode* list,
|
||||
ASTNode* designator_list,
|
||||
ASTNode* initializer, SourceLoc loc);
|
||||
|
||||
// ★ 新增两种 overload,让既能接 enum 也能接节点
|
||||
ASTNode* new_spec_list(ASTNode* spec_node, SourceLoc loc);
|
||||
ASTNode* append_spec_list(ASTNode* list, ASTNode* spec_node, SourceLoc loc);
|
||||
|
||||
|
||||
/* 让列表函数既接受 enum 也接受 ASTNode* -------------------*/
|
||||
// ASTNode* (ASTNode* spec_node);
|
||||
ASTNode* append_spec_list(ASTNode* list, ASTNode* spec_node, SourceLoc loc);
|
||||
|
||||
ASTNode* new_specq_list(ASTNode* node, SourceLoc loc);
|
||||
ASTNode* append_specq_list(ASTNode* list, ASTNode* node, SourceLoc loc);
|
||||
|
||||
static std::string extractNameFromDeclarator(ASTNode* dtor) {
|
||||
std::string name = "";
|
||||
if (!dtor) return name;
|
||||
|
||||
ASTNode* current = dtor;
|
||||
// 循环查找,直到找到带 text 的 DECLARATOR 或 ID
|
||||
while (current) {
|
||||
if (current->tag == ASTTag::DECLARATOR && !current->text.empty()) {
|
||||
name = current->text;
|
||||
break;
|
||||
}
|
||||
if (current->tag == ASTTag::ID) {
|
||||
name = current->text;
|
||||
break;
|
||||
}
|
||||
// 如果当前节点是 DECLARATOR 或 FUNC_DECL 且有子节点,则深入第一个子节点
|
||||
// (这部分逻辑需要根据 AST 结构仔细调整)
|
||||
if ((current->tag == ASTTag::DECLARATOR || current->tag == ASTTag::FUNC_DECL) && !current->kids.empty()) {
|
||||
// 特殊处理函数名情况:FUNC_DECL -> DECLARATOR "name"
|
||||
if (current->tag == ASTTag::FUNC_DECL && current->kids[0] && current->kids[0]->tag == ASTTag::DECLARATOR && !current->kids[0]->text.empty()) {
|
||||
name = current->kids[0]->text;
|
||||
break;
|
||||
}
|
||||
current = current->kids[0]; // 默认深入第一个孩子
|
||||
} else {
|
||||
break; // 无法继续深入
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
#endif /* MINI_C_AST_H */
|
||||
Reference in New Issue
Block a user