我只想解析像
这样的简单表达式IIF(FVAL(PFC) = TRUE, (IIF((ORGVAL(BAS, "2012/12/31") + ORGVAL(DA)) < 6500, (FVAL(BAS) + FVAL(DA)) * 12%, 780)), 0)`
解析后,我应该能够知道哪些函数包含哪些参数。
|-FVAL
|-PFC
|-ORGVAL
|-BAS
|-"2012/12/31"
我坚持使用.Net Framework 2.0,所以没有Linq或lambda表达对我好。此外,我想将代码包含在我的自定义库中,而不仅仅是引用它。任何人都可以给我一些好的图书馆或代码。
我只需要解析而不是评估表达式并找到正在使用的令牌。在找到令牌之后,我需要在解析之前更改表达式字符串,就像使用函数ORGVAL
一样,传递的参数必须以下划线为前缀。与ORGVAL(BAS)
一样,我们会转换为ORGVAL(_BAS)
。某些功能可以包含两个参数,例如ORGVAL(BAS, "2012/12/31")
,这将转换为ORGVAL(_BAS, "2012/12/31")
注意:如果还有其他方式,请让我知道。我很乐意避免使用助手和词霸。
答案 0 :(得分:1)
这看起来像一个未经修改但完整的表达式解析器(尚未对其进行测试,但可能是一个起点)。
http://gbacon.blogspot.it/2005/09/simple-expression-parser-in-c.html
它已经过时了,但你提到了C#2.0,所以无论如何它都可能没问题。我不确定它的目标是哪个版本的C#。
答案 1 :(得分:1)
如果您不介意使用其中一种.NET语言代码,可以使用CodeDom动态编译代码,然后将其作为仅内存中的程序集执行。例如,这将是您显示的示例表达式的最接近的近似值:
private abstract class Logic
{
protected double FVAL(object arg)
{
// put code here
return 0;
}
protected double ORGVAL(object arg)
{
// put code here
return 0;
}
protected double ORGVAL(object arg, string date)
{
// put code here
return 0;
}
public abstract double GetValue(object PFC, object BAS, object DA);
}
private class DynamicLogic : Logic
{
public override double GetValue(object PFC, object BAS, object DA)
{
return (FVAL(PFC) = true ? ((ORGVAL(BAS, "2012/12/31") + ORGVAL(DA)) < 6500 ? (FVAL(BAS) + FVAL(DA)) * .12 : 780) : 0);
}
}
private Logic GenerateLogic(string code)
{
using (CSharpCodeProvider provider = new CSharpCodeProvider())
{
StringBuilder classCode = new StringBuilder();
classCode.AppendLine("private class DynamicLogic : Logic");
classCode.AppendLine(" {");
classCode.AppendLine(" public override int GetValue(object PFC, object BAS, object DA)");
classCode.AppendLine(" {");
classCode.AppendLine(" return (" + code + ");");
classCode.AppendLine(" }");
classCode.AppendLine(" }");
CompilerParameters p = new CompilerParameters();
p.GenerateInMemory = true;
p.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
CompilerResults results = provider.CompileAssemblyFromSource(p, code);
return (Logic)Activator.CreateInstance(type);
if (results.Errors.HasErrors)
{
throw new Exception("Failed to compile DynamicLogic class");
}
return (Logic)results.CompiledAssembly.CreateInstance("DynamicLogic");
}
}
private double evaluate(object PFC, object BAS, object DA)
{
Logic logic = GenerateLogic("FVAL(PFC) = true ? ((ORGVAL(BAS, \"2012/12/31\") + ORGVAL(DA)) < 6500 ? (FVAL(BAS) + FVAL(DA)) * .12 : 780) : 0");
return logic.GetValue(PFC, BAS, DA);
}
编辑:我知道你说你需要实际获得表达式三,本身,不只是评估它,但我编写代码,所以我想我会继续发布它适合未来的路人。
答案 2 :(得分:1)
你想要做的事情听起来很像解析,所以我认为找到一个不涉及解析的解决方案会有很多好运。如果您想说的是您不想自己编写解析器,那么可以使用几个数学表达式解析库。
我是Jep.Net(http://www.singularsys.com/jep.net)的作者之一,它是一个可能满足您需求的表达式解析组件。它具有良好的文档记录,可高度自定义,绝对可以让您跳过实现自定义解析器的繁琐且容易出错的过程。如果它不适合你,谷歌搜索“.net表达式解析库”将获得其他库。
祝你好运!