Merge master into zhm: apply all fixes for evaluation system

zhm
zhm 2 weeks ago
commit e3e01256cd

16
.gitignore vendored

@ -64,6 +64,12 @@ cmake-build-release/
.DS_Store
Thumbs.db
# =========================
# Local-only (not for grader)
# =========================
/include
third_party/antlr4-runtime-4.13.2/runtime/
# =========================
# Project outputs
# =========================
@ -76,3 +82,13 @@ lab4_instcount_results/
lab5_results/
test_tmp/
test_fail/
# =========================
# Local test & build
# =========================
2026test/
build_clang/
build_debug/
build_ubsan/
build_eval/
test5.sh

@ -21,11 +21,8 @@ set(ANTLR4_GENERATED_DIR "${CMAKE_BINARY_DIR}/generated/antlr4")
add_library(build_options INTERFACE)
target_compile_features(build_options INTERFACE cxx_std_17)
target_include_directories(build_options INTERFACE
"${PROJECT_SOURCE_DIR}/include"
"${PROJECT_SOURCE_DIR}/src/include"
"${PROJECT_SOURCE_DIR}/src"
"${ANTLR4_GENERATED_DIR}"
# 使 -Xexact-output-dir ANTLR
"${ANTLR4_GENERATED_DIR}/src/antlr4"
)
option(COMPILER_ENABLE_WARNINGS "Enable common compiler warnings" ON)
@ -39,41 +36,32 @@ endif()
option(COMPILER_PARSE_ONLY "Build only the frontend parser pipeline" OFF)
# 使 third_party ANTLR4 C++ runtime
# third_party runtime third_party/antlr4-runtime-4.13.2/runtime/src
set(ANTLR4_RUNTIME_SRC_DIR "${PROJECT_SOURCE_DIR}/third_party/antlr4-runtime-4.13.2/runtime/src")
add_library(antlr4_runtime STATIC)
target_compile_features(antlr4_runtime PUBLIC cxx_std_17)
target_include_directories(antlr4_runtime PUBLIC
"${ANTLR4_RUNTIME_SRC_DIR}"
"${ANTLR4_RUNTIME_SRC_DIR}/atn"
"${ANTLR4_RUNTIME_SRC_DIR}/dfa"
"${ANTLR4_RUNTIME_SRC_DIR}/internal"
"${ANTLR4_RUNTIME_SRC_DIR}/misc"
"${ANTLR4_RUNTIME_SRC_DIR}/support"
"${ANTLR4_RUNTIME_SRC_DIR}/tree"
"${ANTLR4_RUNTIME_SRC_DIR}/tree/pattern"
"${ANTLR4_RUNTIME_SRC_DIR}/tree/xpath"
)
file(GLOB_RECURSE ANTLR4_RUNTIME_SOURCES CONFIGURE_DEPENDS
"${ANTLR4_RUNTIME_SRC_DIR}/*.cpp"
"${ANTLR4_RUNTIME_SRC_DIR}/atn/*.cpp"
"${ANTLR4_RUNTIME_SRC_DIR}/dfa/*.cpp"
"${ANTLR4_RUNTIME_SRC_DIR}/internal/*.cpp"
"${ANTLR4_RUNTIME_SRC_DIR}/misc/*.cpp"
"${ANTLR4_RUNTIME_SRC_DIR}/support/*.cpp"
"${ANTLR4_RUNTIME_SRC_DIR}/tree/*.cpp"
"${ANTLR4_RUNTIME_SRC_DIR}/tree/pattern/*.cpp"
"${ANTLR4_RUNTIME_SRC_DIR}/tree/xpath/*.cpp"
)
target_sources(antlr4_runtime PRIVATE ${ANTLR4_RUNTIME_SOURCES})
find_package(Threads REQUIRED)
target_link_libraries(antlr4_runtime PUBLIC Threads::Threads)
set(ANTLR4_RUNTIME_TARGET antlr4_runtime)
set(ANTLR4_RUNTIME_LOCAL_DIR "${PROJECT_SOURCE_DIR}/third_party/antlr4-runtime-4.13.2/runtime/src")
if(EXISTS "${ANTLR4_RUNTIME_LOCAL_DIR}/antlr4-runtime.h")
set(ANTLR4_RUNTIME_SRC_DIR "${ANTLR4_RUNTIME_LOCAL_DIR}")
add_library(antlr4_runtime STATIC)
target_compile_features(antlr4_runtime PUBLIC cxx_std_17)
target_include_directories(antlr4_runtime PUBLIC
"${ANTLR4_RUNTIME_SRC_DIR}"
"${ANTLR4_RUNTIME_SRC_DIR}/atn"
"${ANTLR4_RUNTIME_SRC_DIR}/dfa"
"${ANTLR4_RUNTIME_SRC_DIR}/internal"
"${ANTLR4_RUNTIME_SRC_DIR}/misc"
"${ANTLR4_RUNTIME_SRC_DIR}/support"
"${ANTLR4_RUNTIME_SRC_DIR}/tree"
"${ANTLR4_RUNTIME_SRC_DIR}/tree/pattern"
"${ANTLR4_RUNTIME_SRC_DIR}/tree/xpath"
)
file(GLOB_RECURSE ANTLR4_RUNTIME_SOURCES CONFIGURE_DEPENDS
"${ANTLR4_RUNTIME_SRC_DIR}/*.cpp"
)
target_sources(antlr4_runtime PRIVATE ${ANTLR4_RUNTIME_SOURCES})
target_link_libraries(antlr4_runtime PUBLIC Threads::Threads)
set(ANTLR4_RUNTIME_TARGET antlr4_runtime)
else()
set(ANTLR4_RUNTIME_TARGET "antlr4-runtime")
endif()
add_subdirectory(src)
add_subdirectory(src)

@ -0,0 +1,169 @@
clang++ -std=c++17 -O2 -lm -L/extlibs -I/extlibs -lantlr4-runtime -Wl,-rpath=/extlibs /coursegrader/submitdata/src/main.cpp /coursegrader/submitdata/src/ir/Context.cpp /coursegrader/submitdata/src/ir/IRBuilder.cpp /coursegrader/submitdata/src/ir/Function.cpp /coursegrader/submitdata/src/ir/Module.cpp /coursegrader/submitdata/src/ir/IRPrinter.cpp /coursegrader/submitdata/src/ir/Value.cpp /coursegrader/submitdata/src/ir/Type.cpp /coursegrader/submitdata/src/ir/BasicBlock.cpp /coursegrader/submitdata/src/ir/Instruction.cpp /coursegrader/submitdata/src/ir/GlobalValue.cpp /coursegrader/submitdata/src/ir/analysis/LoopInfo.cpp /coursegrader/submitdata/src/ir/analysis/DominatorTree.cpp /coursegrader/submitdata/src/ir/passes/ConstProp.cpp /coursegrader/submitdata/src/ir/passes/LICM.cpp /coursegrader/submitdata/src/ir/passes/DCE.cpp /coursegrader/submitdata/src/ir/passes/Mem2Reg.cpp /coursegrader/submitdata/src/ir/passes/ConstFold.cpp /coursegrader/submitdata/src/ir/passes/PassManager.cpp /coursegrader/submitdata/src/ir/passes/CSE.cpp /coursegrader/submitdata/src/ir/passes/CFGSimplify.cpp /coursegrader/submitdata/src/utils/Log.cpp /coursegrader/submitdata/src/utils/CLI.cpp /coursegrader/submitdata/src/frontend/SyntaxTreePrinter.cpp /coursegrader/submitdata/src/frontend/AntlrDriver.cpp /coursegrader/submitdata/src/sem/SymbolTable.cpp /coursegrader/submitdata/src/sem/Sema.cpp /coursegrader/submitdata/src/sem/ConstEval.cpp /coursegrader/submitdata/src/mir/MIRContext.cpp /coursegrader/submitdata/src/mir/AsmPrinter.cpp /coursegrader/submitdata/src/mir/Register.cpp /coursegrader/submitdata/src/mir/Lowering.cpp /coursegrader/submitdata/src/mir/FrameLowering.cpp /coursegrader/submitdata/src/mir/MIRBasicBlock.cpp /coursegrader/submitdata/src/mir/MIRInstr.cpp /coursegrader/submitdata/src/mir/RegAlloc.cpp /coursegrader/submitdata/src/mir/MIRFunction.cpp /coursegrader/submitdata/src/mir/passes/Peephole.cpp /coursegrader/submitdata/src/mir/passes/PassManager.cpp /coursegrader/submitdata/src/irgen/IRGenDecl.cpp /coursegrader/submitdata/src/irgen/IRGenDriver.cpp /coursegrader/submitdata/src/irgen/IRGenStmt.cpp /coursegrader/submitdata/src/irgen/IRGenFunc.cpp /coursegrader/submitdata/src/irgen/IRGenExp.cpp /coursegrader/submitdata/sylib/sylib.c -I /coursegrader/submitdata/extlibs/utils -I /coursegrader/submitdata/extlibs/sem -I /coursegrader/submitdata/extlibs/mir -I /coursegrader/submitdata/extlibs/irgen -I /coursegrader/submitdata/extlibs/ir -I /coursegrader/submitdata/extlibs/frontend -I /coursegrader/submitdata/include/frontend -I /coursegrader/submitdata/include/utils -I /coursegrader/submitdata/include/ir -I /coursegrader/submitdata/include/irgen -I /coursegrader/submitdata/include/sem -I /coursegrader/submitdata/include/mir -I /coursegrader/submitdata/sylib -o /root/run/compiler
Stdout:
Stderr:
clang++: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]
/coursegrader/submitdata/src/main.cpp:7:10: fatal error: 'frontend/AntlrDriver.h' file not found
7 | #include "frontend/AntlrDriver.h"
| ^~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/ir/Context.cpp:2:10: fatal error: 'ir/IR.h' file not found
2 | #include "ir/IR.h"
| ^~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/ir/IRBuilder.cpp:5:10: fatal error: 'ir/IR.h' file not found
5 | #include "ir/IR.h"
| ^~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/ir/Function.cpp:4:10: fatal error: 'ir/IR.h' file not found
4 | #include "ir/IR.h"
| ^~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/ir/Module.cpp:3:10: fatal error: 'ir/IR.h' file not found
3 | #include "ir/IR.h"
| ^~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/ir/IRPrinter.cpp:5:10: fatal error: 'ir/IR.h' file not found
5 | #include "ir/IR.h"
| ^~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/ir/Value.cpp:4:10: fatal error: 'ir/IR.h' file not found
4 | #include "ir/IR.h"
| ^~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/ir/Type.cpp:2:10: fatal error: 'ir/IR.h' file not found
2 | #include "ir/IR.h"
| ^~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/ir/BasicBlock.cpp:10:10: fatal error: 'ir/IR.h' file not found
10 | #include "ir/IR.h"
| ^~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/ir/Instruction.cpp:4:10: fatal error: 'ir/IR.h' file not found
4 | #include "ir/IR.h"
| ^~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/ir/GlobalValue.cpp:4:10: fatal error: 'ir/IR.h' file not found
4 | #include "ir/IR.h"
| ^~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/ir/analysis/DominatorTree.cpp:1:10: fatal error: 'ir/IR.h' file not found
1 | #include "ir/IR.h"
| ^~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/ir/passes/ConstProp.cpp:7:10: fatal error: 'ir/IR.h' file not found
7 | #include "ir/IR.h"
| ^~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/ir/passes/LICM.cpp:1:10: fatal error: 'ir/IR.h' file not found
1 | #include "ir/IR.h"
| ^~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/ir/passes/DCE.cpp:7:10: fatal error: 'ir/IR.h' file not found
7 | #include "ir/IR.h"
| ^~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/ir/passes/Mem2Reg.cpp:5:10: fatal error: 'ir/IR.h' file not found
5 | #include "ir/IR.h"
| ^~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/ir/passes/ConstFold.cpp:5:10: fatal error: 'ir/IR.h' file not found
5 | #include "ir/IR.h"
| ^~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/ir/passes/PassManager.cpp:3:10: fatal error: 'ir/IR.h' file not found
3 | #include "ir/IR.h"
| ^~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/ir/passes/CSE.cpp:10:10: fatal error: 'ir/IR.h' file not found
10 | #include "ir/IR.h"
| ^~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/ir/passes/CFGSimplify.cpp:5:10: fatal error: 'ir/IR.h' file not found
5 | #include "ir/IR.h"
| ^~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/utils/Log.cpp:3:10: fatal error: 'utils/Log.h' file not found
3 | #include "utils/Log.h"
| ^~~~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/utils/CLI.cpp:5:10: fatal error: 'utils/CLI.h' file not found
5 | #include "utils/CLI.h"
| ^~~~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/frontend/SyntaxTreePrinter.cpp:1:10: fatal error: 'frontend/SyntaxTreePrinter.h' file not found
1 | #include "frontend/SyntaxTreePrinter.h"
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/frontend/AntlrDriver.cpp:2:10: fatal error: 'frontend/AntlrDriver.h' file not found
2 | #include "frontend/AntlrDriver.h"
| ^~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/sem/SymbolTable.cpp:3:10: fatal error: 'sem/SymbolTable.h' file not found
3 | #include "sem/SymbolTable.h"
| ^~~~~~~~~~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/sem/Sema.cpp:1:10: fatal error: 'sem/Sema.h' file not found
1 | #include "sem/Sema.h"
| ^~~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/mir/MIRContext.cpp:1:10: fatal error: 'mir/MIR.h' file not found
1 | #include "mir/MIR.h"
| ^~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/mir/AsmPrinter.cpp:1:10: fatal error: 'mir/MIR.h' file not found
1 | #include "mir/MIR.h"
| ^~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/mir/Register.cpp:1:10: fatal error: 'mir/MIR.h' file not found
1 | #include "mir/MIR.h"
| ^~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/mir/Lowering.cpp:1:10: fatal error: 'mir/MIR.h' file not found
1 | #include "mir/MIR.h"
| ^~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/mir/FrameLowering.cpp:1:10: fatal error: 'mir/MIR.h' file not found
1 | #include "mir/MIR.h"
| ^~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/mir/MIRBasicBlock.cpp:1:10: fatal error: 'mir/MIR.h' file not found
1 | #include "mir/MIR.h"
| ^~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/mir/MIRInstr.cpp:1:10: fatal error: 'mir/MIR.h' file not found
1 | #include "mir/MIR.h"
| ^~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/mir/RegAlloc.cpp:1:10: fatal error: 'mir/MIR.h' file not found
1 | #include "mir/MIR.h"
| ^~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/mir/MIRFunction.cpp:1:10: fatal error: 'mir/MIR.h' file not found
1 | #include "mir/MIR.h"
| ^~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/mir/passes/Peephole.cpp:1:10: fatal error: 'mir/MIR.h' file not found
1 | #include "mir/MIR.h"
| ^~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/irgen/IRGenDecl.cpp:1:10: fatal error: 'irgen/IRGen.h' file not found
1 | #include "irgen/IRGen.h"
| ^~~~~~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/irgen/IRGenDriver.cpp:1:10: fatal error: 'irgen/IRGen.h' file not found
1 | #include "irgen/IRGen.h"
| ^~~~~~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/irgen/IRGenStmt.cpp:1:10: fatal error: 'irgen/IRGen.h' file not found
1 | #include "irgen/IRGen.h"
| ^~~~~~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/irgen/IRGenFunc.cpp:1:10: fatal error: 'irgen/IRGen.h' file not found
1 | #include "irgen/IRGen.h"
| ^~~~~~~~~~~~~~~
1 error generated.
/coursegrader/submitdata/src/irgen/IRGenExp.cpp:1:10: fatal error: 'irgen/IRGen.h' file not found
1 | #include "irgen/IRGen.h"
| ^~~~~~~~~~~~~~~
1 error generated.

@ -1,7 +1,6 @@
<<<<<<< HEAD
# SysY 编译器课程实验C++
本仓库为“并行编译课程实验”提供一个 SysY 编译器的最小可运行示例,实验按 Lab1Lab6 逐步完成:
本仓库为"并行编译课程实验"提供一个 SysY 编译器的最小可运行示例,实验按 Lab1Lab6 逐步完成:
从前端(词法/语法分析与语法树处理到中端IR 生成、基本标量优化再到后端ARM64/AArch64 汇编生成、寄存器分配与后端优化),最后进行循环/并行相关优化。
## 1. 实验介绍
@ -19,7 +18,7 @@
本仓库提供的示例代码和实验文档只是参考。我们非常鼓励大家在阅读当前仓库实现的同时,也结合自己的理解重新设计框架并完成实现,而不是机械照搬。
如果希望进一步参考编译相关项目和往届优秀实现,可以查看编译比赛官网的技术支持栏目:<https://compiler.educg.net/#/index?TYPE=26COM>。其中的“备赛推荐”整理了一些编译相关项目,也能看到往届优秀作品的开源实现,这些内容都很值得参考。
如果希望进一步参考编译相关项目和往届优秀实现,可以查看编译比赛官网的技术支持栏目:<https://compiler.educg.net/#/index?TYPE=26COM>。其中的"备赛推荐"整理了一些编译相关项目,也能看到往届优秀作品的开源实现,这些内容都很值得参考。
## 3. 头歌平台协作流程
@ -101,7 +100,7 @@ Git Commit 提交的信息建议尽量写清楚,推荐使用下面的格式:
`scope` 用来说明改动的大致范围,例如 `frontend`、`irgen`、`backend`、`test`、`doc`。
`subject` 用一句简短的话说明“这次改了什么”
`subject` 用一句简短的话说明"这次改了什么"
例如:
@ -217,44 +216,3 @@ cmake --build build -j "$(nproc)"
如果最终看到 `输出匹配: test/test_case/simple_add.out`,说明当前示例用例 `return a + b` 的完整链路已经跑通。
但这条命令只适合做单个用例检查。完成对应实验后,不能只停留在 `simple_add`,还应覆盖 `test/test_case` 下全部测试用例;如有需要,也可以自行编写批量测试脚本统一执行。
=======
# 2026编译比赛设计赛
#### 介绍
{**以下是 Gitee 平台说明,您可以替换此简介**
Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN。专为开发者提供稳定、高效、安全的云端软件开发协作平台
无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
#### 软件架构
软件架构说明
#### 安装教程
1. xxxx
2. xxxx
3. xxxx
#### 使用说明
1. xxxx
2. xxxx
3. xxxx
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
#### 特技
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
>>>>>>> 52dc8dcff8aa97004fee045667d00c52157e8374

@ -6,8 +6,6 @@
#include <stdexcept>
#include <string>
#include "SysYLexer.h"
#include "SysYParser.h"
#include "antlr4-runtime.h"
#include "utils/Log.h"

@ -0,0 +1,7 @@
// Generated from src/antlr4/SysY.g4 by ANTLR 4.13.2
#include "SysYBaseVisitor.h"

@ -0,0 +1,271 @@
// Generated from src/antlr4/SysY.g4 by ANTLR 4.13.2
#include "SysYLexer.h"
using namespace antlr4;
using namespace antlr4;
namespace {
struct SysYLexerStaticData final {
SysYLexerStaticData(std::vector<std::string> ruleNames,
std::vector<std::string> channelNames,
std::vector<std::string> modeNames,
std::vector<std::string> literalNames,
std::vector<std::string> symbolicNames)
: ruleNames(std::move(ruleNames)), channelNames(std::move(channelNames)),
modeNames(std::move(modeNames)), literalNames(std::move(literalNames)),
symbolicNames(std::move(symbolicNames)),
vocabulary(this->literalNames, this->symbolicNames) {}
SysYLexerStaticData(const SysYLexerStaticData&) = delete;
SysYLexerStaticData(SysYLexerStaticData&&) = delete;
SysYLexerStaticData& operator=(const SysYLexerStaticData&) = delete;
SysYLexerStaticData& operator=(SysYLexerStaticData&&) = delete;
std::vector<antlr4::dfa::DFA> decisionToDFA;
antlr4::atn::PredictionContextCache sharedContextCache;
const std::vector<std::string> ruleNames;
const std::vector<std::string> channelNames;
const std::vector<std::string> modeNames;
const std::vector<std::string> literalNames;
const std::vector<std::string> symbolicNames;
const antlr4::dfa::Vocabulary vocabulary;
antlr4::atn::SerializedATNView serializedATN;
std::unique_ptr<antlr4::atn::ATN> atn;
};
::antlr4::internal::OnceFlag sysylexerLexerOnceFlag;
#if ANTLR4_USE_THREAD_LOCAL_CACHE
static thread_local
#endif
std::unique_ptr<SysYLexerStaticData> sysylexerLexerStaticData = nullptr;
void sysylexerLexerInitialize() {
#if ANTLR4_USE_THREAD_LOCAL_CACHE
if (sysylexerLexerStaticData != nullptr) {
return;
}
#else
assert(sysylexerLexerStaticData == nullptr);
#endif
auto staticData = std::make_unique<SysYLexerStaticData>(
std::vector<std::string>{
"Void", "Int", "Float", "Const", "If", "Else", "While", "Break", "Continue",
"Return", "AddOp", "SubOp", "Assign", "MulOp", "DivOp", "ModOp", "NotOp",
"AndOp", "OrOp", "EqOp", "NeOp", "LtOp", "GtOp", "LeOp", "GeOp", "Semi",
"Comma", "L_PAREN", "R_PAREN", "L_BRACE", "R_BRACE", "L_BRACKET",
"R_BRACKET", "Ident", "IntConst", "FloatConst", "DecFloatConst", "DecFrac",
"DecExp", "HexFloatConst", "HexFrac", "BinExp", "WS", "COMMENT", "BLOCK_COMMENT"
},
std::vector<std::string>{
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
},
std::vector<std::string>{
"DEFAULT_MODE"
},
std::vector<std::string>{
"", "'void'", "'int'", "'float'", "'const'", "'if'", "'else'", "'while'",
"'break'", "'continue'", "'return'", "'+'", "'-'", "'='", "'*'", "'/'",
"'%'", "'!'", "'&&'", "'||'", "'=='", "'!='", "'<'", "'>'", "'<='",
"'>='", "';'", "','", "'('", "')'", "'{'", "'}'", "'['", "']'"
},
std::vector<std::string>{
"", "Void", "Int", "Float", "Const", "If", "Else", "While", "Break",
"Continue", "Return", "AddOp", "SubOp", "Assign", "MulOp", "DivOp",
"ModOp", "NotOp", "AndOp", "OrOp", "EqOp", "NeOp", "LtOp", "GtOp",
"LeOp", "GeOp", "Semi", "Comma", "L_PAREN", "R_PAREN", "L_BRACE",
"R_BRACE", "L_BRACKET", "R_BRACKET", "Ident", "IntConst", "FloatConst",
"WS", "COMMENT", "BLOCK_COMMENT"
}
);
static const int32_t serializedATNSegment[] = {
4,0,39,351,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7,
6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13,2,14,
7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,2,20,7,20,2,21,
7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2,26,7,26,2,27,7,27,2,28,
7,28,2,29,7,29,2,30,7,30,2,31,7,31,2,32,7,32,2,33,7,33,2,34,7,34,2,35,
7,35,2,36,7,36,2,37,7,37,2,38,7,38,2,39,7,39,2,40,7,40,2,41,7,41,2,42,
7,42,2,43,7,43,2,44,7,44,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,2,1,2,
1,2,1,2,1,2,1,2,1,3,1,3,1,3,1,3,1,3,1,3,1,4,1,4,1,4,1,5,1,5,1,5,1,5,1,
5,1,6,1,6,1,6,1,6,1,6,1,6,1,7,1,7,1,7,1,7,1,7,1,7,1,8,1,8,1,8,1,8,1,8,
1,8,1,8,1,8,1,8,1,9,1,9,1,9,1,9,1,9,1,9,1,9,1,10,1,10,1,11,1,11,1,12,
1,12,1,13,1,13,1,14,1,14,1,15,1,15,1,16,1,16,1,17,1,17,1,17,1,18,1,18,
1,18,1,19,1,19,1,19,1,20,1,20,1,20,1,21,1,21,1,22,1,22,1,23,1,23,1,23,
1,24,1,24,1,24,1,25,1,25,1,26,1,26,1,27,1,27,1,28,1,28,1,29,1,29,1,30,
1,30,1,31,1,31,1,32,1,32,1,33,1,33,5,33,203,8,33,10,33,12,33,206,9,33,
1,34,1,34,1,34,4,34,211,8,34,11,34,12,34,212,1,34,1,34,5,34,217,8,34,
10,34,12,34,220,9,34,1,34,1,34,5,34,224,8,34,10,34,12,34,227,9,34,3,34,
229,8,34,1,35,1,35,3,35,233,8,35,1,36,1,36,3,36,237,8,36,1,36,4,36,240,
8,36,11,36,12,36,241,1,36,3,36,245,8,36,1,37,4,37,248,8,37,11,37,12,37,
249,1,37,1,37,5,37,254,8,37,10,37,12,37,257,9,37,1,37,1,37,4,37,261,8,
37,11,37,12,37,262,3,37,265,8,37,1,38,1,38,3,38,269,8,38,1,38,4,38,272,
8,38,11,38,12,38,273,1,39,1,39,1,39,1,39,1,39,1,39,1,39,1,39,4,39,284,
8,39,11,39,12,39,285,1,39,3,39,289,8,39,1,40,4,40,292,8,40,11,40,12,40,
293,1,40,1,40,5,40,298,8,40,10,40,12,40,301,9,40,1,40,1,40,4,40,305,8,
40,11,40,12,40,306,3,40,309,8,40,1,41,1,41,3,41,313,8,41,1,41,4,41,316,
8,41,11,41,12,41,317,1,42,4,42,321,8,42,11,42,12,42,322,1,42,1,42,1,43,
1,43,1,43,1,43,5,43,331,8,43,10,43,12,43,334,9,43,1,43,1,43,1,44,1,44,
1,44,1,44,5,44,342,8,44,10,44,12,44,345,9,44,1,44,1,44,1,44,1,44,1,44,
1,343,0,45,1,1,3,2,5,3,7,4,9,5,11,6,13,7,15,8,17,9,19,10,21,11,23,12,
25,13,27,14,29,15,31,16,33,17,35,18,37,19,39,20,41,21,43,22,45,23,47,
24,49,25,51,26,53,27,55,28,57,29,59,30,61,31,63,32,65,33,67,34,69,35,
71,36,73,0,75,0,77,0,79,0,81,0,83,0,85,37,87,38,89,39,1,0,12,3,0,65,90,
95,95,97,122,4,0,48,57,65,90,95,95,97,122,2,0,88,88,120,120,3,0,48,57,
65,70,97,102,1,0,48,55,1,0,49,57,1,0,48,57,2,0,69,69,101,101,2,0,43,43,
45,45,2,0,80,80,112,112,3,0,9,10,13,13,32,32,2,0,10,10,13,13,371,0,1,
1,0,0,0,0,3,1,0,0,0,0,5,1,0,0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,
0,13,1,0,0,0,0,15,1,0,0,0,0,17,1,0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0,23,
1,0,0,0,0,25,1,0,0,0,0,27,1,0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0,33,1,0,
0,0,0,35,1,0,0,0,0,37,1,0,0,0,0,39,1,0,0,0,0,41,1,0,0,0,0,43,1,0,0,0,
0,45,1,0,0,0,0,47,1,0,0,0,0,49,1,0,0,0,0,51,1,0,0,0,0,53,1,0,0,0,0,55,
1,0,0,0,0,57,1,0,0,0,0,59,1,0,0,0,0,61,1,0,0,0,0,63,1,0,0,0,0,65,1,0,
0,0,0,67,1,0,0,0,0,69,1,0,0,0,0,71,1,0,0,0,0,85,1,0,0,0,0,87,1,0,0,0,
0,89,1,0,0,0,1,91,1,0,0,0,3,96,1,0,0,0,5,100,1,0,0,0,7,106,1,0,0,0,9,
112,1,0,0,0,11,115,1,0,0,0,13,120,1,0,0,0,15,126,1,0,0,0,17,132,1,0,0,
0,19,141,1,0,0,0,21,148,1,0,0,0,23,150,1,0,0,0,25,152,1,0,0,0,27,154,
1,0,0,0,29,156,1,0,0,0,31,158,1,0,0,0,33,160,1,0,0,0,35,162,1,0,0,0,37,
165,1,0,0,0,39,168,1,0,0,0,41,171,1,0,0,0,43,174,1,0,0,0,45,176,1,0,0,
0,47,178,1,0,0,0,49,181,1,0,0,0,51,184,1,0,0,0,53,186,1,0,0,0,55,188,
1,0,0,0,57,190,1,0,0,0,59,192,1,0,0,0,61,194,1,0,0,0,63,196,1,0,0,0,65,
198,1,0,0,0,67,200,1,0,0,0,69,228,1,0,0,0,71,232,1,0,0,0,73,244,1,0,0,
0,75,264,1,0,0,0,77,266,1,0,0,0,79,288,1,0,0,0,81,308,1,0,0,0,83,310,
1,0,0,0,85,320,1,0,0,0,87,326,1,0,0,0,89,337,1,0,0,0,91,92,5,118,0,0,
92,93,5,111,0,0,93,94,5,105,0,0,94,95,5,100,0,0,95,2,1,0,0,0,96,97,5,
105,0,0,97,98,5,110,0,0,98,99,5,116,0,0,99,4,1,0,0,0,100,101,5,102,0,
0,101,102,5,108,0,0,102,103,5,111,0,0,103,104,5,97,0,0,104,105,5,116,
0,0,105,6,1,0,0,0,106,107,5,99,0,0,107,108,5,111,0,0,108,109,5,110,0,
0,109,110,5,115,0,0,110,111,5,116,0,0,111,8,1,0,0,0,112,113,5,105,0,0,
113,114,5,102,0,0,114,10,1,0,0,0,115,116,5,101,0,0,116,117,5,108,0,0,
117,118,5,115,0,0,118,119,5,101,0,0,119,12,1,0,0,0,120,121,5,119,0,0,
121,122,5,104,0,0,122,123,5,105,0,0,123,124,5,108,0,0,124,125,5,101,0,
0,125,14,1,0,0,0,126,127,5,98,0,0,127,128,5,114,0,0,128,129,5,101,0,0,
129,130,5,97,0,0,130,131,5,107,0,0,131,16,1,0,0,0,132,133,5,99,0,0,133,
134,5,111,0,0,134,135,5,110,0,0,135,136,5,116,0,0,136,137,5,105,0,0,137,
138,5,110,0,0,138,139,5,117,0,0,139,140,5,101,0,0,140,18,1,0,0,0,141,
142,5,114,0,0,142,143,5,101,0,0,143,144,5,116,0,0,144,145,5,117,0,0,145,
146,5,114,0,0,146,147,5,110,0,0,147,20,1,0,0,0,148,149,5,43,0,0,149,22,
1,0,0,0,150,151,5,45,0,0,151,24,1,0,0,0,152,153,5,61,0,0,153,26,1,0,0,
0,154,155,5,42,0,0,155,28,1,0,0,0,156,157,5,47,0,0,157,30,1,0,0,0,158,
159,5,37,0,0,159,32,1,0,0,0,160,161,5,33,0,0,161,34,1,0,0,0,162,163,5,
38,0,0,163,164,5,38,0,0,164,36,1,0,0,0,165,166,5,124,0,0,166,167,5,124,
0,0,167,38,1,0,0,0,168,169,5,61,0,0,169,170,5,61,0,0,170,40,1,0,0,0,171,
172,5,33,0,0,172,173,5,61,0,0,173,42,1,0,0,0,174,175,5,60,0,0,175,44,
1,0,0,0,176,177,5,62,0,0,177,46,1,0,0,0,178,179,5,60,0,0,179,180,5,61,
0,0,180,48,1,0,0,0,181,182,5,62,0,0,182,183,5,61,0,0,183,50,1,0,0,0,184,
185,5,59,0,0,185,52,1,0,0,0,186,187,5,44,0,0,187,54,1,0,0,0,188,189,5,
40,0,0,189,56,1,0,0,0,190,191,5,41,0,0,191,58,1,0,0,0,192,193,5,123,0,
0,193,60,1,0,0,0,194,195,5,125,0,0,195,62,1,0,0,0,196,197,5,91,0,0,197,
64,1,0,0,0,198,199,5,93,0,0,199,66,1,0,0,0,200,204,7,0,0,0,201,203,7,
1,0,0,202,201,1,0,0,0,203,206,1,0,0,0,204,202,1,0,0,0,204,205,1,0,0,0,
205,68,1,0,0,0,206,204,1,0,0,0,207,208,5,48,0,0,208,210,7,2,0,0,209,211,
7,3,0,0,210,209,1,0,0,0,211,212,1,0,0,0,212,210,1,0,0,0,212,213,1,0,0,
0,213,229,1,0,0,0,214,218,5,48,0,0,215,217,7,4,0,0,216,215,1,0,0,0,217,
220,1,0,0,0,218,216,1,0,0,0,218,219,1,0,0,0,219,229,1,0,0,0,220,218,1,
0,0,0,221,225,7,5,0,0,222,224,7,6,0,0,223,222,1,0,0,0,224,227,1,0,0,0,
225,223,1,0,0,0,225,226,1,0,0,0,226,229,1,0,0,0,227,225,1,0,0,0,228,207,
1,0,0,0,228,214,1,0,0,0,228,221,1,0,0,0,229,70,1,0,0,0,230,233,3,73,36,
0,231,233,3,79,39,0,232,230,1,0,0,0,232,231,1,0,0,0,233,72,1,0,0,0,234,
236,3,75,37,0,235,237,3,77,38,0,236,235,1,0,0,0,236,237,1,0,0,0,237,245,
1,0,0,0,238,240,7,6,0,0,239,238,1,0,0,0,240,241,1,0,0,0,241,239,1,0,0,
0,241,242,1,0,0,0,242,243,1,0,0,0,243,245,3,77,38,0,244,234,1,0,0,0,244,
239,1,0,0,0,245,74,1,0,0,0,246,248,7,6,0,0,247,246,1,0,0,0,248,249,1,
0,0,0,249,247,1,0,0,0,249,250,1,0,0,0,250,251,1,0,0,0,251,255,5,46,0,
0,252,254,7,6,0,0,253,252,1,0,0,0,254,257,1,0,0,0,255,253,1,0,0,0,255,
256,1,0,0,0,256,265,1,0,0,0,257,255,1,0,0,0,258,260,5,46,0,0,259,261,
7,6,0,0,260,259,1,0,0,0,261,262,1,0,0,0,262,260,1,0,0,0,262,263,1,0,0,
0,263,265,1,0,0,0,264,247,1,0,0,0,264,258,1,0,0,0,265,76,1,0,0,0,266,
268,7,7,0,0,267,269,7,8,0,0,268,267,1,0,0,0,268,269,1,0,0,0,269,271,1,
0,0,0,270,272,7,6,0,0,271,270,1,0,0,0,272,273,1,0,0,0,273,271,1,0,0,0,
273,274,1,0,0,0,274,78,1,0,0,0,275,276,5,48,0,0,276,277,7,2,0,0,277,278,
3,81,40,0,278,279,3,83,41,0,279,289,1,0,0,0,280,281,5,48,0,0,281,283,
7,2,0,0,282,284,7,3,0,0,283,282,1,0,0,0,284,285,1,0,0,0,285,283,1,0,0,
0,285,286,1,0,0,0,286,287,1,0,0,0,287,289,3,83,41,0,288,275,1,0,0,0,288,
280,1,0,0,0,289,80,1,0,0,0,290,292,7,3,0,0,291,290,1,0,0,0,292,293,1,
0,0,0,293,291,1,0,0,0,293,294,1,0,0,0,294,295,1,0,0,0,295,299,5,46,0,
0,296,298,7,3,0,0,297,296,1,0,0,0,298,301,1,0,0,0,299,297,1,0,0,0,299,
300,1,0,0,0,300,309,1,0,0,0,301,299,1,0,0,0,302,304,5,46,0,0,303,305,
7,3,0,0,304,303,1,0,0,0,305,306,1,0,0,0,306,304,1,0,0,0,306,307,1,0,0,
0,307,309,1,0,0,0,308,291,1,0,0,0,308,302,1,0,0,0,309,82,1,0,0,0,310,
312,7,9,0,0,311,313,7,8,0,0,312,311,1,0,0,0,312,313,1,0,0,0,313,315,1,
0,0,0,314,316,7,6,0,0,315,314,1,0,0,0,316,317,1,0,0,0,317,315,1,0,0,0,
317,318,1,0,0,0,318,84,1,0,0,0,319,321,7,10,0,0,320,319,1,0,0,0,321,322,
1,0,0,0,322,320,1,0,0,0,322,323,1,0,0,0,323,324,1,0,0,0,324,325,6,42,
0,0,325,86,1,0,0,0,326,327,5,47,0,0,327,328,5,47,0,0,328,332,1,0,0,0,
329,331,8,11,0,0,330,329,1,0,0,0,331,334,1,0,0,0,332,330,1,0,0,0,332,
333,1,0,0,0,333,335,1,0,0,0,334,332,1,0,0,0,335,336,6,43,0,0,336,88,1,
0,0,0,337,338,5,47,0,0,338,339,5,42,0,0,339,343,1,0,0,0,340,342,9,0,0,
0,341,340,1,0,0,0,342,345,1,0,0,0,343,344,1,0,0,0,343,341,1,0,0,0,344,
346,1,0,0,0,345,343,1,0,0,0,346,347,5,42,0,0,347,348,5,47,0,0,348,349,
1,0,0,0,349,350,6,44,0,0,350,90,1,0,0,0,27,0,204,212,218,225,228,232,
236,241,244,249,255,262,264,268,273,285,288,293,299,306,308,312,317,322,
332,343,1,6,0,0
};
staticData->serializedATN = antlr4::atn::SerializedATNView(serializedATNSegment, sizeof(serializedATNSegment) / sizeof(serializedATNSegment[0]));
antlr4::atn::ATNDeserializer deserializer;
staticData->atn = deserializer.deserialize(staticData->serializedATN);
const size_t count = staticData->atn->getNumberOfDecisions();
staticData->decisionToDFA.reserve(count);
for (size_t i = 0; i < count; i++) {
staticData->decisionToDFA.emplace_back(staticData->atn->getDecisionState(i), i);
}
sysylexerLexerStaticData = std::move(staticData);
}
}
SysYLexer::SysYLexer(CharStream *input) : Lexer(input) {
SysYLexer::initialize();
_interpreter = new atn::LexerATNSimulator(this, *sysylexerLexerStaticData->atn, sysylexerLexerStaticData->decisionToDFA, sysylexerLexerStaticData->sharedContextCache);
}
SysYLexer::~SysYLexer() {
delete _interpreter;
}
std::string SysYLexer::getGrammarFileName() const {
return "SysY.g4";
}
const std::vector<std::string>& SysYLexer::getRuleNames() const {
return sysylexerLexerStaticData->ruleNames;
}
const std::vector<std::string>& SysYLexer::getChannelNames() const {
return sysylexerLexerStaticData->channelNames;
}
const std::vector<std::string>& SysYLexer::getModeNames() const {
return sysylexerLexerStaticData->modeNames;
}
const dfa::Vocabulary& SysYLexer::getVocabulary() const {
return sysylexerLexerStaticData->vocabulary;
}
antlr4::atn::SerializedATNView SysYLexer::getSerializedATN() const {
return sysylexerLexerStaticData->serializedATN;
}
const atn::ATN& SysYLexer::getATN() const {
return *sysylexerLexerStaticData->atn;
}
void SysYLexer::initialize() {
#if ANTLR4_USE_THREAD_LOCAL_CACHE
sysylexerLexerInitialize();
#else
::antlr4::internal::call_once(sysylexerLexerOnceFlag, sysylexerLexerInitialize);
#endif
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,7 @@
// Generated from src/antlr4/SysY.g4 by ANTLR 4.13.2
#include "SysYVisitor.h"

@ -0,0 +1,144 @@
// Generated from src/antlr4/SysY.g4 by ANTLR 4.13.2
#pragma once
#include "antlr4-runtime.h"
#include "SysYVisitor.h"
/**
* This class provides an empty implementation of SysYVisitor, which can be
* extended to create a visitor which only needs to handle a subset of the available methods.
*/
class SysYBaseVisitor : public SysYVisitor {
public:
virtual std::any visitCompUnit(SysYParser::CompUnitContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitFuncDef(SysYParser::FuncDefContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitFuncType(SysYParser::FuncTypeContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitBlock(SysYParser::BlockContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitBlockItem(SysYParser::BlockItemContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitDecl(SysYParser::DeclContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitConstDecl(SysYParser::ConstDeclContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitBType(SysYParser::BTypeContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitConstDef(SysYParser::ConstDefContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitConstInitVal(SysYParser::ConstInitValContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitStmt(SysYParser::StmtContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitCond(SysYParser::CondContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitLVal(SysYParser::LValContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitPrimaryExp(SysYParser::PrimaryExpContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitNumber(SysYParser::NumberContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitUnaryOp(SysYParser::UnaryOpContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitMulExp(SysYParser::MulExpContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitAddExp(SysYParser::AddExpContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitRelExp(SysYParser::RelExpContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitEqExp(SysYParser::EqExpContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitLAndExp(SysYParser::LAndExpContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitLOrExp(SysYParser::LOrExpContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitConstExp(SysYParser::ConstExpContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitVarDecl(SysYParser::VarDeclContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitVarDef(SysYParser::VarDefContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitInitVal(SysYParser::InitValContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitExp(SysYParser::ExpContext *ctx) override {
return visitChildren(ctx);
}
};

@ -0,0 +1,55 @@
// Generated from src/antlr4/SysY.g4 by ANTLR 4.13.2
#pragma once
#include "antlr4-runtime.h"
class SysYLexer : public antlr4::Lexer {
public:
enum {
Void = 1, Int = 2, Float = 3, Const = 4, If = 5, Else = 6, While = 7,
Break = 8, Continue = 9, Return = 10, AddOp = 11, SubOp = 12, Assign = 13,
MulOp = 14, DivOp = 15, ModOp = 16, NotOp = 17, AndOp = 18, OrOp = 19,
EqOp = 20, NeOp = 21, LtOp = 22, GtOp = 23, LeOp = 24, GeOp = 25, Semi = 26,
Comma = 27, L_PAREN = 28, R_PAREN = 29, L_BRACE = 30, R_BRACE = 31,
L_BRACKET = 32, R_BRACKET = 33, Ident = 34, IntConst = 35, FloatConst = 36,
WS = 37, COMMENT = 38, BLOCK_COMMENT = 39
};
explicit SysYLexer(antlr4::CharStream *input);
~SysYLexer() override;
std::string getGrammarFileName() const override;
const std::vector<std::string>& getRuleNames() const override;
const std::vector<std::string>& getChannelNames() const override;
const std::vector<std::string>& getModeNames() const override;
const antlr4::dfa::Vocabulary& getVocabulary() const override;
antlr4::atn::SerializedATNView getSerializedATN() const override;
const antlr4::atn::ATN& getATN() const override;
// By default the static state used to implement the lexer is lazily initialized during the first
// call to the constructor. You can call this function if you wish to initialize the static state
// ahead of time.
static void initialize();
private:
// Individual action functions triggered by action() above.
// Individual semantic predicate functions triggered by sempred() above.
};

@ -0,0 +1,626 @@
// Generated from src/antlr4/SysY.g4 by ANTLR 4.13.2
#pragma once
#include "antlr4-runtime.h"
class SysYParser : public antlr4::Parser {
public:
enum {
Void = 1, Int = 2, Float = 3, Const = 4, If = 5, Else = 6, While = 7,
Break = 8, Continue = 9, Return = 10, AddOp = 11, SubOp = 12, Assign = 13,
MulOp = 14, DivOp = 15, ModOp = 16, NotOp = 17, AndOp = 18, OrOp = 19,
EqOp = 20, NeOp = 21, LtOp = 22, GtOp = 23, LeOp = 24, GeOp = 25, Semi = 26,
Comma = 27, L_PAREN = 28, R_PAREN = 29, L_BRACE = 30, R_BRACE = 31,
L_BRACKET = 32, R_BRACKET = 33, Ident = 34, IntConst = 35, FloatConst = 36,
WS = 37, COMMENT = 38, BLOCK_COMMENT = 39
};
enum {
RuleCompUnit = 0, RuleFuncDef = 1, RuleFuncType = 2, RuleFuncFParams = 3,
RuleFuncFParam = 4, RuleBlock = 5, RuleBlockItem = 6, RuleDecl = 7,
RuleConstDecl = 8, RuleBType = 9, RuleConstDef = 10, RuleConstInitVal = 11,
RuleStmt = 12, RuleCond = 13, RuleLVal = 14, RulePrimaryExp = 15, RuleNumber = 16,
RuleUnaryExp = 17, RuleUnaryOp = 18, RuleFuncRParams = 19, RuleMulExp = 20,
RuleAddExp = 21, RuleRelExp = 22, RuleEqExp = 23, RuleLAndExp = 24,
RuleLOrExp = 25, RuleConstExp = 26, RuleVarDecl = 27, RuleVarDef = 28,
RuleInitVal = 29, RuleExp = 30
};
explicit SysYParser(antlr4::TokenStream *input);
SysYParser(antlr4::TokenStream *input, const antlr4::atn::ParserATNSimulatorOptions &options);
~SysYParser() override;
std::string getGrammarFileName() const override;
const antlr4::atn::ATN& getATN() const override;
const std::vector<std::string>& getRuleNames() const override;
const antlr4::dfa::Vocabulary& getVocabulary() const override;
antlr4::atn::SerializedATNView getSerializedATN() const override;
class CompUnitContext;
class FuncDefContext;
class FuncTypeContext;
class FuncFParamsContext;
class FuncFParamContext;
class BlockContext;
class BlockItemContext;
class DeclContext;
class ConstDeclContext;
class BTypeContext;
class ConstDefContext;
class ConstInitValContext;
class StmtContext;
class CondContext;
class LValContext;
class PrimaryExpContext;
class NumberContext;
class UnaryExpContext;
class UnaryOpContext;
class FuncRParamsContext;
class MulExpContext;
class AddExpContext;
class RelExpContext;
class EqExpContext;
class LAndExpContext;
class LOrExpContext;
class ConstExpContext;
class VarDeclContext;
class VarDefContext;
class InitValContext;
class ExpContext;
class CompUnitContext : public antlr4::ParserRuleContext {
public:
CompUnitContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *EOF();
std::vector<FuncDefContext *> funcDef();
FuncDefContext* funcDef(size_t i);
std::vector<DeclContext *> decl();
DeclContext* decl(size_t i);
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
CompUnitContext* compUnit();
class FuncDefContext : public antlr4::ParserRuleContext {
public:
FuncDefContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
FuncTypeContext *funcType();
antlr4::tree::TerminalNode *Ident();
antlr4::tree::TerminalNode *L_PAREN();
antlr4::tree::TerminalNode *R_PAREN();
BlockContext *block();
FuncFParamsContext *funcFParams();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
FuncDefContext* funcDef();
class FuncTypeContext : public antlr4::ParserRuleContext {
public:
FuncTypeContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *Void();
antlr4::tree::TerminalNode *Int();
antlr4::tree::TerminalNode *Float();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
FuncTypeContext* funcType();
class FuncFParamsContext : public antlr4::ParserRuleContext {
public:
FuncFParamsContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
std::vector<FuncFParamContext *> funcFParam();
FuncFParamContext* funcFParam(size_t i);
std::vector<antlr4::tree::TerminalNode *> Comma();
antlr4::tree::TerminalNode* Comma(size_t i);
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
FuncFParamsContext* funcFParams();
class FuncFParamContext : public antlr4::ParserRuleContext {
public:
FuncFParamContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
BTypeContext *bType();
antlr4::tree::TerminalNode *Ident();
std::vector<antlr4::tree::TerminalNode *> L_BRACKET();
antlr4::tree::TerminalNode* L_BRACKET(size_t i);
std::vector<antlr4::tree::TerminalNode *> R_BRACKET();
antlr4::tree::TerminalNode* R_BRACKET(size_t i);
std::vector<ExpContext *> exp();
ExpContext* exp(size_t i);
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
FuncFParamContext* funcFParam();
class BlockContext : public antlr4::ParserRuleContext {
public:
BlockContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *L_BRACE();
antlr4::tree::TerminalNode *R_BRACE();
std::vector<BlockItemContext *> blockItem();
BlockItemContext* blockItem(size_t i);
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
BlockContext* block();
class BlockItemContext : public antlr4::ParserRuleContext {
public:
BlockItemContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
DeclContext *decl();
StmtContext *stmt();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
BlockItemContext* blockItem();
class DeclContext : public antlr4::ParserRuleContext {
public:
DeclContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
VarDeclContext *varDecl();
ConstDeclContext *constDecl();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
DeclContext* decl();
class ConstDeclContext : public antlr4::ParserRuleContext {
public:
ConstDeclContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *Const();
BTypeContext *bType();
std::vector<ConstDefContext *> constDef();
ConstDefContext* constDef(size_t i);
antlr4::tree::TerminalNode *Semi();
std::vector<antlr4::tree::TerminalNode *> Comma();
antlr4::tree::TerminalNode* Comma(size_t i);
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
ConstDeclContext* constDecl();
class BTypeContext : public antlr4::ParserRuleContext {
public:
BTypeContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *Int();
antlr4::tree::TerminalNode *Float();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
BTypeContext* bType();
class ConstDefContext : public antlr4::ParserRuleContext {
public:
ConstDefContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *Ident();
antlr4::tree::TerminalNode *Assign();
ConstInitValContext *constInitVal();
std::vector<antlr4::tree::TerminalNode *> L_BRACKET();
antlr4::tree::TerminalNode* L_BRACKET(size_t i);
std::vector<ConstExpContext *> constExp();
ConstExpContext* constExp(size_t i);
std::vector<antlr4::tree::TerminalNode *> R_BRACKET();
antlr4::tree::TerminalNode* R_BRACKET(size_t i);
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
ConstDefContext* constDef();
class ConstInitValContext : public antlr4::ParserRuleContext {
public:
ConstInitValContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
ConstExpContext *constExp();
antlr4::tree::TerminalNode *L_BRACE();
antlr4::tree::TerminalNode *R_BRACE();
std::vector<ConstInitValContext *> constInitVal();
ConstInitValContext* constInitVal(size_t i);
std::vector<antlr4::tree::TerminalNode *> Comma();
antlr4::tree::TerminalNode* Comma(size_t i);
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
ConstInitValContext* constInitVal();
class StmtContext : public antlr4::ParserRuleContext {
public:
StmtContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
LValContext *lVal();
antlr4::tree::TerminalNode *Assign();
ExpContext *exp();
antlr4::tree::TerminalNode *Semi();
BlockContext *block();
antlr4::tree::TerminalNode *If();
antlr4::tree::TerminalNode *L_PAREN();
CondContext *cond();
antlr4::tree::TerminalNode *R_PAREN();
std::vector<StmtContext *> stmt();
StmtContext* stmt(size_t i);
antlr4::tree::TerminalNode *Else();
antlr4::tree::TerminalNode *While();
antlr4::tree::TerminalNode *Break();
antlr4::tree::TerminalNode *Continue();
antlr4::tree::TerminalNode *Return();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
StmtContext* stmt();
class CondContext : public antlr4::ParserRuleContext {
public:
CondContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
LOrExpContext *lOrExp();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
CondContext* cond();
class LValContext : public antlr4::ParserRuleContext {
public:
LValContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *Ident();
std::vector<antlr4::tree::TerminalNode *> L_BRACKET();
antlr4::tree::TerminalNode* L_BRACKET(size_t i);
std::vector<ExpContext *> exp();
ExpContext* exp(size_t i);
std::vector<antlr4::tree::TerminalNode *> R_BRACKET();
antlr4::tree::TerminalNode* R_BRACKET(size_t i);
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
LValContext* lVal();
class PrimaryExpContext : public antlr4::ParserRuleContext {
public:
PrimaryExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *L_PAREN();
ExpContext *exp();
antlr4::tree::TerminalNode *R_PAREN();
LValContext *lVal();
NumberContext *number();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
PrimaryExpContext* primaryExp();
class NumberContext : public antlr4::ParserRuleContext {
public:
NumberContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *IntConst();
antlr4::tree::TerminalNode *FloatConst();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
NumberContext* number();
class UnaryExpContext : public antlr4::ParserRuleContext {
public:
UnaryExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
PrimaryExpContext *primaryExp();
antlr4::tree::TerminalNode *Ident();
antlr4::tree::TerminalNode *L_PAREN();
antlr4::tree::TerminalNode *R_PAREN();
FuncRParamsContext *funcRParams();
UnaryOpContext *unaryOp();
UnaryExpContext *unaryExp();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
UnaryExpContext* unaryExp();
class UnaryOpContext : public antlr4::ParserRuleContext {
public:
UnaryOpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *AddOp();
antlr4::tree::TerminalNode *SubOp();
antlr4::tree::TerminalNode *NotOp();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
UnaryOpContext* unaryOp();
class FuncRParamsContext : public antlr4::ParserRuleContext {
public:
FuncRParamsContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
std::vector<ExpContext *> exp();
ExpContext* exp(size_t i);
std::vector<antlr4::tree::TerminalNode *> Comma();
antlr4::tree::TerminalNode* Comma(size_t i);
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
FuncRParamsContext* funcRParams();
class MulExpContext : public antlr4::ParserRuleContext {
public:
MulExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
UnaryExpContext *unaryExp();
MulExpContext *mulExp();
antlr4::tree::TerminalNode *MulOp();
antlr4::tree::TerminalNode *DivOp();
antlr4::tree::TerminalNode *ModOp();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
MulExpContext* mulExp();
MulExpContext* mulExp(int precedence);
class AddExpContext : public antlr4::ParserRuleContext {
public:
AddExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
MulExpContext *mulExp();
AddExpContext *addExp();
antlr4::tree::TerminalNode *AddOp();
antlr4::tree::TerminalNode *SubOp();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
AddExpContext* addExp();
AddExpContext* addExp(int precedence);
class RelExpContext : public antlr4::ParserRuleContext {
public:
RelExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
AddExpContext *addExp();
RelExpContext *relExp();
antlr4::tree::TerminalNode *LtOp();
antlr4::tree::TerminalNode *GtOp();
antlr4::tree::TerminalNode *LeOp();
antlr4::tree::TerminalNode *GeOp();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
RelExpContext* relExp();
RelExpContext* relExp(int precedence);
class EqExpContext : public antlr4::ParserRuleContext {
public:
EqExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
RelExpContext *relExp();
EqExpContext *eqExp();
antlr4::tree::TerminalNode *EqOp();
antlr4::tree::TerminalNode *NeOp();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
EqExpContext* eqExp();
EqExpContext* eqExp(int precedence);
class LAndExpContext : public antlr4::ParserRuleContext {
public:
LAndExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
EqExpContext *eqExp();
LAndExpContext *lAndExp();
antlr4::tree::TerminalNode *AndOp();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
LAndExpContext* lAndExp();
LAndExpContext* lAndExp(int precedence);
class LOrExpContext : public antlr4::ParserRuleContext {
public:
LOrExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
LAndExpContext *lAndExp();
LOrExpContext *lOrExp();
antlr4::tree::TerminalNode *OrOp();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
LOrExpContext* lOrExp();
LOrExpContext* lOrExp(int precedence);
class ConstExpContext : public antlr4::ParserRuleContext {
public:
ConstExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
AddExpContext *addExp();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
ConstExpContext* constExp();
class VarDeclContext : public antlr4::ParserRuleContext {
public:
VarDeclContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
BTypeContext *bType();
std::vector<VarDefContext *> varDef();
VarDefContext* varDef(size_t i);
antlr4::tree::TerminalNode *Semi();
std::vector<antlr4::tree::TerminalNode *> Comma();
antlr4::tree::TerminalNode* Comma(size_t i);
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
VarDeclContext* varDecl();
class VarDefContext : public antlr4::ParserRuleContext {
public:
VarDefContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
antlr4::tree::TerminalNode *Ident();
std::vector<antlr4::tree::TerminalNode *> L_BRACKET();
antlr4::tree::TerminalNode* L_BRACKET(size_t i);
std::vector<ConstExpContext *> constExp();
ConstExpContext* constExp(size_t i);
std::vector<antlr4::tree::TerminalNode *> R_BRACKET();
antlr4::tree::TerminalNode* R_BRACKET(size_t i);
antlr4::tree::TerminalNode *Assign();
InitValContext *initVal();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
VarDefContext* varDef();
class InitValContext : public antlr4::ParserRuleContext {
public:
InitValContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
ExpContext *exp();
antlr4::tree::TerminalNode *L_BRACE();
antlr4::tree::TerminalNode *R_BRACE();
std::vector<InitValContext *> initVal();
InitValContext* initVal(size_t i);
std::vector<antlr4::tree::TerminalNode *> Comma();
antlr4::tree::TerminalNode* Comma(size_t i);
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
InitValContext* initVal();
class ExpContext : public antlr4::ParserRuleContext {
public:
ExpContext(antlr4::ParserRuleContext *parent, size_t invokingState);
virtual size_t getRuleIndex() const override;
AddExpContext *addExp();
virtual std::any accept(antlr4::tree::ParseTreeVisitor *visitor) override;
};
ExpContext* exp();
bool sempred(antlr4::RuleContext *_localctx, size_t ruleIndex, size_t predicateIndex) override;
bool mulExpSempred(MulExpContext *_localctx, size_t predicateIndex);
bool addExpSempred(AddExpContext *_localctx, size_t predicateIndex);
bool relExpSempred(RelExpContext *_localctx, size_t predicateIndex);
bool eqExpSempred(EqExpContext *_localctx, size_t predicateIndex);
bool lAndExpSempred(LAndExpContext *_localctx, size_t predicateIndex);
bool lOrExpSempred(LOrExpContext *_localctx, size_t predicateIndex);
// By default the static state used to implement the parser is lazily initialized during the first
// call to the constructor. You can call this function if you wish to initialize the static state
// ahead of time.
static void initialize();
private:
};

@ -0,0 +1,86 @@
// Generated from src/antlr4/SysY.g4 by ANTLR 4.13.2
#pragma once
#include "antlr4-runtime.h"
#include "SysYParser.h"
/**
* This class defines an abstract visitor for a parse tree
* produced by SysYParser.
*/
class SysYVisitor : public antlr4::tree::AbstractParseTreeVisitor {
public:
/**
* Visit parse trees produced by SysYParser.
*/
virtual std::any visitCompUnit(SysYParser::CompUnitContext *context) = 0;
virtual std::any visitFuncDef(SysYParser::FuncDefContext *context) = 0;
virtual std::any visitFuncType(SysYParser::FuncTypeContext *context) = 0;
virtual std::any visitFuncFParams(SysYParser::FuncFParamsContext *context) = 0;
virtual std::any visitFuncFParam(SysYParser::FuncFParamContext *context) = 0;
virtual std::any visitBlock(SysYParser::BlockContext *context) = 0;
virtual std::any visitBlockItem(SysYParser::BlockItemContext *context) = 0;
virtual std::any visitDecl(SysYParser::DeclContext *context) = 0;
virtual std::any visitConstDecl(SysYParser::ConstDeclContext *context) = 0;
virtual std::any visitBType(SysYParser::BTypeContext *context) = 0;
virtual std::any visitConstDef(SysYParser::ConstDefContext *context) = 0;
virtual std::any visitConstInitVal(SysYParser::ConstInitValContext *context) = 0;
virtual std::any visitStmt(SysYParser::StmtContext *context) = 0;
virtual std::any visitCond(SysYParser::CondContext *context) = 0;
virtual std::any visitLVal(SysYParser::LValContext *context) = 0;
virtual std::any visitPrimaryExp(SysYParser::PrimaryExpContext *context) = 0;
virtual std::any visitNumber(SysYParser::NumberContext *context) = 0;
virtual std::any visitUnaryExp(SysYParser::UnaryExpContext *context) = 0;
virtual std::any visitUnaryOp(SysYParser::UnaryOpContext *context) = 0;
virtual std::any visitFuncRParams(SysYParser::FuncRParamsContext *context) = 0;
virtual std::any visitMulExp(SysYParser::MulExpContext *context) = 0;
virtual std::any visitAddExp(SysYParser::AddExpContext *context) = 0;
virtual std::any visitRelExp(SysYParser::RelExpContext *context) = 0;
virtual std::any visitEqExp(SysYParser::EqExpContext *context) = 0;
virtual std::any visitLAndExp(SysYParser::LAndExpContext *context) = 0;
virtual std::any visitLOrExp(SysYParser::LOrExpContext *context) = 0;
virtual std::any visitConstExp(SysYParser::ConstExpContext *context) = 0;
virtual std::any visitVarDecl(SysYParser::VarDeclContext *context) = 0;
virtual std::any visitVarDef(SysYParser::VarDefContext *context) = 0;
virtual std::any visitInitVal(SysYParser::InitValContext *context) = 0;
virtual std::any visitExp(SysYParser::ExpContext *context) = 0;
};

@ -0,0 +1,20 @@
// 包装 ANTLR4提供简易的解析入口。
#pragma once
#include <memory>
#include <string>
#include "SysYLexer.h"
#include "SysYParser.h"
#include "antlr4-runtime.h"
struct AntlrResult {
std::unique_ptr<antlr4::ANTLRInputStream> input;
std::unique_ptr<SysYLexer> lexer;
std::unique_ptr<antlr4::CommonTokenStream> tokens;
std::unique_ptr<SysYParser> parser;
antlr4::tree::ParseTree* tree = nullptr; // owned by parser
};
// 解析指定文件,发生错误时抛出 std::runtime_error。
AntlrResult ParseFileWithAntlr(const std::string& path);

@ -0,0 +1,9 @@
#pragma once
#include <iosfwd>
#include "antlr4-runtime.h"
// 以树状缩进形式直接打印 ANTLR parse tree。
void PrintSyntaxTree(antlr4::tree::ParseTree* tree, antlr4::Parser* parser,
std::ostream& os);

@ -0,0 +1,545 @@
// 当前只支撑 i32、i32*、void 以及最小的内存/算术指令,演示用。
//
// 当前已经实现:
// 1. 基础类型系统void / i32 / i32*
// 2. Value 体系Value / ConstantValue / ConstantInt / Function / BasicBlock / User / GlobalValue / Instruction
// 3. 最小指令集Add / Alloca / Load / Store / Ret
// 4. BasicBlock / Function / Module 三层组织结构
// 5. IRBuilder便捷创建常量和最小指令
// 6. def-use 关系的轻量实现:
// - Instruction 保存 operand 列表
// - Value 保存 uses
// - 支持 ReplaceAllUsesWith 的简化实现
//
// 当前尚未实现或只做了最小占位:
// 1. 完整类型系统数组、函数类型、label 类型等
// 2. 更完整的指令系统br / condbr / call / phi / gep 等
// 3. 更成熟的 Use 管理(例如 LLVM 风格的双向链式结构)
// 4. 更完整的 IR verifier 和优化基础设施
//
// 当前需要特别说明的两个简化点:
// 1. BasicBlock 虽然已经纳入 Value 体系,但其类型目前仍用 void 作为占位,
// 后续如果补 label type可以再改成更合理的块标签类型。
// 2. ConstantValue 体系目前只实现了 ConstantInt后续可以继续补 ConstantFloat、
// ConstantArray等更完整的常量种类。
//
// 建议的扩展顺序:
// 1. 先补更多指令和类型
// 2. 再补控制流相关 IR
// 3. 最后再考虑把 Value/User/Use 进一步抽象成更完整的框架
#pragma once
#include <iosfwd>
#include <memory>
#include <stdexcept>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
namespace ir {
class Type;
class Value;
class User;
class ConstantValue;
class ConstantInt;
class ConstantFloat;
class GlobalValue;
class Instruction;
class BasicBlock;
class Function;
class Argument;
class GlobalVariable;
// Use 表示一个 Value 的一次使用记录。
// 当前实现设计:
// - value被使用的值
// - user使用该值的 User
// - operand_index该值在 user 操作数列表中的位置
class Use {
public:
Use() = default;
Use(Value* value, User* user, size_t operand_index)
: value_(value), user_(user), operand_index_(operand_index) {}
Value* GetValue() const { return value_; }
User* GetUser() const { return user_; }
size_t GetOperandIndex() const { return operand_index_; }
void SetValue(Value* value) { value_ = value; }
void SetUser(User* user) { user_ = user; }
void SetOperandIndex(size_t operand_index) { operand_index_ = operand_index; }
private:
Value* value_ = nullptr;
User* user_ = nullptr;
size_t operand_index_ = 0;
};
// IR 上下文:集中管理类型、常量等共享资源,便于复用与扩展。
class Context {
public:
Context() = default;
~Context();
// 去重创建 i32 常量。
ConstantInt* GetConstInt(int v);
ConstantFloat* GetConstFloat(double v);
// 去重创建 i1 常量0 或 1
ConstantInt* GetConstBool(int v);
std::string NextTemp();
private:
std::unordered_map<int, std::unique_ptr<ConstantInt>> const_ints_;
std::unordered_map<std::string, std::unique_ptr<ConstantFloat>> const_floats_;
std::unordered_map<int, std::unique_ptr<ConstantInt>> const_bools_;
int temp_index_ = -1;
};
class Type {
public:
enum class Kind { Void, Int1, Int32, Float32, PtrInt32, PtrFloat32 };
explicit Type(Kind k);
// 使用静态共享对象获取类型。
// 同一类型可直接比较返回值是否相等,例如:
// Type::GetInt32Type() == Type::GetInt32Type()
static const std::shared_ptr<Type>& GetVoidType();
static const std::shared_ptr<Type>& GetInt1Type();
static const std::shared_ptr<Type>& GetInt32Type();
static const std::shared_ptr<Type>& GetFloat32Type();
static const std::shared_ptr<Type>& GetPtrInt32Type();
static const std::shared_ptr<Type>& GetPtrFloat32Type();
Kind GetKind() const;
bool IsVoid() const;
bool IsInt1() const;
bool IsInt32() const;
bool IsFloat32() const;
bool IsPtrInt32() const;
bool IsPtrFloat32() const;
private:
Kind kind_;
};
class Value {
public:
Value(std::shared_ptr<Type> ty, std::string name);
virtual ~Value() = default;
const std::shared_ptr<Type>& GetType() const;
const std::string& GetName() const;
void SetName(std::string n);
bool IsVoid() const;
bool IsInt32() const;
bool IsFloat32() const;
bool IsPtrInt32() const;
bool IsPtrFloat32() const;
bool IsConstant() const;
bool IsInstruction() const;
bool IsUser() const;
bool IsFunction() const;
void AddUse(User* user, size_t operand_index);
void RemoveUse(User* user, size_t operand_index);
const std::vector<Use>& GetUses() const;
void ReplaceAllUsesWith(Value* new_value);
protected:
std::shared_ptr<Type> type_;
std::string name_;
std::vector<Use> uses_;
};
// ConstantValue 是常量体系的基类。
// 当前只实现了 ConstantInt后续可继续扩展更多常量种类。
class ConstantValue : public Value {
public:
ConstantValue(std::shared_ptr<Type> ty, std::string name = "");
};
class ConstantInt : public ConstantValue {
public:
ConstantInt(std::shared_ptr<Type> ty, int v);
int GetValue() const { return value_; }
private:
int value_{};
};
class ConstantFloat : public ConstantValue {
public:
ConstantFloat(std::shared_ptr<Type> ty, double v);
double GetValue() const { return value_; }
private:
double value_{};
};
// 后续还需要扩展更多指令类型。
enum class Opcode {
Add,
Sub,
Mul,
Div,
Mod,
SIToFP,
FPToSI,
ZExt,
Eq,
Ne,
Lt,
Le,
Gt,
Ge,
Alloca,
Load,
Store,
GEP,
Call,
Br,
CondBr,
Ret,
Phi
};
// User 是所有“会使用其他 Value 作为输入”的 IR 对象的抽象基类。
// 当前实现中只有 Instruction 继承自 User。
class User : public Value {
public:
User(std::shared_ptr<Type> ty, std::string name);
size_t GetNumOperands() const;
Value* GetOperand(size_t index) const;
void SetOperand(size_t index, Value* value);
void AddOperand(Value* value);
private:
std::vector<Value*> operands_;
};
// GlobalValue 是全局值/全局变量体系的空壳占位类。
// 当前只补齐类层次,具体初始化器、打印和链接语义后续再补。
class GlobalValue : public User {
public:
GlobalValue(std::shared_ptr<Type> ty, std::string name);
};
class GlobalVariable : public GlobalValue {
public:
enum class StorageKind {
Scalar,
Array,
};
enum class ElemKind {
Int32,
Float32,
};
GlobalVariable(std::string name, int init_value);
GlobalVariable(std::string name, double init_value);
GlobalVariable(std::string name, size_t array_size);
GlobalVariable(std::string name, size_t array_size, ElemKind elem_kind);
GlobalVariable(std::string name, size_t array_size, const std::vector<int>& init_values);
GlobalVariable(std::string name, size_t array_size, const std::vector<double>& init_values);
StorageKind GetStorageKind() const;
bool IsArray() const;
ElemKind GetElemKind() const;
bool IsFloatElem() const;
int GetInitValue() const;
double GetInitFloatValue() const;
size_t GetArraySize() const;
const std::vector<int>& GetInitValues() const;
const std::vector<double>& GetInitFloatValues() const;
bool HasInitValues() const;
private:
StorageKind storage_kind_ = StorageKind::Scalar;
ElemKind elem_kind_ = ElemKind::Int32;
int init_value_ = 0;
double init_float_value_ = 0.0;
size_t array_size_ = 0;
std::vector<int> init_values_;
std::vector<double> init_float_values_;
};
class Instruction : public User {
public:
Instruction(Opcode op, std::shared_ptr<Type> ty, std::string name = "");
Opcode GetOpcode() const;
bool IsTerminator() const;
BasicBlock* GetParent() const;
void SetParent(BasicBlock* parent);
private:
Opcode opcode_;
BasicBlock* parent_ = nullptr;
};
class BinaryInst : public Instruction {
public:
BinaryInst(Opcode op, std::shared_ptr<Type> ty, Value* lhs, Value* rhs,
std::string name);
Value* GetLhs() const;
Value* GetRhs() const;
};
class CastInst : public Instruction {
public:
CastInst(Opcode op, std::shared_ptr<Type> ty, Value* operand,
std::string name);
Value* GetOperandValue() const;
};
class BranchInst : public Instruction {
public:
BranchInst(std::shared_ptr<Type> void_ty, BasicBlock* target);
BasicBlock* GetTarget() const;
};
class CondBranchInst : public Instruction {
public:
CondBranchInst(std::shared_ptr<Type> void_ty, Value* cond, BasicBlock* true_bb,
BasicBlock* false_bb);
Value* GetCond() const;
BasicBlock* GetTrueTarget() const;
BasicBlock* GetFalseTarget() const;
};
class CallInst : public Instruction {
public:
CallInst(std::shared_ptr<Type> ret_ty, Function* callee,
const std::vector<Value*>& args, std::string name);
Function* GetCallee() const;
size_t GetNumArgs() const;
Value* GetArg(size_t index) const;
};
class ReturnInst : public Instruction {
public:
ReturnInst(std::shared_ptr<Type> void_ty, Value* val = nullptr);
Value* GetValue() const;
bool HasValue() const;
};
class AllocaInst : public Instruction {
public:
AllocaInst(std::shared_ptr<Type> elem_ty, std::string name,
Value* count = nullptr);
bool IsArrayAlloca() const;
Value* GetCount() const;
std::shared_ptr<Type> GetElementType() const;
};
class GetElementPtrInst : public Instruction {
public:
GetElementPtrInst(std::shared_ptr<Type> ptr_ty, Value* base_ptr,
Value* index, std::string name);
Value* GetBasePtr() const;
Value* GetIndex() const;
};
class LoadInst : public Instruction {
public:
LoadInst(std::shared_ptr<Type> val_ty, Value* ptr, std::string name);
Value* GetPtr() const;
};
class StoreInst : public Instruction {
public:
StoreInst(std::shared_ptr<Type> void_ty, Value* val, Value* ptr);
Value* GetValue() const;
Value* GetPtr() const;
};
class PhiInst : public Instruction {
public:
PhiInst(std::shared_ptr<Type> ty, std::string name);
AllocaInst* GetAlloca() const { return alloca_; }
void SetAlloca(AllocaInst* alloca) { alloca_ = alloca; }
private:
AllocaInst* alloca_;
};
class Argument : public Value {
public:
Argument(std::shared_ptr<Type> ty, std::string name, size_t index);
size_t GetIndex() const;
private:
size_t index_ = 0;
};
// BasicBlock 已纳入 Value 体系,便于后续向更完整 IR 类图靠拢。
// 当前其类型仍使用 void 作为占位,后续可替换为专门的 label type。
class BasicBlock : public Value {
public:
explicit BasicBlock(std::string name);
Function* GetParent() const;
void SetParent(Function* parent);
bool HasTerminator() const;
const std::vector<std::unique_ptr<Instruction>>& GetInstructions() const;
const std::vector<BasicBlock*>& GetPredecessors() const;
const std::vector<BasicBlock*>& GetSuccessors() const;
std::vector<BasicBlock*>& GetMutablePredecessors() {
return predecessors_;
}
std::vector<BasicBlock*>& GetMutableSuccessors() {
return successors_;
}
template <typename T, typename... Args>
T* Append(Args&&... args) {
if (HasTerminator()) {
throw std::runtime_error("BasicBlock 已有 terminator不能继续追加指令: " +
name_);
}
auto inst = std::make_unique<T>(std::forward<Args>(args)...);
auto* ptr = inst.get();
ptr->SetParent(this);
instructions_.push_back(std::move(inst));
return ptr;
}
template <typename T, typename... Args>
T* Prepend(Args&&... args) {
auto inst = std::make_unique<T>(std::forward<Args>(args)...);
auto* ptr = inst.get();
ptr->SetParent(this);
instructions_.insert(instructions_.begin(), std::move(inst));
return ptr;
}
template <typename T, typename... Args>
T* InsertAlloca(Args&&... args) {
auto inst = std::make_unique<T>(std::forward<Args>(args)...);
auto* ptr = inst.get();
ptr->SetParent(this);
instructions_.insert(instructions_.begin() + alloca_insert_index_, std::move(inst));
++alloca_insert_index_;
return ptr;
}
void RemoveInstruction(Instruction* inst) {
for (auto it = instructions_.begin(); it != instructions_.end(); ++it) {
if (it->get() == inst) {
instructions_.erase(it);
break;
}
}
}
std::unique_ptr<Instruction> TakeInstruction(Instruction* inst);
void InsertInstructionBeforeTerminator(std::unique_ptr<Instruction> inst);
private:
Function* parent_ = nullptr;
std::vector<std::unique_ptr<Instruction>> instructions_;
std::vector<BasicBlock*> predecessors_;
std::vector<BasicBlock*> successors_;
size_t alloca_insert_index_ = 0;
};
// Function 当前也采用了最小实现。
// 需要特别注意:由于项目里还没有单独的 FunctionType
// Function 继承自 Value 后,其 type_ 目前只保存“返回类型”,
// 并不能完整表达“返回类型 + 形参列表”这一整套函数签名。
// 这对当前只支持 int main() 的最小 IR 足够,但后续若补普通函数、
// 形参和调用,通常需要引入专门的函数类型表示。
class Function : public Value {
public:
// 当前构造函数接收的也是返回类型,而不是完整函数类型。
Function(std::string name, std::shared_ptr<Type> ret_type,
bool is_external = false);
Argument* AddParam(const std::string& name, std::shared_ptr<Type> type);
const std::vector<std::unique_ptr<Argument>>& GetParams() const;
bool IsExternal() const;
BasicBlock* CreateBlock(const std::string& name);
BasicBlock* GetEntry();
const BasicBlock* GetEntry() const;
const std::vector<std::unique_ptr<BasicBlock>>& GetBlocks() const;
private:
bool is_external_ = false;
BasicBlock* entry_ = nullptr;
std::vector<std::unique_ptr<Argument>> params_;
std::vector<std::unique_ptr<BasicBlock>> blocks_;
};
class Module {
public:
Module() = default;
Context& GetContext();
const Context& GetContext() const;
// 创建函数时当前只显式传入返回类型,尚未接入完整的 FunctionType。
Function* CreateFunction(const std::string& name,
std::shared_ptr<Type> ret_type,
bool is_external = false);
Function* GetFunction(const std::string& name) const;
GlobalVariable* CreateGlobalI32(const std::string& name, int init_value);
GlobalVariable* CreateGlobalF32(const std::string& name, double init_value);
GlobalVariable* CreateGlobalArrayI32(const std::string& name,
size_t array_size);
GlobalVariable* CreateGlobalArrayF32(const std::string& name,
size_t array_size);
GlobalVariable* CreateGlobalArrayI32(const std::string& name,
size_t array_size,
const std::vector<int>& init_values);
GlobalVariable* CreateGlobalArrayF32(const std::string& name,
size_t array_size,
const std::vector<double>& init_values);
GlobalVariable* GetGlobal(const std::string& name) const;
const std::vector<std::unique_ptr<GlobalVariable>>& GetGlobals() const;
const std::vector<std::unique_ptr<Function>>& GetFunctions() const;
private:
Context context_;
std::vector<std::unique_ptr<GlobalVariable>> globals_;
std::vector<std::unique_ptr<Function>> functions_;
};
class IRBuilder {
public:
IRBuilder(Context& ctx, BasicBlock* bb);
void SetInsertPoint(BasicBlock* bb);
BasicBlock* GetInsertBlock() const;
// 构造常量、二元运算、返回指令的最小集合。
ConstantInt* CreateConstInt(int v);
ConstantFloat* CreateConstFloat(double v);
BinaryInst* CreateBinary(Opcode op, Value* lhs, Value* rhs,
const std::string& name);
BinaryInst* CreateAdd(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateICmp(Opcode op, Value* lhs, Value* rhs,
const std::string& name);
CastInst* CreateSIToFP(Value* operand, const std::string& name);
CastInst* CreateFPToSI(Value* operand, const std::string& name);
CastInst* CreateZExt(Value* operand, std::shared_ptr<Type> target_ty, const std::string& name);
AllocaInst* CreateAlloca(std::shared_ptr<Type> elem_ty, const std::string& name,
Value* count = nullptr);
AllocaInst* CreateAllocaI32(const std::string& name,
Value* count = nullptr);
AllocaInst* CreateAllocaF32(const std::string& name,
Value* count = nullptr);
LoadInst* CreateLoad(Value* ptr, const std::string& name);
StoreInst* CreateStore(Value* val, Value* ptr);
GetElementPtrInst* CreateGEP(Value* base_ptr, Value* index,
const std::string& name);
CallInst* CreateCall(Function* callee, const std::vector<Value*>& args,
const std::string& name);
BranchInst* CreateBr(BasicBlock* target);
CondBranchInst* CreateCondBr(Value* cond, BasicBlock* true_bb,
BasicBlock* false_bb);
ReturnInst* CreateRet(Value* v);
ReturnInst* CreateRetVoid();
PhiInst* CreatePhi(std::shared_ptr<Type> ty, const std::string& name);
private:
Context& ctx_;
BasicBlock* insert_block_;
};
class IRPrinter {
public:
void Print(const Module& module, std::ostream& os);
};
} // namespace ir

@ -0,0 +1,83 @@
#ifndef IR_PASSES_PASSMANAGER_H_
#define IR_PASSES_PASSMANAGER_H_
#include "ir/IR.h"
#include <sstream>
#include <string>
namespace ir {
void RunMem2Reg(Module& module);
void RunLICM(Module* module);
void RunConstFold(Module& module);
void RunConstProp(Module& module);
void RunDCE(Module& module);
void RunCFGSimplify(Module& module);
void RunCSE(Module& module);
class PassManagerModule {
public:
explicit PassManagerModule(Module* module) : module_(module) {}
void Run() {
if (!module_) {
return;
}
RunMem2Reg(*module_);
RunLICM(module_);
bool changed = true;
int max_iterations = 10;
int iterations = 0;
while (changed && iterations < max_iterations) {
changed = false;
iterations++;
auto before = SerializeModule(*module_);
RunConstFold(*module_);
RunConstProp(*module_);
RunCFGSimplify(*module_);
RunCSE(*module_);
RunDCE(*module_);
auto after = SerializeModule(*module_);
changed = (before != after);
}
}
private:
std::string SerializeModule(const Module& module) {
std::ostringstream oss;
IRPrinter printer;
printer.Print(module, oss);
return oss.str();
}
Module* module_;
};
class PassManager {
public:
PassManager() = default;
void RunScalarOptimizationPasses(Module* module) {
if (!module) return;
RunMem2Reg(*module);
RunConstFold(*module);
RunDCE(*module);
RunCFGSimplify(*module);
}
private:
};
} // namespace ir
#endif // IR_PASSES_PASSMANAGER_H_

@ -0,0 +1,122 @@
// 将语法树翻译为 IR。
// 实现拆分在 IRGenFunc/IRGenStmt/IRGenExp/IRGenDecl。
#pragma once
#include <any>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include "SysYBaseVisitor.h"
#include "SysYParser.h"
#include "ir/IR.h"
#include "sem/Sema.h"
namespace ir {
class Module;
class Function;
class IRBuilder;
class Value;
}
class IRGenImpl final : public SysYBaseVisitor {
public:
IRGenImpl(ir::Module& module, const SemanticContext& sema);
std::any visitCompUnit(SysYParser::CompUnitContext* ctx) override;
std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override;
std::any visitBlock(SysYParser::BlockContext* ctx) override;
std::any visitBlockItem(SysYParser::BlockItemContext* ctx) override;
std::any visitDecl(SysYParser::DeclContext* ctx) override;
std::any visitVarDecl(SysYParser::VarDeclContext* ctx) override;
std::any visitStmt(SysYParser::StmtContext* ctx) override;
std::any visitVarDef(SysYParser::VarDefContext* ctx) override;
std::any visitExp(SysYParser::ExpContext* 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 visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) override;
std::any visitLVal(SysYParser::LValContext* ctx) override;
std::any visitNumber(SysYParser::NumberContext* ctx) override;
private:
enum class BlockFlow {
Continue,
Terminated,
};
BlockFlow VisitBlockItemResult(SysYParser::BlockItemContext& item);
ir::Value* EvalExpr(SysYParser::ExpContext& expr);
ir::Value* EvalBinaryOrFold(ir::Opcode op, ir::Value* lhs, ir::Value* rhs);
std::shared_ptr<ir::Type> ResolveBType(SysYParser::BTypeContext* btype) const;
int EvalConstIntExpr(SysYParser::ExpContext& expr);
int EvalConstIntExpr(SysYParser::ConstExpContext& expr);
int EvalConstIntAddExp(SysYParser::AddExpContext& expr);
int EvalConstIntMulExp(SysYParser::MulExpContext& expr);
int EvalConstIntUnaryExp(SysYParser::UnaryExpContext& expr);
int EvalConstIntPrimaryExp(SysYParser::PrimaryExpContext& expr);
double EvalConstFloatExpr(SysYParser::ConstExpContext& expr);
double EvalConstFloatAddExp(SysYParser::AddExpContext& expr);
double EvalConstFloatMulExp(SysYParser::MulExpContext& expr);
double EvalConstFloatUnaryExp(SysYParser::UnaryExpContext& expr);
double EvalConstFloatPrimaryExp(SysYParser::PrimaryExpContext& expr);
std::vector<int> EvalArrayExtents(
const std::vector<SysYParser::ConstExpContext*>& dims);
std::vector<int> GetArrayExtentsForDecl(SysYParser::VarDefContext* decl);
std::vector<int> GetArrayExtentsForConstDecl(
SysYParser::ConstDefContext* decl);
std::vector<int> GetArrayExtentsForLVal(SysYParser::LValContext& lval,
bool& is_array);
ir::Value* BuildLinearizedIndex(
const std::vector<ir::Value*>& indices,
const std::vector<int>& extents_with_first_dim) ;
ir::Value* CastValueTo(ir::Value* value,
const std::shared_ptr<ir::Type>& target_type);
ir::Value* GetLValAddress(SysYParser::LValContext& lval);
ir::AllocaInst* CreateEntryBlockAlloca(std::shared_ptr<ir::Type> elem_ty,
const std::string& name,
ir::Value* count = nullptr);
std::string NextBlockName(const std::string& prefix);
void EmitCondBranch(SysYParser::CondContext& cond, ir::BasicBlock* true_bb,
ir::BasicBlock* false_bb);
void EmitLOrBranch(SysYParser::LOrExpContext& expr, ir::BasicBlock* true_bb,
ir::BasicBlock* false_bb);
void EmitLAndBranch(SysYParser::LAndExpContext& expr, ir::BasicBlock* true_bb,
ir::BasicBlock* false_bb);
void EmitEqBranch(SysYParser::EqExpContext& expr, ir::BasicBlock* true_bb,
ir::BasicBlock* false_bb);
void EmitRelBranch(SysYParser::RelExpContext& expr, ir::BasicBlock* true_bb,
ir::BasicBlock* false_bb);
ir::Value* EvalEqValue(SysYParser::EqExpContext& expr);
ir::Value* EvalRelValue(SysYParser::RelExpContext& expr);
ir::Module& module_;
const SemanticContext& sema_;
ir::Function* func_;
ir::IRBuilder builder_;
std::unordered_map<std::string, ir::Function*> function_map_;
std::unordered_map<std::string, int> const_value_map_;
std::vector<std::unordered_map<std::string, int>> local_const_stack_;
std::vector<std::unordered_map<std::string, int>> const_value_history_;
std::unordered_map<SysYParser::VarDefContext*, std::vector<int>>
array_extents_map_;
std::unordered_map<SysYParser::ConstDefContext*, std::vector<int>>
const_array_extents_map_;
std::unordered_map<std::string, std::vector<int>> param_array_extents_map_;
std::unordered_map<std::string, ir::Value*> param_storage_map_;
std::unordered_map<std::string, ir::Value*> param_pointer_map_;
std::unordered_map<SysYParser::VarDefContext*, ir::Value*> global_storage_map_;
std::unordered_map<SysYParser::ConstDefContext*, ir::Value*>
const_global_storage_map_;
// 名称绑定由 Sema 负责IRGen 只维护“声明 -> 存储槽位”的代码生成状态。
std::unordered_map<SysYParser::VarDefContext*, ir::Value*> storage_map_;
std::unordered_map<SysYParser::ConstDefContext*, ir::Value*>
const_storage_map_;
std::vector<std::pair<ir::BasicBlock*, ir::BasicBlock*>> loop_stack_;
int block_index_ = 0;
};
std::unique_ptr<ir::Module> GenerateIR(SysYParser::CompUnitContext& tree,
const SemanticContext& sema);

@ -0,0 +1,414 @@
#pragma once
#include <initializer_list>
#include <iosfwd>
#include <memory>
#include <string>
#include <vector>
namespace ir
{
class Module;
}
namespace mir
{
class MIRContext
{
public:
MIRContext() = default;
};
MIRContext &DefaultContext();
enum class PhysReg
{
W0,
W1,
W2,
W3,
W4,
W5,
W6,
W7,
W8,
W9,
W10,
W11,
W12,
W13,
W14,
W15,
W16,
W17,
W18,
W19,
W20,
W21,
W22,
W23,
W24,
W25,
W26,
W27,
W28,
W29,
W30,
X0,
X1,
X2,
X3,
X4,
X5,
X6,
X7,
X8,
X9,
X10,
X11,
X12,
X13,
X14,
X15,
X16,
X17,
X18,
X19,
X20,
X21,
X22,
X23,
X24,
X25,
X26,
X27,
X28,
X29,
X30,
S0,
S1,
S2,
S3,
S4,
S5,
S6,
S7,
S8,
S9,
S10,
S11,
S12,
S13,
S14,
S15,
S16,
S17,
S18,
S19,
S20,
S21,
S22,
S23,
S24,
S25,
S26,
S27,
S28,
S29,
S30,
S31,
XZR,
SP,
WZR
};
const char *PhysRegName(PhysReg reg);
enum class VRegClass
{
Int,
Float,
Ptr
};
enum class Opcode
{
Prologue,
Epilogue,
MovImm,
LoadStack,
StoreStack,
LoadStackAddr,
LoadGlobal,
StoreGlobal,
LoadGlobalAddr,
LoadMem,
StoreMem,
AddRR,
SubRR,
MulRR,
DivRR,
ModRR,
AndRR,
OrRR,
XorRR,
ShlRR,
ShrRR,
AsrRR,
Asr64RR,
Uxtw,
Sxtw,
CmpRR,
CmpImm,
FCmpRR,
CSet,
Csel,
Smull,
Msub,
NegRR,
FAddRR,
FSubRR,
FMulRR,
FDivRR,
Scvtf,
FCvtzs,
FMovWS,
Br,
CondBr,
Call,
Ret,
LoadAddr,
MovReg,
};
enum class CondCode
{
EQ,
NE,
LT,
LE,
GT,
GE
};
class Operand
{
public:
enum class Kind
{
Reg,
VReg,
Imm,
FrameIndex,
Label,
Symbol
};
static Operand Reg(PhysReg reg);
static Operand VReg(int id, VRegClass vreg_class);
static Operand Imm(int value);
static Operand FrameIndex(int index);
static Operand Label(int label_id);
static Operand Symbol(std::string symbol);
Kind GetKind() const { return kind_; }
PhysReg GetReg() const { return reg_; }
int GetImm() const { return imm_; }
int GetFrameIndex() const { return imm_; }
int GetLabel() const { return imm_; }
const std::string &GetSymbol() const { return symbol_; }
int GetVRegId() const { return imm_; }
VRegClass GetVRegClass() const { return vreg_class_; }
private:
Operand(Kind kind, PhysReg reg, int imm,
VRegClass vreg_class = VRegClass::Int, std::string symbol = "");
Kind kind_;
PhysReg reg_;
int imm_;
std::string symbol_;
VRegClass vreg_class_;
};
class MachineInstr
{
public:
MachineInstr(Opcode opcode, std::vector<Operand> operands = {});
Opcode GetOpcode() const { return opcode_; }
const std::vector<Operand> &GetOperands() const { return operands_; }
std::vector<Operand> &GetOperands() { return operands_; }
private:
Opcode opcode_;
std::vector<Operand> operands_;
};
struct FrameSlot
{
int index = 0;
int size = 4;
int offset = 0;
bool is_stack_arg = false;
bool is_callee_stack_arg = false;
};
class MachineBasicBlock
{
public:
explicit MachineBasicBlock(std::string name, int label_id = -1);
const std::string &GetName() const { return name_; }
int GetLabelId() const { return label_id_; }
void SetLabelId(int label_id) { label_id_ = label_id; }
std::vector<MachineInstr> &GetInstructions() { return instructions_; }
const std::vector<MachineInstr> &GetInstructions() const { return instructions_; }
MachineInstr &Append(Opcode opcode,
std::initializer_list<Operand> operands = {});
private:
std::string name_;
int label_id_ = -1;
std::vector<MachineInstr> instructions_;
};
class MachineFunction
{
public:
explicit MachineFunction(std::string name);
const std::string &GetName() const { return name_; }
MachineBasicBlock &GetEntry() { return *entry_; }
const MachineBasicBlock &GetEntry() const { return *entry_; }
MachineBasicBlock *GetEntryPtr() { return entry_; }
const MachineBasicBlock *GetEntryPtr() const { return entry_; }
MachineBasicBlock &CreateBlock(std::string name);
MachineBasicBlock *FindBlock(const std::string &name);
const MachineBasicBlock *FindBlock(const std::string &name) const;
std::vector<std::unique_ptr<MachineBasicBlock>> &GetBlocks()
{
return blocks_;
}
const std::vector<std::unique_ptr<MachineBasicBlock>> &GetBlocks() const
{
return blocks_;
}
int CreateLabel();
int CreateFrameIndex(int size = 4);
int CreateStackArgFrameIndex(int size = 4);
int CreateCalleeStackArgFrameIndex(int size = 4);
FrameSlot &GetFrameSlot(int index);
const FrameSlot &GetFrameSlot(int index) const;
const std::vector<FrameSlot> &GetFrameSlots() const { return frame_slots_; }
std::vector<FrameSlot> &GetFrameSlots() { return frame_slots_; }
int GetFrameSize() const { return frame_size_; }
void SetFrameSize(int size) { frame_size_ = size; }
int CreateVReg(VRegClass vreg_class);
VRegClass GetVRegClass(int vreg_id) const;
int GetNumVRegs() const { return static_cast<int>(vreg_classes_.size()); }
void AddCalleeSavedReg(PhysReg reg);
const std::vector<PhysReg> &GetCalleeSavedRegs() const { return callee_saved_regs_; }
private:
std::string name_;
std::vector<std::unique_ptr<MachineBasicBlock>> blocks_;
MachineBasicBlock *entry_ = nullptr;
std::vector<FrameSlot> frame_slots_;
int frame_size_ = 0;
int next_label_id_ = 0;
std::vector<VRegClass> vreg_classes_;
std::vector<PhysReg> callee_saved_regs_;
};
struct MachineGlobal
{
enum class Kind
{
I32Scalar,
I32Array
};
std::string name;
Kind kind = Kind::I32Scalar;
int init_value = 0;
size_t array_size = 0;
std::vector<int> init_values;
};
class MachineModule
{
public:
MachineModule() = default;
MachineFunction &CreateFunction(std::string name);
MachineFunction *GetFunction(const std::string &name);
const MachineFunction *GetFunction(const std::string &name) const;
std::vector<std::unique_ptr<MachineFunction>> &GetFunctions()
{
return functions_;
}
const std::vector<std::unique_ptr<MachineFunction>> &GetFunctions() const
{
return functions_;
}
void AddGlobalI32(std::string name, int init_value)
{
MachineGlobal g;
g.name = std::move(name);
g.kind = MachineGlobal::Kind::I32Scalar;
g.init_value = init_value;
globals_.push_back(std::move(g));
}
void AddGlobalArrayI32(std::string name, size_t array_size,
std::vector<int> init_values = {})
{
MachineGlobal g;
g.name = std::move(name);
g.kind = MachineGlobal::Kind::I32Array;
g.array_size = array_size;
g.init_values = std::move(init_values);
globals_.push_back(std::move(g));
}
std::vector<MachineGlobal> &GetGlobals() { return globals_; }
const std::vector<MachineGlobal> &GetGlobals() const { return globals_; }
private:
std::vector<std::unique_ptr<MachineFunction>> functions_;
std::vector<MachineGlobal> globals_;
};
std::unique_ptr<MachineModule> LowerModuleToMIR(const ir::Module &module);
std::unique_ptr<MachineFunction> LowerToMIR(const ir::Module &module);
void RunRegAlloc(MachineFunction &function);
void RunRegAlloc(MachineModule &module);
void RunFrameLowering(MachineFunction &function);
void RunFrameLowering(MachineModule &module);
void RunPeephole(MachineFunction &function);
void RunPeephole(MachineModule &module);
void PrintAsm(const MachineFunction &function, std::ostream &os);
void PrintAsm(const MachineModule &module, std::ostream &os);
} // namespace mir

@ -0,0 +1,92 @@
// 基于语法树的语义检查与名称绑定。
#pragma once
#include <unordered_map>
#include "SysYParser.h"
class SemanticContext {
public:
void BindVarUse(SysYParser::LValContext* use,
SysYParser::VarDefContext* decl) {
var_uses_[use] = decl;
}
SysYParser::VarDefContext* ResolveVarUse(
const SysYParser::LValContext* use) const {
auto it = var_uses_.find(use);
return it == var_uses_.end() ? nullptr : it->second;
}
void BindConstArrayUse(SysYParser::LValContext* use,
SysYParser::ConstDefContext* decl) {
const_array_uses_[use] = decl;
}
SysYParser::ConstDefContext* ResolveConstArrayUse(
const SysYParser::LValContext* use) const {
auto it = const_array_uses_.find(use);
return it == const_array_uses_.end() ? nullptr : it->second;
}
void BindConstScalarUse(SysYParser::LValContext* use,
SysYParser::ConstDefContext* decl) {
const_scalar_uses_[use] = decl;
}
SysYParser::ConstDefContext* ResolveConstScalarUse(
const SysYParser::LValContext* use) const {
auto it = const_scalar_uses_.find(use);
return it == const_scalar_uses_.end() ? nullptr : it->second;
}
void BindConstUse(SysYParser::LValContext* use, int value) {
const_uses_[use] = value;
}
const int* ResolveConstUse(const SysYParser::LValContext* use) const {
auto it = const_uses_.find(use);
return it == const_uses_.end() ? nullptr : &it->second;
}
void BindConstFloatUse(SysYParser::LValContext* use, double value) {
const_float_uses_[use] = value;
}
const double* ResolveConstFloatUse(const SysYParser::LValContext* use) const {
auto it = const_float_uses_.find(use);
return it == const_float_uses_.end() ? nullptr : &it->second;
}
void BindCallUse(SysYParser::UnaryExpContext* call,
SysYParser::FuncDefContext* decl) {
call_uses_[call] = decl;
}
SysYParser::FuncDefContext* ResolveCallUse(
const SysYParser::UnaryExpContext* call) const {
auto it = call_uses_.find(call);
return it == call_uses_.end() ? nullptr : it->second;
}
private:
std::unordered_map<const SysYParser::LValContext*,
SysYParser::VarDefContext*>
var_uses_;
std::unordered_map<const SysYParser::LValContext*, int> const_uses_;
std::unordered_map<const SysYParser::LValContext*, double> const_float_uses_;
std::unordered_map<const SysYParser::LValContext*,
SysYParser::ConstDefContext*>
const_array_uses_;
std::unordered_map<const SysYParser::LValContext*,
SysYParser::ConstDefContext*>
const_scalar_uses_;
std::unordered_map<const SysYParser::UnaryExpContext*,
SysYParser::FuncDefContext*>
call_uses_;
};
// 目前仅检查:
// - 变量先声明后使用
// - 局部变量不允许重复定义
SemanticContext RunSema(SysYParser::CompUnitContext& comp_unit);

@ -0,0 +1,22 @@
// 极简符号表:记录局部变量定义点。
#pragma once
#include <string>
#include <unordered_map>
#include <vector>
#include "SysYParser.h"
class SymbolTable {
public:
void EnterScope();
void ExitScope();
void Add(const std::string& name, SysYParser::VarDefContext* decl);
bool ContainsInCurrent(const std::string& name) const;
bool Contains(const std::string& name) const;
SysYParser::VarDefContext* Lookup(const std::string& name) const;
private:
std::vector<std::unordered_map<std::string, SysYParser::VarDefContext*>>
scopes_;
};

@ -0,0 +1,17 @@
// 命令行解析:支持比赛要求的 -S -o -O1 格式
#pragma once
#include <string>
struct CLIOptions {
std::string input;
std::string output; // -o 指定的输出文件路径
bool emit_parse_tree = false;
bool emit_ir = false;
bool emit_asm = false;
bool show_help = false;
bool optimize = false; // -O 或 -O1
int opt_level = 0; // 优化级别: 0, 1, 2, 3
};
CLIOptions ParseCLI(int argc, char** argv);

@ -0,0 +1,20 @@
// 轻量日志接口。
#pragma once
#include <cstddef>
#include <exception>
#include <iosfwd>
#include <string>
#include <string_view>
void LogInfo(std::string_view msg, std::ostream& os);
void LogError(std::string_view msg, std::ostream& os);
std::string FormatError(std::string_view stage, std::string_view msg);
std::string FormatErrorAt(std::string_view stage, std::size_t line,
std::size_t column, std::string_view msg);
bool HasErrorPrefix(std::string_view msg, std::string_view stage);
void PrintException(std::ostream& os, const std::exception& ex);
// 打印命令行帮助信息(用于 `compiler --help`)。
void PrintHelp(std::ostream& os);

@ -5,6 +5,7 @@
#include "ir/IR.h"
#include <algorithm>
#include <climits>
#include <cmath>
#include <iostream>
#include <memory>
@ -28,15 +29,17 @@ ConstantValue* TryFoldBinary(Opcode op, Value* lhs, Value* rhs, Context& ctx) {
int result = 0;
switch (op) {
case Opcode::Add: result = lv + rv; break;
case Opcode::Sub: result = lv - rv; break;
case Opcode::Mul: result = lv * rv; break;
case Opcode::Add: result = static_cast<int>(static_cast<unsigned int>(lv) + static_cast<unsigned int>(rv)); break;
case Opcode::Sub: result = static_cast<int>(static_cast<unsigned int>(lv) - static_cast<unsigned int>(rv)); break;
case Opcode::Mul: result = static_cast<int>(static_cast<unsigned int>(lv) * static_cast<unsigned int>(rv)); break;
case Opcode::Div:
if (rv == 0) return nullptr; // 除零错误
if (rv == 0) return nullptr;
if (lv == INT_MIN && rv == -1) return nullptr;
result = lv / rv;
break;
case Opcode::Mod:
if (rv == 0) return nullptr;
if (lv == INT_MIN && rv == -1) return nullptr;
result = lv % rv;
break;
case Opcode::Eq: return ctx.GetConstBool(lv == rv ? 1 : 0);
@ -91,7 +94,10 @@ ConstantValue* TryFoldCast(Opcode op, Value* operand, Context& ctx) {
// FPToSI: float -> int
if (op == Opcode::FPToSI) {
if (auto* cfloat = dynamic_cast<ConstantFloat*>(operand)) {
return ctx.GetConstInt(static_cast<int>(cfloat->GetValue()));
double val = cfloat->GetValue();
if (val < static_cast<double>(INT_MIN) || val >= static_cast<double>(INT_MAX) || std::isnan(val))
return nullptr;
return ctx.GetConstInt(static_cast<int>(val));
}
}

@ -1,65 +1 @@
// IR Pass 管理骨架。
#include "ir/IR.h"
#include <memory>
#include <sstream>
#include <string>
#include <vector>
namespace ir {
void RunMem2Reg(Module& module);
void RunLICM(Module* module);
void RunConstFold(Module& module);
void RunConstProp(Module& module);
void RunDCE(Module& module);
void RunCFGSimplify(Module& module);
void RunCSE(Module& module);
class PassManagerModule {
public:
explicit PassManagerModule(Module* module) : module_(module) {}
void Run() {
if (!module_) {
return;
}
RunMem2Reg(*module_);
RunLICM(module_);
bool changed = true;
int max_iterations = 10;
int iterations = 0;
while (changed && iterations < max_iterations) {
changed = false;
iterations++;
auto before = SerializeModule(*module_);
RunConstFold(*module_);
RunConstProp(*module_);
RunCFGSimplify(*module_);
RunCSE(*module_);
RunDCE(*module_);
auto after = SerializeModule(*module_);
changed = (before != after);
}
}
private:
std::string SerializeModule(const Module& module) {
std::ostringstream oss;
IRPrinter printer;
printer.Print(module, oss);
return oss.str();
}
Module* module_;
};
} // namespace ir
#include "ir/passes/PassManager.h"

@ -1,5 +1,6 @@
#include "irgen/IRGen.h"
#include <climits>
#include <limits>
#include <stdexcept>
@ -60,10 +61,10 @@ int IRGenImpl::EvalConstIntAddExp(SysYParser::AddExpContext& expr) {
const int lhs = EvalConstIntAddExp(*expr.addExp());
const int rhs = EvalConstIntMulExp(*expr.mulExp());
if (expr.AddOp()) {
return lhs + rhs;
return static_cast<int>(static_cast<unsigned int>(lhs) + static_cast<unsigned int>(rhs));
}
if (expr.SubOp()) {
return lhs - rhs;
return static_cast<int>(static_cast<unsigned int>(lhs) - static_cast<unsigned int>(rhs));
}
throw std::runtime_error(FormatError("irgen", "非法常量加法表达式"));
}
@ -81,18 +82,24 @@ int IRGenImpl::EvalConstIntMulExp(SysYParser::MulExpContext& expr) {
const int lhs = EvalConstIntMulExp(*expr.mulExp());
const int rhs = EvalConstIntUnaryExp(*expr.unaryExp());
if (expr.MulOp()) {
return lhs * rhs;
return static_cast<int>(static_cast<unsigned int>(lhs) * static_cast<unsigned int>(rhs));
}
if (expr.DivOp()) {
if (rhs == 0) {
throw std::runtime_error(FormatError("irgen", "常量表达式除零"));
}
if (lhs == INT_MIN && rhs == -1) {
throw std::runtime_error(FormatError("irgen", "常量表达式除法溢出"));
}
return lhs / rhs;
}
if (expr.ModOp()) {
if (rhs == 0) {
throw std::runtime_error(FormatError("irgen", "常量表达式取模除零"));
}
if (lhs == INT_MIN && rhs == -1) {
throw std::runtime_error(FormatError("irgen", "常量表达式取模溢出"));
}
return lhs % rhs;
}
throw std::runtime_error(FormatError("irgen", "非法常量乘法表达式"));
@ -113,7 +120,7 @@ int IRGenImpl::EvalConstIntUnaryExp(SysYParser::UnaryExpContext& expr) {
return operand;
}
if (expr.unaryOp()->SubOp()) {
return -operand;
return static_cast<int>(-static_cast<unsigned int>(operand));
}
if (expr.unaryOp()->NotOp()) {
return operand == 0 ? 1 : 0;
@ -130,7 +137,10 @@ int IRGenImpl::EvalConstIntPrimaryExp(SysYParser::PrimaryExpContext& expr) {
return ParseIntLiteral(expr.number()->IntConst()->getText());
}
if (expr.number()->FloatConst()) {
return static_cast<int>(ParseFloatLiteral(expr.number()->FloatConst()->getText()));
double fval = ParseFloatLiteral(expr.number()->FloatConst()->getText());
if (fval < static_cast<double>(INT_MIN) || fval >= static_cast<double>(INT_MAX))
throw std::runtime_error(FormatError("irgen", "浮点常量转整数溢出"));
return static_cast<int>(fval);
}
throw std::runtime_error(
FormatError("irgen", "数组维度表达式仅支持数字常量"));
@ -265,7 +275,7 @@ ir::Value* IRGenImpl::BuildLinearizedIndex(
if (extents_with_first_dim[j] <= 0) {
throw std::runtime_error(FormatError("irgen", "数组维度必须为正整数"));
}
stride *= extents_with_first_dim[j];
stride = static_cast<int>(static_cast<unsigned int>(stride) * static_cast<unsigned int>(extents_with_first_dim[j]));
}
if (stride != 1) {
term = EvalBinaryOrFold(ir::Opcode::Mul, term, builder_.CreateConstInt(stride));
@ -307,7 +317,10 @@ ir::Value* IRGenImpl::CastValueTo(
}
if (target_type->IsInt32() && value->GetType()->IsFloat32()) {
if (auto* cf = dynamic_cast<ir::ConstantFloat*>(value)) {
return builder_.CreateConstInt(static_cast<int>(cf->GetValue()));
double fval = cf->GetValue();
if (fval < static_cast<double>(INT_MIN) || fval >= static_cast<double>(INT_MAX))
return builder_.CreateFPToSI(value, module_.GetContext().NextTemp());
return builder_.CreateConstInt(static_cast<int>(fval));
}
return builder_.CreateFPToSI(value, module_.GetContext().NextTemp());
}
@ -642,9 +655,17 @@ std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
args.push_back(EvalExpr(*exp));
}
}
if (callee_name == "starttime" || callee_name == "stoptime") {
int lineno = ctx->getStart()->getLine();
args.push_back(static_cast<ir::Value*>(builder_.CreateConstInt(lineno)));
}
if (args.size() != func_it->second->GetParams().size()) {
throw std::runtime_error(
FormatError("irgen", "函数参数个数不匹配: " + callee_name));
if (callee_name != "starttime" && callee_name != "stoptime") {
throw std::runtime_error(
FormatError("irgen", "函数参数个数不匹配: " + callee_name));
}
}
for (size_t i = 0; i < args.size(); ++i) {
args[i] = CastValueTo(args[i], func_it->second->GetParams()[i]->GetType());

@ -119,10 +119,12 @@ std::any IRGenImpl::visitCompUnit(SysYParser::CompUnitContext* ctx) {
auto* putch = module_.CreateFunction("putch", ir::Type::GetVoidType(), true);
putch->AddParam("%arg.x", ir::Type::GetInt32Type());
function_map_["putch"] = putch;
function_map_["starttime"] =
module_.CreateFunction("starttime", ir::Type::GetVoidType(), true);
function_map_["stoptime"] =
module_.CreateFunction("stoptime", ir::Type::GetVoidType(), true);
auto* sysy_starttime = module_.CreateFunction("_sysy_starttime", ir::Type::GetVoidType(), true);
sysy_starttime->AddParam("%arg.lineno", ir::Type::GetInt32Type());
function_map_["starttime"] = sysy_starttime;
auto* sysy_stoptime = module_.CreateFunction("_sysy_stoptime", ir::Type::GetVoidType(), true);
sysy_stoptime->AddParam("%arg.lineno", ir::Type::GetInt32Type());
function_map_["stoptime"] = sysy_stoptime;
SysYParser::FuncDefContext* main_func = nullptr;
for (auto* func : funcs) {

@ -1,12 +1,14 @@
#include <exception>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <sstream>
#include "frontend/AntlrDriver.h"
#include "frontend/SyntaxTreePrinter.h"
#if !COMPILER_PARSE_ONLY
#include "ir/IR.h"
#include "ir/passes/PassManager.cpp"
#include "ir/passes/PassManager.h"
#include "irgen/IRGen.h"
#include "mir/MIR.h"
#include "sem/Sema.h"
@ -14,75 +16,83 @@
#include "utils/CLI.h"
#include "utils/Log.h"
int main(int argc, char **argv)
{
try
{
int main(int argc, char** argv) {
try {
auto opts = ParseCLI(argc, argv);
if (opts.show_help)
{
if (opts.show_help) {
PrintHelp(std::cout);
return 0;
}
auto antlr = ParseFileWithAntlr(opts.input);
bool need_blank_line = false;
if (opts.emit_parse_tree)
{
if (opts.emit_parse_tree) {
PrintSyntaxTree(antlr.tree, antlr.parser.get(), std::cout);
need_blank_line = true;
}
#if !COMPILER_PARSE_ONLY
auto *comp_unit = dynamic_cast<SysYParser::CompUnitContext *>(antlr.tree);
if (!comp_unit)
{
throw std::runtime_error(FormatError("main", "语法树根节点不是 compUnit"));
auto* comp_unit =
dynamic_cast<SysYParser::CompUnitContext*>(antlr.tree);
if (!comp_unit) {
throw std::runtime_error(
FormatError("main", "语法树根节点不是 compUnit"));
}
auto sema = RunSema(*comp_unit);
auto module = GenerateIR(*comp_unit, sema);
// 执行优化(如果启用)
if (opts.optimize) {
ir::PassManagerModule pass_manager(module.get());
pass_manager.Run();
}
if (opts.emit_ir) {
ir::IRPrinter printer;
if (need_blank_line) {
std::cout << "\n";
}
printer.Print(*module, std::cout);
need_blank_line = true;
ir::PassManager pass_manager;
pass_manager.RunScalarOptimizationPasses(module.get());
}
if (opts.emit_asm)
{
// 汇编输出到文件或标准输出
if (opts.emit_asm) {
auto machine_module = mir::LowerModuleToMIR(*module);
mir::RunRegAlloc(*machine_module);
mir::RunFrameLowering(*machine_module);
mir::RunPeephole(*machine_module);
if (need_blank_line)
{
std::ostringstream asm_ss;
mir::PrintAsm(*machine_module, asm_ss);
if (!opts.output.empty()) {
// 写入指定文件(-o 参数)
std::ofstream ofs(opts.output);
if (!ofs) {
throw std::runtime_error(FormatError("main", std::string("无法打开输出文件: ") + opts.output));
}
ofs << asm_ss.str();
ofs.close();
} else {
// 输出到标准输出
if (need_blank_line) {
std::cout << "\n";
}
std::cout << asm_ss.str();
}
}
if (opts.emit_ir) {
ir::IRPrinter printer;
if (need_blank_line) {
std::cout << "\n";
}
mir::PrintAsm(*machine_module, std::cout);
printer.Print(*module, std::cout);
need_blank_line = true;
}
#else
if (opts.emit_ir || opts.emit_asm)
{
if (opts.emit_ir || opts.emit_asm) {
throw std::runtime_error(
FormatError("main", "当前为 parse-only 构建IR/汇编输出已禁用"));
}
#endif
}
catch (const std::exception &ex)
{
} catch (const std::exception& ex) {
PrintException(std::cerr, ex);
return 1;
}
return 0;
}
}

@ -882,7 +882,7 @@ namespace mir
int idx_imm = 0;
if (TryGetConstantInt(gep->GetIndex(), idx_imm))
{
const int byte_offset = idx_imm * 4;
const int byte_offset = static_cast<int>(static_cast<unsigned int>(idx_imm) * 4u);
if (byte_offset == 0)
{
value_vregs[value] = base;

@ -399,7 +399,7 @@ namespace mir
static long long MakeEdgeKey(int u, int v)
{
if (u > v) std::swap(u, v);
return (static_cast<long long>(u) << 32) | static_cast<unsigned int>(v);
return (static_cast<long long>(static_cast<unsigned long long>(static_cast<unsigned int>(u)) << 32)) | static_cast<unsigned int>(v);
}
void AddNode(int v) { nodes.insert(v); }

@ -1,6 +1,7 @@
#include "sem/Sema.h"
#include <any>
#include <climits>
#include <limits>
#include <optional>
#include <stdexcept>
@ -832,10 +833,10 @@ class SemaVisitor final : public SysYBaseVisitor {
const int lhs = EvalAddExp(*ctx.addExp());
const int rhs = EvalMulExp(*ctx.mulExp());
if (ctx.AddOp()) {
return lhs + rhs;
return static_cast<int>(static_cast<unsigned int>(lhs) + static_cast<unsigned int>(rhs));
}
if (ctx.SubOp()) {
return lhs - rhs;
return static_cast<int>(static_cast<unsigned int>(lhs) - static_cast<unsigned int>(rhs));
}
throw std::runtime_error(FormatError("sema", "非法常量加法表达式"));
}
@ -853,18 +854,24 @@ class SemaVisitor final : public SysYBaseVisitor {
const int lhs = EvalMulExp(*ctx.mulExp());
const int rhs = EvalUnaryExp(*ctx.unaryExp());
if (ctx.MulOp()) {
return lhs * rhs;
return static_cast<int>(static_cast<unsigned int>(lhs) * static_cast<unsigned int>(rhs));
}
if (ctx.DivOp()) {
if (rhs == 0) {
throw std::runtime_error(FormatError("sema", "常量表达式除零"));
}
if (lhs == INT_MIN && rhs == -1) {
throw std::runtime_error(FormatError("sema", "常量表达式除法溢出"));
}
return lhs / rhs;
}
if (ctx.ModOp()) {
if (rhs == 0) {
throw std::runtime_error(FormatError("sema", "常量表达式取模除零"));
}
if (lhs == INT_MIN && rhs == -1) {
throw std::runtime_error(FormatError("sema", "常量表达式取模溢出"));
}
return lhs % rhs;
}
throw std::runtime_error(FormatError("sema", "非法常量乘法表达式"));
@ -885,7 +892,7 @@ class SemaVisitor final : public SysYBaseVisitor {
return operand;
}
if (ctx.unaryOp()->SubOp()) {
return -operand;
return static_cast<int>(-static_cast<unsigned int>(operand));
}
if (ctx.unaryOp()->NotOp()) {
return operand == 0 ? 1 : 0;

@ -1,4 +1,6 @@
// 解析帮助、输入文件和输出阶段选项。
// 解析命令行参数,支持比赛要求的格式:
// compiler -S -o testcase.s testcase.sy
// compiler -S -o testcase.s testcase.sy -O1
#include "utils/CLI.h"
@ -15,21 +17,77 @@ CLIOptions ParseCLI(int argc, char** argv) {
if (argc <= 1) {
throw std::runtime_error(FormatError(
"cli",
"用法: compiler [--help] [--emit-parse-tree] [--emit-ir] [--emit-asm] [-O] <input.sy>"));
"用法: compiler [-S] [-o output.s] [-O|-O1|-O2|-O3] <input.sy>"));
}
for (int i = 1; i < argc; ++i) {
const char* arg = argv[i];
// 帮助
if (std::strcmp(arg, "-h") == 0 || std::strcmp(arg, "--help") == 0) {
opt.show_help = true;
return opt;
}
if (std::strcmp(arg, "-O") == 0 || std::strcmp(arg, "--optimize") == 0) {
// -S: 生成汇编(比赛要求)
if (std::strcmp(arg, "-S") == 0) {
if (!explicit_emit) {
opt.emit_parse_tree = false;
opt.emit_ir = false;
opt.emit_asm = false;
explicit_emit = true;
}
opt.emit_asm = true;
continue;
}
// -o <file>: 指定输出文件
if (std::strcmp(arg, "-o") == 0) {
if (i + 1 < argc) {
opt.output = argv[++i];
} else {
throw std::runtime_error(FormatError("cli", "-o 需要指定输出文件"));
}
continue;
}
if (std::strcmp(arg, "-O") == 0) {
opt.optimize = true;
opt.opt_level = 1;
continue;
}
if (std::strcmp(arg, "-O0") == 0) {
opt.optimize = false;
opt.opt_level = 0;
continue;
}
if (std::strcmp(arg, "-O1") == 0) {
opt.optimize = true;
opt.opt_level = 1;
continue;
}
if (std::strcmp(arg, "-O2") == 0) {
opt.optimize = true;
opt.opt_level = 2;
continue;
}
if (std::strcmp(arg, "-O3") == 0) {
opt.optimize = true;
opt.opt_level = 3;
continue;
}
if (std::strcmp(arg, "--optimize") == 0) {
opt.optimize = true;
opt.opt_level = 1;
continue;
}
// 兼容旧格式
if (std::strcmp(arg, "--emit-parse-tree") == 0) {
if (!explicit_emit) {
opt.emit_parse_tree = false;
@ -80,9 +138,12 @@ CLIOptions ParseCLI(int argc, char** argv) {
throw std::runtime_error(
FormatError("cli", "缺少输入文件:请提供 <input.sy>(使用 --help 查看用法)"));
}
// 如果没有指定任何输出模式,默认生成汇编(比赛场景)
if (!opt.emit_parse_tree && !opt.emit_ir && !opt.emit_asm) {
throw std::runtime_error(FormatError(
"cli", "未选择任何输出:请使用 --emit-parse-tree / --emit-ir / --emit-asm"));
opt.emit_asm = true;
explicit_emit = true;
}
return opt;
}

Binary file not shown.
Loading…
Cancel
Save