数学表达式的自定义解释器

我必须评估包含变量的大量表达式,我正在考虑编写一个小的自定义解释器来保持编译的快速和小。 但是我对这个主题没有经验并且有一些问题。

假设我们有一个包含数学表达式和一组有限对象的文件。 该文件可能如下所示:

expr[x,y,z] = 2*x*y + x^2 + 28/14*z*(x*y^2 + 15*z) + ... 

我想以某种方式解析它,所以我可以通过简单地调用函数expr(float x, float y, float z)在我的应用程序中以数字方式计算表达式。 不应修复参数的数量(编辑:每个表达式都有自己的定义,带有适当数量的参数或接受数组)并且应该允许嵌套括号以使输入文件保持相当小。

由于表达式都是多项式类型,我可以想一想数据结构应该是什么样子,但解析看起来很困难。 我已经在SO上找到了一些类似问题的答案,例如使用Lua。

然而,最大的问题是,与直接从自动生成的C代码编译这些表达式相比,创建和调用这些对象时的性能损失是什么。

提前致谢!

编辑:请仅考虑上面的expr()示例。 我想最好的方法是让模板类的对象保存稀疏数组中变量的系数和幂。

性能是一个长篇字符串问题。 解释语言几乎总是比编译的C代码慢,以评估算术表达式。 但并不是很多程序花费大部分时间进行算术运算,所以大部分时间都无关紧要。 无论是在每次评估表达式时解析表达式还是(从你说的话看起来更可能),它都会有所不同,将其解析为某种中间forms。

你不可能从你说的内容,它是否对你很重要,或者你会写一个解释器有多快,但我不认为它会比评估表达式的时间慢10倍。被关注到。 首次尝试解释的情况要糟糕得多。

至于那个中间forms – 通常的起点是使用Dijkstra的“shunting-yard”算法将你的中缀表达式转换为反向波兰语forms。 这给你一系列“符号”,“字节代码”,调用它们你喜欢的东西,并且很容易为该表单编写一个表达式求值器 – 每个运算符只是从堆栈中弹出它的操作数,执行操作,然后推送结果到堆栈,直到表达式的最终值是结尾处唯一的结果。 数字文字和变量名称就像不运行操作数的“运算符”,并推动其值。

[编辑 – 取决于您的用户是谁,您的程序可能可以获取该文本文件,从中生成C程序,运行编译器然后运行生成的程序(或者打开并调用生成的dll)。 显然,它依赖于许多特定于系统的东西(正在安装一个编译器),并且需要对表达式进行足够的评估,以便克服编译的开销。

您将问题描述为“大型复杂表达”,并且您担心性能损失。 那么你应该考虑编译它们,而不是解释它们。 (良好的解释器比编译代码慢10倍作为经验法则;糟糕/临时解释器往往会更糟糕)。

通常的方法是以某种方式“编译”表达式,这涉及构建解析器,代码生成器,优化等。

C编译器已经完成了这一切。 因此,我认为将这些表达式转换为C会好得多。编译它们很容易,与你希望作为解释器做的任何事情相比,执行速度会快。 这也可以使用解析器和更简单的语法定向转换来完成。

但是如果这些表达式都是由Mathematica生成的,那么它们将具有相当标准但不复杂的结构。 在这种情况下,我猜你可以编写一个基于正则表达式的翻译器,可以将Mathematica表格映射到C函数,而不会有太多麻烦; Perl对此非常理想。 这为您提供了易于实施且速度非常快的解决方案。

对于它的价值,我相信Mathematica可以选择将Mathematica表达式直接转换为C.似乎也值得一试。

“ 野牛手册”中有一个简单的例子。