首先感谢 Eve 大手子绘制的封面~
阅读之前, 读者应该拥有以下基础
- 阅读代码的能力
- 阅读 Rust 代码的能力
本文目的
- 避开生涩枯燥的理论, 尽量用大白话简单分享编译相关知识
- 太久没写博客了, 写个专栏玩玩
引言
笔者的毕设做了一个代码格式化工具, 期间学习了一些编译原理相关的知识, 写个专栏来分享一下
由于完整的代码格式化工具体量很大, 且机械性的重复逻辑很多, 核心部分其实非常简单, 因此选择以精简过后的四则运算表达式解析器作为本专栏的项目
需求如下:
- 0 外部依赖
- 对疑似表达式的字符串进行解析, 若为合法输入则进行以下处理
- 求值
- 支持计算求值
- 支持正负数
- 支持括号提升运算优先级
- 格式化
- 去除冗余符号
- 操作符左右添加空格
- 求值
举例如下
合法输入: "1*(+2+-3)"
求值输出: -1
格式输出: "1 * (2 + (-3))"
非法输入: "01 + 1"
非法输入: "1+++1"
成果展示
源码传送门, 目前已经完成了上述需求, 下面的测试将顺利通过
#[test]
fn smoke() {
let expr = "1*2+(3/(4+(-5)))";
let ast = build_ast(expr).unwrap();
assert_eq!(-1, eval(&ast));
assert_eq!("1 * 2 + 3 / (4 + (-5))", format(&ast));
}
目录
Q&A
Q: 为什么要用 Rust?
A: 个人兴趣
Q: 你不是前端仔么, 为什么捣鼓编译?
A: 个人兴趣
Q: 为什么非得要 0 外部依赖
A: 没有到非得追求性能和可靠性的时候, 还是想更多的把握实现细节