首要感谢 Eve 大手子制作的封面~

阅览之前, 读者应该具有以下基础

  1. 阅览代码的才能
  2. 阅览 Rust 代码的才能

本文目的

  1. 避开生涩单调的理论, 尽量用大白话简略共享编译相关常识
  2. 太久没写博客了, 写个专栏玩玩

导言

笔者的毕设做了一个代码格局化东西, 期间学习了一些编译原理相关的常识, 写个专栏来共享一下

因为完好的代码格局化东西体量很大, 且机械性的重复逻辑许多, 核心部分其实非常简略, 因而选择以精简过后的四则运算表达式解析器作为本专栏的项目

需求如下:

  • 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));
}

目录

  1. 前置干货
  2. 全体设计
  3. 类型界说
  4. dfa 完成
  5. lexer 完成
  6. 文法编写及优化
  7. parser combinator 简略封装
  8. parser 完成
  9. 访问者完成
  10. 求值功用完成
  11. 格局化功用完成
  12. 总结

Q&A

Q: 为什么要用 Rust?

A: 个人兴趣

Q: 你不是前端仔么, 为什么捣鼓编译?

A: 个人兴趣

Q: 为什么非得要 0 外部依靠

A: 没有到非得追求性能和可靠性的时候, 还是想更多的掌握完成细节