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

bbt*_*trb 11 c c++ parsing interpreter

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

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

expr[x,y,z] = 2*x*y + x^2 + 28/14*z*(x*y^2 + 15*z) + ...
Run Code Online (Sandbox Code Playgroud)

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

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

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

提前致谢!

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

Ste*_*sop 6

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

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

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

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