forked from ph7n2ofui/SysyCompiler_Arm
parent
ed701d9e4d
commit
5a82467d04
@ -1,28 +0,0 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include "ASTPrinter.h"
|
||||
#include "SysYParser.h"
|
||||
|
||||
any ASTPrinter::visitNumber(SysYParser::NumberContext *ctx) {
|
||||
cout << ctx->IntConst()->getText();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
any ASTPrinter::visitString(SysYParser::StringContext *ctx) {
|
||||
cout << ctx->String()->getText();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
any ASTPrinter::visitFuncRParams(SysYParser::FuncRParamsContext *ctx) {
|
||||
if (ctx->funcRParam().empty())
|
||||
return nullptr;
|
||||
auto numParams = ctx->funcRParam().size();
|
||||
ctx->funcRParam(0)->accept(this);
|
||||
for (int i = 1; i < numParams; ++i) {
|
||||
cout << ", ";
|
||||
ctx->funcRParam(i)->accept(this);
|
||||
}
|
||||
cout << '\n';
|
||||
return nullptr;
|
||||
}
|
||||
@ -1,12 +1,181 @@
|
||||
#pragma once
|
||||
|
||||
#include "SysYBaseVisitor.h"
|
||||
#include "SysYBaseListener.h"
|
||||
#include <ostream>
|
||||
|
||||
class SysYASTPrinter : public SysYBaseListener {
|
||||
std::ostream &os;
|
||||
int indent;
|
||||
|
||||
class ASTPrinter : public SysYBaseVisitor {
|
||||
public:
|
||||
std::any visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override;
|
||||
// std::any visitExpAsRParam(SysYParser::ExpAsRParamContext *ctx) override;
|
||||
// std::any visitStringAsRParam(SysYParser::StringAsRParamContext *ctx) override;
|
||||
std::any visitNumber(SysYParser::NumberContext *ctx) override;
|
||||
std::any visitString(SysYParser::StringContext *ctx) override;
|
||||
};
|
||||
SysYASTPrinter(std::ostream &os = std::cout) : os(os), indent(0) {}
|
||||
|
||||
protected:
|
||||
void enter(const std::string &name) {
|
||||
os << std::string(indent, ' ') << name << '\n';
|
||||
indent += 2;
|
||||
}
|
||||
void exit() { indent -= 2; }
|
||||
|
||||
public:
|
||||
virtual void enterModule(SysYParser::ModuleContext * /*ctx*/) override {
|
||||
enter("module");
|
||||
}
|
||||
|
||||
virtual void enterDecl(SysYParser::DeclContext * /*ctx*/) override {
|
||||
enter("decl");
|
||||
}
|
||||
|
||||
virtual void enterBtype(SysYParser::BtypeContext * /*ctx*/) override {
|
||||
enter("btype");
|
||||
}
|
||||
|
||||
// virtual void
|
||||
// enterConstValue(SysYParser::ConstValueContext * /*ctx*/) override {
|
||||
// enter("constValue");
|
||||
// }
|
||||
|
||||
virtual void enterVarDef(SysYParser::VarDefContext *ctx) override {
|
||||
enter("varDef");
|
||||
}
|
||||
|
||||
virtual void enterFunc(SysYParser::FuncContext * /*ctx*/) override {
|
||||
enter("func");
|
||||
}
|
||||
|
||||
virtual void enterFuncType(SysYParser::FuncTypeContext * /*ctx*/) override {
|
||||
enter("funcType");
|
||||
}
|
||||
|
||||
virtual void
|
||||
enterFuncFParams(SysYParser::FuncFParamsContext * /*ctx*/) override {
|
||||
enter("funcFParams");
|
||||
}
|
||||
|
||||
virtual void
|
||||
enterFuncFParam(SysYParser::FuncFParamContext * /*ctx*/) override {
|
||||
enter("funcFParam");
|
||||
}
|
||||
|
||||
virtual void enterBlockStmt(SysYParser::BlockStmtContext * /*ctx*/) override {
|
||||
enter("blockStmt");
|
||||
}
|
||||
|
||||
virtual void enterBlockItem(SysYParser::BlockItemContext * /*ctx*/) override {
|
||||
enter("blockIterm");
|
||||
}
|
||||
|
||||
virtual void enterStmt(SysYParser::StmtContext * /*ctx*/) override {
|
||||
enter("stmt");
|
||||
}
|
||||
|
||||
virtual void
|
||||
enterAssignStmt(SysYParser::AssignStmtContext * /*ctx*/) override {
|
||||
enter("assignStmt");
|
||||
}
|
||||
|
||||
virtual void enterExpStmt(SysYParser::ExpStmtContext * /*ctx*/) override {
|
||||
enter("expStmt");
|
||||
}
|
||||
|
||||
virtual void enterIfStmt(SysYParser::IfStmtContext *ctx) override {
|
||||
enter("ifStmt " + ctx->getText());
|
||||
}
|
||||
|
||||
virtual void enterWhileStmt(SysYParser::WhileStmtContext * /*ctx*/) override {
|
||||
enter("whileStmt");
|
||||
}
|
||||
|
||||
virtual void enterBreakStmt(SysYParser::BreakStmtContext * /*ctx*/) override {
|
||||
enter("break");
|
||||
}
|
||||
|
||||
virtual void
|
||||
enterContinueStmt(SysYParser::ContinueStmtContext * /*ctx*/) override {
|
||||
enter("continueStmt");
|
||||
}
|
||||
|
||||
virtual void
|
||||
enterReturnStmt(SysYParser::ReturnStmtContext * /*ctx*/) override {
|
||||
enter("returnStmt");
|
||||
}
|
||||
|
||||
virtual void enterEmptyStmt(SysYParser::EmptyStmtContext * /*ctx*/) override {
|
||||
enter("emptyStmt");
|
||||
}
|
||||
|
||||
virtual void enterRelationExp(SysYParser::RelationExpContext *ctx) override {
|
||||
enter(std::string("relationExp: ") + ctx->getText());
|
||||
}
|
||||
|
||||
virtual void
|
||||
enterMultiplicativeExp(SysYParser::MultiplicativeExpContext *ctx) override {
|
||||
enter(std::string("multiplicativeExp: ") + ctx->getText());
|
||||
}
|
||||
|
||||
virtual void enterCallExp(SysYParser::CallExpContext * ctx) override {
|
||||
enter("callExp " + ctx->getText());
|
||||
}
|
||||
virtual void enterLValueExp(SysYParser::LValueExpContext * /*ctx*/) override {
|
||||
enter("lValueExp");
|
||||
}
|
||||
|
||||
virtual void enterNumberExp(SysYParser::NumberExpContext * /*ctx*/) override {
|
||||
enter("numberExp");
|
||||
}
|
||||
|
||||
virtual void enterAndExp(SysYParser::AndExpContext * /*ctx*/) override {
|
||||
enter("andExp");
|
||||
}
|
||||
|
||||
virtual void enterUnaryExp(SysYParser::UnaryExpContext *ctx) override {
|
||||
enter(std::string("multiplicativeExp: ") + ctx->getText());
|
||||
}
|
||||
|
||||
virtual void enterParenExp(SysYParser::ParenExpContext * /*ctx*/) override {
|
||||
enter("parenExp");
|
||||
}
|
||||
|
||||
virtual void enterStringExp(SysYParser::StringExpContext * /*ctx*/) override {
|
||||
enter("stringExp");
|
||||
}
|
||||
|
||||
virtual void enterOrExp(SysYParser::OrExpContext * /*ctx*/) override {
|
||||
enter("orExp");
|
||||
}
|
||||
|
||||
virtual void enterAdditiveExp(SysYParser::AdditiveExpContext *ctx) override {
|
||||
enter(std::string("additiveExp: ") + ctx->getText());
|
||||
}
|
||||
|
||||
virtual void enterEqualExp(SysYParser::EqualExpContext *ctx) override {
|
||||
enter(std::string("equalExp: ") + ctx->getText());
|
||||
}
|
||||
|
||||
virtual void enterLValue(SysYParser::LValueContext * /*ctx*/) override {
|
||||
enter("lValue");
|
||||
}
|
||||
|
||||
virtual void enterNumber(SysYParser::NumberContext * /*ctx*/) override {
|
||||
enter("number");
|
||||
}
|
||||
|
||||
virtual void enterString(SysYParser::StringContext * /*ctx*/) override {
|
||||
enter("string");
|
||||
}
|
||||
|
||||
virtual void
|
||||
enterFuncRParams(SysYParser::FuncRParamsContext * /*ctx*/) override {
|
||||
enter("funcRparams");
|
||||
}
|
||||
|
||||
virtual void enterEveryRule(antlr4::ParserRuleContext *ctx) override {
|
||||
// os << ctx->getText();
|
||||
// enter("");
|
||||
}
|
||||
virtual void exitEveryRule(antlr4::ParserRuleContext * /*ctx*/) override {
|
||||
exit();
|
||||
}
|
||||
virtual void visitTerminal(antlr4::tree::TerminalNode * /*node*/) override {}
|
||||
virtual void visitErrorNode(antlr4::tree::ErrorNode * /*node*/) override {}
|
||||
};
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#include "SysYParser.h"
|
||||
#include "SysYFormatter.h"
|
||||
|
||||
// any ASTPrinter::visitNumber(SysYParser::NumberContext *ctx) {
|
||||
// cout << ctx->IntConst()->getText();
|
||||
// return nullptr;
|
||||
// }
|
||||
|
||||
// any ASTPrinter::visitString(SysYParser::StringContext *ctx) {
|
||||
// cout << ctx->String()->getText();
|
||||
// return nullptr;
|
||||
// }
|
||||
|
||||
// any ASTPrinter::visitFuncRParams(SysYParser::FuncRParamsContext *ctx) {
|
||||
// if (ctx->funcRParam().empty())
|
||||
// return nullptr;
|
||||
// auto numParams = ctx->funcRParam().size();
|
||||
// ctx->funcRParam(0)->accept(this);
|
||||
// for (int i = 1; i < numParams; ++i) {
|
||||
// cout << ", ";
|
||||
// ctx->funcRParam(i)->accept(this);
|
||||
// }
|
||||
// cout << '\n';
|
||||
// return nullptr;
|
||||
// }
|
||||
@ -0,0 +1,334 @@
|
||||
#pragma once
|
||||
|
||||
#include "SysYBaseVisitor.h"
|
||||
#include "SysYParser.h"
|
||||
#include <ostream>
|
||||
|
||||
class SysYFormatter : public SysYBaseVisitor {
|
||||
protected:
|
||||
std::ostream &os;
|
||||
int indent = 0;
|
||||
|
||||
public:
|
||||
SysYFormatter(std::ostream &os) : os(os), indent(0) {}
|
||||
|
||||
protected:
|
||||
struct Indentor {
|
||||
static constexpr int TabSize = 2;
|
||||
int &indent;
|
||||
Indentor(int &indent) : indent(indent) { indent += TabSize; }
|
||||
~Indentor() { indent -= TabSize; }
|
||||
};
|
||||
std::ostream &space() { return os << std::string(indent, ' '); }
|
||||
template <typename T>
|
||||
std::ostream &interleave(const T &container, const std::string sep = ", ") {
|
||||
auto b = container.begin(), e = container.end();
|
||||
(*b)->accept(this);
|
||||
for (b = std::next(b); b != e; b = std::next(b)) {
|
||||
os << sep;
|
||||
(*b)->accept(this);
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
public:
|
||||
// virtual std::any visitModule(SysYParser::ModuleContext *ctx) override {
|
||||
// return visitChildren(ctx);
|
||||
// }
|
||||
|
||||
virtual std::any visitBtype(SysYParser::BtypeContext *ctx) override {
|
||||
os << ctx->getText();
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any visitDecl(SysYParser::DeclContext *ctx) override {
|
||||
space();
|
||||
if (ctx->CONST())
|
||||
os << ctx->CONST()->getText() << ' ';
|
||||
ctx->btype()->accept(this);
|
||||
os << ' ';
|
||||
interleave(ctx->varDef(), ", ") << ';' << '\n';
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any visitVarDef(SysYParser::VarDefContext *ctx) override {
|
||||
ctx->lValue()->accept(this);
|
||||
if (ctx->initValue()) {
|
||||
os << ' ' << '=' << ' ';
|
||||
ctx->initValue()->accept(this);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any
|
||||
visitArrayInitValue(SysYParser::ArrayInitValueContext *ctx) override {
|
||||
os << '{';
|
||||
auto values = ctx->initValue();
|
||||
if (values.size())
|
||||
interleave(values, ", ");
|
||||
os << '}';
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any visitFunc(SysYParser::FuncContext *ctx) override {
|
||||
ctx->funcType()->accept(this);
|
||||
os << ' ' << ctx->ID()->getText() << '(';
|
||||
if (ctx->funcFParams())
|
||||
ctx->funcFParams()->accept(this);
|
||||
os << ')' << ' ';
|
||||
ctx->blockStmt()->accept(this);
|
||||
os << '\n';
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any visitFuncType(SysYParser::FuncTypeContext *ctx) override {
|
||||
os << ctx->getText();
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any
|
||||
visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override {
|
||||
interleave(ctx->funcFParam(), ", ");
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any
|
||||
visitFuncFParam(SysYParser::FuncFParamContext *ctx) override {
|
||||
ctx->btype()->accept(this);
|
||||
os << ' ' << ctx->ID()->getText();
|
||||
if (not ctx->LBRACKET().empty()) {
|
||||
os << '[';
|
||||
auto exp = ctx->exp();
|
||||
if (not exp.empty()) {
|
||||
os << '[';
|
||||
interleave(exp, "][") << ']';
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any visitBlockStmt(SysYParser::BlockStmtContext *ctx) override {
|
||||
os << '{' << '\n';
|
||||
{
|
||||
Indentor indentor(indent);
|
||||
auto items = ctx->blockItem();
|
||||
if (not items.empty())
|
||||
interleave(items, "");
|
||||
}
|
||||
space() << ctx->RBRACE()->getText() << '\n';
|
||||
return 0;
|
||||
}
|
||||
|
||||
// virtual std::any visitBlockItem(SysYParser::BlockItemContext *ctx)
|
||||
// override {
|
||||
// return visitChildren(ctx);
|
||||
// }
|
||||
|
||||
// virtual std::any visitStmt(SysYParser::StmtContext *ctx) override {
|
||||
// return visitChildren(ctx);
|
||||
// }
|
||||
|
||||
virtual std::any
|
||||
visitAssignStmt(SysYParser::AssignStmtContext *ctx) override {
|
||||
space();
|
||||
ctx->lValue()->accept(this);
|
||||
os << " = ";
|
||||
ctx->exp()->accept(this);
|
||||
os << ';' << '\n';
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any visitExpStmt(SysYParser::ExpStmtContext *ctx) override {
|
||||
space();
|
||||
ctx->exp()->accept(this);
|
||||
os << ';' << '\n';
|
||||
return 0;
|
||||
}
|
||||
|
||||
void wrapBlock(SysYParser::StmtContext *stmt) {
|
||||
bool isBlock = stmt->blockStmt();
|
||||
if (isBlock) {
|
||||
stmt->accept(this);
|
||||
} else {
|
||||
os << "{\n";
|
||||
{
|
||||
Indentor indentor(indent);
|
||||
stmt->accept(this);
|
||||
}
|
||||
space() << "}\n";
|
||||
}
|
||||
};
|
||||
virtual std::any visitIfStmt(SysYParser::IfStmtContext *ctx) override {
|
||||
space();
|
||||
os << ctx->IF()->getText() << " (";
|
||||
ctx->exp()->accept(this);
|
||||
os << ") ";
|
||||
auto stmt = ctx->stmt();
|
||||
auto ifStmt = stmt[0];
|
||||
wrapBlock(ifStmt);
|
||||
if (stmt.size() == 2) {
|
||||
auto elseStmt = stmt[1];
|
||||
wrapBlock(elseStmt);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override {
|
||||
space();
|
||||
os << ctx->WHILE()->getText() << " (";
|
||||
ctx->exp()->accept(this);
|
||||
os << ") ";
|
||||
wrapBlock(ctx->stmt());
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override {
|
||||
space() << ctx->BREAK()->getText() << ';' << '\n';
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any
|
||||
visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override {
|
||||
space() << ctx->CONTINUE()->getText() << ';'
|
||||
<< '\n';
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any
|
||||
visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override {
|
||||
space() << ctx->RETURN()->getText();
|
||||
if (ctx->exp()) {
|
||||
os << ' ';
|
||||
ctx->exp()->accept(this);
|
||||
}
|
||||
os << ';' << '\n';
|
||||
return 0;
|
||||
}
|
||||
|
||||
// virtual std::any visitEmptyStmt(SysYParser::EmptyStmtContext *ctx)
|
||||
// override {
|
||||
// return visitChildren(ctx);
|
||||
// }
|
||||
|
||||
virtual std::any
|
||||
visitRelationExp(SysYParser::RelationExpContext *ctx) override {
|
||||
auto lhs = ctx->exp(0);
|
||||
auto rhs = ctx->exp(1);
|
||||
std::string op =
|
||||
ctx->LT() ? "<" : (ctx->LE() ? "<=" : (ctx->GT() ? ">" : ">="));
|
||||
lhs->accept(this);
|
||||
os << ' ' << op << ' ';
|
||||
rhs->accept(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any
|
||||
visitMultiplicativeExp(SysYParser::MultiplicativeExpContext *ctx) override {
|
||||
auto lhs = ctx->exp(0);
|
||||
auto rhs = ctx->exp(1);
|
||||
std::string op = ctx->MUL() ? "*" : (ctx->DIV() ? "/" : "%");
|
||||
lhs->accept(this);
|
||||
os << ' ' << op << ' ';
|
||||
rhs->accept(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// virtual std::any visitLValueExp(SysYParser::LValueExpContext *ctx) override {
|
||||
// return visitChildren(ctx);
|
||||
// }
|
||||
|
||||
// virtual std::any visitNumberExp(SysYParser::NumberExpContext *ctx) override {
|
||||
// return visitChildren(ctx);
|
||||
// }
|
||||
|
||||
virtual std::any visitAndExp(SysYParser::AndExpContext *ctx) override {
|
||||
ctx->exp(0)->accept(this);
|
||||
os << " && ";
|
||||
ctx->exp(1)->accept(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override {
|
||||
std::string op = ctx->ADD() ? "+" : (ctx->SUB() ? "-" : "!");
|
||||
os << op;
|
||||
ctx->exp()->accept(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any visitParenExp(SysYParser::ParenExpContext *ctx) override {
|
||||
os << '(';
|
||||
ctx->exp()->accept(this);
|
||||
os << ')';
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any visitStringExp(SysYParser::StringExpContext *ctx) override {
|
||||
return visitChildren(ctx);
|
||||
}
|
||||
|
||||
virtual std::any visitOrExp(SysYParser::OrExpContext *ctx) override {
|
||||
ctx->exp(0)->accept(this);
|
||||
os << " || ";
|
||||
ctx->exp(1)->accept(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// virtual std::any visitCallExp(SysYParser::CallExpContext *ctx) override {
|
||||
// return visitChildren(ctx);
|
||||
// }
|
||||
|
||||
virtual std::any
|
||||
visitAdditiveExp(SysYParser::AdditiveExpContext *ctx) override {
|
||||
auto lhs = ctx->exp(0);
|
||||
auto rhs = ctx->exp(1);
|
||||
std::string op = ctx->ADD() ? "+" : "-";
|
||||
lhs->accept(this);
|
||||
os << ' ' << op << ' ';
|
||||
rhs->accept(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any visitEqualExp(SysYParser::EqualExpContext *ctx) override {
|
||||
auto lhs = ctx->exp(0);
|
||||
auto rhs = ctx->exp(1);
|
||||
std::string op = ctx->EQ() ? "==" : "!=";
|
||||
lhs->accept(this);
|
||||
os << ' ' << op << ' ';
|
||||
rhs->accept(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any visitCall(SysYParser::CallContext *ctx) override {
|
||||
os << ctx->ID()->getText() << '(';
|
||||
if (ctx->funcRParams())
|
||||
ctx->funcRParams()->accept(this);
|
||||
os << ')';
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any visitLValue(SysYParser::LValueContext *ctx) override {
|
||||
os << ctx->ID()->getText();
|
||||
auto exp = ctx->exp();
|
||||
if (not exp.empty()) {
|
||||
os << '[';
|
||||
interleave(exp, "][") << ']';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any visitNumber(SysYParser::NumberContext *ctx) override {
|
||||
os << ctx->getText();
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any visitString(SysYParser::StringContext *ctx) override {
|
||||
os << ctx->getText();
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual std::any
|
||||
visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override {
|
||||
interleave(ctx->exp(), ", ");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
Loading…
Reference in new issue