diff --git a/src/ASTPrinter.cpp b/src/ASTPrinter.cpp deleted file mode 100644 index 47e9f92..0000000 --- a/src/ASTPrinter.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -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; -} diff --git a/src/ASTPrinter.h b/src/ASTPrinter.h index ed68869..1294c46 100644 --- a/src/ASTPrinter.h +++ b/src/ASTPrinter.h @@ -1,12 +1,181 @@ #pragma once -#include "SysYBaseVisitor.h" +#include "SysYBaseListener.h" +#include + +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; -}; \ No newline at end of file + 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 {} +}; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 68f8942..d0bc1c6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,6 +5,7 @@ antlr_target(SysYGen SysY.g4 LEXER PARSER OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} VISITOR + LISTENER ) add_library(SysYParser SHARED ${ANTLR_SysYGen_CXX_OUTPUTS}) @@ -13,7 +14,7 @@ target_link_libraries(SysYParser PUBLIC antlr4_shared) add_executable(sysyc sysyc.cpp - ASTPrinter.cpp + SysYFormatter.cpp ) target_include_directories(sysyc PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_link_libraries(sysyc PRIVATE SysYParser) diff --git a/src/SysY.g4 b/src/SysY.g4 index 0f7790a..b6b4232 100644 --- a/src/SysY.g4 +++ b/src/SysY.g4 @@ -4,33 +4,165 @@ grammar SysY; /* Lexer rules */ /*===-------------------------------------------===*/ -Comma: ','; +// fragments -fragment Decimal: [0-9]; -fragment Octal: [0-7]; -fragment Heximal: [0-9a-fA-F]; -fragment NonZeroDecimal: [1-9]; +// keywords +CONST: 'const'; +INT: 'int'; +FLOAT: 'float'; +VOID: 'void'; +IF: 'if'; +ELSE: 'else'; +WHILE: 'while'; +BREAK: 'break'; +CONTINUE: 'continue'; +RETURN: 'return'; -IntConst: NonZeroDecimal Decimal* - | '0' Octal+ - | ('0x' | '0X') Heximal+; +// operators +ASSIGN: '='; +ADD: '+'; +SUB: '-'; +MUL: '*'; +DIV: '/'; +MODULO: '%'; +LT: '<'; +GT: '>'; +LE: '<='; +GE: '>='; +EQ: '=='; +NE: '!='; +AND: '&&'; +OR: '||'; +NOT: '!'; -String: '"' (ESC | .)*? '"'; +// punctuations +LPAREN: '('; +RPAREN: ')'; +LBRACKET: '['; +RBRACKET: ']'; +LBRACE: '{'; +RBRACE: '}'; +COMMA: ','; +SEMICOLON: ';'; +// identifier +fragment ALPHA: [a-zA-Z]; +fragment ALPHANUM: [a-zA-Z0-9]; +fragment NONDIGIT: [a-zA-Z_]; +ID: NONDIGIT (ALPHANUM | '_')*; + +// literals +fragment DecDigit: [0-9]; +fragment OctDigit: [0-7]; +fragment HexDigit: [0-9a-fA-F]; +fragment OctPrefix: '0'; +fragment HexPrefix: '0' [xX]; +fragment NonZeroDecDigit: [1-9]; +fragment Sign: [+-]; +fragment DecFractional: DecDigit* '.' DecDigit+ | DecDigit+ '.'; +fragment Exponent: [eE] Sign? DecDigit+; +fragment DecFloat: DecFractional Exponent? | DecDigit+ Exponent; +fragment HexFractional: HexDigit* '.' HexDigit+ | HexDigit+ '.'; +fragment BinExponent: [pP] Sign? DecDigit+; +fragment HexFloat: + HexPrefix HexFractional BinExponent + | HexDigit+ BinExponent; + +ILITERAL: + NonZeroDecDigit DecDigit* + | OctPrefix OctDigit* + | HexPrefix HexDigit+; + +FLITERAL: DecFloat | HexFloat; + +// string fragment ESC: '\\"' | '\\\\'; +STRING: '"' (ESC | .)*? '"'; +// white space and comments WS: [ \t\r\n] -> skip; - -LINE_COMMENT: '//' .*? '\r'? '\n' -> skip; -COMMENT: '/*' .*? '*/' -> skip; +LINECOMMENT: '//' .*? '\r'? '\n' -> skip; +BLOCKCOMMENT: '/*' .*? '*/' -> skip; /*===-------------------------------------------===*/ /* Syntax rules */ /*===-------------------------------------------===*/ -funcRParams: funcRParam (Comma funcRParam)* EOF; +module: (decl | func)+; + +// constDecl and varDecl shares the same syntax structure, except that constDecl must have constant +// initial values. We combine these two syntax rules, and ensure the constraint above at the +// semantic check phase. +decl: CONST? btype varDef (COMMA varDef)* SEMICOLON; + +btype: INT | FLOAT; + +varDef: lValue (ASSIGN initValue)?; + +initValue: + exp # scalarInitValue + | LBRACE (initValue (COMMA initValue)*)? # arrayInitValue; + +func: funcType ID LPAREN funcFParams? RPAREN blockStmt; + +funcType: VOID | INT | FLOAT; + +funcFParams: funcFParam (COMMA funcFParam)*; + +funcFParam: + btype ID (LBRACKET RBRACKET (LBRACKET exp RBRACKET)*)?; + +blockStmt: LBRACE blockItem* RBRACE; + +blockItem: decl | stmt; + +stmt: + assignStmt + | expStmt + | ifStmt + | whileStmt + | breakStmt + | continueStmt + | returnStmt + | blockStmt + | emptyStmt; + +assignStmt: lValue ASSIGN exp SEMICOLON; + +expStmt: exp SEMICOLON; + +ifStmt: IF LPAREN exp RPAREN stmt (ELSE stmt)?; + +whileStmt: WHILE LPAREN exp RPAREN stmt; + +breakStmt: BREAK SEMICOLON; + +continueStmt: CONTINUE SEMICOLON; + +returnStmt: RETURN exp? SEMICOLON; + +emptyStmt: SEMICOLON; + +exp: + LPAREN exp RPAREN # parenExp + | lValue # lValueExp + | number # numberExp + | string # stringExp + | call # callExp + | (ADD | SUB | NOT) exp # unaryExp + | exp (MUL | DIV | MODULO) exp # multiplicativeExp + | exp (ADD | SUB) exp # additiveExp + | exp (LT | GT | LE | GE) exp # relationExp + | exp (EQ | NE) exp # equalExp + | exp AND exp # andExp + | exp OR exp # orExp; + +call: ID LPAREN funcRParams? RPAREN; + +lValue: ID (LBRACKET exp RBRACKET)*; + +number: ILITERAL | FLITERAL; -funcRParam: number # expAsRParam | string # stringAsRParam; +string: STRING; -number: IntConst; -string: String; +funcRParams: exp (COMMA exp)*; diff --git a/src/SysYFormatter.cpp b/src/SysYFormatter.cpp new file mode 100644 index 0000000..145b4e8 --- /dev/null +++ b/src/SysYFormatter.cpp @@ -0,0 +1,28 @@ +#include +#include +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; +// } diff --git a/src/SysYFormatter.h b/src/SysYFormatter.h new file mode 100644 index 0000000..ac6192b --- /dev/null +++ b/src/SysYFormatter.h @@ -0,0 +1,334 @@ +#pragma once + +#include "SysYBaseVisitor.h" +#include "SysYParser.h" +#include + +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 + 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; + } +}; \ No newline at end of file diff --git a/src/sysyc.cpp b/src/sysyc.cpp index 3835829..4c2d1f3 100644 --- a/src/sysyc.cpp +++ b/src/sysyc.cpp @@ -1,12 +1,13 @@ #include "ASTPrinter.h" +#include "tree/ParseTreeWalker.h" #include #include #include using namespace std; using namespace antlr4; +#include "SysYFormatter.h" #include "SysYLexer.h" #include "SysYParser.h" -#include "ASTPrinter.h" int main(int argc, char **argv) { if (argc != 2) { @@ -22,10 +23,13 @@ int main(int argc, char **argv) { SysYLexer lexer(&input); CommonTokenStream tokens(&lexer); SysYParser parser(&tokens); - SysYParser::FuncRParamsContext *params = parser.funcRParams(); - - ASTPrinter printer; - printer.visitFuncRParams(params); + auto module = parser.module(); + // tree::ParseTreeWalker walker; + // SysYASTPrinter printer(cout); + // cout << module->getText() << '\n'; + // walker.walk(&printer, module); + SysYFormatter formatter(cout); + formatter.visitModule(module); return EXIT_SUCCESS; } \ No newline at end of file