Rust 实现一个表达式 Parser(10) Eval 实现

255 阅读1分钟

本文将实现在专栏开篇提出的第一个需求: 表达式求值

源码: 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));
}