#表达式解析器 #数学 #表达式 #解析器 #复数

mexprp

一个数学表达式解析和评估库

4 个版本 (2 个重大变更)

0.3.1 2022年11月25日
0.3.0 2018年4月7日
0.2.0 2018年4月3日
0.1.0 2018年4月2日

#1402 in 解析器实现

Download history 82/week @ 2024-03-14 46/week @ 2024-03-21 98/week @ 2024-03-28 195/week @ 2024-04-04 190/week @ 2024-04-11 85/week @ 2024-04-18 94/week @ 2024-04-25 78/week @ 2024-05-02 78/week @ 2024-05-09 115/week @ 2024-05-16 165/week @ 2024-05-23 148/week @ 2024-05-30 316/week @ 2024-06-06 200/week @ 2024-06-13 207/week @ 2024-06-20 116/week @ 2024-06-27

854 每月下载量
用于 morphius

MPL-2.0LGPL-3.0+

88KB
2K SLoC

MEXPRP

Crates.io Docs.rs License

Rust的数学表达式解析和评估库

API文档在此。还可以查看 examples/ 目录。

动机

我编写MEXPRP的主要原因是为一款我正在开发的3D方程图形绘制器(vgraph)。我无法确切地说为什么我没有选择任何现有的库,除了因为我想要一个学习经历,因为我想要灵活性。我很高兴地说,我从这个项目中学到了很多,它也非常灵活。

特性

  • f64 精度
  • 多精度/任意精度(部分不完整)
  • 低依赖性
  • 自定义变量上下文
  • 自定义函数上下文
  • 内置常量和函数(例如pi、sin、max)
  • 隐式乘法
  • UTF-8就绪
  • 支持多解
  • 复数(部分不完整)

用法

有多种不同的方式来解析和评估一个方程。

使用 eval()

此函数使用默认上下文一次性解析和评估一个字符串。还有一个 eval_ctx() 函数,它也接受一个对 Context 的引用,该引用将用于替代默认的 Context。类型参数可以是实现 Num 特性的任何类型。一些 Num 类型支持比其他类型更多的操作。有关 Num 的更多信息,请参阅 Num 模块。

mexprp::eval::<f64>("10 / (2 + 3)"); // Ok(Answer::Single(2.0))

使用 Expression

表达式::parse() 将字符串解析为树形表示(一个 Term)。它还可以使用 parse_ctx() 进行解析,并将该上下文存储在其中以供将来评估。它还可以使用 eval_ctx 对任何其他上下文进行评估。确保自定义上下文包含 Expression 依赖的任何定义是非常重要的。

let expr: Expression<f64> = Expression::parse("3 ^ 4 / 9").unwrap();
let res = expr.eval(); // Ok(Answer::Single(9.0))

使用上下文

您可以通过定义上下文来评估带有自定义变量和函数定义的表达式。当定义自定义函数时,请记住使用自定义上下文解析表达式,否则解析器会将您的函数识别为变量。一种绕过此问题的方法是在用于解析的上下文中禁用隐式乘法,这样它就会将所有跟有括号的名称解析为函数,而不管它们是否定义在 Context 中。

Context 还包含配置值,这些值定义了 MEXPRP 如何解析和评估方程。这些配置值包括启用/禁用隐式乘法、支持选择精度的类型(目前仅为 Complex)的精度以及 sqrt() 函数的行为。更多信息可以在 API 文档中找到(查看 context 模块)。

let mut context: Context<f64> = Context::new();
context.set_var("x", 4.0);
let expr = Expression::parse_ctx("4x", context).unwrap();
let res = expr.eval(); // Ok(Answer::Single(16.0))

有关 Context 中的内置函数/常量的列表,请参阅 Context 结构的 API 文档。

多精度

MEXPRP 支持 Num 特性来评估不同精度的表达式和复数。目前支持的数量类型包括

  • f64
  • ComplexFloat
  • ComplexRugRat(使用 rug crate)
  • Rational(来自 rug crate)
  • Complex(来自 rug crate)

然而,某些类型的实现尚不完整。只有 f64 类型完全实现了所有操作。Complex 是下一个最佳选择,但即使是它也缺少一些。其他类型仅实现了 Num 特性的(小的)子集,并在尝试执行不受支持的操作时返回 MathError::Unimplemented。希望未来将实现更多函数,但有些对于任意精度或有理数来说非常难以实现。

有关类型的信息,请参阅 num 模块的文档。要查看数字实现进度,请查看 GitHub 上带有 number 标签的 问题

要使用其他数字类型,更改您的 MEXPRP 类型注释。

extern crate rug;
use rug::Rational;
mexprp::eval::<Rational>("10/15"); // 2/3
extern crate rug;
use rug::Complex;
mexprp::eval::<Complex>("(2+3i)(2-3i)"); // 23 + 2i

多个答案

在 MEXPRP 中对表达式进行评估会返回一个 Answer。答案是一个简单的枚举,可以是 Single(N)Multiple(Vec<N>),其中 N 是此表达式使用的数字类型。这代表了对可能产生多个值的操作(如 sqrt()± 运算符)的答案。如果您知道表达式的结果只有一个答案,可以使用答案的 unwrap_single() 方法来获取该答案。

请务必查看 API 文档 以获取更深入的用法说明。

许可证

MPL-2.0

依赖项

~3.5MB
~64K SLoC