C#中的自定义表达式解析器

时间:2015-08-23 04:53:16

标签: c# math expression eval finance

我正在为财务应用程序开发计算器程序。 我需要解析和评估如下所述的复杂财务表达。

表达式是自定义函数和算术表达式的混合。 我正在使用NCalc来解析算术表达式。但是,我在解决自定义功能时遇到问题。

IF((COALESCE(X1,X2)-X3+IF(X4<=0,0,X5))>0, CUSTOM_FUNCTION(X6), X7)

关于最佳方法的任何建议?

我目前正致力于一个复杂的逻辑,涉及递归调用和Stack Push / Pop。但它没有用。

4 个答案:

答案 0 :(得分:4)

这是很久以前解决的老问题。解决方案是使用解析器生成器,而不是从头开始编写自己的解析器。有许多选项,其中一个比较受欢迎的选项是ANTLR

使用像ANTLR这样的解析器生成器,您可以使用易于理解的EBNF生成规则来描述您的问题。解析器生成器将生成复杂的逻辑,您似乎正在尝试用您选择的语言手动编写,在您的情况下为C#。可能您的语言语法已经以这种格式提供,或者您已使用此格式向用户和开发团队描述语言。

答案 1 :(得分:2)

Mishax是对的,你编写规则的方式比在C#中直接编码更清楚。如果您遇到ANTLR和C#(我有)的问题,还有其他专用于C#的生成器 - IronyCoco/RGOLDANTLRLLLPGSprache或我的NLT

不要因为信仰而离开你(如果你只想要结果):

expr -> e1:expr "+" e2:expr { e1+e2 }
      | e1:expr "*" e2:expr { e1*e2 }
      ... and so on ...
      ;

原始C#中的等效部分会更长。

答案 2 :(得分:0)

我认为你必须使用有限状态机。 Compilators就是基于它的。 您必须逐个字母地解析字符串,并定义您的操作: 这样的事情:

  

待办事项   {      //你的解析器      我++;   }   当我

答案 3 :(得分:0)

我建议使用JavaScript Interpretor进行一些替代方法。

https://github.com/sebastienros/jint

JInt有一个强大的解析器,但是你需要改变一些东西。

JavaScript中不存在IF和COALESCE,但可以转换为例如。

IF表达

x = IF(CONDITION,THEN,ELSE) 

JavaScript等价物是

x = CONDITION ? THEN : ELSE

COALESCE表达

x = COALESCE(x1,x2,x3)

JavaScript等价物是

x = x1 != null ? x1 : 
        (x2 != null ? x2 : 
             (x3 != null ? x3 : null ))

JInt会给你一个解析的AST,你可以操纵AST并转换相应的IF和COALESCE运算符。

使用组织良好的JInt解析器并简单地发布进程AST将比重新发明轮子容易得多。

通过使用JInt,您还可以使用各种已有的.NET方法,并且可以轻松地注入自己的类来表示上下文值。