我正在为财务应用程序开发计算器程序。 我需要解析和评估如下所述的复杂财务表达。
表达式是自定义函数和算术表达式的混合。
我正在使用NCalc
来解析算术表达式。但是,我在解决自定义功能时遇到问题。
IF((COALESCE(X1,X2)-X3+IF(X4<=0,0,X5))>0, CUSTOM_FUNCTION(X6), X7)
关于最佳方法的任何建议?
我目前正致力于一个复杂的逻辑,涉及递归调用和Stack Push / Pop。但它没有用。
答案 0 :(得分:4)
这是很久以前解决的老问题。解决方案是使用解析器生成器,而不是从头开始编写自己的解析器。有许多选项,其中一个比较受欢迎的选项是ANTLR。
使用像ANTLR这样的解析器生成器,您可以使用易于理解的EBNF生成规则来描述您的问题。解析器生成器将生成复杂的逻辑,您似乎正在尝试用您选择的语言手动编写,在您的情况下为C#。可能您的语言语法已经以这种格式提供,或者您已使用此格式向用户和开发团队描述语言。
答案 1 :(得分:2)
Mishax是对的,你编写规则的方式比在C#中直接编码更清楚。如果您遇到ANTLR和C#(我有)的问题,还有其他专用于C#的生成器 - Irony,Coco/R,GOLD,ANTLR,LLLPG ,Sprache或我的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方法,并且可以轻松地注入自己的类来表示上下文值。