Mat*_*olf 3 .net c# mathematical-expressions string-parsing roslyn
我正在寻找一种算法或方法来评估表示为字符串的数学表达式。该表达式包含数学成分,还包含自定义函数。我希望在C#/。Net中实现所说的算法。
我知道罗斯林可以让我评估那种表达
"var value = 3+5*11-Math.Sqrt(9);"
我也很熟悉如何使用“节点重写”来避免变量声明或完全限定的函数名,或者为了评估而省略尾随分号
"value = 3+5*11-Sqrt(9)"
但是,我想在此基础上实现的是提供自定义脚本功能,例如
"value = Ratio(A,B)",其中Ratio是一个自定义函数,用于将向量A中的每个元素除以向量B中的每个元素,并返回相同长度的向量。
要么
"value = Sma(A, 10)",其中Sma是自定义函数,用于计算回溯窗口为10的向量/时间序列A的简单移动平均值。
理想情况下,我想获得提供更多复杂性的能力,例如
"value = Ratio(A,B) * Pi + 0.5 * Spread(C,D) + Sma(E, lookback)",由此解析引擎将尊重运算符的优先级,并构建一个解析树以便获取评估表达式所需的值。
我无法解决罗斯林如何解决此类问题的问题。
还有什么其他方法可以使我入门,或者我缺少Roslyn提供的有助于解决此问题的功能?
假设所有表达式都是有效的C#表达式,则可以通过多种方式使用Roslyn。
您只能将Roslyn用于解析。SyntaxFactory.ParseExpression将为您提供表达式的语法树。请注意,您的第一个(var v = expr;)示例不是表达式,而是变量声明。但是v = expr是一个表达式,即AssignmentExpressionSyntax。然后,您可以遍历此AST,并对每个节点执行您想做的事情,基本上,您将编写一个解释器。这种方法的好处是您不必编写自己的解析器,对AST进行遍历非常简单,并且这种方法非常灵活,因为使用“未知”方法定义您的工作将完全由您决定。
也可以使用Roslyn进行评估。这可以通过多种方式完成:要么将有效的C#文件放在一起,然后将其编译为程序集,要么可以通过Scripting API来完成。这种方法基本上需要一个类库,其中包含所有其他方法的实现,例如Sma,,Spread...,但是在第一种方法中也需要以某种形式使用这些方法,因此,这实际上不是额外的工作。
如果唯一的目标是评估表达式,那么我将采用第二种方法。如果还有其他要求(您没有提到),例如能够生成简化形式的表达式,那么我考虑第一个解决方案。
MathParser.org-mXparser评论中建议的内容似乎与您要查找的内容差不多。