diff --git a/.gitignore b/.gitignore index 0f95955b..ef54b105 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/CMakeLists.txt b/CMakeLists.txt index 74dcb270..e11093dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) \ No newline at end of file diff --git a/Error.txt b/Error.txt new file mode 100644 index 00000000..83d595df --- /dev/null +++ b/Error.txt @@ -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. \ No newline at end of file diff --git a/README.md b/README.md index a6c1b509..4885ef10 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ -<<<<<<< HEAD # SysY 编译器课程实验(C++) -本仓库为“并行编译课程实验”提供一个 SysY 编译器的最小可运行示例,实验按 Lab1–Lab6 逐步完成: +本仓库为"并行编译课程实验"提供一个 SysY 编译器的最小可运行示例,实验按 Lab1–Lab6 逐步完成: 从前端(词法/语法分析与语法树处理)到中端(IR 生成、基本标量优化),再到后端(ARM64/AArch64 汇编生成、寄存器分配与后端优化),最后进行循环/并行相关优化。 ## 1. 实验介绍 @@ -19,7 +18,7 @@ 本仓库提供的示例代码和实验文档只是参考。我们非常鼓励大家在阅读当前仓库实现的同时,也结合自己的理解重新设计框架并完成实现,而不是机械照搬。 -如果希望进一步参考编译相关项目和往届优秀实现,可以查看编译比赛官网的技术支持栏目:。其中的“备赛推荐”整理了一些编译相关项目,也能看到往届优秀作品的开源实现,这些内容都很值得参考。 +如果希望进一步参考编译相关项目和往届优秀实现,可以查看编译比赛官网的技术支持栏目:。其中的"备赛推荐"整理了一些编译相关项目,也能看到往届优秀作品的开源实现,这些内容都很值得参考。 ## 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 diff --git a/src/frontend/AntlrDriver.cpp b/src/frontend/AntlrDriver.cpp index ee3c98c6..e0388a26 100644 --- a/src/frontend/AntlrDriver.cpp +++ b/src/frontend/AntlrDriver.cpp @@ -6,8 +6,6 @@ #include #include -#include "SysYLexer.h" -#include "SysYParser.h" #include "antlr4-runtime.h" #include "utils/Log.h" diff --git a/src/frontend/SysYBaseVisitor.cpp b/src/frontend/SysYBaseVisitor.cpp new file mode 100644 index 00000000..ff228214 --- /dev/null +++ b/src/frontend/SysYBaseVisitor.cpp @@ -0,0 +1,7 @@ + +// Generated from src/antlr4/SysY.g4 by ANTLR 4.13.2 + + +#include "SysYBaseVisitor.h" + + diff --git a/src/frontend/SysYLexer.cpp b/src/frontend/SysYLexer.cpp new file mode 100644 index 00000000..6548c73d --- /dev/null +++ b/src/frontend/SysYLexer.cpp @@ -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 ruleNames, + std::vector channelNames, + std::vector modeNames, + std::vector literalNames, + std::vector 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 decisionToDFA; + antlr4::atn::PredictionContextCache sharedContextCache; + const std::vector ruleNames; + const std::vector channelNames; + const std::vector modeNames; + const std::vector literalNames; + const std::vector symbolicNames; + const antlr4::dfa::Vocabulary vocabulary; + antlr4::atn::SerializedATNView serializedATN; + std::unique_ptr atn; +}; + +::antlr4::internal::OnceFlag sysylexerLexerOnceFlag; +#if ANTLR4_USE_THREAD_LOCAL_CACHE +static thread_local +#endif +std::unique_ptr sysylexerLexerStaticData = nullptr; + +void sysylexerLexerInitialize() { +#if ANTLR4_USE_THREAD_LOCAL_CACHE + if (sysylexerLexerStaticData != nullptr) { + return; + } +#else + assert(sysylexerLexerStaticData == nullptr); +#endif + auto staticData = std::make_unique( + std::vector{ + "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{ + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }, + std::vector{ + "DEFAULT_MODE" + }, + std::vector{ + "", "'void'", "'int'", "'float'", "'const'", "'if'", "'else'", "'while'", + "'break'", "'continue'", "'return'", "'+'", "'-'", "'='", "'*'", "'/'", + "'%'", "'!'", "'&&'", "'||'", "'=='", "'!='", "'<'", "'>'", "'<='", + "'>='", "';'", "','", "'('", "')'", "'{'", "'}'", "'['", "']'" + }, + std::vector{ + "", "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& SysYLexer::getRuleNames() const { + return sysylexerLexerStaticData->ruleNames; +} + +const std::vector& SysYLexer::getChannelNames() const { + return sysylexerLexerStaticData->channelNames; +} + +const std::vector& 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 +} diff --git a/src/frontend/SysYParser.cpp b/src/frontend/SysYParser.cpp new file mode 100644 index 00000000..6f82938a --- /dev/null +++ b/src/frontend/SysYParser.cpp @@ -0,0 +1,3179 @@ + +// Generated from src/antlr4/SysY.g4 by ANTLR 4.13.2 + + +#include "SysYVisitor.h" + +#include "SysYParser.h" + + +using namespace antlrcpp; + +using namespace antlr4; + +namespace { + +struct SysYParserStaticData final { + SysYParserStaticData(std::vector ruleNames, + std::vector literalNames, + std::vector symbolicNames) + : ruleNames(std::move(ruleNames)), literalNames(std::move(literalNames)), + symbolicNames(std::move(symbolicNames)), + vocabulary(this->literalNames, this->symbolicNames) {} + + SysYParserStaticData(const SysYParserStaticData&) = delete; + SysYParserStaticData(SysYParserStaticData&&) = delete; + SysYParserStaticData& operator=(const SysYParserStaticData&) = delete; + SysYParserStaticData& operator=(SysYParserStaticData&&) = delete; + + std::vector decisionToDFA; + antlr4::atn::PredictionContextCache sharedContextCache; + const std::vector ruleNames; + const std::vector literalNames; + const std::vector symbolicNames; + const antlr4::dfa::Vocabulary vocabulary; + antlr4::atn::SerializedATNView serializedATN; + std::unique_ptr atn; +}; + +::antlr4::internal::OnceFlag sysyParserOnceFlag; +#if ANTLR4_USE_THREAD_LOCAL_CACHE +static thread_local +#endif +std::unique_ptr sysyParserStaticData = nullptr; + +void sysyParserInitialize() { +#if ANTLR4_USE_THREAD_LOCAL_CACHE + if (sysyParserStaticData != nullptr) { + return; + } +#else + assert(sysyParserStaticData == nullptr); +#endif + auto staticData = std::make_unique( + std::vector{ + "compUnit", "funcDef", "funcType", "funcFParams", "funcFParam", "block", + "blockItem", "decl", "constDecl", "bType", "constDef", "constInitVal", + "stmt", "cond", "lVal", "primaryExp", "number", "unaryExp", "unaryOp", + "funcRParams", "mulExp", "addExp", "relExp", "eqExp", "lAndExp", "lOrExp", + "constExp", "varDecl", "varDef", "initVal", "exp" + }, + std::vector{ + "", "'void'", "'int'", "'float'", "'const'", "'if'", "'else'", "'while'", + "'break'", "'continue'", "'return'", "'+'", "'-'", "'='", "'*'", "'/'", + "'%'", "'!'", "'&&'", "'||'", "'=='", "'!='", "'<'", "'>'", "'<='", + "'>='", "';'", "','", "'('", "')'", "'{'", "'}'", "'['", "']'" + }, + std::vector{ + "", "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,1,39,364,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,1,0,1,0,4,0,65,8,0,11,0,12,0,66,1,0,1,0,1,1,1, + 1,1,1,1,1,3,1,75,8,1,1,1,1,1,1,1,1,2,1,2,1,3,1,3,1,3,5,3,85,8,3,10,3, + 12,3,88,9,3,1,4,1,4,1,4,1,4,1,4,1,4,1,4,1,4,5,4,98,8,4,10,4,12,4,101, + 9,4,3,4,103,8,4,1,5,1,5,5,5,107,8,5,10,5,12,5,110,9,5,1,5,1,5,1,6,1,6, + 3,6,116,8,6,1,7,1,7,3,7,120,8,7,1,8,1,8,1,8,1,8,1,8,5,8,127,8,8,10,8, + 12,8,130,9,8,1,8,1,8,1,9,1,9,1,10,1,10,1,10,1,10,1,10,5,10,141,8,10,10, + 10,12,10,144,9,10,1,10,1,10,1,10,1,11,1,11,1,11,1,11,1,11,5,11,154,8, + 11,10,11,12,11,157,9,11,3,11,159,8,11,1,11,3,11,162,8,11,1,12,1,12,1, + 12,1,12,1,12,1,12,3,12,170,8,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1, + 12,1,12,3,12,181,8,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1,12,1, + 12,1,12,1,12,3,12,195,8,12,1,12,3,12,198,8,12,1,13,1,13,1,14,1,14,1,14, + 1,14,1,14,5,14,207,8,14,10,14,12,14,210,9,14,1,15,1,15,1,15,1,15,1,15, + 1,15,3,15,218,8,15,1,16,1,16,1,17,1,17,1,17,1,17,3,17,226,8,17,1,17,1, + 17,1,17,1,17,3,17,232,8,17,1,18,1,18,1,19,1,19,1,19,5,19,239,8,19,10, + 19,12,19,242,9,19,1,20,1,20,1,20,1,20,1,20,1,20,5,20,250,8,20,10,20,12, + 20,253,9,20,1,21,1,21,1,21,1,21,1,21,1,21,5,21,261,8,21,10,21,12,21,264, + 9,21,1,22,1,22,1,22,1,22,1,22,1,22,5,22,272,8,22,10,22,12,22,275,9,22, + 1,23,1,23,1,23,1,23,1,23,1,23,5,23,283,8,23,10,23,12,23,286,9,23,1,24, + 1,24,1,24,1,24,1,24,1,24,5,24,294,8,24,10,24,12,24,297,9,24,1,25,1,25, + 1,25,1,25,1,25,1,25,5,25,305,8,25,10,25,12,25,308,9,25,1,26,1,26,1,27, + 1,27,1,27,1,27,5,27,316,8,27,10,27,12,27,319,9,27,1,27,1,27,1,28,1,28, + 1,28,1,28,1,28,5,28,328,8,28,10,28,12,28,331,9,28,1,28,1,28,1,28,1,28, + 1,28,5,28,338,8,28,10,28,12,28,341,9,28,1,28,1,28,3,28,345,8,28,1,29, + 1,29,1,29,1,29,1,29,5,29,352,8,29,10,29,12,29,355,9,29,3,29,357,8,29, + 1,29,3,29,360,8,29,1,30,1,30,1,30,0,6,40,42,44,46,48,50,31,0,2,4,6,8, + 10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54, + 56,58,60,0,8,1,0,1,3,1,0,2,3,1,0,35,36,2,0,11,12,17,17,1,0,14,16,1,0, + 11,12,1,0,22,25,1,0,20,21,376,0,64,1,0,0,0,2,70,1,0,0,0,4,79,1,0,0,0, + 6,81,1,0,0,0,8,89,1,0,0,0,10,104,1,0,0,0,12,115,1,0,0,0,14,119,1,0,0, + 0,16,121,1,0,0,0,18,133,1,0,0,0,20,135,1,0,0,0,22,161,1,0,0,0,24,197, + 1,0,0,0,26,199,1,0,0,0,28,201,1,0,0,0,30,217,1,0,0,0,32,219,1,0,0,0,34, + 231,1,0,0,0,36,233,1,0,0,0,38,235,1,0,0,0,40,243,1,0,0,0,42,254,1,0,0, + 0,44,265,1,0,0,0,46,276,1,0,0,0,48,287,1,0,0,0,50,298,1,0,0,0,52,309, + 1,0,0,0,54,311,1,0,0,0,56,344,1,0,0,0,58,359,1,0,0,0,60,361,1,0,0,0,62, + 65,3,2,1,0,63,65,3,14,7,0,64,62,1,0,0,0,64,63,1,0,0,0,65,66,1,0,0,0,66, + 64,1,0,0,0,66,67,1,0,0,0,67,68,1,0,0,0,68,69,5,0,0,1,69,1,1,0,0,0,70, + 71,3,4,2,0,71,72,5,34,0,0,72,74,5,28,0,0,73,75,3,6,3,0,74,73,1,0,0,0, + 74,75,1,0,0,0,75,76,1,0,0,0,76,77,5,29,0,0,77,78,3,10,5,0,78,3,1,0,0, + 0,79,80,7,0,0,0,80,5,1,0,0,0,81,86,3,8,4,0,82,83,5,27,0,0,83,85,3,8,4, + 0,84,82,1,0,0,0,85,88,1,0,0,0,86,84,1,0,0,0,86,87,1,0,0,0,87,7,1,0,0, + 0,88,86,1,0,0,0,89,90,3,18,9,0,90,102,5,34,0,0,91,92,5,32,0,0,92,99,5, + 33,0,0,93,94,5,32,0,0,94,95,3,60,30,0,95,96,5,33,0,0,96,98,1,0,0,0,97, + 93,1,0,0,0,98,101,1,0,0,0,99,97,1,0,0,0,99,100,1,0,0,0,100,103,1,0,0, + 0,101,99,1,0,0,0,102,91,1,0,0,0,102,103,1,0,0,0,103,9,1,0,0,0,104,108, + 5,30,0,0,105,107,3,12,6,0,106,105,1,0,0,0,107,110,1,0,0,0,108,106,1,0, + 0,0,108,109,1,0,0,0,109,111,1,0,0,0,110,108,1,0,0,0,111,112,5,31,0,0, + 112,11,1,0,0,0,113,116,3,14,7,0,114,116,3,24,12,0,115,113,1,0,0,0,115, + 114,1,0,0,0,116,13,1,0,0,0,117,120,3,54,27,0,118,120,3,16,8,0,119,117, + 1,0,0,0,119,118,1,0,0,0,120,15,1,0,0,0,121,122,5,4,0,0,122,123,3,18,9, + 0,123,128,3,20,10,0,124,125,5,27,0,0,125,127,3,20,10,0,126,124,1,0,0, + 0,127,130,1,0,0,0,128,126,1,0,0,0,128,129,1,0,0,0,129,131,1,0,0,0,130, + 128,1,0,0,0,131,132,5,26,0,0,132,17,1,0,0,0,133,134,7,1,0,0,134,19,1, + 0,0,0,135,142,5,34,0,0,136,137,5,32,0,0,137,138,3,52,26,0,138,139,5,33, + 0,0,139,141,1,0,0,0,140,136,1,0,0,0,141,144,1,0,0,0,142,140,1,0,0,0,142, + 143,1,0,0,0,143,145,1,0,0,0,144,142,1,0,0,0,145,146,5,13,0,0,146,147, + 3,22,11,0,147,21,1,0,0,0,148,162,3,52,26,0,149,158,5,30,0,0,150,155,3, + 22,11,0,151,152,5,27,0,0,152,154,3,22,11,0,153,151,1,0,0,0,154,157,1, + 0,0,0,155,153,1,0,0,0,155,156,1,0,0,0,156,159,1,0,0,0,157,155,1,0,0,0, + 158,150,1,0,0,0,158,159,1,0,0,0,159,160,1,0,0,0,160,162,5,31,0,0,161, + 148,1,0,0,0,161,149,1,0,0,0,162,23,1,0,0,0,163,164,3,28,14,0,164,165, + 5,13,0,0,165,166,3,60,30,0,166,167,5,26,0,0,167,198,1,0,0,0,168,170,3, + 60,30,0,169,168,1,0,0,0,169,170,1,0,0,0,170,171,1,0,0,0,171,198,5,26, + 0,0,172,198,3,10,5,0,173,174,5,5,0,0,174,175,5,28,0,0,175,176,3,26,13, + 0,176,177,5,29,0,0,177,180,3,24,12,0,178,179,5,6,0,0,179,181,3,24,12, + 0,180,178,1,0,0,0,180,181,1,0,0,0,181,198,1,0,0,0,182,183,5,7,0,0,183, + 184,5,28,0,0,184,185,3,26,13,0,185,186,5,29,0,0,186,187,3,24,12,0,187, + 198,1,0,0,0,188,189,5,8,0,0,189,198,5,26,0,0,190,191,5,9,0,0,191,198, + 5,26,0,0,192,194,5,10,0,0,193,195,3,60,30,0,194,193,1,0,0,0,194,195,1, + 0,0,0,195,196,1,0,0,0,196,198,5,26,0,0,197,163,1,0,0,0,197,169,1,0,0, + 0,197,172,1,0,0,0,197,173,1,0,0,0,197,182,1,0,0,0,197,188,1,0,0,0,197, + 190,1,0,0,0,197,192,1,0,0,0,198,25,1,0,0,0,199,200,3,50,25,0,200,27,1, + 0,0,0,201,208,5,34,0,0,202,203,5,32,0,0,203,204,3,60,30,0,204,205,5,33, + 0,0,205,207,1,0,0,0,206,202,1,0,0,0,207,210,1,0,0,0,208,206,1,0,0,0,208, + 209,1,0,0,0,209,29,1,0,0,0,210,208,1,0,0,0,211,212,5,28,0,0,212,213,3, + 60,30,0,213,214,5,29,0,0,214,218,1,0,0,0,215,218,3,28,14,0,216,218,3, + 32,16,0,217,211,1,0,0,0,217,215,1,0,0,0,217,216,1,0,0,0,218,31,1,0,0, + 0,219,220,7,2,0,0,220,33,1,0,0,0,221,232,3,30,15,0,222,223,5,34,0,0,223, + 225,5,28,0,0,224,226,3,38,19,0,225,224,1,0,0,0,225,226,1,0,0,0,226,227, + 1,0,0,0,227,232,5,29,0,0,228,229,3,36,18,0,229,230,3,34,17,0,230,232, + 1,0,0,0,231,221,1,0,0,0,231,222,1,0,0,0,231,228,1,0,0,0,232,35,1,0,0, + 0,233,234,7,3,0,0,234,37,1,0,0,0,235,240,3,60,30,0,236,237,5,27,0,0,237, + 239,3,60,30,0,238,236,1,0,0,0,239,242,1,0,0,0,240,238,1,0,0,0,240,241, + 1,0,0,0,241,39,1,0,0,0,242,240,1,0,0,0,243,244,6,20,-1,0,244,245,3,34, + 17,0,245,251,1,0,0,0,246,247,10,1,0,0,247,248,7,4,0,0,248,250,3,34,17, + 0,249,246,1,0,0,0,250,253,1,0,0,0,251,249,1,0,0,0,251,252,1,0,0,0,252, + 41,1,0,0,0,253,251,1,0,0,0,254,255,6,21,-1,0,255,256,3,40,20,0,256,262, + 1,0,0,0,257,258,10,1,0,0,258,259,7,5,0,0,259,261,3,40,20,0,260,257,1, + 0,0,0,261,264,1,0,0,0,262,260,1,0,0,0,262,263,1,0,0,0,263,43,1,0,0,0, + 264,262,1,0,0,0,265,266,6,22,-1,0,266,267,3,42,21,0,267,273,1,0,0,0,268, + 269,10,1,0,0,269,270,7,6,0,0,270,272,3,42,21,0,271,268,1,0,0,0,272,275, + 1,0,0,0,273,271,1,0,0,0,273,274,1,0,0,0,274,45,1,0,0,0,275,273,1,0,0, + 0,276,277,6,23,-1,0,277,278,3,44,22,0,278,284,1,0,0,0,279,280,10,1,0, + 0,280,281,7,7,0,0,281,283,3,44,22,0,282,279,1,0,0,0,283,286,1,0,0,0,284, + 282,1,0,0,0,284,285,1,0,0,0,285,47,1,0,0,0,286,284,1,0,0,0,287,288,6, + 24,-1,0,288,289,3,46,23,0,289,295,1,0,0,0,290,291,10,1,0,0,291,292,5, + 18,0,0,292,294,3,46,23,0,293,290,1,0,0,0,294,297,1,0,0,0,295,293,1,0, + 0,0,295,296,1,0,0,0,296,49,1,0,0,0,297,295,1,0,0,0,298,299,6,25,-1,0, + 299,300,3,48,24,0,300,306,1,0,0,0,301,302,10,1,0,0,302,303,5,19,0,0,303, + 305,3,48,24,0,304,301,1,0,0,0,305,308,1,0,0,0,306,304,1,0,0,0,306,307, + 1,0,0,0,307,51,1,0,0,0,308,306,1,0,0,0,309,310,3,42,21,0,310,53,1,0,0, + 0,311,312,3,18,9,0,312,317,3,56,28,0,313,314,5,27,0,0,314,316,3,56,28, + 0,315,313,1,0,0,0,316,319,1,0,0,0,317,315,1,0,0,0,317,318,1,0,0,0,318, + 320,1,0,0,0,319,317,1,0,0,0,320,321,5,26,0,0,321,55,1,0,0,0,322,329,5, + 34,0,0,323,324,5,32,0,0,324,325,3,52,26,0,325,326,5,33,0,0,326,328,1, + 0,0,0,327,323,1,0,0,0,328,331,1,0,0,0,329,327,1,0,0,0,329,330,1,0,0,0, + 330,345,1,0,0,0,331,329,1,0,0,0,332,339,5,34,0,0,333,334,5,32,0,0,334, + 335,3,52,26,0,335,336,5,33,0,0,336,338,1,0,0,0,337,333,1,0,0,0,338,341, + 1,0,0,0,339,337,1,0,0,0,339,340,1,0,0,0,340,342,1,0,0,0,341,339,1,0,0, + 0,342,343,5,13,0,0,343,345,3,58,29,0,344,322,1,0,0,0,344,332,1,0,0,0, + 345,57,1,0,0,0,346,360,3,60,30,0,347,356,5,30,0,0,348,353,3,58,29,0,349, + 350,5,27,0,0,350,352,3,58,29,0,351,349,1,0,0,0,352,355,1,0,0,0,353,351, + 1,0,0,0,353,354,1,0,0,0,354,357,1,0,0,0,355,353,1,0,0,0,356,348,1,0,0, + 0,356,357,1,0,0,0,357,358,1,0,0,0,358,360,5,31,0,0,359,346,1,0,0,0,359, + 347,1,0,0,0,360,59,1,0,0,0,361,362,3,42,21,0,362,61,1,0,0,0,36,64,66, + 74,86,99,102,108,115,119,128,142,155,158,161,169,180,194,197,208,217, + 225,231,240,251,262,273,284,295,306,317,329,339,344,353,356,359 + }; + 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); + } + sysyParserStaticData = std::move(staticData); +} + +} + +SysYParser::SysYParser(TokenStream *input) : SysYParser(input, antlr4::atn::ParserATNSimulatorOptions()) {} + +SysYParser::SysYParser(TokenStream *input, const antlr4::atn::ParserATNSimulatorOptions &options) : Parser(input) { + SysYParser::initialize(); + _interpreter = new atn::ParserATNSimulator(this, *sysyParserStaticData->atn, sysyParserStaticData->decisionToDFA, sysyParserStaticData->sharedContextCache, options); +} + +SysYParser::~SysYParser() { + delete _interpreter; +} + +const atn::ATN& SysYParser::getATN() const { + return *sysyParserStaticData->atn; +} + +std::string SysYParser::getGrammarFileName() const { + return "SysY.g4"; +} + +const std::vector& SysYParser::getRuleNames() const { + return sysyParserStaticData->ruleNames; +} + +const dfa::Vocabulary& SysYParser::getVocabulary() const { + return sysyParserStaticData->vocabulary; +} + +antlr4::atn::SerializedATNView SysYParser::getSerializedATN() const { + return sysyParserStaticData->serializedATN; +} + + +//----------------- CompUnitContext ------------------------------------------------------------------ + +SysYParser::CompUnitContext::CompUnitContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +tree::TerminalNode* SysYParser::CompUnitContext::EOF() { + return getToken(SysYParser::EOF, 0); +} + +std::vector SysYParser::CompUnitContext::funcDef() { + return getRuleContexts(); +} + +SysYParser::FuncDefContext* SysYParser::CompUnitContext::funcDef(size_t i) { + return getRuleContext(i); +} + +std::vector SysYParser::CompUnitContext::decl() { + return getRuleContexts(); +} + +SysYParser::DeclContext* SysYParser::CompUnitContext::decl(size_t i) { + return getRuleContext(i); +} + + +size_t SysYParser::CompUnitContext::getRuleIndex() const { + return SysYParser::RuleCompUnit; +} + + +std::any SysYParser::CompUnitContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitCompUnit(this); + else + return visitor->visitChildren(this); +} + +SysYParser::CompUnitContext* SysYParser::compUnit() { + CompUnitContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 0, SysYParser::RuleCompUnit); + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + enterOuterAlt(_localctx, 1); + setState(64); + _errHandler->sync(this); + _la = _input->LA(1); + do { + setState(64); + _errHandler->sync(this); + switch (getInterpreter()->adaptivePredict(_input, 0, _ctx)) { + case 1: { + setState(62); + funcDef(); + break; + } + + case 2: { + setState(63); + decl(); + break; + } + + default: + break; + } + setState(66); + _errHandler->sync(this); + _la = _input->LA(1); + } while ((((_la & ~ 0x3fULL) == 0) && + ((1ULL << _la) & 30) != 0)); + setState(68); + match(SysYParser::EOF); + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- FuncDefContext ------------------------------------------------------------------ + +SysYParser::FuncDefContext::FuncDefContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +SysYParser::FuncTypeContext* SysYParser::FuncDefContext::funcType() { + return getRuleContext(0); +} + +tree::TerminalNode* SysYParser::FuncDefContext::Ident() { + return getToken(SysYParser::Ident, 0); +} + +tree::TerminalNode* SysYParser::FuncDefContext::L_PAREN() { + return getToken(SysYParser::L_PAREN, 0); +} + +tree::TerminalNode* SysYParser::FuncDefContext::R_PAREN() { + return getToken(SysYParser::R_PAREN, 0); +} + +SysYParser::BlockContext* SysYParser::FuncDefContext::block() { + return getRuleContext(0); +} + +SysYParser::FuncFParamsContext* SysYParser::FuncDefContext::funcFParams() { + return getRuleContext(0); +} + + +size_t SysYParser::FuncDefContext::getRuleIndex() const { + return SysYParser::RuleFuncDef; +} + + +std::any SysYParser::FuncDefContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitFuncDef(this); + else + return visitor->visitChildren(this); +} + +SysYParser::FuncDefContext* SysYParser::funcDef() { + FuncDefContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 2, SysYParser::RuleFuncDef); + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + enterOuterAlt(_localctx, 1); + setState(70); + funcType(); + setState(71); + match(SysYParser::Ident); + setState(72); + match(SysYParser::L_PAREN); + setState(74); + _errHandler->sync(this); + + _la = _input->LA(1); + if (_la == SysYParser::Int + + || _la == SysYParser::Float) { + setState(73); + funcFParams(); + } + setState(76); + match(SysYParser::R_PAREN); + setState(77); + block(); + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- FuncTypeContext ------------------------------------------------------------------ + +SysYParser::FuncTypeContext::FuncTypeContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +tree::TerminalNode* SysYParser::FuncTypeContext::Void() { + return getToken(SysYParser::Void, 0); +} + +tree::TerminalNode* SysYParser::FuncTypeContext::Int() { + return getToken(SysYParser::Int, 0); +} + +tree::TerminalNode* SysYParser::FuncTypeContext::Float() { + return getToken(SysYParser::Float, 0); +} + + +size_t SysYParser::FuncTypeContext::getRuleIndex() const { + return SysYParser::RuleFuncType; +} + + +std::any SysYParser::FuncTypeContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitFuncType(this); + else + return visitor->visitChildren(this); +} + +SysYParser::FuncTypeContext* SysYParser::funcType() { + FuncTypeContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 4, SysYParser::RuleFuncType); + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + enterOuterAlt(_localctx, 1); + setState(79); + _la = _input->LA(1); + if (!((((_la & ~ 0x3fULL) == 0) && + ((1ULL << _la) & 14) != 0))) { + _errHandler->recoverInline(this); + } + else { + _errHandler->reportMatch(this); + consume(); + } + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- FuncFParamsContext ------------------------------------------------------------------ + +SysYParser::FuncFParamsContext::FuncFParamsContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +std::vector SysYParser::FuncFParamsContext::funcFParam() { + return getRuleContexts(); +} + +SysYParser::FuncFParamContext* SysYParser::FuncFParamsContext::funcFParam(size_t i) { + return getRuleContext(i); +} + +std::vector SysYParser::FuncFParamsContext::Comma() { + return getTokens(SysYParser::Comma); +} + +tree::TerminalNode* SysYParser::FuncFParamsContext::Comma(size_t i) { + return getToken(SysYParser::Comma, i); +} + + +size_t SysYParser::FuncFParamsContext::getRuleIndex() const { + return SysYParser::RuleFuncFParams; +} + + +std::any SysYParser::FuncFParamsContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitFuncFParams(this); + else + return visitor->visitChildren(this); +} + +SysYParser::FuncFParamsContext* SysYParser::funcFParams() { + FuncFParamsContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 6, SysYParser::RuleFuncFParams); + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + enterOuterAlt(_localctx, 1); + setState(81); + funcFParam(); + setState(86); + _errHandler->sync(this); + _la = _input->LA(1); + while (_la == SysYParser::Comma) { + setState(82); + match(SysYParser::Comma); + setState(83); + funcFParam(); + setState(88); + _errHandler->sync(this); + _la = _input->LA(1); + } + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- FuncFParamContext ------------------------------------------------------------------ + +SysYParser::FuncFParamContext::FuncFParamContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +SysYParser::BTypeContext* SysYParser::FuncFParamContext::bType() { + return getRuleContext(0); +} + +tree::TerminalNode* SysYParser::FuncFParamContext::Ident() { + return getToken(SysYParser::Ident, 0); +} + +std::vector SysYParser::FuncFParamContext::L_BRACKET() { + return getTokens(SysYParser::L_BRACKET); +} + +tree::TerminalNode* SysYParser::FuncFParamContext::L_BRACKET(size_t i) { + return getToken(SysYParser::L_BRACKET, i); +} + +std::vector SysYParser::FuncFParamContext::R_BRACKET() { + return getTokens(SysYParser::R_BRACKET); +} + +tree::TerminalNode* SysYParser::FuncFParamContext::R_BRACKET(size_t i) { + return getToken(SysYParser::R_BRACKET, i); +} + +std::vector SysYParser::FuncFParamContext::exp() { + return getRuleContexts(); +} + +SysYParser::ExpContext* SysYParser::FuncFParamContext::exp(size_t i) { + return getRuleContext(i); +} + + +size_t SysYParser::FuncFParamContext::getRuleIndex() const { + return SysYParser::RuleFuncFParam; +} + + +std::any SysYParser::FuncFParamContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitFuncFParam(this); + else + return visitor->visitChildren(this); +} + +SysYParser::FuncFParamContext* SysYParser::funcFParam() { + FuncFParamContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 8, SysYParser::RuleFuncFParam); + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + enterOuterAlt(_localctx, 1); + setState(89); + bType(); + setState(90); + match(SysYParser::Ident); + setState(102); + _errHandler->sync(this); + + _la = _input->LA(1); + if (_la == SysYParser::L_BRACKET) { + setState(91); + match(SysYParser::L_BRACKET); + setState(92); + match(SysYParser::R_BRACKET); + setState(99); + _errHandler->sync(this); + _la = _input->LA(1); + while (_la == SysYParser::L_BRACKET) { + setState(93); + match(SysYParser::L_BRACKET); + setState(94); + exp(); + setState(95); + match(SysYParser::R_BRACKET); + setState(101); + _errHandler->sync(this); + _la = _input->LA(1); + } + } + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- BlockContext ------------------------------------------------------------------ + +SysYParser::BlockContext::BlockContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +tree::TerminalNode* SysYParser::BlockContext::L_BRACE() { + return getToken(SysYParser::L_BRACE, 0); +} + +tree::TerminalNode* SysYParser::BlockContext::R_BRACE() { + return getToken(SysYParser::R_BRACE, 0); +} + +std::vector SysYParser::BlockContext::blockItem() { + return getRuleContexts(); +} + +SysYParser::BlockItemContext* SysYParser::BlockContext::blockItem(size_t i) { + return getRuleContext(i); +} + + +size_t SysYParser::BlockContext::getRuleIndex() const { + return SysYParser::RuleBlock; +} + + +std::any SysYParser::BlockContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitBlock(this); + else + return visitor->visitChildren(this); +} + +SysYParser::BlockContext* SysYParser::block() { + BlockContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 10, SysYParser::RuleBlock); + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + enterOuterAlt(_localctx, 1); + setState(104); + match(SysYParser::L_BRACE); + setState(108); + _errHandler->sync(this); + _la = _input->LA(1); + while ((((_la & ~ 0x3fULL) == 0) && + ((1ULL << _la) & 121668509628) != 0)) { + setState(105); + blockItem(); + setState(110); + _errHandler->sync(this); + _la = _input->LA(1); + } + setState(111); + match(SysYParser::R_BRACE); + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- BlockItemContext ------------------------------------------------------------------ + +SysYParser::BlockItemContext::BlockItemContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +SysYParser::DeclContext* SysYParser::BlockItemContext::decl() { + return getRuleContext(0); +} + +SysYParser::StmtContext* SysYParser::BlockItemContext::stmt() { + return getRuleContext(0); +} + + +size_t SysYParser::BlockItemContext::getRuleIndex() const { + return SysYParser::RuleBlockItem; +} + + +std::any SysYParser::BlockItemContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitBlockItem(this); + else + return visitor->visitChildren(this); +} + +SysYParser::BlockItemContext* SysYParser::blockItem() { + BlockItemContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 12, SysYParser::RuleBlockItem); + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + setState(115); + _errHandler->sync(this); + switch (_input->LA(1)) { + case SysYParser::Int: + case SysYParser::Float: + case SysYParser::Const: { + enterOuterAlt(_localctx, 1); + setState(113); + decl(); + break; + } + + case SysYParser::If: + case SysYParser::While: + case SysYParser::Break: + case SysYParser::Continue: + case SysYParser::Return: + case SysYParser::AddOp: + case SysYParser::SubOp: + case SysYParser::NotOp: + case SysYParser::Semi: + case SysYParser::L_PAREN: + case SysYParser::L_BRACE: + case SysYParser::Ident: + case SysYParser::IntConst: + case SysYParser::FloatConst: { + enterOuterAlt(_localctx, 2); + setState(114); + stmt(); + break; + } + + default: + throw NoViableAltException(this); + } + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- DeclContext ------------------------------------------------------------------ + +SysYParser::DeclContext::DeclContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +SysYParser::VarDeclContext* SysYParser::DeclContext::varDecl() { + return getRuleContext(0); +} + +SysYParser::ConstDeclContext* SysYParser::DeclContext::constDecl() { + return getRuleContext(0); +} + + +size_t SysYParser::DeclContext::getRuleIndex() const { + return SysYParser::RuleDecl; +} + + +std::any SysYParser::DeclContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitDecl(this); + else + return visitor->visitChildren(this); +} + +SysYParser::DeclContext* SysYParser::decl() { + DeclContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 14, SysYParser::RuleDecl); + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + setState(119); + _errHandler->sync(this); + switch (_input->LA(1)) { + case SysYParser::Int: + case SysYParser::Float: { + enterOuterAlt(_localctx, 1); + setState(117); + varDecl(); + break; + } + + case SysYParser::Const: { + enterOuterAlt(_localctx, 2); + setState(118); + constDecl(); + break; + } + + default: + throw NoViableAltException(this); + } + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- ConstDeclContext ------------------------------------------------------------------ + +SysYParser::ConstDeclContext::ConstDeclContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +tree::TerminalNode* SysYParser::ConstDeclContext::Const() { + return getToken(SysYParser::Const, 0); +} + +SysYParser::BTypeContext* SysYParser::ConstDeclContext::bType() { + return getRuleContext(0); +} + +std::vector SysYParser::ConstDeclContext::constDef() { + return getRuleContexts(); +} + +SysYParser::ConstDefContext* SysYParser::ConstDeclContext::constDef(size_t i) { + return getRuleContext(i); +} + +tree::TerminalNode* SysYParser::ConstDeclContext::Semi() { + return getToken(SysYParser::Semi, 0); +} + +std::vector SysYParser::ConstDeclContext::Comma() { + return getTokens(SysYParser::Comma); +} + +tree::TerminalNode* SysYParser::ConstDeclContext::Comma(size_t i) { + return getToken(SysYParser::Comma, i); +} + + +size_t SysYParser::ConstDeclContext::getRuleIndex() const { + return SysYParser::RuleConstDecl; +} + + +std::any SysYParser::ConstDeclContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitConstDecl(this); + else + return visitor->visitChildren(this); +} + +SysYParser::ConstDeclContext* SysYParser::constDecl() { + ConstDeclContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 16, SysYParser::RuleConstDecl); + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + enterOuterAlt(_localctx, 1); + setState(121); + match(SysYParser::Const); + setState(122); + bType(); + setState(123); + constDef(); + setState(128); + _errHandler->sync(this); + _la = _input->LA(1); + while (_la == SysYParser::Comma) { + setState(124); + match(SysYParser::Comma); + setState(125); + constDef(); + setState(130); + _errHandler->sync(this); + _la = _input->LA(1); + } + setState(131); + match(SysYParser::Semi); + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- BTypeContext ------------------------------------------------------------------ + +SysYParser::BTypeContext::BTypeContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +tree::TerminalNode* SysYParser::BTypeContext::Int() { + return getToken(SysYParser::Int, 0); +} + +tree::TerminalNode* SysYParser::BTypeContext::Float() { + return getToken(SysYParser::Float, 0); +} + + +size_t SysYParser::BTypeContext::getRuleIndex() const { + return SysYParser::RuleBType; +} + + +std::any SysYParser::BTypeContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitBType(this); + else + return visitor->visitChildren(this); +} + +SysYParser::BTypeContext* SysYParser::bType() { + BTypeContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 18, SysYParser::RuleBType); + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + enterOuterAlt(_localctx, 1); + setState(133); + _la = _input->LA(1); + if (!(_la == SysYParser::Int + + || _la == SysYParser::Float)) { + _errHandler->recoverInline(this); + } + else { + _errHandler->reportMatch(this); + consume(); + } + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- ConstDefContext ------------------------------------------------------------------ + +SysYParser::ConstDefContext::ConstDefContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +tree::TerminalNode* SysYParser::ConstDefContext::Ident() { + return getToken(SysYParser::Ident, 0); +} + +tree::TerminalNode* SysYParser::ConstDefContext::Assign() { + return getToken(SysYParser::Assign, 0); +} + +SysYParser::ConstInitValContext* SysYParser::ConstDefContext::constInitVal() { + return getRuleContext(0); +} + +std::vector SysYParser::ConstDefContext::L_BRACKET() { + return getTokens(SysYParser::L_BRACKET); +} + +tree::TerminalNode* SysYParser::ConstDefContext::L_BRACKET(size_t i) { + return getToken(SysYParser::L_BRACKET, i); +} + +std::vector SysYParser::ConstDefContext::constExp() { + return getRuleContexts(); +} + +SysYParser::ConstExpContext* SysYParser::ConstDefContext::constExp(size_t i) { + return getRuleContext(i); +} + +std::vector SysYParser::ConstDefContext::R_BRACKET() { + return getTokens(SysYParser::R_BRACKET); +} + +tree::TerminalNode* SysYParser::ConstDefContext::R_BRACKET(size_t i) { + return getToken(SysYParser::R_BRACKET, i); +} + + +size_t SysYParser::ConstDefContext::getRuleIndex() const { + return SysYParser::RuleConstDef; +} + + +std::any SysYParser::ConstDefContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitConstDef(this); + else + return visitor->visitChildren(this); +} + +SysYParser::ConstDefContext* SysYParser::constDef() { + ConstDefContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 20, SysYParser::RuleConstDef); + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + enterOuterAlt(_localctx, 1); + setState(135); + match(SysYParser::Ident); + setState(142); + _errHandler->sync(this); + _la = _input->LA(1); + while (_la == SysYParser::L_BRACKET) { + setState(136); + match(SysYParser::L_BRACKET); + setState(137); + constExp(); + setState(138); + match(SysYParser::R_BRACKET); + setState(144); + _errHandler->sync(this); + _la = _input->LA(1); + } + setState(145); + match(SysYParser::Assign); + setState(146); + constInitVal(); + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- ConstInitValContext ------------------------------------------------------------------ + +SysYParser::ConstInitValContext::ConstInitValContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +SysYParser::ConstExpContext* SysYParser::ConstInitValContext::constExp() { + return getRuleContext(0); +} + +tree::TerminalNode* SysYParser::ConstInitValContext::L_BRACE() { + return getToken(SysYParser::L_BRACE, 0); +} + +tree::TerminalNode* SysYParser::ConstInitValContext::R_BRACE() { + return getToken(SysYParser::R_BRACE, 0); +} + +std::vector SysYParser::ConstInitValContext::constInitVal() { + return getRuleContexts(); +} + +SysYParser::ConstInitValContext* SysYParser::ConstInitValContext::constInitVal(size_t i) { + return getRuleContext(i); +} + +std::vector SysYParser::ConstInitValContext::Comma() { + return getTokens(SysYParser::Comma); +} + +tree::TerminalNode* SysYParser::ConstInitValContext::Comma(size_t i) { + return getToken(SysYParser::Comma, i); +} + + +size_t SysYParser::ConstInitValContext::getRuleIndex() const { + return SysYParser::RuleConstInitVal; +} + + +std::any SysYParser::ConstInitValContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitConstInitVal(this); + else + return visitor->visitChildren(this); +} + +SysYParser::ConstInitValContext* SysYParser::constInitVal() { + ConstInitValContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 22, SysYParser::RuleConstInitVal); + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + setState(161); + _errHandler->sync(this); + switch (_input->LA(1)) { + case SysYParser::AddOp: + case SysYParser::SubOp: + case SysYParser::NotOp: + case SysYParser::L_PAREN: + case SysYParser::Ident: + case SysYParser::IntConst: + case SysYParser::FloatConst: { + enterOuterAlt(_localctx, 1); + setState(148); + constExp(); + break; + } + + case SysYParser::L_BRACE: { + enterOuterAlt(_localctx, 2); + setState(149); + match(SysYParser::L_BRACE); + setState(158); + _errHandler->sync(this); + + _la = _input->LA(1); + if ((((_la & ~ 0x3fULL) == 0) && + ((1ULL << _la) & 121601398784) != 0)) { + setState(150); + constInitVal(); + setState(155); + _errHandler->sync(this); + _la = _input->LA(1); + while (_la == SysYParser::Comma) { + setState(151); + match(SysYParser::Comma); + setState(152); + constInitVal(); + setState(157); + _errHandler->sync(this); + _la = _input->LA(1); + } + } + setState(160); + match(SysYParser::R_BRACE); + break; + } + + default: + throw NoViableAltException(this); + } + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- StmtContext ------------------------------------------------------------------ + +SysYParser::StmtContext::StmtContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +SysYParser::LValContext* SysYParser::StmtContext::lVal() { + return getRuleContext(0); +} + +tree::TerminalNode* SysYParser::StmtContext::Assign() { + return getToken(SysYParser::Assign, 0); +} + +SysYParser::ExpContext* SysYParser::StmtContext::exp() { + return getRuleContext(0); +} + +tree::TerminalNode* SysYParser::StmtContext::Semi() { + return getToken(SysYParser::Semi, 0); +} + +SysYParser::BlockContext* SysYParser::StmtContext::block() { + return getRuleContext(0); +} + +tree::TerminalNode* SysYParser::StmtContext::If() { + return getToken(SysYParser::If, 0); +} + +tree::TerminalNode* SysYParser::StmtContext::L_PAREN() { + return getToken(SysYParser::L_PAREN, 0); +} + +SysYParser::CondContext* SysYParser::StmtContext::cond() { + return getRuleContext(0); +} + +tree::TerminalNode* SysYParser::StmtContext::R_PAREN() { + return getToken(SysYParser::R_PAREN, 0); +} + +std::vector SysYParser::StmtContext::stmt() { + return getRuleContexts(); +} + +SysYParser::StmtContext* SysYParser::StmtContext::stmt(size_t i) { + return getRuleContext(i); +} + +tree::TerminalNode* SysYParser::StmtContext::Else() { + return getToken(SysYParser::Else, 0); +} + +tree::TerminalNode* SysYParser::StmtContext::While() { + return getToken(SysYParser::While, 0); +} + +tree::TerminalNode* SysYParser::StmtContext::Break() { + return getToken(SysYParser::Break, 0); +} + +tree::TerminalNode* SysYParser::StmtContext::Continue() { + return getToken(SysYParser::Continue, 0); +} + +tree::TerminalNode* SysYParser::StmtContext::Return() { + return getToken(SysYParser::Return, 0); +} + + +size_t SysYParser::StmtContext::getRuleIndex() const { + return SysYParser::RuleStmt; +} + + +std::any SysYParser::StmtContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitStmt(this); + else + return visitor->visitChildren(this); +} + +SysYParser::StmtContext* SysYParser::stmt() { + StmtContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 24, SysYParser::RuleStmt); + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + setState(197); + _errHandler->sync(this); + switch (getInterpreter()->adaptivePredict(_input, 17, _ctx)) { + case 1: { + enterOuterAlt(_localctx, 1); + setState(163); + lVal(); + setState(164); + match(SysYParser::Assign); + setState(165); + exp(); + setState(166); + match(SysYParser::Semi); + break; + } + + case 2: { + enterOuterAlt(_localctx, 2); + setState(169); + _errHandler->sync(this); + + _la = _input->LA(1); + if ((((_la & ~ 0x3fULL) == 0) && + ((1ULL << _la) & 120527656960) != 0)) { + setState(168); + exp(); + } + setState(171); + match(SysYParser::Semi); + break; + } + + case 3: { + enterOuterAlt(_localctx, 3); + setState(172); + block(); + break; + } + + case 4: { + enterOuterAlt(_localctx, 4); + setState(173); + match(SysYParser::If); + setState(174); + match(SysYParser::L_PAREN); + setState(175); + cond(); + setState(176); + match(SysYParser::R_PAREN); + setState(177); + stmt(); + setState(180); + _errHandler->sync(this); + + switch (getInterpreter()->adaptivePredict(_input, 15, _ctx)) { + case 1: { + setState(178); + match(SysYParser::Else); + setState(179); + stmt(); + break; + } + + default: + break; + } + break; + } + + case 5: { + enterOuterAlt(_localctx, 5); + setState(182); + match(SysYParser::While); + setState(183); + match(SysYParser::L_PAREN); + setState(184); + cond(); + setState(185); + match(SysYParser::R_PAREN); + setState(186); + stmt(); + break; + } + + case 6: { + enterOuterAlt(_localctx, 6); + setState(188); + match(SysYParser::Break); + setState(189); + match(SysYParser::Semi); + break; + } + + case 7: { + enterOuterAlt(_localctx, 7); + setState(190); + match(SysYParser::Continue); + setState(191); + match(SysYParser::Semi); + break; + } + + case 8: { + enterOuterAlt(_localctx, 8); + setState(192); + match(SysYParser::Return); + setState(194); + _errHandler->sync(this); + + _la = _input->LA(1); + if ((((_la & ~ 0x3fULL) == 0) && + ((1ULL << _la) & 120527656960) != 0)) { + setState(193); + exp(); + } + setState(196); + match(SysYParser::Semi); + break; + } + + default: + break; + } + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- CondContext ------------------------------------------------------------------ + +SysYParser::CondContext::CondContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +SysYParser::LOrExpContext* SysYParser::CondContext::lOrExp() { + return getRuleContext(0); +} + + +size_t SysYParser::CondContext::getRuleIndex() const { + return SysYParser::RuleCond; +} + + +std::any SysYParser::CondContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitCond(this); + else + return visitor->visitChildren(this); +} + +SysYParser::CondContext* SysYParser::cond() { + CondContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 26, SysYParser::RuleCond); + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + enterOuterAlt(_localctx, 1); + setState(199); + lOrExp(0); + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- LValContext ------------------------------------------------------------------ + +SysYParser::LValContext::LValContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +tree::TerminalNode* SysYParser::LValContext::Ident() { + return getToken(SysYParser::Ident, 0); +} + +std::vector SysYParser::LValContext::L_BRACKET() { + return getTokens(SysYParser::L_BRACKET); +} + +tree::TerminalNode* SysYParser::LValContext::L_BRACKET(size_t i) { + return getToken(SysYParser::L_BRACKET, i); +} + +std::vector SysYParser::LValContext::exp() { + return getRuleContexts(); +} + +SysYParser::ExpContext* SysYParser::LValContext::exp(size_t i) { + return getRuleContext(i); +} + +std::vector SysYParser::LValContext::R_BRACKET() { + return getTokens(SysYParser::R_BRACKET); +} + +tree::TerminalNode* SysYParser::LValContext::R_BRACKET(size_t i) { + return getToken(SysYParser::R_BRACKET, i); +} + + +size_t SysYParser::LValContext::getRuleIndex() const { + return SysYParser::RuleLVal; +} + + +std::any SysYParser::LValContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitLVal(this); + else + return visitor->visitChildren(this); +} + +SysYParser::LValContext* SysYParser::lVal() { + LValContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 28, SysYParser::RuleLVal); + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + size_t alt; + enterOuterAlt(_localctx, 1); + setState(201); + match(SysYParser::Ident); + setState(208); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 18, _ctx); + while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) { + if (alt == 1) { + setState(202); + match(SysYParser::L_BRACKET); + setState(203); + exp(); + setState(204); + match(SysYParser::R_BRACKET); + } + setState(210); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 18, _ctx); + } + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- PrimaryExpContext ------------------------------------------------------------------ + +SysYParser::PrimaryExpContext::PrimaryExpContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +tree::TerminalNode* SysYParser::PrimaryExpContext::L_PAREN() { + return getToken(SysYParser::L_PAREN, 0); +} + +SysYParser::ExpContext* SysYParser::PrimaryExpContext::exp() { + return getRuleContext(0); +} + +tree::TerminalNode* SysYParser::PrimaryExpContext::R_PAREN() { + return getToken(SysYParser::R_PAREN, 0); +} + +SysYParser::LValContext* SysYParser::PrimaryExpContext::lVal() { + return getRuleContext(0); +} + +SysYParser::NumberContext* SysYParser::PrimaryExpContext::number() { + return getRuleContext(0); +} + + +size_t SysYParser::PrimaryExpContext::getRuleIndex() const { + return SysYParser::RulePrimaryExp; +} + + +std::any SysYParser::PrimaryExpContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitPrimaryExp(this); + else + return visitor->visitChildren(this); +} + +SysYParser::PrimaryExpContext* SysYParser::primaryExp() { + PrimaryExpContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 30, SysYParser::RulePrimaryExp); + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + setState(217); + _errHandler->sync(this); + switch (_input->LA(1)) { + case SysYParser::L_PAREN: { + enterOuterAlt(_localctx, 1); + setState(211); + match(SysYParser::L_PAREN); + setState(212); + exp(); + setState(213); + match(SysYParser::R_PAREN); + break; + } + + case SysYParser::Ident: { + enterOuterAlt(_localctx, 2); + setState(215); + lVal(); + break; + } + + case SysYParser::IntConst: + case SysYParser::FloatConst: { + enterOuterAlt(_localctx, 3); + setState(216); + number(); + break; + } + + default: + throw NoViableAltException(this); + } + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- NumberContext ------------------------------------------------------------------ + +SysYParser::NumberContext::NumberContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +tree::TerminalNode* SysYParser::NumberContext::IntConst() { + return getToken(SysYParser::IntConst, 0); +} + +tree::TerminalNode* SysYParser::NumberContext::FloatConst() { + return getToken(SysYParser::FloatConst, 0); +} + + +size_t SysYParser::NumberContext::getRuleIndex() const { + return SysYParser::RuleNumber; +} + + +std::any SysYParser::NumberContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitNumber(this); + else + return visitor->visitChildren(this); +} + +SysYParser::NumberContext* SysYParser::number() { + NumberContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 32, SysYParser::RuleNumber); + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + enterOuterAlt(_localctx, 1); + setState(219); + _la = _input->LA(1); + if (!(_la == SysYParser::IntConst + + || _la == SysYParser::FloatConst)) { + _errHandler->recoverInline(this); + } + else { + _errHandler->reportMatch(this); + consume(); + } + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- UnaryExpContext ------------------------------------------------------------------ + +SysYParser::UnaryExpContext::UnaryExpContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +SysYParser::PrimaryExpContext* SysYParser::UnaryExpContext::primaryExp() { + return getRuleContext(0); +} + +tree::TerminalNode* SysYParser::UnaryExpContext::Ident() { + return getToken(SysYParser::Ident, 0); +} + +tree::TerminalNode* SysYParser::UnaryExpContext::L_PAREN() { + return getToken(SysYParser::L_PAREN, 0); +} + +tree::TerminalNode* SysYParser::UnaryExpContext::R_PAREN() { + return getToken(SysYParser::R_PAREN, 0); +} + +SysYParser::FuncRParamsContext* SysYParser::UnaryExpContext::funcRParams() { + return getRuleContext(0); +} + +SysYParser::UnaryOpContext* SysYParser::UnaryExpContext::unaryOp() { + return getRuleContext(0); +} + +SysYParser::UnaryExpContext* SysYParser::UnaryExpContext::unaryExp() { + return getRuleContext(0); +} + + +size_t SysYParser::UnaryExpContext::getRuleIndex() const { + return SysYParser::RuleUnaryExp; +} + + +std::any SysYParser::UnaryExpContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitUnaryExp(this); + else + return visitor->visitChildren(this); +} + +SysYParser::UnaryExpContext* SysYParser::unaryExp() { + UnaryExpContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 34, SysYParser::RuleUnaryExp); + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + setState(231); + _errHandler->sync(this); + switch (getInterpreter()->adaptivePredict(_input, 21, _ctx)) { + case 1: { + enterOuterAlt(_localctx, 1); + setState(221); + primaryExp(); + break; + } + + case 2: { + enterOuterAlt(_localctx, 2); + setState(222); + match(SysYParser::Ident); + setState(223); + match(SysYParser::L_PAREN); + setState(225); + _errHandler->sync(this); + + _la = _input->LA(1); + if ((((_la & ~ 0x3fULL) == 0) && + ((1ULL << _la) & 120527656960) != 0)) { + setState(224); + funcRParams(); + } + setState(227); + match(SysYParser::R_PAREN); + break; + } + + case 3: { + enterOuterAlt(_localctx, 3); + setState(228); + unaryOp(); + setState(229); + unaryExp(); + break; + } + + default: + break; + } + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- UnaryOpContext ------------------------------------------------------------------ + +SysYParser::UnaryOpContext::UnaryOpContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +tree::TerminalNode* SysYParser::UnaryOpContext::AddOp() { + return getToken(SysYParser::AddOp, 0); +} + +tree::TerminalNode* SysYParser::UnaryOpContext::SubOp() { + return getToken(SysYParser::SubOp, 0); +} + +tree::TerminalNode* SysYParser::UnaryOpContext::NotOp() { + return getToken(SysYParser::NotOp, 0); +} + + +size_t SysYParser::UnaryOpContext::getRuleIndex() const { + return SysYParser::RuleUnaryOp; +} + + +std::any SysYParser::UnaryOpContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitUnaryOp(this); + else + return visitor->visitChildren(this); +} + +SysYParser::UnaryOpContext* SysYParser::unaryOp() { + UnaryOpContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 36, SysYParser::RuleUnaryOp); + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + enterOuterAlt(_localctx, 1); + setState(233); + _la = _input->LA(1); + if (!((((_la & ~ 0x3fULL) == 0) && + ((1ULL << _la) & 137216) != 0))) { + _errHandler->recoverInline(this); + } + else { + _errHandler->reportMatch(this); + consume(); + } + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- FuncRParamsContext ------------------------------------------------------------------ + +SysYParser::FuncRParamsContext::FuncRParamsContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +std::vector SysYParser::FuncRParamsContext::exp() { + return getRuleContexts(); +} + +SysYParser::ExpContext* SysYParser::FuncRParamsContext::exp(size_t i) { + return getRuleContext(i); +} + +std::vector SysYParser::FuncRParamsContext::Comma() { + return getTokens(SysYParser::Comma); +} + +tree::TerminalNode* SysYParser::FuncRParamsContext::Comma(size_t i) { + return getToken(SysYParser::Comma, i); +} + + +size_t SysYParser::FuncRParamsContext::getRuleIndex() const { + return SysYParser::RuleFuncRParams; +} + + +std::any SysYParser::FuncRParamsContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitFuncRParams(this); + else + return visitor->visitChildren(this); +} + +SysYParser::FuncRParamsContext* SysYParser::funcRParams() { + FuncRParamsContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 38, SysYParser::RuleFuncRParams); + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + enterOuterAlt(_localctx, 1); + setState(235); + exp(); + setState(240); + _errHandler->sync(this); + _la = _input->LA(1); + while (_la == SysYParser::Comma) { + setState(236); + match(SysYParser::Comma); + setState(237); + exp(); + setState(242); + _errHandler->sync(this); + _la = _input->LA(1); + } + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- MulExpContext ------------------------------------------------------------------ + +SysYParser::MulExpContext::MulExpContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +SysYParser::UnaryExpContext* SysYParser::MulExpContext::unaryExp() { + return getRuleContext(0); +} + +SysYParser::MulExpContext* SysYParser::MulExpContext::mulExp() { + return getRuleContext(0); +} + +tree::TerminalNode* SysYParser::MulExpContext::MulOp() { + return getToken(SysYParser::MulOp, 0); +} + +tree::TerminalNode* SysYParser::MulExpContext::DivOp() { + return getToken(SysYParser::DivOp, 0); +} + +tree::TerminalNode* SysYParser::MulExpContext::ModOp() { + return getToken(SysYParser::ModOp, 0); +} + + +size_t SysYParser::MulExpContext::getRuleIndex() const { + return SysYParser::RuleMulExp; +} + + +std::any SysYParser::MulExpContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitMulExp(this); + else + return visitor->visitChildren(this); +} + + +SysYParser::MulExpContext* SysYParser::mulExp() { + return mulExp(0); +} + +SysYParser::MulExpContext* SysYParser::mulExp(int precedence) { + ParserRuleContext *parentContext = _ctx; + size_t parentState = getState(); + SysYParser::MulExpContext *_localctx = _tracker.createInstance(_ctx, parentState); + SysYParser::MulExpContext *previousContext = _localctx; + (void)previousContext; // Silence compiler, in case the context is not used by generated code. + size_t startState = 40; + enterRecursionRule(_localctx, 40, SysYParser::RuleMulExp, precedence); + + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + unrollRecursionContexts(parentContext); + }); + try { + size_t alt; + enterOuterAlt(_localctx, 1); + setState(244); + unaryExp(); + _ctx->stop = _input->LT(-1); + setState(251); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 23, _ctx); + while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) { + if (alt == 1) { + if (!_parseListeners.empty()) + triggerExitRuleEvent(); + previousContext = _localctx; + _localctx = _tracker.createInstance(parentContext, parentState); + pushNewRecursionContext(_localctx, startState, RuleMulExp); + setState(246); + + if (!(precpred(_ctx, 1))) throw FailedPredicateException(this, "precpred(_ctx, 1)"); + setState(247); + _la = _input->LA(1); + if (!((((_la & ~ 0x3fULL) == 0) && + ((1ULL << _la) & 114688) != 0))) { + _errHandler->recoverInline(this); + } + else { + _errHandler->reportMatch(this); + consume(); + } + setState(248); + unaryExp(); + } + setState(253); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 23, _ctx); + } + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + return _localctx; +} + +//----------------- AddExpContext ------------------------------------------------------------------ + +SysYParser::AddExpContext::AddExpContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +SysYParser::MulExpContext* SysYParser::AddExpContext::mulExp() { + return getRuleContext(0); +} + +SysYParser::AddExpContext* SysYParser::AddExpContext::addExp() { + return getRuleContext(0); +} + +tree::TerminalNode* SysYParser::AddExpContext::AddOp() { + return getToken(SysYParser::AddOp, 0); +} + +tree::TerminalNode* SysYParser::AddExpContext::SubOp() { + return getToken(SysYParser::SubOp, 0); +} + + +size_t SysYParser::AddExpContext::getRuleIndex() const { + return SysYParser::RuleAddExp; +} + + +std::any SysYParser::AddExpContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitAddExp(this); + else + return visitor->visitChildren(this); +} + + +SysYParser::AddExpContext* SysYParser::addExp() { + return addExp(0); +} + +SysYParser::AddExpContext* SysYParser::addExp(int precedence) { + ParserRuleContext *parentContext = _ctx; + size_t parentState = getState(); + SysYParser::AddExpContext *_localctx = _tracker.createInstance(_ctx, parentState); + SysYParser::AddExpContext *previousContext = _localctx; + (void)previousContext; // Silence compiler, in case the context is not used by generated code. + size_t startState = 42; + enterRecursionRule(_localctx, 42, SysYParser::RuleAddExp, precedence); + + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + unrollRecursionContexts(parentContext); + }); + try { + size_t alt; + enterOuterAlt(_localctx, 1); + setState(255); + mulExp(0); + _ctx->stop = _input->LT(-1); + setState(262); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 24, _ctx); + while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) { + if (alt == 1) { + if (!_parseListeners.empty()) + triggerExitRuleEvent(); + previousContext = _localctx; + _localctx = _tracker.createInstance(parentContext, parentState); + pushNewRecursionContext(_localctx, startState, RuleAddExp); + setState(257); + + if (!(precpred(_ctx, 1))) throw FailedPredicateException(this, "precpred(_ctx, 1)"); + setState(258); + _la = _input->LA(1); + if (!(_la == SysYParser::AddOp + + || _la == SysYParser::SubOp)) { + _errHandler->recoverInline(this); + } + else { + _errHandler->reportMatch(this); + consume(); + } + setState(259); + mulExp(0); + } + setState(264); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 24, _ctx); + } + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + return _localctx; +} + +//----------------- RelExpContext ------------------------------------------------------------------ + +SysYParser::RelExpContext::RelExpContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +SysYParser::AddExpContext* SysYParser::RelExpContext::addExp() { + return getRuleContext(0); +} + +SysYParser::RelExpContext* SysYParser::RelExpContext::relExp() { + return getRuleContext(0); +} + +tree::TerminalNode* SysYParser::RelExpContext::LtOp() { + return getToken(SysYParser::LtOp, 0); +} + +tree::TerminalNode* SysYParser::RelExpContext::GtOp() { + return getToken(SysYParser::GtOp, 0); +} + +tree::TerminalNode* SysYParser::RelExpContext::LeOp() { + return getToken(SysYParser::LeOp, 0); +} + +tree::TerminalNode* SysYParser::RelExpContext::GeOp() { + return getToken(SysYParser::GeOp, 0); +} + + +size_t SysYParser::RelExpContext::getRuleIndex() const { + return SysYParser::RuleRelExp; +} + + +std::any SysYParser::RelExpContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitRelExp(this); + else + return visitor->visitChildren(this); +} + + +SysYParser::RelExpContext* SysYParser::relExp() { + return relExp(0); +} + +SysYParser::RelExpContext* SysYParser::relExp(int precedence) { + ParserRuleContext *parentContext = _ctx; + size_t parentState = getState(); + SysYParser::RelExpContext *_localctx = _tracker.createInstance(_ctx, parentState); + SysYParser::RelExpContext *previousContext = _localctx; + (void)previousContext; // Silence compiler, in case the context is not used by generated code. + size_t startState = 44; + enterRecursionRule(_localctx, 44, SysYParser::RuleRelExp, precedence); + + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + unrollRecursionContexts(parentContext); + }); + try { + size_t alt; + enterOuterAlt(_localctx, 1); + setState(266); + addExp(0); + _ctx->stop = _input->LT(-1); + setState(273); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 25, _ctx); + while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) { + if (alt == 1) { + if (!_parseListeners.empty()) + triggerExitRuleEvent(); + previousContext = _localctx; + _localctx = _tracker.createInstance(parentContext, parentState); + pushNewRecursionContext(_localctx, startState, RuleRelExp); + setState(268); + + if (!(precpred(_ctx, 1))) throw FailedPredicateException(this, "precpred(_ctx, 1)"); + setState(269); + _la = _input->LA(1); + if (!((((_la & ~ 0x3fULL) == 0) && + ((1ULL << _la) & 62914560) != 0))) { + _errHandler->recoverInline(this); + } + else { + _errHandler->reportMatch(this); + consume(); + } + setState(270); + addExp(0); + } + setState(275); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 25, _ctx); + } + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + return _localctx; +} + +//----------------- EqExpContext ------------------------------------------------------------------ + +SysYParser::EqExpContext::EqExpContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +SysYParser::RelExpContext* SysYParser::EqExpContext::relExp() { + return getRuleContext(0); +} + +SysYParser::EqExpContext* SysYParser::EqExpContext::eqExp() { + return getRuleContext(0); +} + +tree::TerminalNode* SysYParser::EqExpContext::EqOp() { + return getToken(SysYParser::EqOp, 0); +} + +tree::TerminalNode* SysYParser::EqExpContext::NeOp() { + return getToken(SysYParser::NeOp, 0); +} + + +size_t SysYParser::EqExpContext::getRuleIndex() const { + return SysYParser::RuleEqExp; +} + + +std::any SysYParser::EqExpContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitEqExp(this); + else + return visitor->visitChildren(this); +} + + +SysYParser::EqExpContext* SysYParser::eqExp() { + return eqExp(0); +} + +SysYParser::EqExpContext* SysYParser::eqExp(int precedence) { + ParserRuleContext *parentContext = _ctx; + size_t parentState = getState(); + SysYParser::EqExpContext *_localctx = _tracker.createInstance(_ctx, parentState); + SysYParser::EqExpContext *previousContext = _localctx; + (void)previousContext; // Silence compiler, in case the context is not used by generated code. + size_t startState = 46; + enterRecursionRule(_localctx, 46, SysYParser::RuleEqExp, precedence); + + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + unrollRecursionContexts(parentContext); + }); + try { + size_t alt; + enterOuterAlt(_localctx, 1); + setState(277); + relExp(0); + _ctx->stop = _input->LT(-1); + setState(284); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 26, _ctx); + while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) { + if (alt == 1) { + if (!_parseListeners.empty()) + triggerExitRuleEvent(); + previousContext = _localctx; + _localctx = _tracker.createInstance(parentContext, parentState); + pushNewRecursionContext(_localctx, startState, RuleEqExp); + setState(279); + + if (!(precpred(_ctx, 1))) throw FailedPredicateException(this, "precpred(_ctx, 1)"); + setState(280); + _la = _input->LA(1); + if (!(_la == SysYParser::EqOp + + || _la == SysYParser::NeOp)) { + _errHandler->recoverInline(this); + } + else { + _errHandler->reportMatch(this); + consume(); + } + setState(281); + relExp(0); + } + setState(286); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 26, _ctx); + } + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + return _localctx; +} + +//----------------- LAndExpContext ------------------------------------------------------------------ + +SysYParser::LAndExpContext::LAndExpContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +SysYParser::EqExpContext* SysYParser::LAndExpContext::eqExp() { + return getRuleContext(0); +} + +SysYParser::LAndExpContext* SysYParser::LAndExpContext::lAndExp() { + return getRuleContext(0); +} + +tree::TerminalNode* SysYParser::LAndExpContext::AndOp() { + return getToken(SysYParser::AndOp, 0); +} + + +size_t SysYParser::LAndExpContext::getRuleIndex() const { + return SysYParser::RuleLAndExp; +} + + +std::any SysYParser::LAndExpContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitLAndExp(this); + else + return visitor->visitChildren(this); +} + + +SysYParser::LAndExpContext* SysYParser::lAndExp() { + return lAndExp(0); +} + +SysYParser::LAndExpContext* SysYParser::lAndExp(int precedence) { + ParserRuleContext *parentContext = _ctx; + size_t parentState = getState(); + SysYParser::LAndExpContext *_localctx = _tracker.createInstance(_ctx, parentState); + SysYParser::LAndExpContext *previousContext = _localctx; + (void)previousContext; // Silence compiler, in case the context is not used by generated code. + size_t startState = 48; + enterRecursionRule(_localctx, 48, SysYParser::RuleLAndExp, precedence); + + + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + unrollRecursionContexts(parentContext); + }); + try { + size_t alt; + enterOuterAlt(_localctx, 1); + setState(288); + eqExp(0); + _ctx->stop = _input->LT(-1); + setState(295); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 27, _ctx); + while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) { + if (alt == 1) { + if (!_parseListeners.empty()) + triggerExitRuleEvent(); + previousContext = _localctx; + _localctx = _tracker.createInstance(parentContext, parentState); + pushNewRecursionContext(_localctx, startState, RuleLAndExp); + setState(290); + + if (!(precpred(_ctx, 1))) throw FailedPredicateException(this, "precpred(_ctx, 1)"); + setState(291); + match(SysYParser::AndOp); + setState(292); + eqExp(0); + } + setState(297); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 27, _ctx); + } + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + return _localctx; +} + +//----------------- LOrExpContext ------------------------------------------------------------------ + +SysYParser::LOrExpContext::LOrExpContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +SysYParser::LAndExpContext* SysYParser::LOrExpContext::lAndExp() { + return getRuleContext(0); +} + +SysYParser::LOrExpContext* SysYParser::LOrExpContext::lOrExp() { + return getRuleContext(0); +} + +tree::TerminalNode* SysYParser::LOrExpContext::OrOp() { + return getToken(SysYParser::OrOp, 0); +} + + +size_t SysYParser::LOrExpContext::getRuleIndex() const { + return SysYParser::RuleLOrExp; +} + + +std::any SysYParser::LOrExpContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitLOrExp(this); + else + return visitor->visitChildren(this); +} + + +SysYParser::LOrExpContext* SysYParser::lOrExp() { + return lOrExp(0); +} + +SysYParser::LOrExpContext* SysYParser::lOrExp(int precedence) { + ParserRuleContext *parentContext = _ctx; + size_t parentState = getState(); + SysYParser::LOrExpContext *_localctx = _tracker.createInstance(_ctx, parentState); + SysYParser::LOrExpContext *previousContext = _localctx; + (void)previousContext; // Silence compiler, in case the context is not used by generated code. + size_t startState = 50; + enterRecursionRule(_localctx, 50, SysYParser::RuleLOrExp, precedence); + + + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + unrollRecursionContexts(parentContext); + }); + try { + size_t alt; + enterOuterAlt(_localctx, 1); + setState(299); + lAndExp(0); + _ctx->stop = _input->LT(-1); + setState(306); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 28, _ctx); + while (alt != 2 && alt != atn::ATN::INVALID_ALT_NUMBER) { + if (alt == 1) { + if (!_parseListeners.empty()) + triggerExitRuleEvent(); + previousContext = _localctx; + _localctx = _tracker.createInstance(parentContext, parentState); + pushNewRecursionContext(_localctx, startState, RuleLOrExp); + setState(301); + + if (!(precpred(_ctx, 1))) throw FailedPredicateException(this, "precpred(_ctx, 1)"); + setState(302); + match(SysYParser::OrOp); + setState(303); + lAndExp(0); + } + setState(308); + _errHandler->sync(this); + alt = getInterpreter()->adaptivePredict(_input, 28, _ctx); + } + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + return _localctx; +} + +//----------------- ConstExpContext ------------------------------------------------------------------ + +SysYParser::ConstExpContext::ConstExpContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +SysYParser::AddExpContext* SysYParser::ConstExpContext::addExp() { + return getRuleContext(0); +} + + +size_t SysYParser::ConstExpContext::getRuleIndex() const { + return SysYParser::RuleConstExp; +} + + +std::any SysYParser::ConstExpContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitConstExp(this); + else + return visitor->visitChildren(this); +} + +SysYParser::ConstExpContext* SysYParser::constExp() { + ConstExpContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 52, SysYParser::RuleConstExp); + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + enterOuterAlt(_localctx, 1); + setState(309); + addExp(0); + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- VarDeclContext ------------------------------------------------------------------ + +SysYParser::VarDeclContext::VarDeclContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +SysYParser::BTypeContext* SysYParser::VarDeclContext::bType() { + return getRuleContext(0); +} + +std::vector SysYParser::VarDeclContext::varDef() { + return getRuleContexts(); +} + +SysYParser::VarDefContext* SysYParser::VarDeclContext::varDef(size_t i) { + return getRuleContext(i); +} + +tree::TerminalNode* SysYParser::VarDeclContext::Semi() { + return getToken(SysYParser::Semi, 0); +} + +std::vector SysYParser::VarDeclContext::Comma() { + return getTokens(SysYParser::Comma); +} + +tree::TerminalNode* SysYParser::VarDeclContext::Comma(size_t i) { + return getToken(SysYParser::Comma, i); +} + + +size_t SysYParser::VarDeclContext::getRuleIndex() const { + return SysYParser::RuleVarDecl; +} + + +std::any SysYParser::VarDeclContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitVarDecl(this); + else + return visitor->visitChildren(this); +} + +SysYParser::VarDeclContext* SysYParser::varDecl() { + VarDeclContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 54, SysYParser::RuleVarDecl); + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + enterOuterAlt(_localctx, 1); + setState(311); + bType(); + setState(312); + varDef(); + setState(317); + _errHandler->sync(this); + _la = _input->LA(1); + while (_la == SysYParser::Comma) { + setState(313); + match(SysYParser::Comma); + setState(314); + varDef(); + setState(319); + _errHandler->sync(this); + _la = _input->LA(1); + } + setState(320); + match(SysYParser::Semi); + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- VarDefContext ------------------------------------------------------------------ + +SysYParser::VarDefContext::VarDefContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +tree::TerminalNode* SysYParser::VarDefContext::Ident() { + return getToken(SysYParser::Ident, 0); +} + +std::vector SysYParser::VarDefContext::L_BRACKET() { + return getTokens(SysYParser::L_BRACKET); +} + +tree::TerminalNode* SysYParser::VarDefContext::L_BRACKET(size_t i) { + return getToken(SysYParser::L_BRACKET, i); +} + +std::vector SysYParser::VarDefContext::constExp() { + return getRuleContexts(); +} + +SysYParser::ConstExpContext* SysYParser::VarDefContext::constExp(size_t i) { + return getRuleContext(i); +} + +std::vector SysYParser::VarDefContext::R_BRACKET() { + return getTokens(SysYParser::R_BRACKET); +} + +tree::TerminalNode* SysYParser::VarDefContext::R_BRACKET(size_t i) { + return getToken(SysYParser::R_BRACKET, i); +} + +tree::TerminalNode* SysYParser::VarDefContext::Assign() { + return getToken(SysYParser::Assign, 0); +} + +SysYParser::InitValContext* SysYParser::VarDefContext::initVal() { + return getRuleContext(0); +} + + +size_t SysYParser::VarDefContext::getRuleIndex() const { + return SysYParser::RuleVarDef; +} + + +std::any SysYParser::VarDefContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitVarDef(this); + else + return visitor->visitChildren(this); +} + +SysYParser::VarDefContext* SysYParser::varDef() { + VarDefContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 56, SysYParser::RuleVarDef); + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + setState(344); + _errHandler->sync(this); + switch (getInterpreter()->adaptivePredict(_input, 32, _ctx)) { + case 1: { + enterOuterAlt(_localctx, 1); + setState(322); + match(SysYParser::Ident); + setState(329); + _errHandler->sync(this); + _la = _input->LA(1); + while (_la == SysYParser::L_BRACKET) { + setState(323); + match(SysYParser::L_BRACKET); + setState(324); + constExp(); + setState(325); + match(SysYParser::R_BRACKET); + setState(331); + _errHandler->sync(this); + _la = _input->LA(1); + } + break; + } + + case 2: { + enterOuterAlt(_localctx, 2); + setState(332); + match(SysYParser::Ident); + setState(339); + _errHandler->sync(this); + _la = _input->LA(1); + while (_la == SysYParser::L_BRACKET) { + setState(333); + match(SysYParser::L_BRACKET); + setState(334); + constExp(); + setState(335); + match(SysYParser::R_BRACKET); + setState(341); + _errHandler->sync(this); + _la = _input->LA(1); + } + setState(342); + match(SysYParser::Assign); + setState(343); + initVal(); + break; + } + + default: + break; + } + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- InitValContext ------------------------------------------------------------------ + +SysYParser::InitValContext::InitValContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +SysYParser::ExpContext* SysYParser::InitValContext::exp() { + return getRuleContext(0); +} + +tree::TerminalNode* SysYParser::InitValContext::L_BRACE() { + return getToken(SysYParser::L_BRACE, 0); +} + +tree::TerminalNode* SysYParser::InitValContext::R_BRACE() { + return getToken(SysYParser::R_BRACE, 0); +} + +std::vector SysYParser::InitValContext::initVal() { + return getRuleContexts(); +} + +SysYParser::InitValContext* SysYParser::InitValContext::initVal(size_t i) { + return getRuleContext(i); +} + +std::vector SysYParser::InitValContext::Comma() { + return getTokens(SysYParser::Comma); +} + +tree::TerminalNode* SysYParser::InitValContext::Comma(size_t i) { + return getToken(SysYParser::Comma, i); +} + + +size_t SysYParser::InitValContext::getRuleIndex() const { + return SysYParser::RuleInitVal; +} + + +std::any SysYParser::InitValContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitInitVal(this); + else + return visitor->visitChildren(this); +} + +SysYParser::InitValContext* SysYParser::initVal() { + InitValContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 58, SysYParser::RuleInitVal); + size_t _la = 0; + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + setState(359); + _errHandler->sync(this); + switch (_input->LA(1)) { + case SysYParser::AddOp: + case SysYParser::SubOp: + case SysYParser::NotOp: + case SysYParser::L_PAREN: + case SysYParser::Ident: + case SysYParser::IntConst: + case SysYParser::FloatConst: { + enterOuterAlt(_localctx, 1); + setState(346); + exp(); + break; + } + + case SysYParser::L_BRACE: { + enterOuterAlt(_localctx, 2); + setState(347); + match(SysYParser::L_BRACE); + setState(356); + _errHandler->sync(this); + + _la = _input->LA(1); + if ((((_la & ~ 0x3fULL) == 0) && + ((1ULL << _la) & 121601398784) != 0)) { + setState(348); + initVal(); + setState(353); + _errHandler->sync(this); + _la = _input->LA(1); + while (_la == SysYParser::Comma) { + setState(349); + match(SysYParser::Comma); + setState(350); + initVal(); + setState(355); + _errHandler->sync(this); + _la = _input->LA(1); + } + } + setState(358); + match(SysYParser::R_BRACE); + break; + } + + default: + throw NoViableAltException(this); + } + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +//----------------- ExpContext ------------------------------------------------------------------ + +SysYParser::ExpContext::ExpContext(ParserRuleContext *parent, size_t invokingState) + : ParserRuleContext(parent, invokingState) { +} + +SysYParser::AddExpContext* SysYParser::ExpContext::addExp() { + return getRuleContext(0); +} + + +size_t SysYParser::ExpContext::getRuleIndex() const { + return SysYParser::RuleExp; +} + + +std::any SysYParser::ExpContext::accept(tree::ParseTreeVisitor *visitor) { + if (auto parserVisitor = dynamic_cast(visitor)) + return parserVisitor->visitExp(this); + else + return visitor->visitChildren(this); +} + +SysYParser::ExpContext* SysYParser::exp() { + ExpContext *_localctx = _tracker.createInstance(_ctx, getState()); + enterRule(_localctx, 60, SysYParser::RuleExp); + +#if __cplusplus > 201703L + auto onExit = finally([=, this] { +#else + auto onExit = finally([=] { +#endif + exitRule(); + }); + try { + enterOuterAlt(_localctx, 1); + setState(361); + addExp(0); + + } + catch (RecognitionException &e) { + _errHandler->reportError(this, e); + _localctx->exception = std::current_exception(); + _errHandler->recover(this, _localctx->exception); + } + + return _localctx; +} + +bool SysYParser::sempred(RuleContext *context, size_t ruleIndex, size_t predicateIndex) { + switch (ruleIndex) { + case 20: return mulExpSempred(antlrcpp::downCast(context), predicateIndex); + case 21: return addExpSempred(antlrcpp::downCast(context), predicateIndex); + case 22: return relExpSempred(antlrcpp::downCast(context), predicateIndex); + case 23: return eqExpSempred(antlrcpp::downCast(context), predicateIndex); + case 24: return lAndExpSempred(antlrcpp::downCast(context), predicateIndex); + case 25: return lOrExpSempred(antlrcpp::downCast(context), predicateIndex); + + default: + break; + } + return true; +} + +bool SysYParser::mulExpSempred(MulExpContext *_localctx, size_t predicateIndex) { + switch (predicateIndex) { + case 0: return precpred(_ctx, 1); + + default: + break; + } + return true; +} + +bool SysYParser::addExpSempred(AddExpContext *_localctx, size_t predicateIndex) { + switch (predicateIndex) { + case 1: return precpred(_ctx, 1); + + default: + break; + } + return true; +} + +bool SysYParser::relExpSempred(RelExpContext *_localctx, size_t predicateIndex) { + switch (predicateIndex) { + case 2: return precpred(_ctx, 1); + + default: + break; + } + return true; +} + +bool SysYParser::eqExpSempred(EqExpContext *_localctx, size_t predicateIndex) { + switch (predicateIndex) { + case 3: return precpred(_ctx, 1); + + default: + break; + } + return true; +} + +bool SysYParser::lAndExpSempred(LAndExpContext *_localctx, size_t predicateIndex) { + switch (predicateIndex) { + case 4: return precpred(_ctx, 1); + + default: + break; + } + return true; +} + +bool SysYParser::lOrExpSempred(LOrExpContext *_localctx, size_t predicateIndex) { + switch (predicateIndex) { + case 5: return precpred(_ctx, 1); + + default: + break; + } + return true; +} + +void SysYParser::initialize() { +#if ANTLR4_USE_THREAD_LOCAL_CACHE + sysyParserInitialize(); +#else + ::antlr4::internal::call_once(sysyParserOnceFlag, sysyParserInitialize); +#endif +} diff --git a/src/frontend/SysYVisitor.cpp b/src/frontend/SysYVisitor.cpp new file mode 100644 index 00000000..b91ddfed --- /dev/null +++ b/src/frontend/SysYVisitor.cpp @@ -0,0 +1,7 @@ + +// Generated from src/antlr4/SysY.g4 by ANTLR 4.13.2 + + +#include "SysYVisitor.h" + + diff --git a/src/include/SysYBaseVisitor.h b/src/include/SysYBaseVisitor.h new file mode 100644 index 00000000..8aa51a71 --- /dev/null +++ b/src/include/SysYBaseVisitor.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); + } + + +}; + diff --git a/src/include/SysYLexer.h b/src/include/SysYLexer.h new file mode 100644 index 00000000..fc75625f --- /dev/null +++ b/src/include/SysYLexer.h @@ -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& getRuleNames() const override; + + const std::vector& getChannelNames() const override; + + const std::vector& 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. + +}; + diff --git a/src/include/SysYParser.h b/src/include/SysYParser.h new file mode 100644 index 00000000..8d8831b7 --- /dev/null +++ b/src/include/SysYParser.h @@ -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& 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 funcDef(); + FuncDefContext* funcDef(size_t i); + std::vector 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 funcFParam(); + FuncFParamContext* funcFParam(size_t i); + std::vector 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 L_BRACKET(); + antlr4::tree::TerminalNode* L_BRACKET(size_t i); + std::vector R_BRACKET(); + antlr4::tree::TerminalNode* R_BRACKET(size_t i); + std::vector 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 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 constDef(); + ConstDefContext* constDef(size_t i); + antlr4::tree::TerminalNode *Semi(); + std::vector 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 L_BRACKET(); + antlr4::tree::TerminalNode* L_BRACKET(size_t i); + std::vector constExp(); + ConstExpContext* constExp(size_t i); + std::vector 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 constInitVal(); + ConstInitValContext* constInitVal(size_t i); + std::vector 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 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 L_BRACKET(); + antlr4::tree::TerminalNode* L_BRACKET(size_t i); + std::vector exp(); + ExpContext* exp(size_t i); + std::vector 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 exp(); + ExpContext* exp(size_t i); + std::vector 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 varDef(); + VarDefContext* varDef(size_t i); + antlr4::tree::TerminalNode *Semi(); + std::vector 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 L_BRACKET(); + antlr4::tree::TerminalNode* L_BRACKET(size_t i); + std::vector constExp(); + ConstExpContext* constExp(size_t i); + std::vector 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 initVal(); + InitValContext* initVal(size_t i); + std::vector 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: +}; + diff --git a/src/include/SysYVisitor.h b/src/include/SysYVisitor.h new file mode 100644 index 00000000..8fb90dce --- /dev/null +++ b/src/include/SysYVisitor.h @@ -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; + + +}; + diff --git a/src/include/frontend/AntlrDriver.h b/src/include/frontend/AntlrDriver.h new file mode 100644 index 00000000..ee22da95 --- /dev/null +++ b/src/include/frontend/AntlrDriver.h @@ -0,0 +1,20 @@ +// 包装 ANTLR4,提供简易的解析入口。 +#pragma once + +#include +#include + +#include "SysYLexer.h" +#include "SysYParser.h" +#include "antlr4-runtime.h" + +struct AntlrResult { + std::unique_ptr input; + std::unique_ptr lexer; + std::unique_ptr tokens; + std::unique_ptr parser; + antlr4::tree::ParseTree* tree = nullptr; // owned by parser +}; + +// 解析指定文件,发生错误时抛出 std::runtime_error。 +AntlrResult ParseFileWithAntlr(const std::string& path); diff --git a/src/include/frontend/SyntaxTreePrinter.h b/src/include/frontend/SyntaxTreePrinter.h new file mode 100644 index 00000000..4633b5ec --- /dev/null +++ b/src/include/frontend/SyntaxTreePrinter.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +#include "antlr4-runtime.h" + +// 以树状缩进形式直接打印 ANTLR parse tree。 +void PrintSyntaxTree(antlr4::tree::ParseTree* tree, antlr4::Parser* parser, + std::ostream& os); diff --git a/src/include/ir/IR.h b/src/include/ir/IR.h new file mode 100644 index 00000000..87a35e0e --- /dev/null +++ b/src/include/ir/IR.h @@ -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 +#include +#include +#include +#include +#include +#include + +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> const_ints_; + std::unordered_map> const_floats_; + std::unordered_map> 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& GetVoidType(); + static const std::shared_ptr& GetInt1Type(); + static const std::shared_ptr& GetInt32Type(); + static const std::shared_ptr& GetFloat32Type(); + static const std::shared_ptr& GetPtrInt32Type(); + static const std::shared_ptr& 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 ty, std::string name); + virtual ~Value() = default; + const std::shared_ptr& 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& GetUses() const; + void ReplaceAllUsesWith(Value* new_value); + + protected: + std::shared_ptr type_; + std::string name_; + std::vector uses_; +}; + +// ConstantValue 是常量体系的基类。 +// 当前只实现了 ConstantInt,后续可继续扩展更多常量种类。 +class ConstantValue : public Value { + public: + ConstantValue(std::shared_ptr ty, std::string name = ""); +}; + +class ConstantInt : public ConstantValue { + public: + ConstantInt(std::shared_ptr ty, int v); + int GetValue() const { return value_; } + + private: + int value_{}; +}; + +class ConstantFloat : public ConstantValue { + public: + ConstantFloat(std::shared_ptr 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 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 operands_; +}; + +// GlobalValue 是全局值/全局变量体系的空壳占位类。 +// 当前只补齐类层次,具体初始化器、打印和链接语义后续再补。 +class GlobalValue : public User { + public: + GlobalValue(std::shared_ptr 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& init_values); + GlobalVariable(std::string name, size_t array_size, const std::vector& 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& GetInitValues() const; + const std::vector& 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 init_values_; + std::vector init_float_values_; +}; + +class Instruction : public User { + public: + Instruction(Opcode op, std::shared_ptr 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 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 ty, Value* operand, + std::string name); + Value* GetOperandValue() const; +}; + +class BranchInst : public Instruction { + public: + BranchInst(std::shared_ptr void_ty, BasicBlock* target); + BasicBlock* GetTarget() const; +}; + +class CondBranchInst : public Instruction { + public: + CondBranchInst(std::shared_ptr 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 ret_ty, Function* callee, + const std::vector& 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 void_ty, Value* val = nullptr); + Value* GetValue() const; + bool HasValue() const; +}; + +class AllocaInst : public Instruction { + public: + AllocaInst(std::shared_ptr elem_ty, std::string name, + Value* count = nullptr); + bool IsArrayAlloca() const; + Value* GetCount() const; + std::shared_ptr GetElementType() const; +}; + +class GetElementPtrInst : public Instruction { + public: + GetElementPtrInst(std::shared_ptr 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 val_ty, Value* ptr, std::string name); + Value* GetPtr() const; +}; + +class StoreInst : public Instruction { +public: + StoreInst(std::shared_ptr void_ty, Value* val, Value* ptr); + Value* GetValue() const; + Value* GetPtr() const; +}; + +class PhiInst : public Instruction { +public: + PhiInst(std::shared_ptr 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 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>& GetInstructions() const; + const std::vector& GetPredecessors() const; + const std::vector& GetSuccessors() const; + std::vector& GetMutablePredecessors() { + return predecessors_; + } + std::vector& GetMutableSuccessors() { + return successors_; + } + template + T* Append(Args&&... args) { + if (HasTerminator()) { + throw std::runtime_error("BasicBlock 已有 terminator,不能继续追加指令: " + + name_); + } + auto inst = std::make_unique(std::forward(args)...); + auto* ptr = inst.get(); + ptr->SetParent(this); + instructions_.push_back(std::move(inst)); + return ptr; + } + template + T* Prepend(Args&&... args) { + auto inst = std::make_unique(std::forward(args)...); + auto* ptr = inst.get(); + ptr->SetParent(this); + instructions_.insert(instructions_.begin(), std::move(inst)); + return ptr; + } + template + T* InsertAlloca(Args&&... args) { + auto inst = std::make_unique(std::forward(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 TakeInstruction(Instruction* inst); + void InsertInstructionBeforeTerminator(std::unique_ptr inst); + + private: + Function* parent_ = nullptr; + std::vector> instructions_; + std::vector predecessors_; + std::vector 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 ret_type, + bool is_external = false); + Argument* AddParam(const std::string& name, std::shared_ptr type); + const std::vector>& GetParams() const; + bool IsExternal() const; + BasicBlock* CreateBlock(const std::string& name); + BasicBlock* GetEntry(); + const BasicBlock* GetEntry() const; + const std::vector>& GetBlocks() const; + + private: + bool is_external_ = false; + BasicBlock* entry_ = nullptr; + std::vector> params_; + std::vector> blocks_; +}; + +class Module { + public: + Module() = default; + Context& GetContext(); + const Context& GetContext() const; + // 创建函数时当前只显式传入返回类型,尚未接入完整的 FunctionType。 + Function* CreateFunction(const std::string& name, + std::shared_ptr 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& init_values); + GlobalVariable* CreateGlobalArrayF32(const std::string& name, + size_t array_size, + const std::vector& init_values); + GlobalVariable* GetGlobal(const std::string& name) const; + const std::vector>& GetGlobals() const; + const std::vector>& GetFunctions() const; + + private: + Context context_; + std::vector> globals_; + std::vector> 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 target_ty, const std::string& name); + AllocaInst* CreateAlloca(std::shared_ptr 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& 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 ty, const std::string& name); + + private: + Context& ctx_; + BasicBlock* insert_block_; +}; + +class IRPrinter { + public: + void Print(const Module& module, std::ostream& os); +}; + +} // namespace ir diff --git a/src/include/ir/passes/PassManager.h b/src/include/ir/passes/PassManager.h new file mode 100644 index 00000000..286389e5 --- /dev/null +++ b/src/include/ir/passes/PassManager.h @@ -0,0 +1,83 @@ +#ifndef IR_PASSES_PASSMANAGER_H_ +#define IR_PASSES_PASSMANAGER_H_ + +#include "ir/IR.h" + +#include +#include + +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_ diff --git a/src/include/irgen/IRGen.h b/src/include/irgen/IRGen.h new file mode 100644 index 00000000..861f6fcb --- /dev/null +++ b/src/include/irgen/IRGen.h @@ -0,0 +1,122 @@ +// 将语法树翻译为 IR。 +// 实现拆分在 IRGenFunc/IRGenStmt/IRGenExp/IRGenDecl。 + +#pragma once + +#include +#include +#include +#include +#include + +#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 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 EvalArrayExtents( + const std::vector& dims); + std::vector GetArrayExtentsForDecl(SysYParser::VarDefContext* decl); + std::vector GetArrayExtentsForConstDecl( + SysYParser::ConstDefContext* decl); + std::vector GetArrayExtentsForLVal(SysYParser::LValContext& lval, + bool& is_array); + ir::Value* BuildLinearizedIndex( + const std::vector& indices, + const std::vector& extents_with_first_dim) ; + ir::Value* CastValueTo(ir::Value* value, + const std::shared_ptr& target_type); + ir::Value* GetLValAddress(SysYParser::LValContext& lval); + ir::AllocaInst* CreateEntryBlockAlloca(std::shared_ptr 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 function_map_; + std::unordered_map const_value_map_; + std::vector> local_const_stack_; + std::vector> const_value_history_; + std::unordered_map> + array_extents_map_; + std::unordered_map> + const_array_extents_map_; + std::unordered_map> param_array_extents_map_; + std::unordered_map param_storage_map_; + std::unordered_map param_pointer_map_; + std::unordered_map global_storage_map_; + std::unordered_map + const_global_storage_map_; + // 名称绑定由 Sema 负责;IRGen 只维护“声明 -> 存储槽位”的代码生成状态。 + std::unordered_map storage_map_; + std::unordered_map + const_storage_map_; + std::vector> loop_stack_; + int block_index_ = 0; +}; + +std::unique_ptr GenerateIR(SysYParser::CompUnitContext& tree, + const SemanticContext& sema); diff --git a/src/include/mir/MIR.h b/src/include/mir/MIR.h new file mode 100644 index 00000000..dabbd02c --- /dev/null +++ b/src/include/mir/MIR.h @@ -0,0 +1,414 @@ +#pragma once + +#include +#include +#include +#include +#include + +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 operands = {}); + + Opcode GetOpcode() const { return opcode_; } + const std::vector &GetOperands() const { return operands_; } + std::vector &GetOperands() { return operands_; } + + private: + Opcode opcode_; + std::vector 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 &GetInstructions() { return instructions_; } + const std::vector &GetInstructions() const { return instructions_; } + + MachineInstr &Append(Opcode opcode, + std::initializer_list operands = {}); + + private: + std::string name_; + int label_id_ = -1; + std::vector 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> &GetBlocks() + { + return blocks_; + } + const std::vector> &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 &GetFrameSlots() const { return frame_slots_; } + std::vector &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(vreg_classes_.size()); } + + void AddCalleeSavedReg(PhysReg reg); + const std::vector &GetCalleeSavedRegs() const { return callee_saved_regs_; } + + private: + std::string name_; + std::vector> blocks_; + MachineBasicBlock *entry_ = nullptr; + + std::vector frame_slots_; + int frame_size_ = 0; + int next_label_id_ = 0; + + std::vector vreg_classes_; + std::vector 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 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> &GetFunctions() + { + return functions_; + } + const std::vector> &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 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 &GetGlobals() { return globals_; } + const std::vector &GetGlobals() const { return globals_; } + + private: + std::vector> functions_; + std::vector globals_; + }; + + std::unique_ptr LowerModuleToMIR(const ir::Module &module); + std::unique_ptr 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 diff --git a/src/include/sem/Sema.h b/src/include/sem/Sema.h new file mode 100644 index 00000000..5a677fd0 --- /dev/null +++ b/src/include/sem/Sema.h @@ -0,0 +1,92 @@ +// 基于语法树的语义检查与名称绑定。 +#pragma once + +#include + +#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 + var_uses_; + std::unordered_map const_uses_; + std::unordered_map const_float_uses_; + std::unordered_map + const_array_uses_; + std::unordered_map + const_scalar_uses_; + std::unordered_map + call_uses_; +}; + +// 目前仅检查: +// - 变量先声明后使用 +// - 局部变量不允许重复定义 +SemanticContext RunSema(SysYParser::CompUnitContext& comp_unit); diff --git a/src/include/sem/SymbolTable.h b/src/include/sem/SymbolTable.h new file mode 100644 index 00000000..61275509 --- /dev/null +++ b/src/include/sem/SymbolTable.h @@ -0,0 +1,22 @@ +// 极简符号表:记录局部变量定义点。 +#pragma once + +#include +#include +#include + +#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> + scopes_; +}; diff --git a/src/include/utils/CLI.h b/src/include/utils/CLI.h new file mode 100644 index 00000000..a06106b6 --- /dev/null +++ b/src/include/utils/CLI.h @@ -0,0 +1,17 @@ +// 命令行解析:支持比赛要求的 -S -o -O1 格式 +#pragma once + +#include + +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); diff --git a/src/include/utils/Log.h b/src/include/utils/Log.h new file mode 100644 index 00000000..303f1a11 --- /dev/null +++ b/src/include/utils/Log.h @@ -0,0 +1,20 @@ +// 轻量日志接口。 +#pragma once + +#include +#include +#include +#include +#include + +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); diff --git a/src/ir/passes/ConstFold.cpp b/src/ir/passes/ConstFold.cpp index 23343d72..015a84fa 100644 --- a/src/ir/passes/ConstFold.cpp +++ b/src/ir/passes/ConstFold.cpp @@ -5,6 +5,7 @@ #include "ir/IR.h" #include +#include #include #include #include @@ -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(static_cast(lv) + static_cast(rv)); break; + case Opcode::Sub: result = static_cast(static_cast(lv) - static_cast(rv)); break; + case Opcode::Mul: result = static_cast(static_cast(lv) * static_cast(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(operand)) { - return ctx.GetConstInt(static_cast(cfloat->GetValue())); + double val = cfloat->GetValue(); + if (val < static_cast(INT_MIN) || val >= static_cast(INT_MAX) || std::isnan(val)) + return nullptr; + return ctx.GetConstInt(static_cast(val)); } } diff --git a/src/ir/passes/PassManager.cpp b/src/ir/passes/PassManager.cpp index 34ea284e..55db3cd1 100644 --- a/src/ir/passes/PassManager.cpp +++ b/src/ir/passes/PassManager.cpp @@ -1,65 +1 @@ -// IR Pass 管理骨架。 - -#include "ir/IR.h" - -#include -#include -#include -#include - -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" diff --git a/src/irgen/IRGenExp.cpp b/src/irgen/IRGenExp.cpp index 8c1c8043..2f94f941 100644 --- a/src/irgen/IRGenExp.cpp +++ b/src/irgen/IRGenExp.cpp @@ -1,5 +1,6 @@ #include "irgen/IRGen.h" +#include #include #include @@ -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(static_cast(lhs) + static_cast(rhs)); } if (expr.SubOp()) { - return lhs - rhs; + return static_cast(static_cast(lhs) - static_cast(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(static_cast(lhs) * static_cast(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(-static_cast(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(ParseFloatLiteral(expr.number()->FloatConst()->getText())); + double fval = ParseFloatLiteral(expr.number()->FloatConst()->getText()); + if (fval < static_cast(INT_MIN) || fval >= static_cast(INT_MAX)) + throw std::runtime_error(FormatError("irgen", "浮点常量转整数溢出")); + return static_cast(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(static_cast(stride) * static_cast(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(value)) { - return builder_.CreateConstInt(static_cast(cf->GetValue())); + double fval = cf->GetValue(); + if (fval < static_cast(INT_MIN) || fval >= static_cast(INT_MAX)) + return builder_.CreateFPToSI(value, module_.GetContext().NextTemp()); + return builder_.CreateConstInt(static_cast(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(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()); diff --git a/src/irgen/IRGenFunc.cpp b/src/irgen/IRGenFunc.cpp index 3401c50c..9c6c1342 100644 --- a/src/irgen/IRGenFunc.cpp +++ b/src/irgen/IRGenFunc.cpp @@ -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) { diff --git a/src/main.cpp b/src/main.cpp index a81497e2..643a987e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,12 +1,14 @@ #include +#include #include #include +#include #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(antlr.tree); - if (!comp_unit) - { - throw std::runtime_error(FormatError("main", "语法树根节点不是 compUnit")); + auto* comp_unit = + dynamic_cast(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; -} \ No newline at end of file +} diff --git a/src/mir/Lowering.cpp b/src/mir/Lowering.cpp index 7d9fc63e..cbbfaaf5 100644 --- a/src/mir/Lowering.cpp +++ b/src/mir/Lowering.cpp @@ -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(static_cast(idx_imm) * 4u); if (byte_offset == 0) { value_vregs[value] = base; diff --git a/src/mir/RegAlloc.cpp b/src/mir/RegAlloc.cpp index ba086fe1..5fc46ce9 100644 --- a/src/mir/RegAlloc.cpp +++ b/src/mir/RegAlloc.cpp @@ -399,7 +399,7 @@ namespace mir static long long MakeEdgeKey(int u, int v) { if (u > v) std::swap(u, v); - return (static_cast(u) << 32) | static_cast(v); + return (static_cast(static_cast(static_cast(u)) << 32)) | static_cast(v); } void AddNode(int v) { nodes.insert(v); } diff --git a/src/sem/Sema.cpp b/src/sem/Sema.cpp index 0c30422e..4f8c0bf2 100644 --- a/src/sem/Sema.cpp +++ b/src/sem/Sema.cpp @@ -1,6 +1,7 @@ #include "sem/Sema.h" #include +#include #include #include #include @@ -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(static_cast(lhs) + static_cast(rhs)); } if (ctx.SubOp()) { - return lhs - rhs; + return static_cast(static_cast(lhs) - static_cast(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(static_cast(lhs) * static_cast(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(-static_cast(operand)); } if (ctx.unaryOp()->NotOp()) { return operand == 0 ? 1 : 0; diff --git a/src/utils/CLI.cpp b/src/utils/CLI.cpp index 8fb107b3..16245faa 100644 --- a/src/utils/CLI.cpp +++ b/src/utils/CLI.cpp @@ -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] ")); + "用法: compiler [-S] [-o output.s] [-O|-O1|-O2|-O3] ")); } 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 : 指定输出文件 + 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", "缺少输入文件:请提供 (使用 --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; } diff --git a/third_party/antlr4-runtime-4.13.2.zip b/third_party/antlr4-runtime-4.13.2.zip new file mode 100644 index 00000000..9b2b3357 Binary files /dev/null and b/third_party/antlr4-runtime-4.13.2.zip differ