Files
Compiler/ast.h

326 lines
14 KiB
C
Raw Permalink Normal View History

2025-11-16 21:04:02 +08:00
#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 // typedefalias
};
//——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 */