fix(frontend): 修复部分实现

This commit is contained in:
jing
2026-03-09 15:37:36 +08:00
parent 8aec500b5b
commit e01995a33d
21 changed files with 321 additions and 165 deletions

View File

@@ -40,11 +40,10 @@
| scope | 含义 |
|---|---|
| `frontend` | 前端(ANTLR 驱动、AST 构建入口等) |
| `ast` | AST 相关 |
| `frontend` | 前端(语法解析、语法树打印等) |
| `sema` | 语义分析(符号表、常量求值等) |
| `ir` | IR 核心结构 |
| `irgen` | AST → IR 生成 |
| `irgen` | 语法树 → IR 生成 |
| `mir` | Machine IR指令选择、寄存器分配、栈帧等 |
| `backend` | 后端目标相关(如需要可细化 `aarch64` |
| `antlr` | 语法文件/ANTLR 相关 |

View File

@@ -1,4 +1,4 @@
# Lab1语法树构建
# Lab1构建antlr规则生成语法树
## 1. 本实验定位
@@ -16,13 +16,10 @@ Lab1 聚焦前端第一步:词法/语法分析。
## 3. Lab1 需要补充的内容
1. 必须修改的文件
1. 需要修改的文件
- `src/antlr4/SysY.g4`:补全文法规则。
- `src/frontend/AstBuilder.cpp`同步扩展 parse tree 到 AST 的构建逻辑
- `src/ast/AstNodes.h``src/ast/AstNodes.cpp`:按新增语法补充或调整 AST 节点定义
2. 建议同步修改的文件
- `src/ast/AstPrinter.cpp`:为新增节点补充文本 AST 输出(`--ast-dot` 仅调试辅助,不是必做要求)。
- `src/frontend/AntlrDriver.cpp`解析入口与错误处理
- `src/frontend/SyntaxTreePrinter.cpp`:语法树打印逻辑(用于调试验证)
@@ -64,50 +61,11 @@ java -jar third_party/antlr-4.13.2-complete.jar \
按提供的测试输入回归验证:
1. 运行 `./build/bin/compiler <case.sy>` 检查解析是否成功。
2. 出现报错时优先回查 `SysY.g4` 与对应 AST 构建逻辑。
1. 运行 `./build/bin/compiler --emit-parse-tree <case.sy>` 检查解析是否成功。
2. 出现报错时优先回查 `SysY.g4` 逻辑。
可选输出控制命令:
```bash
# 仅输出 AST 文本
./build/bin/compiler --emit-ast test/test_case/simple_add.sy
# 仅输出 IR
./build/bin/compiler --emit-ir test/test_case/simple_add.sy
# 同时输出 AST 与 IR默认行为
./build/bin/compiler --emit-ast --emit-ir test/test_case/simple_add.sy
# 仅输出语法树
./build/bin/compiler --emit-parse-tree test/test_case/simple_add.sy
```
## 7. AST 输出相关说明(辅助)
AST 输出是调试手段,可以根据 AST 结果检查语法/词法实现逻辑问题。
**此功能完善与否不会影响整个流程的功能,可以选择性的实现**
当前仓库中的 AST 文本输出与 `AST -> dot` 导出仅覆盖“已实现的最小语法子集”,并非完整 SysY 通用版本。 后续每新增语法/节点类型时,需要在 `src/ast/AstPrinter.cpp` 中同步补充文本输出与 dot 导出逻辑。
1. 基础文本 AST 输出(默认)
```bash
./build/bin/compiler test/test_case/simple_add.sy
```
2. 图形化 AST 输出(可选)
依赖安装Ubuntu/WSL
```bash
sudo apt update
sudo apt install -y graphviz
```
生成 DOT 与 PNG
```bash
mkdir -p test/test_result/ast
./build/bin/compiler --emit-ast --ast-dot test/test_result/ast/simple_add.ast.dot test/test_case/simple_add.sy
dot -Tpng test/test_result/ast/simple_add.ast.dot -o test/test_result/ast/simple_add.ast.png
```
直接查看图片即可

View File

@@ -1,8 +1,7 @@
# Lab2从 ANTLR 解析结果生成中间表示IR
# Lab2生成中间表示IR
## 1. 本实验定位
本仓库当前提供了一个“最小可运行”的 ANTLR 解析结果 -> IR 示例链路。
Lab2 的目标是在该示例基础上扩展语义覆盖范围,逐步把更多 SysY 语法正确翻译为 IR。
## 2. Lab2 要求
@@ -10,11 +9,10 @@ Lab2 的目标是在该示例基础上扩展语义覆盖范围,逐步把更多
需要同学完成:
1. 熟悉 IR 相关数据结构与构建接口。
2. 理解当前 ANTLR 解析结果 -> IR 的最小实现流程。
2. 理解当前语法树 -> IR 的最小实现流程。
3. 在现有框架上扩展 IR 生成能力使其覆盖课程要求的Sysy语法。
## 3. 当前代码框架(与 Lab2 直接相关)
1. IR 定义与打印
@@ -22,7 +20,7 @@ Lab2 的目标是在该示例基础上扩展语义覆盖范围,逐步把更多
- `src/ir/IRBuilder.cpp`
- `src/ir/IRPrinter.cpp`
2. ParseTree -> IR 生成器
2. 语法树 -> IR 生成器
- `src/irgen/IRGen.h`
- `src/irgen/IRGenDriver.cpp`
- `src/irgen/IRGenFunc.cpp`
@@ -49,7 +47,7 @@ Lab2 的目标是在该示例基础上扩展语义覆盖范围,逐步把更多
## 5. 当前最小示例实现说明
当前 ParseTree -> IR 仅覆盖最小子集:
当前语法树 -> IR 仅覆盖最小子集:
1. 常量整数、变量引用、二元加法表达式。
2. 局部变量声明(当前采用 LLVM 前端常见的 `alloca/load/store` 内存模型)。
@@ -74,14 +72,14 @@ cmake --build build -j "$(nproc)"
./build/bin/compiler --emit-ir test/test_case/simple_add.sy
```
如需打印 ANTLR 语法树:
如需打印语法树:
```bash
./build/bin/compiler --emit-parse-tree test/test_case/simple_add.sy
```
推荐使用统一脚本验证 “IR -> LLVM 后端 -> 可执行程序” 整体链路,用于验证 IR 的正确性:
推荐使用统一脚本验证 “IR -> LLVM 后端 -> 可执行程序” 整体链路,用于验证 IR 的正确性:
```bash
./scripts/verify_ir_with_llvm.sh test/test_case/simple_add.sy out/ir --run

View File

@@ -8,12 +8,12 @@
Lexer / ParserANTLR
AST 构建 + 语义分析Sema
语法树构建 + 语义分析Sema
AST带类型 / 符号 / 常量
语法树(附加语义信息
[ 中端 Middle-end ]
AST
语法树
IR 构建(平台无关 IRLLVM 风格)
@@ -51,10 +51,7 @@
│ │ └── SysY.g4
│ ├── frontend/
│ │ ├── AntlrDriver.cpp
│ │ └── AstBuilder.cpp
│ ├── ast/
│ │ ├── AstNodes.cpp
│ │ └── AstPrinter.cpp
│ │ └── SyntaxTreePrinter.cpp
│ ├── sem/
│ │ ├── Sema.cpp
│ │ ├── SymbolTable.cpp
@@ -103,7 +100,6 @@
│ └── CLI.cpp
├── include/
│ ├── frontend/
│ ├── ast/
│ ├── sem/
│ ├── irgen/
│ ├── ir/
@@ -154,36 +150,28 @@
- `SysYBaseVisitor.cpp/.h``SysYVisitor.cpp/.h`
- `*.tokens``*.interp`
#### 3.2.3 `src/frontend/`ANTLR 调用与 AST 构建
#### 3.2.3 `src/frontend/`语法解析与语法树输出
- `src/frontend/AntlrDriver.cpp`
- 读取源代码并调用 ANTLR 生成的 lexer/parser得到 parse tree
- 读取源代码并调用解析流程,得到语法树
- 由于语法正确性由测试保证,该模块只需提供“可用的解析入口”,不需要实现复杂的语法错误报告体系。
- `src/frontend/AstBuilder.cpp`
- 将 parse tree 转换为 AST`src/ast/*`),并在 AST 节点上保留必要的定位信息(可选,用于调试/日志)
- `src/frontend/SyntaxTreePrinter.cpp`
- 语法树调试打印:用于验证语法规则与前端解析行为是否符合预期
#### 3.2.4 `src/ast/`抽象语法树AST
- `src/ast/AstNodes.cpp`
- AST 节点定义与实现:表达式、语句、声明、函数、类型等。
- AST 节点应当能够承载后续阶段附加信息(类型、符号绑定、常量值等)。
- `src/ast/AstPrinter.cpp`
- AST 调试打印:用于验证 AST 构建是否符合预期,便于定位前端/语义阶段问题。
#### 3.2.5 `src/sem/`语义分析Sema
#### 3.2.4 `src/sem/`语义分析Sema
- `src/sem/Sema.cpp`
- 语义分析主流程:符号解析、类型检查、控制流规则检查、必要的隐式转换插入/记录等。
- 输出为“带类型 / 符号 / 常量信息”的 AST可通过在 AST 节点上附加属性实现)
- 在语法树基础上完成语义检查,并为后续 IR 生成提供约束
- `src/sem/SymbolTable.cpp`
- 符号表与作用域管理:支持嵌套作用域、变量/函数/参数/常量的注册与查找。
- `src/sem/ConstEval.cpp`
- 常量求值:用于数组维度、全局初始化、`const` 表达式等需要编译期计算的场景。
#### 3.2.6 `src/irgen/`AST → IR平台无关LLVM 风格)
#### 3.2.5 `src/irgen/`语法树 → IR平台无关LLVM 风格)
- `src/irgen/IRGenDriver.cpp`
- 驱动 Visitor 遍历 AST,调度各子模块完成翻译。
- 驱动语法树遍历,调度各子模块完成翻译。
- `src/irgen/IRGenFunc.cpp`
- 函数翻译:函数定义、参数列表与返回值翻译;创建对应 IR 函数对象。
- `src/irgen/IRGenStmt.cpp`
@@ -193,7 +181,7 @@
- `src/irgen/IRGenDecl.cpp`
- 声明翻译:处理全局变量、局部变量、数组初始化与空间分配等。
#### 3.2.7 `src/ir/`LLVM 风格 IR 核心
#### 3.2.6 `src/ir/`LLVM 风格 IR 核心
- `src/ir/Context.cpp`
- IR 上下文:管理类型/常量创建与复用、字符串/符号等公共资源。
@@ -228,7 +216,7 @@
- `src/ir/passes/CFGSimplify.cpp`
- CFG 简化:删除不可达块、合并空块、简化分支等。
#### 3.2.8 `src/mir/`Machine IR
#### 3.2.7 `src/mir/`Machine IR
- `src/mir/MIRContext.cpp`
- MIR 上下文:保存目标约束、指令集信息等。
@@ -254,7 +242,7 @@
- `src/mir/passes/Peephole.cpp`
- 窥孔优化:删除冗余 move、合并常见指令模式提升最终汇编质量。
#### 3.2.9 `src/utils/`:日志与命令行
#### 3.2.8 `src/utils/`:日志与命令行
- `src/utils/Log.cpp`
- 日志输出:统一调试信息、阶段信息与错误信息输出。