#include "sem/Sema.h" #include 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(); }