You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nudt-compiler-cpp/src/sem/Sema.cpp

225 lines
5.7 KiB

#include "sem/Sema.h"
#include <stdexcept>
namespace {
SymbolType ParseType(const std::string& text) {
if (text == "int") {
return SymbolType::TYPE_INT;
}
if (text == "float") {
return SymbolType::TYPE_FLOAT;
}
if (text == "void") {
return SymbolType::TYPE_VOID;
}
return SymbolType::TYPE_UNKNOWN;
}
} // namespace
std::any SemaVisitor::visitCompUnit(SysYParser::CompUnitContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitDecl(SysYParser::DeclContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitConstDecl(SysYParser::ConstDeclContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitBtype(SysYParser::BtypeContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitConstDef(SysYParser::ConstDefContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitConstInitValue(SysYParser::ConstInitValueContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitVarDecl(SysYParser::VarDeclContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitVarDef(SysYParser::VarDefContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitInitValue(SysYParser::InitValueContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitFuncDef(SysYParser::FuncDefContext* ctx) {
SymbolType ret_type = SymbolType::TYPE_UNKNOWN;
if (ctx && ctx->funcType()) {
ret_type = ParseType(ctx->funcType()->getText());
}
ir_ctx_.SetCurrentFuncReturnType(ret_type);
return visitChildren(ctx);
}
std::any SemaVisitor::visitFuncType(SysYParser::FuncTypeContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitFuncFParams(SysYParser::FuncFParamsContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitFuncFParam(SysYParser::FuncFParamContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitBlockStmt(SysYParser::BlockStmtContext* ctx) {
ir_ctx_.EnterScope();
std::any result = visitChildren(ctx);
ir_ctx_.LeaveScope();
return result;
}
std::any SemaVisitor::visitBlockItem(SysYParser::BlockItemContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitStmt(SysYParser::StmtContext* ctx) {
if (!ctx) {
return {};
}
if (ctx->WHILE()) {
ir_ctx_.EnterLoop();
std::any result = visitChildren(ctx);
ir_ctx_.ExitLoop();
return result;
}
if (ctx->BREAK() && !ir_ctx_.InLoop()) {
ir_ctx_.RecordError(
ErrorMsg("break 只能出现在循环语句中", ctx->getStart()->getLine(),
ctx->getStart()->getCharPositionInLine() + 1));
}
if (ctx->CONTINUE() && !ir_ctx_.InLoop()) {
ir_ctx_.RecordError(
ErrorMsg("continue 只能出现在循环语句中", ctx->getStart()->getLine(),
ctx->getStart()->getCharPositionInLine() + 1));
}
return visitChildren(ctx);
}
std::any SemaVisitor::visitReturnStmt(SysYParser::ReturnStmtContext* ctx) {
if (!ctx) {
return {};
}
if (ctx->exp() && ir_ctx_.GetCurrentFuncReturnType() == SymbolType::TYPE_VOID) {
ir_ctx_.RecordError(
ErrorMsg("void 函数不应返回表达式", ctx->getStart()->getLine(),
ctx->getStart()->getCharPositionInLine() + 1));
}
if (!ctx->exp() &&
ir_ctx_.GetCurrentFuncReturnType() != SymbolType::TYPE_VOID &&
ir_ctx_.GetCurrentFuncReturnType() != SymbolType::TYPE_UNKNOWN) {
ir_ctx_.RecordError(
ErrorMsg("非 void 函数 return 必须带表达式", ctx->getStart()->getLine(),
ctx->getStart()->getCharPositionInLine() + 1));
}
return visitChildren(ctx);
}
std::any SemaVisitor::visitExp(SysYParser::ExpContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitCond(SysYParser::CondContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitLValue(SysYParser::LValueContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitNumber(SysYParser::NumberContext* ctx) {
if (!ctx) {
return {};
}
if (ctx->ILITERAL()) {
ir_ctx_.SetType(ctx, SymbolType::TYPE_INT);
ir_ctx_.SetConstVal(ctx, std::any(0L));
} else if (ctx->FLITERAL()) {
ir_ctx_.SetType(ctx, SymbolType::TYPE_FLOAT);
ir_ctx_.SetConstVal(ctx, std::any(0.0));
}
return {};
}
std::any SemaVisitor::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitUnaryOp(SysYParser::UnaryOpContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitFuncRParams(SysYParser::FuncRParamsContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitMulExp(SysYParser::MulExpContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitAddExp(SysYParser::AddExpContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitRelExp(SysYParser::RelExpContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitEqExp(SysYParser::EqExpContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitLAndExp(SysYParser::LAndExpContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitLOrExp(SysYParser::LOrExpContext* ctx) {
return visitChildren(ctx);
}
std::any SemaVisitor::visitConstExp(SysYParser::ConstExpContext* ctx) {
return visitChildren(ctx);
}
void RunSemanticAnalysis(SysYParser::CompUnitContext* ctx, IRGenContext& ir_ctx) {
if (!ctx) {
throw std::invalid_argument("CompUnitContext is null");
}
SemaVisitor visitor(ir_ctx);
visitor.visit(ctx);
}
SemanticContext RunSema(SysYParser::CompUnitContext& comp_unit) {
IRGenContext ctx;
RunSemanticAnalysis(&comp_unit, ctx);
return SemanticContext();
}