9个稳定版本

2.1.1 2023年1月13日
2.0.6 2022年12月5日
2.0.3 2022年5月27日
2.0.1 2022年5月26日
2.0.0 2022年5月24日

#305 in 解析器实现

Download history 17/week @ 2024-03-11 65/week @ 2024-03-18 13/week @ 2024-03-25 65/week @ 2024-04-01 8/week @ 2024-04-08 382/week @ 2024-04-15 40/week @ 2024-04-22 18/week @ 2024-04-29 253/week @ 2024-05-06 165/week @ 2024-05-13 1/week @ 2024-05-20 51/week @ 2024-05-27 69/week @ 2024-06-03 51/week @ 2024-06-10 70/week @ 2024-06-17 90/week @ 2024-06-24

315 每月下载量
3 个crate(2直接) 中使用

MIT 许可证

270KB
3K SLoC

fasteval

代数表达式的快速且安全评估

fasteval 是一个用于解析、编译和评估代数表达式的库。它可以直接用作计算器语言(类似于 python),并且是构建高级语言的优秀基础。

文档

使用方法

将此内容添加到您的Cargo.toml中

[dependencies]
fasteval2 = "0.2.4"

您可以使用 codegen-units=1 以获得更好的运行时性能。在某些情况下,它将极大地提高LLVM的编译时优化。(请参阅 如何编写快速的Rust代码)。

如果您使用的是 'nightly' Rust编译器,您可以使用 --features nightly 来构建以启用在 'stable' Rust中尚不可用的优化。

您可以使用 --no-default-features 来禁用诸如 andorNaNinf 等字母顺序关键字。 (这些单词可能对您的应用程序很重要。)

您可以使用 --features unsafe-vars 来启用 不安全变量

特性

  • 无依赖项。
  • 安全执行不受信任的表达式。
  • 支持稳定Rust。
  • 支持解释(即解析和评估)以及编译执行(即解析、编译、评估)。
  • 支持变量和自定义函数。
  • fasteval 是构建高级语言的优秀基础。
  • 支持许多内置函数和常量。
  • 支持所有标准的代数一元和二元运算符(+ - * / ^ %),以及比较运算符(< <= == != >= >)和逻辑运算符(&& ||)并支持短路。
  • 易于集成到多种不同的应用中,包括作用域评估。
  • 性能非常快。

简单示例

这里有一个简单的示例。更多示例请参阅API参考

函数ez_eval()为您执行整个分配-解析-评估过程。它稍微有些低效,因为它总是分配一个新的Slab,但它使用起来非常简单

fn main() -> Result<(), fasteval2::Error> {
    // This example doesn't use any variables, so just use an EmptyNamespace:
    let mut ns = fasteval2::EmptyNamespace;

    let val = fasteval2::ez_eval(
        "1+2*3/4^5%6 + log(100K) + log(e(),100) + [3*(3-3)/3] + (2<3) && 1.23",    &mut ns)?;
    //    |            |      |    |   |          |               |   |
    //    |            |      |    |   |          |               |   boolean logic with short-circuit support
    //    |            |      |    |   |          |               comparisons
    //    |            |      |    |   |          square-brackets act like parenthesis
    //    |            |      |    |   built-in constants: e(), pi()
    //    |            |      |    'log' can take an optional first 'base' argument, defaults to 10
    //    |            |      numeric literal with suffix: p, n, µ, m, K, M, G, T
    //    |            many built-in functions: print, int, ceil, floor, abs, sign, log, round, min, max, sin, asin, ...
    //    standard binary operators

    assert_eq!(val, 1.23);

    Ok(())
}

REPL演示

github.com/likebike/fasteval$ rlwrap cargo run --release --example repl
    Finished release [optimized] target(s) in 0.01s
     Running `target/release/examples/repl`
>>> print("Hello fasteval", 1, 2, 3)
Hello fasteval 1 2 3
3
>>> _ + 1
4
>>> _ + 1
5
>>> _ * 2
10
>>> _ ^ 0.5
3.1622776601683795
>>> let a = 1
1
>>> let b = a + 1
2
>>> let c = a + b * 3
7
>>> a + b + c
10
>>> push
Entered scope[1]
>>> let b = b + 10
12
>>> a + b + c
20
>>> pop
Exited scope[1]
>>> a + b + c
10
>>> 1+2*3/4^5%6 + log(100K) + log(e(),100) + [3*(3-3)/3] + (2<3) && 1.23
1.23
>>> 1+2*3/4^5%6 + print("log(100K) =",log(100K)) + log(e(),100) + [3*(3-3)/3] + (2<3) && 1.23
log(100K) = 5
1.23

安全性

fasteval旨在安全地评估不受信任的表达式。默认情况下,表达式只能执行数学运算;它无法访问其他类型的操作(如网络、文件系统或外部命令)。此外,我们还能防止恶意表达式

  • 过长(大于4KB)的表达式。
  • 过深嵌套(大于32层)的表达式。
  • 值过多(大于64)的表达式。
  • 子表达式过多(大于64)的表达式。

所有限制都可以在解析时自定义。如果任何限制被超过,parse()将返回一个Error

请注意,您(开发者)可以定义可能执行危险操作的函数。确保所有自定义功能安全是您的责任。

性能基准

以下是性能基准的简要总结。对于更完整报告和分析,请参阅官方文档

图表

请注意,以下图表使用对数刻度。因此,微小的视觉差异实际上代表了非常显著的性能差异。

编译表达式的评估性能
Compiled Eval Performance

一次性解释(解析和评估)的性能
Interpretation Performance

编译不安全变量的性能,与C库tinyexpr(我们测试集中唯一支持此模式的库)相比
Unsafe Compiled Eval Performance

解释不安全变量的性能,与C库tinyexpr(我们测试集中唯一支持此模式的库)相比
Unsafe Interpretation Performance

总结

这些结果令人印象深刻的是,fasteval在每次基准测试的每个操作模式(解释、编译和不安全)中都始终达到最快的时间。要牺牲其他方面的性能来获得任何这些指标的排名第一,很容易,但要创建一个在所有方面都能排名第一的设计是困难的。

由于广泛的强大性能优势,fasteval很可能成为您动态评估需求的绝佳选择。

许可证

fasteval根据MIT许可证条款分发。

有关详细信息,请参阅LICENSE

无运行时依赖

特性