【2025-11-16】现有代码上传

This commit is contained in:
hym816
2025-11-16 21:04:02 +08:00
parent 6e114d8735
commit d71eb4576e
28 changed files with 11524 additions and 0 deletions

411
PrettyPrinter.cpp Normal file
View File

@@ -0,0 +1,411 @@
// PrettyPrinter.cpp
#include "PrettyPrinter.h"
void PrettyPrinter::print(ASTNode* root) {
printNode(root);
out.flush();
}
void PrettyPrinter::indent(){
out << std::string(indentLevel * indentWidth, ' ');
}
void PrettyPrinter::newline(){
out << "\n";
}
void PrettyPrinter::withIndent(const std::function<void()>& f){
indentLevel++;
f();
indentLevel--;
}
bool PrettyPrinter::isStmt(ASTTag t){
using T = ASTTag;
return t==T::IF_STMT || t==T::FOR_STMT || t==T::FOR_DECL_STMT
|| t==T::WHILE_STMT|| t==T::RETURN_STMT
|| t==T::EXPR_STMT || t==T::COMPOUND_STMT
|| t==T::DECL_STMT;
}
void PrettyPrinter::printNode(ASTNode* n){
if (!n) return;
switch (n->tag) {
case ASTTag::TRANSL_UNIT: printTranslationUnit(n); break;
case ASTTag::FUNCTION_DEF: printFunctionDef(n); break;
case ASTTag::DECL_STMT: printDeclStmt(n); break;
case ASTTag::DECLARATION:
indent();
printDeclaration(n);
out << ";";
newline();
break;
case ASTTag::IF_STMT: printIfStmt(n); break;
case ASTTag::FOR_STMT:
case ASTTag::FOR_DECL_STMT: printForStmt(n); break;
case ASTTag::WHILE_STMT: printWhileStmt(n); break;
case ASTTag::RETURN_STMT: printReturnStmt(n); break;
case ASTTag::COMPOUND_STMT: printCompoundStmt(n); break;
case ASTTag::EXPR_STMT:
indent();
// EXPR_STMT.kids[0] 可能是 nullptr空语句或者表达式
if (!n->kids.empty() && n->kids[0]) {
printExpr(n->kids[0]);
}
out << ";";
newline();
break;
default:
if (isStmt(n->tag)) {
// 其它语句回退到 “表达式语句” 的处理
indent();
printExpr(n);
out << ";";
newline();
} else {
printExpr(n);
}
}
}
// ── 顶层翻译单元 ──
void PrettyPrinter::printTranslationUnit(ASTNode* n){
for (auto child : n->kids){
printNode(child);
newline();
}
}
// ── 函数定义 ──
// kids: [spec_list, declarator, (opt decl_list), compound_stmt]
void PrettyPrinter::printFunctionDef(ASTNode* n){
indent();
printDeclSpec(n->kids[0]);
out<<" ";
printDeclarator(n->kids[1]); // 包含函数名和参数
out<<" ";
printCompoundStmt(n->kids.back());
newline();
}
// ── 声明语句、声明 ──
void PrettyPrinter::printDeclStmt(ASTNode* n){
indent();
printDeclaration(n->kids[0]);
out<<";";
newline();
}
void PrettyPrinter::printDeclaration(ASTNode* n) {
// kids: [spec_list, init_decl_list]
printDeclSpec(n->kids[0]);
// 如果有初始化列表,就输出空格并专门打印它
if (n->kids.size() > 1 && n->kids[1]) {
out << " ";
printInitDeclList(n->kids[1]);
}
}
// ── If ──
void PrettyPrinter::printIfStmt(ASTNode* n){
indent(); out<<"if ("; printExpr(n->kids[0]); out<<") ";
if (n->kids[1]->tag==ASTTag::COMPOUND_STMT){
printCompoundStmt(n->kids[1]);
} else {
newline();
withIndent([&](){ printNode(n->kids[1]); });
}
if (n->kids.size()==3){
indent(); out<<"else ";
if (n->kids[2]->tag==ASTTag::COMPOUND_STMT)
printCompoundStmt(n->kids[2]);
else {
newline();
withIndent([&](){ printNode(n->kids[2]); });
}
}
}
// ── For ──
// kids: [init, cond, iter?, body]
void PrettyPrinter::printForStmt(ASTNode* n){
indent(); out<<"for (";
if (n->kids[0]) {
if (n->kids[0]->tag == ASTTag::DECLARATION) {
printDeclaration(n->kids[0]);
} else {
ASTNode* initNode = n->kids[0];
if (initNode->tag == ASTTag::EXPR_STMT
&& !initNode->kids.empty()
&& initNode->kids[0])
initNode = initNode->kids[0];
printExpr(initNode);
}
}
out<<"; ";
// cond: 通常是 EXPR_STMT 包装
if (n->kids[1]) {
ASTNode* condNode = n->kids[1];
if (condNode->tag == ASTTag::EXPR_STMT
&& !condNode->kids.empty()
&& condNode->kids[0])
condNode = condNode->kids[0];
printExpr(condNode);
}
out<<"; ";
// ASTNode* iter = (n->kids.size()>2 ? n->kids[2] : nullptr);
// if (iter) printExpr(iter);
// iter: 有时也是 EXPR_STMT有时直接是表达式
if (n->kids.size() > 2 && n->kids[2]) {
ASTNode* iterNode = n->kids[2];
if (iterNode->tag == ASTTag::EXPR_STMT
&& !iterNode->kids.empty()
&& iterNode->kids[0])
iterNode = iterNode->kids[0];
printExpr(iterNode);
}
out<<") ";
if (n->kids.back()->tag==ASTTag::COMPOUND_STMT)
printCompoundStmt(n->kids.back());
else {
newline();
withIndent([&](){ printNode(n->kids.back()); });
}
}
// ── While ──
void PrettyPrinter::printWhileStmt(ASTNode* n){
indent(); out<<"while ("; printExpr(n->kids[0]); out<<") ";
if (n->kids[1]->tag==ASTTag::COMPOUND_STMT)
printCompoundStmt(n->kids[1]);
else {
newline();
withIndent([&](){ printNode(n->kids[1]); });
}
}
// ── Return ──
void PrettyPrinter::printReturnStmt(ASTNode* n){
indent(); out<<"return";
if (!n->kids.empty()){
out<<" ";
printExpr(n->kids[0]);
}
out<<";"; newline();
}
// ── Compound ──
void PrettyPrinter::printCompoundStmt(ASTNode* n) {
indent();
out << "{";
newline();
withIndent([&]() {
// 先检查是否真的是一个 BLOCK_ITEM_LIST
if (!n->kids.empty()
&& n->kids[0]
&& n->kids[0]->tag == ASTTag::BLOCK_ITEM_LIST) {
ASTNode* blockList = n->kids[0];
for (ASTNode* item : blockList->kids) {
if (!item) continue;
switch (item->tag) {
case ASTTag::BLOCK_DECL:
// 声明包装:拆开并打印
indent();
printDeclaration(item->kids[0]);
out << ";";
newline();
break;
case ASTTag::BLOCK_STMT:
// 语句包装:取出里面的真正 stmt
if (!item->kids.empty() && item->kids[0]) {
printNode(item->kids[0]);
}
break;
default:
// 其它直接递归
printNode(item);
}
}
} else {
// 回退:如果 kids[0] 不是 BLOCK_ITEM_LIST就打印所有子节点
for (ASTNode* child : n->kids) {
if (child) printNode(child);
}
}
});
indent();
out << "}";
newline();
}
// ── 声明符 & 类型相关 ──
// spec_list: kids 是一连串枚举值
void PrettyPrinter::printDeclSpec(ASTNode* n){
if (!n) return;
bool first = true;
for (ASTNode* leaf : n->kids) {
// 跳过 nullptr 或者不是 SPECIFIER 的节点
if (!leaf || leaf->tag != ASTTag::SPECIFIER)
continue;
if (!first) out << " ";
first = false;
int spec = leaf->ival;
switch (spec) {
case TS_INT: out << "int"; break;
case TS_CHAR: out << "char"; break;
case TS_VOID: out << "void"; break;
// … 其他类型 …
default: out << "/*spec" << spec << "*/";
}
}
}
// declarator: 可能包含指针、标识符、参数列表
void PrettyPrinter::printDeclarator(ASTNode* n){
// 简化处理:直接从 text 中读函数名或变量名
if (!n->text.empty()){
out<<n->text;
} else if (!n->kids.empty()){
// 对于 FUNC_DECL: kids[0] 是 DECLARATOR带函数名kids[1] 是 PARAM_LIST
if (n->tag==ASTTag::FUNC_DECL){
printDeclarator(n->kids[0]);
out<<"(";
if (n->kids.size()>1) printParamList(n->kids[1]);
out<<")";
return;
} else {
printDeclarator(n->kids[0]);
}
}
}
// 参数列表
void PrettyPrinter::printParamList(ASTNode* n){
bool first=true;
for (auto pd : n->kids){
if (!first) out<<", ";
first=false;
// pd: PARAM_DECL 节点kids[0] 是 spec_listkids[1] 可选 declarator
printDeclSpec(pd->kids[0]);
if (pd->kids.size()>1){
out<<" ";
printDeclarator(pd->kids[1]);
}
}
}
// ── 表达式打印 ──
void PrettyPrinter::printExpr(ASTNode* n){
using T = ASTTag;
switch (n->tag){
case T::ID:
out<<n->text; break;
case T::CONST:
out<<n->text; break;
case T::BINARY:
printExpr(n->kids[0]);
out<<" "<< static_cast<char>(n->ival) <<" ";
printExpr(n->kids[1]);
break;
case T::UNARY:{
int op = n->ival;
const char* s = op=='-'? "-" : op=='+'? "+" : "";
printUnary(n, s, true);
break;
}
case T::ASSIGN:
printExpr(n->kids[0]);
out<<" = ";
printExpr(n->kids[1]);
break;
case T::FUNC_CALL:
printFuncCall(n);
break;
case T::ARRAY_REF:
printArrayRef(n);
break;
case T::STRUCT_REF:
printStructRef(n);
break;
case T::INIT_EXPR:
// 把初始化表达式里的真实表达式解包再打印
if (!n->kids.empty() && n->kids[0])
printExpr(n->kids[0]);
break;
default:
out<<"/*unhandled:"<<(int)n->tag<<"*/";
}
}
void PrettyPrinter::printUnary(ASTNode* n, const char* op, bool prefix){
if (prefix) out<<op;
printExpr(n->kids[0]);
if (!prefix) out<<op;
}
void PrettyPrinter::printFuncCall(ASTNode* n){
printExpr(n->kids[0]);
out<<"(";
if (n->kids.size()>1) printExpr(n->kids[1]);
out<<")";
}
void PrettyPrinter::printArrayRef(ASTNode* n){
printExpr(n->kids[0]);
out<<"[";
printExpr(n->kids[1]);
out<<"]";
}
void PrettyPrinter::printStructRef(ASTNode* n){
printExpr(n->kids[0]);
out<<(n->flag? "->" : ".");
out<<n->text;
}
void PrettyPrinter::printInitDeclList(ASTNode* n) {
if (!n) return;
bool first = true;
for (ASTNode* initDecl : n->kids) {
if (!initDecl) continue;
if (!first) out << ", ";
first = false;
// declarator
ASTNode* dtor = initDecl->kids[0];
printDeclarator(dtor);
// // initializer?
// if (initDecl->kids.size() > 1 && initDecl->kids[1]) {
// out << " = ";
// printExpr(initDecl->kids[1]);
// }
// initializer?
if (initDecl->kids.size() > 1 && initDecl->kids[1]) {
out << " = ";
ASTNode* initNode = initDecl->kids[1];
// 如果是 INIT_EXPR解包再打印
if (initNode->tag == ASTTag::INIT_EXPR
&& !initNode->kids.empty()
&& initNode->kids[0])
initNode = initNode->kids[0];
printExpr(initNode);
}
}
}