3 个不稳定版本

0.2.1 2020年1月28日
0.2.0 2020年1月28日
0.1.0 2019年8月12日

1576 in 数学

MIT 许可证

54KB
954

Cruncher

该库可以接受字符串,例如 "x + 2 / 3 * ( z ^ 4 )",并允许您传递一个字典,其中包含每个变量的值,以获取结果。

目前测试做得最好,提供了如何与库交互的示例。

这是一个正在进行中的项目,但主要功能已经存在。词法分析器/解析器需要改进,因为它对空格敏感。


lib.rs:

Cruncher,一个用于动态评估数学表达式的 crate。

这个 crate 提供了在字符串中嵌入的数学表达式的运行时评估。使用这个 crate 最简单的方法是使用 eval 函数

assert_eq!(cruncher::eval("3 + 5 * 2", None), Ok(13.0));

eval 的第二个参数是一个 HashMap,它可以定义变量

use hashbrown::HashMap;

let mut context :HashMap<String,f64> = HashMap::new();
context.insert("a".into(), 3.5);
assert_eq!(cruncher::eval("2 * a", &context), Ok(7.0));

还可以使用 Expr 类型将表达式的解析与评估分离。这允许使用不同的变量值重复使用相同的表达式。

use hashbrown::HashMap;
use cruncher::{Expr};

let expr = Expr::parse("3 + 5 * 2").unwrap();
assert_eq!(expr.eval(None), Ok(13.0));

let expr = Expr::parse("3 / c + b").unwrap();
let mut context :HashMap<String,f64> = HashMap::new();
context.insert("c".into(), 1.0);
context.insert("b".into(), 5.0);
assert_eq!(expr.eval(&context), Ok(8.0));

context.insert("b".into(), 10.0);
assert_eq!(expr.eval(&context), Ok(13.0));

语言定义

Cruncher 实现的语言可以包含以下元素

  • 浮点字面值:-12.456+0.0045e78 等;
  • 左右括号;
  • 数学运算符:+ 用于加法,- 用于减法,* 用于乘法,/ 用于除法,以及 ^ 用于指数运算(std::f64::powf);
  • 变量。变量名称仅限于 ASCII,可以以字母或 _ 开头,可以包含字母、数字、._[]
  • 函数调用:sin(a)atan(22.0)。以下函数可访问,与相应的 std::f64 函数具有相同意义:sqrtcbrtsincostanasinacosatansinhcoshtanhasinhacoshatanhfloorceilabsexplnlog2log10

输入中禁止使用任何其他符号。

数学运算符遵循通常的结合性和优先级关系,但仍然具有浮点数属性:加法不是交换律,存在 NaN 和无穷大...

技术细节

cruncher 基于AST解释器,并使用简单的Shunting Yard算法解析表达式。它仅与 f64 数据一起工作,并执行简单的常量传播以优化表达式。

依赖关系

~8MB
~174K SLoC