解析表达式和检索解析树的最简单方法是什么? [英] What is the simplest way to parse an expression and retrieve a parse tree?

查看:89
本文介绍了解析表达式和检索解析树的最简单方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只想解析诸如-的简单表达式

I just want to parse simple expressions like -

IIF(FVAL(PFC) = TRUE, (IIF((ORGVAL(BAS, "2012/12/31") + ORGVAL(DA)) < 6500, (FVAL(BAS)  + FVAL(DA)) * 12%, 780)), 0)`

解析之后,我应该能够知道哪些函数包含哪些参数.

After parsing this I should be able to know what functions contains what parameters.

|-FVAL
       |-PFC
|-ORGVAL 
       |-BAS
       |-"2012/12/31"

我坚持使用.Net Framework 2.0,所以没有Linq或lambda表达式对我有用.我也想将代码包含在我的自定义库中,而不仅仅是引用它.谁能指出我一些好的库或代码.

I'm stuck with .Net Framework 2.0, so no Linq or lambda expression goodies for me. Also I want to include the code in my custom library and not just reference it. Can anyone point me to some good library or code.

我只需要分析而不评估表达式并查找正在使用的标记.找到标记后,我需要在解析之前更改表达式字符串,例如,如果使用函数ORGVAL,则传递的参数必须以下划线作为前缀.像ORGVAL(BAS)一样会转换为ORGVAL(_BAS).某些功能可能具有两个参数,例如ORGVAL(BAS, "2012/12/31"),这将转换为ORGVAL(_BAS, "2012/12/31")

I just need to parse and not evaluate the expression and find what tokens are in use. After finding the tokens I need to change the expression string before parsing, like if the function ORGVAL is used then the parameter passed has has to be prefixed by an underscore. Like ORGVAL(BAS) will transform to ORGVAL(_BAS). Some functions can have tow parameters like ORGVAL(BAS, "2012/12/31") and this will transform to ORGVAL(_BAS, "2012/12/31")

注意:如果还有其他方法,请让我知道.我希望避免使用解析器和词法分析器.

推荐答案

如果您不介意使用一种.NET语言编写代码,则可以使用CodeDom即时编译并执行代码,然后执行它作为仅内存中的程序集.例如,这将是您显示的示例表达式的最接近的近似值:

If you don't mind using one of the .NET languages for the code, you can use CodeDom to compile and the code on the fly and then execute it as an in-memory-only assembly. For instance, this would be the closest approximation to the example expression you showed:

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);
}

编辑:我知道您说过,您实际上需要真正获得表达式3本身,而不仅是对其求值,而且我编写了代码,因此我认为我要继续发布它供未来的路人使用.

I know you said you need to actually get the expression three, itself, not just evaluate it, but I worked up the code, so I figured I'd just go ahead and post it for future passers-by.

这篇关于解析表达式和检索解析树的最简单方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆