3 个不稳定版本
0.2.1 | 2020年1月28日 |
---|---|
0.2.0 | 2020年1月28日 |
0.1.0 | 2019年8月12日 |
1576 in 数学
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
函数具有相同意义:sqrt
,cbrt
,sin
,cos
,tan
,asin
,acos
,atan
,sinh
,cosh
,tanh
,asinh
,acosh
,atanh
,floor
,ceil
,abs
,exp
,ln
,log2
,log10
。
输入中禁止使用任何其他符号。
数学运算符遵循通常的结合性和优先级关系,但仍然具有浮点数属性:加法不是交换律,存在 NaN
和无穷大...
技术细节
cruncher 基于AST解释器,并使用简单的Shunting Yard算法解析表达式。它仅与 f64
数据一起工作,并执行简单的常量传播以优化表达式。
依赖关系
~8MB
~174K SLoC