给 Remusys-IR 写个文本前端(〇)—— 序言
Remusys-IR 是我使用 Rust 编写的类 LLVM 中间代码组件。在 CSCC 竞赛期间, Remusys-IR 只有一个核心组件和少量优化器——这很合理,毕竟验证的事情可以交给 LLVM 来做,我没有解析文本输入的需求。但很快我发现 Remusys-IR 可以给我做毕设——我想搞一个 SSA IR 可视化的网页来弥补我前几年学 SSA 学歪了的遗憾,亲手编写的项目总比庞杂笨重还不太熟悉的 LLVM 合适。但这个时候要是还不支持 IR 文本输入的话, 那这个 IR 可视化到底要可视化些甚么就不得而知了。
所以我就得用 Rust 再给 Remusys-IR 写一套前端,就有了 Remusys-IR Parser 项目. 记这几篇文章主要防止以后我忘了代码是怎么写的,顺便还可以拿来当 Remusys-IR 的架构文档、使用说明之类的。
技术说明
Remusys-IR: 使用 Rust 编写的类 LLVM-IR 组件,采用 SSA-only 表示,控制流与数据流图分离。smol_str: rust-analyzer 团队开发的不可变字符串实现, 采用内联小字符串、隐式共享等技术省内存、省拷贝.logos: 词法分析器生成器, 可以通过派生宏的方式嵌入在项目代码中。
设计思路
虽然解析对象是 IR 文本格式, 但 remusys-ir-parser 仍然按照一般编程语言编译器的设计思路设计总体流程:做词法/语法分析、生成一棵额外设计的语法树,再在语法树上做语义分析和检查,检查完毕后生成中间代码和中间代码的文本映射。这么做是因为 remusys-ir 含有大量的后向引用甚至循环引用,在这种场景下 AST 树上访问的代码比语法制导翻译好写一些。
词法分析阶段将会使用 logos 词法分析器生成器编写 Token 类型并自动生成词法分析器。remusys-ir 中含有大量的上下文关键字、条件关键字,因此词法分析器只会做一部分词法分析的工作, 并把关键字识别等操作交给语法分析器完成。项目将会采用 AST 驱动语法分析的模型, 手写递归下降语法分析器, 这样就有足够的灵活性来处理词法分析器遗留下来的坑了。
构建好的语法树要做语义分析、有效性检查,理清后向引用、循环引用,找到一个可行的 IR 对象搭建顺序——这里涉及类型系统、CFG/DFG 相关的不变式了。接下来,从全局到局部解析符号、搭建 IR 骨架,然后填充 CFG 和 DFG 关系,一个 IR Module 就造好、能用了。
项目模块组织
1 | ├── Cargo.toml |
实现计划表
- 实现词法分析器
- 实现语法树、语法分析
- 解析类型别名图、找出类型创建顺序、翻译 IR 的类型图
- 解析全局符号并搭建 IR 全局框架
- 解析基本块符号并搭建每个函数的基本块框架
- 解析指令并搭建指令框架
- 解决操作数翻译问题
- IR 模块的最终检查