@@ -1,149 +1,205 @@
|
|||||||
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
#include "ASTPrinter.h"
|
#include "ASTPrinter.h"
|
||||||
#include "SysYParser.h"
|
#include "SysYParser.h"
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
std::any ASTPrinter::visitNumber(SysYParser::NumberContext *ctx) {
|
any ASTPrinter::visitCompUnit(SysYParser::CompUnitContext *ctx) {
|
||||||
cout << ctx->ILITERAL()->getText();
|
if(ctx->decl().empty() && ctx->funcDef().empty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
for (auto dcl : ctx->decl()) {dcl->accept(this);cout << '\n';}cout << '\n';
|
||||||
|
for (auto func : ctx->funcDef()) {func->accept(this);cout << "\n";}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::any ASTPrinter::visitString(SysYParser::StringContext *ctx) {
|
// std::any ASTPrinter::visitBType(SysYParser::BTypeContext *ctx);
|
||||||
cout << ctx->STRING()->getText();
|
// std::any ASTPrinter::visitDecl(SysYParser::DeclContext *ctx);
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::any ASTPrinter::visitModule(SysYParser::ModuleContext *ctx) {
|
|
||||||
for (auto dcl : ctx->dcl()) dcl->accept(this);
|
|
||||||
for (auto func : ctx->funcDef()) func->accept(this);
|
|
||||||
if (ctx->funcRParams()) ctx->funcRParams()->accept(this);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::any ASTPrinter::visitFuncRParams(SysYParser::FuncRParamsContext *ctx) {
|
|
||||||
bool first = true;
|
|
||||||
for (auto param : ctx->funcRParam()) {
|
|
||||||
if (!first) cout << ", ";
|
|
||||||
param->accept(this);
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::any ASTPrinter::visitExpAsRParam(SysYParser::ExpAsRParamContext *ctx) {
|
|
||||||
ctx->number()->accept(this);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::any ASTPrinter::visitStringAsRParam(SysYParser::StringAsRParamContext *ctx) {
|
|
||||||
ctx->string()->accept(this);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::any ASTPrinter::visitExpsAsRParam(SysYParser::ExpsAsRParamContext *ctx) {
|
|
||||||
bool first = true;
|
|
||||||
for (auto exp : ctx->exp()) {
|
|
||||||
if (!first) cout << ", ";
|
|
||||||
exp->accept(this);
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::any ASTPrinter::visitConstDecl(SysYParser::ConstDeclContext *ctx) {
|
std::any ASTPrinter::visitConstDecl(SysYParser::ConstDeclContext *ctx) {
|
||||||
cout << getIndent() << "const " << ctx->bType()->getText() << " ";
|
cout << getIndent() << ctx->CONST()->getText() << ' ' << ctx->bType()->getText() << ' ';
|
||||||
bool first = true;
|
auto numConstDefs = ctx->constDef().size();
|
||||||
for (auto def : ctx->constDef()) {
|
ctx->constDef(0)->accept(this);
|
||||||
if (!first) cout << ", ";
|
for (int i = 1; i < numConstDefs; ++i) {
|
||||||
def->accept(this);
|
cout << ctx->COMMA(i - 1)->getText() << ' ';
|
||||||
first = false;
|
ctx->constDef(i)->accept(this);
|
||||||
}
|
}
|
||||||
cout << ";" << endl;
|
cout << ctx->SEMICOLON()->getText() << '\n';
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
std::any ASTPrinter::visitVarDecl(SysYParser::VarDeclContext *ctx) {
|
|
||||||
cout << getIndent() << ctx->bType()->getText() << " ";
|
|
||||||
bool first = true;
|
|
||||||
for (auto def : ctx->varDef()) {
|
|
||||||
if (!first) cout << ", ";
|
|
||||||
def->accept(this);
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
cout << ";" << endl;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::any ASTPrinter::visitVarDef(SysYParser::VarDefContext *ctx) {
|
|
||||||
cout << ctx->IDENT()->getText();
|
|
||||||
for (auto exp : ctx->constExp()) {
|
|
||||||
cout << "[";
|
|
||||||
exp->accept(this);
|
|
||||||
cout << "]";
|
|
||||||
}
|
|
||||||
if (ctx->initVal()) {
|
|
||||||
cout << " = ";
|
|
||||||
ctx->initVal()->accept(this);
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::any ASTPrinter::visitConstDef(SysYParser::ConstDefContext *ctx) {
|
std::any ASTPrinter::visitConstDef(SysYParser::ConstDefContext *ctx) {
|
||||||
cout << ctx->IDENT()->getText();
|
cout << ctx->Ident()->getText();
|
||||||
for (auto exp : ctx->constExp()) {
|
auto numConstExps = ctx->constExp().size();
|
||||||
cout << "[";
|
for (int i = 0; i < numConstExps; ++i) {
|
||||||
exp->accept(this);
|
cout << ctx->LBRACK(i)->getText();
|
||||||
cout << "]";
|
ctx->constExp(i)->accept(this);
|
||||||
|
cout << ctx->RBRACK(i)->getText();
|
||||||
|
}
|
||||||
|
cout << ' ' << ctx->ASSIGN()->getText() << ' ';
|
||||||
|
ctx->constInitVal()->accept(this);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// std::any ASTPrinter::visitConstInitVal(SysYParser::ConstInitValContext *ctx);
|
||||||
|
|
||||||
|
std::any ASTPrinter::visitVarDecl(SysYParser::VarDeclContext *ctx){
|
||||||
|
cout << getIndent() << ctx->bType()->getText() << ' ';
|
||||||
|
auto numVarDefs = ctx->varDef().size();
|
||||||
|
ctx->varDef(0)->accept(this);
|
||||||
|
for (int i = 1; i < numVarDefs; ++i) {
|
||||||
|
cout << ", ";
|
||||||
|
ctx->varDef(i)->accept(this);
|
||||||
|
}
|
||||||
|
cout << ctx->SEMICOLON()->getText() << '\n';
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::any ASTPrinter::visitVarDef(SysYParser::VarDefContext *ctx){
|
||||||
|
cout << ctx->Ident()->getText();
|
||||||
|
auto numConstExps = ctx->constExp().size();
|
||||||
|
for (int i = 0; i < numConstExps; ++i) {
|
||||||
|
cout << ctx->LBRACK(i)->getText();
|
||||||
|
ctx->constExp(i)->accept(this);
|
||||||
|
cout << ctx->RBRACK(i)->getText();
|
||||||
|
}
|
||||||
|
if (ctx->initVal()) {
|
||||||
|
cout << ' ' << ctx->ASSIGN()->getText() << ' ';
|
||||||
|
ctx->initVal()->accept(this);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::any ASTPrinter::visitInitVal(SysYParser::InitValContext *ctx){
|
||||||
|
if (ctx->exp()) {
|
||||||
|
ctx->exp()->accept(this);
|
||||||
|
} else {
|
||||||
|
cout << ctx->LBRACE()->getText();
|
||||||
|
auto numInitVals = ctx->initVal().size();
|
||||||
|
ctx->initVal(0)->accept(this);
|
||||||
|
for (int i = 1; i < numInitVals; ++i) {
|
||||||
|
cout << ctx->COMMA(i - 1)->getText() << ' ';
|
||||||
|
ctx->initVal(i)->accept(this);
|
||||||
}
|
}
|
||||||
cout << " = ";
|
cout << ctx->RBRACE()->getText();
|
||||||
ctx->constInitVal()->accept(this);
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::any ASTPrinter::visitFuncDef(SysYParser::FuncDefContext *ctx) {
|
std::any ASTPrinter::visitFuncDef(SysYParser::FuncDefContext *ctx){
|
||||||
cout << getIndent() << ctx->funcType()->getText() << " " << ctx->IDENT()->getText() << "(";
|
cout << getIndent() << ctx->funcType()->getText() << ' ' << ctx->Ident()->getText();
|
||||||
if (ctx->funcFParams()) ctx->funcFParams()->accept(this);
|
cout << ctx->LPAREN()->getText();
|
||||||
cout << ")" << endl;
|
if (ctx->funcFParams()) ctx->funcFParams()->accept(this);
|
||||||
ctx->block()->accept(this);
|
cout << ctx->RPAREN()->getText();
|
||||||
return nullptr;
|
ctx->blockStmt()->accept(this);
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::any ASTPrinter::visitFuncFParams(SysYParser::FuncFParamsContext *ctx) {
|
// std::any ASTPrinter::visitFuncType(SysYParser::FuncTypeContext *ctx);
|
||||||
bool first = true;
|
|
||||||
for (auto param : ctx->funcFParam()) {
|
std::any ASTPrinter::visitFuncFParams(SysYParser::FuncFParamsContext *ctx){
|
||||||
if (!first) cout << ", ";
|
auto numFuncFParams = ctx->funcFParam().size();
|
||||||
param->accept(this);
|
ctx->funcFParam(0)->accept(this);
|
||||||
first = false;
|
for (int i = 1; i < numFuncFParams; ++i) {
|
||||||
|
cout << ctx->COMMA(i - 1)->getText() << ' ';
|
||||||
|
ctx->funcFParam(i)->accept(this);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::any ASTPrinter::visitFuncFParam(SysYParser::FuncFParamContext *ctx){
|
||||||
|
cout << ctx->bType()->getText() << ' ' << ctx->Ident()->getText();
|
||||||
|
if (!ctx->exp().empty()) {
|
||||||
|
cout << "[]";
|
||||||
|
for (auto exp : ctx->exp()) {
|
||||||
|
cout << '[';
|
||||||
|
exp->accept(this);
|
||||||
|
cout << ']';
|
||||||
}
|
}
|
||||||
return nullptr;
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::any ASTPrinter::visitFuncFParam(SysYParser::FuncFParamContext *ctx) {
|
std::any ASTPrinter::visitBlockStmt(SysYParser::BlockStmtContext *ctx){
|
||||||
cout << ctx->bType()->getText() << " " << ctx->IDENT()->getText();
|
cout << ' ' << ctx->LBRACE()->getText() << endl;
|
||||||
if (!ctx->exp().empty()) {
|
indentLevel++;
|
||||||
cout << "[]";
|
for (auto item : ctx->blockItem()) item->accept(this);
|
||||||
for (auto exp : ctx->exp()) {
|
indentLevel--;
|
||||||
cout << "[";
|
cout << getIndent() << ctx->RBRACE()->getText() << endl;
|
||||||
exp->accept(this);
|
return nullptr;
|
||||||
cout << "]";
|
}
|
||||||
}
|
// std::any ASTPrinter::visitBlockItem(SysYParser::BlockItemContext *ctx);
|
||||||
|
|
||||||
|
std::any ASTPrinter::visitStmt(SysYParser::StmtContext *ctx){
|
||||||
|
if(ctx->lValue()&& ctx->exp()) {
|
||||||
|
cout << getIndent();
|
||||||
|
ctx->lValue()->accept(this);
|
||||||
|
cout << ' ' << ctx->ASSIGN()->getText() <<' ';
|
||||||
|
ctx->exp()->accept(this);
|
||||||
|
cout << ctx->SEMICOLON()->getText() << endl;
|
||||||
|
}
|
||||||
|
else if(ctx->blockStmt()){
|
||||||
|
ctx->blockStmt()->accept(this);
|
||||||
|
}
|
||||||
|
else if(ctx->IF()){
|
||||||
|
cout << getIndent() << "if (";
|
||||||
|
ctx->cond()->accept(this);
|
||||||
|
cout << ")";
|
||||||
|
// visit ctx->stmt(0) to judge if it is a blockStmt or a Lvale=exp
|
||||||
|
if(ctx->stmt(0)->blockStmt())ctx->stmt(0)->accept(this);
|
||||||
|
else{
|
||||||
|
cout << " {"<< endl;
|
||||||
|
indentLevel++;
|
||||||
|
ctx->stmt(0)->accept(this);
|
||||||
|
indentLevel--;
|
||||||
|
cout << getIndent() << "}" << endl;
|
||||||
}
|
}
|
||||||
return nullptr;
|
if (ctx->stmt().size() > 1) {
|
||||||
|
cout << getIndent() << "else" << endl;
|
||||||
|
if(ctx->stmt(1)->blockStmt())ctx->stmt(1)->accept(this);
|
||||||
|
else{
|
||||||
|
cout << " {"<< endl;
|
||||||
|
indentLevel++;
|
||||||
|
ctx->stmt(1)->accept(this);
|
||||||
|
indentLevel--;
|
||||||
|
cout << getIndent() << "}" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(ctx->WHILE()){
|
||||||
|
cout << getIndent() << "while (";
|
||||||
|
ctx->cond()->accept(this);
|
||||||
|
cout << ")";
|
||||||
|
if(ctx->stmt(0)->blockStmt())ctx->stmt(0)->accept(this);
|
||||||
|
else{
|
||||||
|
cout << " {"<< endl;
|
||||||
|
indentLevel++;
|
||||||
|
ctx->stmt(0)->accept(this);
|
||||||
|
indentLevel--;
|
||||||
|
cout << getIndent() << "}" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(ctx->BREAK()){
|
||||||
|
cout << getIndent() << "break;" << endl;
|
||||||
|
}
|
||||||
|
else if(ctx->CONTINUE()){
|
||||||
|
cout << getIndent() << "continue;" << endl;
|
||||||
|
}
|
||||||
|
else if(ctx->RETURN()){
|
||||||
|
cout << getIndent() << "return";
|
||||||
|
if(ctx->exp()){
|
||||||
|
cout << ' ';
|
||||||
|
ctx->exp()->accept(this);
|
||||||
|
}
|
||||||
|
cout << ctx->SEMICOLON()->getText() << endl;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::any ASTPrinter::visitExp(SysYParser::ExpContext *ctx) {
|
// std::any ASTPrinter::visitExp(SysYParser::ExpContext *ctx);
|
||||||
ctx->addExp()->accept(this);
|
// std::any ASTPrinter::visitCond(SysYParser::CondContext *ctx);
|
||||||
return nullptr;
|
std::any ASTPrinter::visitLValue(SysYParser::LValueContext *ctx){
|
||||||
}
|
cout << ctx->Ident()->getText();
|
||||||
|
|
||||||
std::any ASTPrinter::visitCond(SysYParser::CondContext *ctx) {
|
|
||||||
ctx->lorExp()->accept(this);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::any ASTPrinter::visitLVal(SysYParser::LValContext *ctx) {
|
|
||||||
cout << ctx->IDENT()->getText();
|
|
||||||
for (auto exp : ctx->exp()) {
|
for (auto exp : ctx->exp()) {
|
||||||
cout << "[";
|
cout << "[";
|
||||||
exp->accept(this);
|
exp->accept(this);
|
||||||
@@ -151,118 +207,149 @@ std::any ASTPrinter::visitLVal(SysYParser::LValContext *ctx) {
|
|||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
// std::any ASTPrinter::visitPrimaryExp(SysYParser::PrimaryExpContext *ctx);
|
||||||
|
|
||||||
std::any ASTPrinter::visitAddExp(SysYParser::AddExpContext *ctx) {
|
std::any ASTPrinter::visitNumber(SysYParser::NumberContext *ctx) {
|
||||||
if (ctx->addExp()) {
|
if(ctx->ILITERAL())cout << ctx->ILITERAL()->getText();
|
||||||
ctx->addExp()->accept(this);
|
if(ctx->FLITERAL())cout << ctx->FLITERAL()->getText();
|
||||||
cout << " " << ctx->ADD()->getText() << " ";
|
return nullptr;
|
||||||
ctx->mulExp()->accept(this);
|
|
||||||
} else {
|
|
||||||
ctx->mulExp()->accept(this);
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::any ASTPrinter::visitMulExp(SysYParser::MulExpContext *ctx) {
|
std::any ASTPrinter::visitString(SysYParser::StringContext *ctx) {
|
||||||
auto unaryExps = ctx->unaryExp();
|
cout << ctx->STRING()->getText();
|
||||||
if (unaryExps.size() == 1) {
|
return nullptr;
|
||||||
unaryExps[0]->accept(this);
|
}
|
||||||
|
|
||||||
|
std::any ASTPrinter::visitUnaryExp(SysYParser::UnaryExpContext *ctx){
|
||||||
|
if(ctx->primaryExp())
|
||||||
|
ctx->primaryExp()->accept(this);
|
||||||
|
else if(ctx->Ident()){
|
||||||
|
cout << ctx->Ident()->getText() << ctx->LPAREN()->getText();
|
||||||
|
if(ctx->funcRParams())
|
||||||
|
ctx->funcRParams()->accept(this);
|
||||||
|
cout << ctx->RPAREN()->getText();
|
||||||
|
}
|
||||||
|
else if(ctx->unaryExp()){
|
||||||
|
cout << ctx->unaryOp()->getText();
|
||||||
|
ctx->unaryExp()->accept(this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ctx->accept(this);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
// std::any ASTPrinter::visitUnaryOp(SysYParser::UnaryOpContext *ctx);
|
||||||
|
|
||||||
|
any ASTPrinter::visitFuncRParams(SysYParser::FuncRParamsContext *ctx) {
|
||||||
|
if (ctx->exp().empty())
|
||||||
|
return nullptr;
|
||||||
|
auto numParams = ctx->exp().size();
|
||||||
|
ctx->exp(0)->accept(this);
|
||||||
|
for (int i = 1; i < numParams; ++i) {
|
||||||
|
cout << ctx->COMMA(i - 1)->getText() << ' ';
|
||||||
|
ctx->exp(i)->accept(this);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::any ASTPrinter::visitMulExp(SysYParser::MulExpContext *ctx){
|
||||||
|
auto unaryExps = ctx->unaryExp();
|
||||||
|
if (unaryExps.size() == 1) {
|
||||||
|
unaryExps[0]->accept(this);
|
||||||
|
} else {
|
||||||
|
for (size_t i = 0; i < unaryExps.size() - 1; ++i) {
|
||||||
|
auto opNode = dynamic_cast<antlr4::tree::TerminalNode *>(ctx->children[2 * i + 1]);
|
||||||
|
if (opNode) {
|
||||||
|
unaryExps[i]->accept(this);
|
||||||
|
cout << " " << opNode->getText() << " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unaryExps.back()->accept(this);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::any ASTPrinter::visitAddExp(SysYParser::AddExpContext *ctx){
|
||||||
|
auto mulExps = ctx->mulExp();
|
||||||
|
if (mulExps.size() == 1) {
|
||||||
|
mulExps[0]->accept(this);
|
||||||
|
} else {
|
||||||
|
for (size_t i = 0; i < mulExps.size() - 1; ++i) {
|
||||||
|
auto opNode = dynamic_cast<antlr4::tree::TerminalNode *>(ctx->children[2 * i + 1]);
|
||||||
|
if (opNode) {
|
||||||
|
mulExps[i]->accept(this);
|
||||||
|
cout << " " << opNode->getText() << " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mulExps.back()->accept(this);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
// 以下表达式待补全形式同addexp mulexp
|
||||||
|
std::any ASTPrinter::visitRelExp(SysYParser::RelExpContext *ctx){
|
||||||
|
auto relExps = ctx->addExp();
|
||||||
|
if (relExps.size() == 1) {
|
||||||
|
relExps[0]->accept(this);
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < unaryExps.size() - 1; ++i) {
|
for (size_t i = 0; i < relExps.size() - 1; ++i) {
|
||||||
auto opNode = dynamic_cast<antlr4::tree::TerminalNode *>(ctx->children[2 * i + 1]);
|
auto opNode = dynamic_cast<antlr4::tree::TerminalNode *>(ctx->children[2 * i + 1]);
|
||||||
if (opNode) {
|
if (opNode) {
|
||||||
unaryExps[i]->accept(this);
|
relExps[i]->accept(this);
|
||||||
cout << " " << opNode->getText() << " ";
|
cout << " " << opNode->getText() << " ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unaryExps.back()->accept(this);
|
relExps.back()->accept(this);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
std::any ASTPrinter::visitEqExp(SysYParser::EqExpContext *ctx){
|
||||||
std::any ASTPrinter::visitUnaryExp(SysYParser::UnaryExpContext *ctx) {
|
auto eqExps = ctx->relExp();
|
||||||
if (ctx->primaryExp()) {
|
if (eqExps.size() == 1) {
|
||||||
ctx->primaryExp()->accept(this);
|
eqExps[0]->accept(this);
|
||||||
} else if (ctx->IDENT()) {
|
|
||||||
cout << ctx->IDENT()->getText() << "(";
|
|
||||||
if (ctx->funcRParams()) ctx->funcRParams()->accept(this);
|
|
||||||
cout << ")";
|
|
||||||
} else if (ctx->unaryOp()) {
|
|
||||||
cout << ctx->unaryOp()->getText();
|
|
||||||
ctx->unaryExp()->accept(this);
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// std::any ASTPrinter::visitLorExp(SysYParser::LorExpContext *ctx) {
|
|
||||||
// if (ctx->lorExp()) {
|
|
||||||
// // 左递归部分
|
|
||||||
// ctx->lorExp()->accept(this);
|
|
||||||
// cout << " || ";
|
|
||||||
// ctx->landExp()->accept(this);
|
|
||||||
// } else {
|
|
||||||
// // 基础部分
|
|
||||||
// ctx->landExp()->accept(this);
|
|
||||||
// }
|
|
||||||
// return nullptr;
|
|
||||||
// }
|
|
||||||
|
|
||||||
std::any ASTPrinter::visitStmt(SysYParser::StmtContext *ctx) {
|
|
||||||
if (ctx->lVal() && ctx->exp()) {
|
|
||||||
cout << getIndent();
|
|
||||||
ctx->lVal()->accept(this);
|
|
||||||
cout << " = ";
|
|
||||||
ctx->exp()->accept(this);
|
|
||||||
cout << ";" << endl;
|
|
||||||
}
|
|
||||||
// else if (ctx->exp()) {
|
|
||||||
// cout << getIndent();
|
|
||||||
// ctx->exp()->accept(this);
|
|
||||||
// cout << ";" << endl;
|
|
||||||
// }
|
|
||||||
else if (ctx->block()) {
|
|
||||||
ctx->block()->accept(this);
|
|
||||||
} else {
|
} else {
|
||||||
for (auto child : ctx->children) {
|
for (size_t i = 0; i < eqExps.size() - 1; ++i) {
|
||||||
if (auto terminal = dynamic_cast<antlr4::tree::TerminalNode *>(child)) {
|
auto opNode = dynamic_cast<antlr4::tree::TerminalNode *>(ctx->children[2 * i + 1]);
|
||||||
if (terminal->getText() == "if") {
|
if (opNode) {
|
||||||
cout << getIndent() << "if (";
|
eqExps[i]->accept(this);
|
||||||
ctx->cond()->accept(this);
|
cout << " " << opNode->getText() << " ";
|
||||||
cout << ")" << endl;
|
|
||||||
ctx->stmt(0)->accept(this);
|
|
||||||
if (ctx->stmt().size() > 1) {
|
|
||||||
cout << getIndent() << "else" << endl;
|
|
||||||
ctx->stmt(1)->accept(this);
|
|
||||||
}
|
|
||||||
} else if (terminal->getText() == "while") {
|
|
||||||
cout << getIndent() << "while (";
|
|
||||||
ctx->cond()->accept(this);
|
|
||||||
cout << ")" << endl;
|
|
||||||
ctx->stmt(0)->accept(this);
|
|
||||||
} else if (terminal->getText() == "return") {
|
|
||||||
cout << getIndent() << "return";
|
|
||||||
if (ctx->exp()) {
|
|
||||||
cout << " ";
|
|
||||||
ctx->exp()->accept(this);
|
|
||||||
}
|
|
||||||
cout << ";" << endl;
|
|
||||||
} else if (terminal->getText() == "break") {
|
|
||||||
cout << getIndent() << "break;" << endl;
|
|
||||||
} else if (terminal->getText() == "continue") {
|
|
||||||
cout << getIndent() << "continue;" << endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
eqExps.back()->accept(this);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
std::any ASTPrinter::visitLAndExp(SysYParser::LAndExpContext *ctx){
|
||||||
std::any ASTPrinter::visitBlock(SysYParser::BlockContext *ctx) {
|
auto lAndExps = ctx->eqExp();
|
||||||
cout << getIndent() << "{" << endl;
|
if (lAndExps.size() == 1) {
|
||||||
indentLevel++;
|
lAndExps[0]->accept(this);
|
||||||
for (auto item : ctx->blockItem()) item->accept(this);
|
} else {
|
||||||
indentLevel--;
|
for (size_t i = 0; i < lAndExps.size() - 1; ++i) {
|
||||||
cout << getIndent() << "}" << endl;
|
auto opNode = dynamic_cast<antlr4::tree::TerminalNode *>(ctx->children[2 * i + 1]);
|
||||||
|
if (opNode) {
|
||||||
|
lAndExps[i]->accept(this);
|
||||||
|
cout << " " << opNode->getText() << " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lAndExps.back()->accept(this);
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
std::any ASTPrinter::visitLOrExp(SysYParser::LOrExpContext *ctx){
|
||||||
|
auto lOrExps = ctx->lAndExp();
|
||||||
|
if (lOrExps.size() == 1) {
|
||||||
|
lOrExps[0]->accept(this);
|
||||||
|
} else {
|
||||||
|
for (size_t i = 0; i < lOrExps.size() - 1; ++i) {
|
||||||
|
auto opNode = dynamic_cast<antlr4::tree::TerminalNode *>(ctx->children[2 * i + 1]);
|
||||||
|
if (opNode) {
|
||||||
|
lOrExps[i]->accept(this);
|
||||||
|
cout << " " << opNode->getText() << " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lOrExps.back()->accept(this);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
std::any ASTPrinter::visitConstExp(SysYParser::ConstExpContext *ctx){
|
||||||
|
ctx->addExp()->accept(this);
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
#include "SysYBaseVisitor.h"
|
#include "SysYBaseVisitor.h"
|
||||||
#include "SysYParser.h"
|
#include "SysYParser.h"
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class ASTPrinter : public SysYBaseVisitor {
|
class ASTPrinter : public SysYBaseVisitor {
|
||||||
private:
|
private:
|
||||||
@@ -12,35 +10,37 @@ private:
|
|||||||
std::string getIndent() {
|
std::string getIndent() {
|
||||||
return std::string(indentLevel * 4, ' ');
|
return std::string(indentLevel * 4, ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::any visitModule(SysYParser::ModuleContext *ctx) override;
|
std::any visitCompUnit(SysYParser::CompUnitContext *ctx) override;
|
||||||
|
// std::any visitBType(SysYParser::BTypeContext *ctx) override;
|
||||||
|
// std::any visitDecl(SysYParser::DeclContext *ctx) override;
|
||||||
std::any visitConstDecl(SysYParser::ConstDeclContext *ctx) override;
|
std::any visitConstDecl(SysYParser::ConstDeclContext *ctx) override;
|
||||||
|
std::any visitConstDef(SysYParser::ConstDefContext *ctx) override;
|
||||||
|
// std::any visitConstInitVal(SysYParser::ConstInitValContext *ctx) override;
|
||||||
std::any visitVarDecl(SysYParser::VarDeclContext *ctx) override;
|
std::any visitVarDecl(SysYParser::VarDeclContext *ctx) override;
|
||||||
std::any visitVarDef(SysYParser::VarDefContext *ctx) override;
|
std::any visitVarDef(SysYParser::VarDefContext *ctx) override;
|
||||||
std::any visitConstDef(SysYParser::ConstDefContext *ctx) override; // 新增
|
std::any visitInitVal(SysYParser::InitValContext *ctx) override;
|
||||||
std::any visitFuncDef(SysYParser::FuncDefContext *ctx) override;
|
std::any visitFuncDef(SysYParser::FuncDefContext *ctx) override;
|
||||||
|
// std::any visitFuncType(SysYParser::FuncTypeContext *ctx) override;
|
||||||
std::any visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override;
|
std::any visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override;
|
||||||
std::any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override;
|
std::any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override;
|
||||||
std::any visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override;
|
std::any visitBlockStmt(SysYParser::BlockStmtContext *ctx) override;
|
||||||
|
// std::any visitBlockItem(SysYParser::BlockItemContext *ctx) override;
|
||||||
std::any visitExpAsRParam(SysYParser::ExpAsRParamContext *ctx) override;
|
std::any visitStmt(SysYParser::StmtContext *ctx) override;
|
||||||
std::any visitStringAsRParam(SysYParser::StringAsRParamContext *ctx) override;
|
// std::any visitExp(SysYParser::ExpContext *ctx) override;
|
||||||
std::any visitExpsAsRParam(SysYParser::ExpsAsRParamContext *ctx) override;
|
// std::any visitCond(SysYParser::CondContext *ctx) override;
|
||||||
|
std::any visitLValue(SysYParser::LValueContext *ctx) override;
|
||||||
std::any visitExp(SysYParser::ExpContext *ctx) override;
|
// std::any visitPrimaryExp(SysYParser::PrimaryExpContext *ctx) override;
|
||||||
std::any visitCond(SysYParser::CondContext *ctx) override;
|
|
||||||
std::any visitLVal(SysYParser::LValContext *ctx) override;
|
|
||||||
std::any visitAddExp(SysYParser::AddExpContext *ctx) override;
|
|
||||||
std::any visitMulExp(SysYParser::MulExpContext *ctx) override;
|
|
||||||
std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override;
|
|
||||||
|
|
||||||
std::any visitNumber(SysYParser::NumberContext *ctx) override;
|
std::any visitNumber(SysYParser::NumberContext *ctx) override;
|
||||||
std::any visitString(SysYParser::StringContext *ctx) override;
|
std::any visitString(SysYParser::StringContext *ctx) override;
|
||||||
|
std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override;
|
||||||
std::any visitStmt(SysYParser::StmtContext *ctx) override;
|
// std::any visitUnaryOp(SysYParser::UnaryOpContext *ctx) override;
|
||||||
std::any visitBlock(SysYParser::BlockContext *ctx) override;
|
std::any visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override;
|
||||||
// std::any ASTPrinter::visitLorExp(SysYParser::LorExpContext *ctx) override;
|
std::any visitMulExp(SysYParser::MulExpContext *ctx) override;
|
||||||
};
|
std::any visitAddExp(SysYParser::AddExpContext *ctx) override;
|
||||||
|
std::any visitRelExp(SysYParser::RelExpContext *ctx) override;
|
||||||
|
std::any visitEqExp(SysYParser::EqExpContext *ctx) override;
|
||||||
|
std::any visitLAndExp(SysYParser::LAndExpContext *ctx) override;
|
||||||
|
std::any visitLOrExp(SysYParser::LOrExpContext *ctx) override;
|
||||||
|
std::any visitConstExp(SysYParser::ConstExpContext *ctx) override;
|
||||||
|
};
|
||||||
|
|||||||
224
src/SysY.g4
224
src/SysY.g4
@@ -4,6 +4,52 @@ grammar SysY;
|
|||||||
/* Lexer rules */
|
/* Lexer rules */
|
||||||
/*===-------------------------------------------===*/
|
/*===-------------------------------------------===*/
|
||||||
|
|
||||||
|
|
||||||
|
// keywords
|
||||||
|
CONST: 'const';
|
||||||
|
INT: 'int';
|
||||||
|
FLOAT: 'float';
|
||||||
|
VOID: 'void';
|
||||||
|
IF: 'if';
|
||||||
|
ELSE: 'else';
|
||||||
|
WHILE: 'while';
|
||||||
|
BREAK: 'break';
|
||||||
|
CONTINUE: 'continue';
|
||||||
|
RETURN: 'return';
|
||||||
|
|
||||||
|
// operators
|
||||||
|
ADD: '+';
|
||||||
|
SUB: '-';
|
||||||
|
MUL: '*';
|
||||||
|
DIV: '/';
|
||||||
|
MOD: '%';
|
||||||
|
|
||||||
|
// relational operators
|
||||||
|
EQ: '==';
|
||||||
|
NE: '!=';
|
||||||
|
LT: '<';
|
||||||
|
LE: '<=';
|
||||||
|
GT: '>';
|
||||||
|
GE: '>=';
|
||||||
|
|
||||||
|
// logical operators
|
||||||
|
AND: '&&';
|
||||||
|
OR: '||';
|
||||||
|
NOT: '!';
|
||||||
|
|
||||||
|
// assignment operators
|
||||||
|
ASSIGN: '=';
|
||||||
|
|
||||||
|
// punctuations
|
||||||
|
COMMA: ',';
|
||||||
|
SEMICOLON: ';';
|
||||||
|
LPAREN: '(';
|
||||||
|
RPAREN: ')';
|
||||||
|
LBRACE: '{';
|
||||||
|
RBRACE: '}';
|
||||||
|
LBRACK: '[';
|
||||||
|
RBRACK: ']';
|
||||||
|
|
||||||
// fragments
|
// fragments
|
||||||
fragment DecDigit: [0-9];
|
fragment DecDigit: [0-9];
|
||||||
fragment OctDigit: [0-7];
|
fragment OctDigit: [0-7];
|
||||||
@@ -11,112 +57,122 @@ fragment HexDigit: [0-9a-fA-F];
|
|||||||
fragment OctPrefix: '0';
|
fragment OctPrefix: '0';
|
||||||
fragment HexPrefix: '0' [xX];
|
fragment HexPrefix: '0' [xX];
|
||||||
fragment NonZeroDecDigit: [1-9];
|
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
|
||||||
|
| HexPrefix HexDigit+ BinExponent;
|
||||||
|
|
||||||
fragment ESC: '\\"' | '\\\\';
|
fragment ESC: '\\"' | '\\\\';
|
||||||
|
|
||||||
// keywords
|
|
||||||
INT: 'int';
|
|
||||||
FLOAT: 'float';
|
|
||||||
CONST: 'const';
|
|
||||||
// operators
|
|
||||||
ADD: '+';
|
|
||||||
|
|
||||||
// punctuations
|
|
||||||
|
|
||||||
// identifier
|
// identifier
|
||||||
IDENT: IDENTNONDIGIT (IDENTNONDIGIT | DecDigit)*;
|
fragment ALPHA: [a-zA-Z];
|
||||||
IDENTNONDIGIT: [a-zA-Z_];
|
fragment ALPHANUM: [a-zA-Z0-9];
|
||||||
|
fragment NONDIGIT: [a-zA-Z_];
|
||||||
|
Ident: NONDIGIT (ALPHANUM | '_')*;
|
||||||
|
|
||||||
|
// IntConst -> ILITERAL
|
||||||
|
// FloatConst -> FLITERAL
|
||||||
// literals
|
// literals
|
||||||
ILITERAL: INTCONST | FLOATCONST;
|
ILITERAL:
|
||||||
|
NonZeroDecDigit DecDigit*
|
||||||
|
| OctPrefix OctDigit*
|
||||||
|
| HexPrefix HexDigit+;
|
||||||
|
|
||||||
|
// fliteral
|
||||||
|
FLITERAL: DecFloat | HexFloat;
|
||||||
|
|
||||||
// string
|
// string
|
||||||
STRING: '"' (ESC | .)*? '"';
|
STRING: '"' (ESC | .)*? '"';
|
||||||
|
|
||||||
// white space and comments
|
// white space and comments
|
||||||
WS: [ \t\r\n] -> skip;
|
WS: [\t\r\n ] -> skip;
|
||||||
LINECOMMENT: '//' .*? '\r'? '\n' -> skip;
|
LINECOMMENT: '//' .*? '\r'? '\n' -> skip;
|
||||||
BLOCKCOMMENT: '/*' .*? '*/' -> skip;
|
BLOCKCOMMENT: '/*' .*? '*/' -> skip;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
INTCONST: NonZeroDecDigit DecDigit*
|
|
||||||
| OctPrefix OctDigit*
|
|
||||||
| HexPrefix HexDigit+;
|
|
||||||
|
|
||||||
DIGITSEQUENCE: DecDigit+;
|
|
||||||
|
|
||||||
// Floating point constants
|
|
||||||
FLOATCONST: DecimalFloatingConstant
|
|
||||||
| HexadecimalFloatingConstant;
|
|
||||||
DecimalFloatingConstant: FractionalConstant ExponentPart? // 允许无指数
|
|
||||||
| DIGITSEQUENCE ExponentPart; // 保留原有形式
|
|
||||||
|
|
||||||
HexadecimalFloatingConstant: HexPrefix HexadecimalFractionalConstant BinaryExponentPart
|
|
||||||
| HexPrefix HexadecimalDigitSequence BinaryExponentPart;
|
|
||||||
FractionalConstant: DIGITSEQUENCE? '.' DIGITSEQUENCE
|
|
||||||
| DIGITSEQUENCE '.';
|
|
||||||
ExponentPart:
|
|
||||||
[eE] [+-]? DIGITSEQUENCE;
|
|
||||||
HexadecimalFractionalConstant: HexadecimalDigitSequence? '.' HexadecimalDigitSequence
|
|
||||||
| HexadecimalDigitSequence '.';
|
|
||||||
HexadecimalDigitSequence: HexDigit+;
|
|
||||||
BinaryExponentPart:
|
|
||||||
[pP] [+-]? DIGITSEQUENCE;
|
|
||||||
|
|
||||||
/*===-------------------------------------------===*/
|
/*===-------------------------------------------===*/
|
||||||
/* Syntax rules */
|
/* Syntax rules */
|
||||||
/*===-------------------------------------------===*/
|
/*===-------------------------------------------===*/
|
||||||
// module: funcRParams;
|
|
||||||
// compUnit: (dcl | funcDef)+;
|
|
||||||
module: (dcl | funcDef)+ | funcRParams;
|
|
||||||
|
|
||||||
funcRParams: funcRParam (',' funcRParam)*;
|
// CompUnit: (CompUnit)? (decl |funcDef);
|
||||||
|
|
||||||
funcRParam: number # expAsRParam | string # stringAsRParam | exp (',' exp)* # expsAsRParam;
|
compUnit: (decl |funcDef)+;
|
||||||
// funcRParam: exp (',' exp)*;
|
|
||||||
|
|
||||||
number: ILITERAL;
|
decl: constDecl | varDecl;
|
||||||
|
|
||||||
string: STRING;
|
constDecl: CONST bType constDef (COMMA constDef)* SEMICOLON;
|
||||||
|
|
||||||
bType: INT | FLOAT;
|
bType: INT | FLOAT;
|
||||||
dcl: constDecl | varDecl;
|
|
||||||
constDecl: CONST bType constDef (',' constDef)* ';';
|
|
||||||
constDef: IDENT ( '[' constExp ']' )* '=' constInitVal;
|
|
||||||
constInitVal: constExp
|
|
||||||
| '{' (constInitVal (',' constInitVal)*)? '}';
|
|
||||||
varDecl: bType varDef (',' varDef)* ';';
|
|
||||||
varDef: IDENT ( '[' constExp ']' )* initVal?
|
|
||||||
| IDENT ( '[' constExp ']' )* '=' initVal;
|
|
||||||
initVal: exp | '{' ( initVal ( ',' initVal )* )? '}';
|
|
||||||
|
|
||||||
funcDef: funcType IDENT '(' funcFParams? ')' block;
|
constDef: Ident (LBRACK constExp RBRACK)* ASSIGN constInitVal;
|
||||||
funcType: bType | 'void';
|
|
||||||
funcFParams: funcFParam (',' funcFParam )*;
|
constInitVal: constExp
|
||||||
funcFParam: bType IDENT ( '[' ']' ( '[' exp ']' )* )?;
|
| LBRACE (constInitVal (COMMA constInitVal)*)? RBRACE;
|
||||||
block: '{' blockItem* '}';
|
|
||||||
blockItem: dcl | stmt;
|
varDecl: bType varDef (COMMA varDef)* SEMICOLON;
|
||||||
stmt: lVal '=' exp ';'
|
|
||||||
| exp? ';'
|
varDef: Ident (LBRACK constExp RBRACK)*
|
||||||
// | IDENT '(' funcRParams? ')' ';'
|
| Ident (LBRACK constExp RBRACK)* ASSIGN initVal;
|
||||||
| block
|
|
||||||
| 'if' '(' cond ')' stmt ('else' stmt)?
|
initVal: exp
|
||||||
| 'while' '(' cond ')' stmt
|
| LBRACE (initVal (COMMA initVal)*)? RBRACE;
|
||||||
| 'break' ';'
|
|
||||||
| 'continue' ';'
|
funcType: VOID | INT | FLOAT;
|
||||||
| 'return' exp? ';';
|
|
||||||
|
funcDef: funcType Ident LPAREN funcFParams? RPAREN blockStmt;
|
||||||
|
|
||||||
|
funcFParams: funcFParam (COMMA funcFParam)*;
|
||||||
|
|
||||||
|
// 函数形参感觉定义有问题
|
||||||
|
// 应该是funcFParam: bType Ident ((LBRACK RBRACK)* (LBRACK exp RBRACK)*)?;
|
||||||
|
funcFParam: bType Ident (LBRACK RBRACK (LBRACK exp RBRACK)*)?;
|
||||||
|
|
||||||
|
blockStmt: LBRACE blockItem* RBRACE;
|
||||||
|
|
||||||
|
blockItem: decl | stmt;
|
||||||
|
|
||||||
|
stmt: lValue ASSIGN exp SEMICOLON
|
||||||
|
| blockStmt
|
||||||
|
| IF LPAREN cond RPAREN stmt (ELSE stmt)?
|
||||||
|
| WHILE LPAREN cond RPAREN stmt
|
||||||
|
| BREAK SEMICOLON
|
||||||
|
| CONTINUE SEMICOLON
|
||||||
|
| RETURN exp? SEMICOLON;
|
||||||
|
|
||||||
exp: addExp;
|
exp: addExp;
|
||||||
cond: lorExp;
|
cond: lOrExp;
|
||||||
lVal: IDENT ( '[' exp ']' )*;
|
lValue: Ident (LBRACK exp RBRACK)*;
|
||||||
primaryExp: '(' exp ')' | lVal | number;
|
|
||||||
// number: INTCONST | FLOATCONST;
|
// 为了方便测试 primaryExp 可以是一个string
|
||||||
unaryExp: primaryExp | IDENT '(' funcRParams? ')'
|
primaryExp: LPAREN exp RPAREN
|
||||||
| unaryOp unaryExp;
|
| lValue
|
||||||
unaryOp: '+' | '-' | '!';
|
| number
|
||||||
mulExp: unaryExp (('*' | '/' | '%') unaryExp)*;
|
| string;
|
||||||
addExp: mulExp | addExp ('+' | '-') mulExp;
|
|
||||||
relExp: addExp | relExp ('<' | '>' | '<=' | '>=') addExp;
|
number: ILITERAL | FLITERAL;
|
||||||
eqExp: relExp | eqExp ('==' | '!=') relExp;
|
unaryExp: primaryExp
|
||||||
landExp: eqExp | landExp '&&' eqExp;
|
| Ident LPAREN (funcRParams)? RPAREN
|
||||||
lorExp: landExp | lorExp '||' landExp;
|
| unaryOp unaryExp;
|
||||||
constExp: addExp;
|
|
||||||
|
unaryOp: ADD|SUB|NOT;
|
||||||
|
funcRParams: exp (COMMA exp)*;
|
||||||
|
string: STRING;
|
||||||
|
mulExp: unaryExp ((MUL|DIV|MOD) unaryExp)*;
|
||||||
|
addExp: mulExp ((ADD|SUB) mulExp)*;
|
||||||
|
relExp: addExp ((LT|GT|LE|GE) addExp)*;
|
||||||
|
eqExp: relExp ((EQ|NE) relExp)*;
|
||||||
|
lAndExp: eqExp (AND eqExp)*;
|
||||||
|
lOrExp: lAndExp (OR lAndExp)*;
|
||||||
|
constExp: addExp;
|
||||||
|
// mulExp: unaryExp ((MUL|DIV|MOD) unaryExp)*;
|
||||||
|
// addExp: mulExp | addExp (ADD|SUB) mulExp;
|
||||||
|
// relExp: addExp | relExp (LT|GT|LE|GE) addExp;
|
||||||
|
// eqExp: relExp | eqExp (EQ|NE) relExp;
|
||||||
|
// lAndExp: eqExp | lAndExp AND eqExp;
|
||||||
|
// lOrExp: lAndExp | lOrExp OR lAndExp;
|
||||||
|
// constExp: addExp;
|
||||||
@@ -63,7 +63,7 @@ int main(int argc, char **argv) {
|
|||||||
SysYLexer lexer(&input);
|
SysYLexer lexer(&input);
|
||||||
CommonTokenStream tokens(&lexer);
|
CommonTokenStream tokens(&lexer);
|
||||||
SysYParser parser(&tokens);
|
SysYParser parser(&tokens);
|
||||||
auto moduleAST = parser.module();
|
auto moduleAST = parser.compUnit();
|
||||||
if (argStopAfter == "ast") {
|
if (argStopAfter == "ast") {
|
||||||
cout << moduleAST->toStringTree(true) << '\n';
|
cout << moduleAST->toStringTree(true) << '\n';
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
@@ -72,13 +72,13 @@ int main(int argc, char **argv) {
|
|||||||
// pretty format the input file
|
// pretty format the input file
|
||||||
if (argFormat) {
|
if (argFormat) {
|
||||||
ASTPrinter printer;
|
ASTPrinter printer;
|
||||||
printer.visitModule(moduleAST);
|
printer.visitCompUnit(moduleAST);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// visit AST to generate IR
|
// visit AST to generate IR
|
||||||
SysYIRGenerator generator;
|
SysYIRGenerator generator;
|
||||||
generator.visitModule(moduleAST);
|
generator.visitCompUnit(moduleAST);
|
||||||
auto moduleIR = generator.get();
|
auto moduleIR = generator.get();
|
||||||
if (argStopAfter == "ir") {
|
if (argStopAfter == "ir") {
|
||||||
moduleIR->print(cout);
|
moduleIR->print(cout);
|
||||||
|
|||||||
Reference in New Issue
Block a user