[lab1]almost completed

Merge pull request !1 from Downright/master
This commit is contained in:
LixuanWang
2025-03-04 06:32:37 +00:00
committed by Gitee
4 changed files with 472 additions and 329 deletions

View File

@@ -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;
} }

View File

@@ -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;
};

View File

@@ -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;

View File

@@ -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);