本文将实现在专栏开篇提出的第一个需求: 表达式求值
源码: src/traversal/eval.rs
实现目标
能够计算这个表达式 "1 * 2 + ( 3 / ( 4 + (-5)))"
写一下
实现非常简单, 这里直接定义一个简单的结构体作为 visitor 就可以了
Executor 定义
pub struct Executor;
impl Executor {
pub fn new() -> Self {
Executor
}
pub fn eval(&mut self, node: &Node) -> i32 {
// 即将实现 Visitor Trait
self.visit(node)
}
}
实现 Visitor
很简单, 就直接贴代码
impl Visitor<i32> for Executor {
// Literal 节点的访问逻辑
fn visit_num(&mut self, value: i32, _: &str) -> i32 {
value
}
// Expr 节点的访问逻辑
fn visit_expr(&mut self, left: &Node, op: &str, right: &Node) -> i32 {
// 优先访问左子树
let left = self.visit(left);
// 访问右子树
let right = self.visit(right);
// 根据当前操作符执行不同的计算逻辑
match op {
"+" => left + right,
"-" => left - right,
"*" => left * right,
"/" => left / right,
_ => panic!("unexpected operator: {}", op),
}
}
}
跑一下
看起来是没什么问题
#[test]
fn smoke_test() {
let mut e = Executor::new();
let ast = syntax(lex("1 * 2 + ( 3 / ( 4 + (-5)))").unwrap()).unwrap();
assert_eq!(-1, e.eval(&ast));
}