【问题标题】:Parser for query filter expression tree查询过滤器表达式树的解析器
【发布时间】:2009-09-17 10:12:59
【问题描述】:

我正在寻找可以对查询过滤器进行操作的解析器。但是,我不太确定这些术语,因此证明工作很辛苦。我希望有人能帮助我。我读过“递归下降解析器”,但我想知道这些是否适用于成熟的语言解析器,而不是我正在寻找的逻辑表达式评估。

理想情况下,我正在寻找 .NET 代码 (C#),但也寻找适用于 T-SQL 的类似解析器。

我想要的是解析例如:

((a=b)|(e=1))&(c

理想情况下,运算符可以是可定义的(例如 '

解析器最好提出最少数量的问题才能得出最终结果 - 例如如果 AND 的一侧为假,则评估另一侧没有意义,并且首先评估最简单的一侧(即在上面的表达式中,应该假设 'c

我可以想象,这需要做很多工作,但是相当普遍。任何人都可以给我任何指示吗?如果没有像上面那样灵活的解析器,是否有任何基本的解析器可以作为开始使用?

非常感谢

【问题讨论】:

    标签: c# tsql parsing expression-trees


    【解决方案1】:

    看看this。 ANTLR 是一个很好的解析器生成器,链接到的文章有工作代码,您可以根据自己的需要进行调整。

    【讨论】:

    • 谢谢维奈。这真的很有帮助,自从我发布这个问题以来,我学到了很多关于解析等的知识。我也一直在查看 .NET 表达式树,想知道这是否可行?看起来定义语法的灵活性较低,但它是框架的一部分的优势。唯一的事情是我找不到将字符串加载到树中,然后被“回调”以评估单个表达式的示例。我会继续寻找,但目前 ANTLR 看起来像是解决方案。谢谢,李
    • @Lee:您可以编写代码将您的 ANTLR 树转换为 .Net 表达式树,以便使用 ANTLR 中的 AST 功能进行评估。
    【解决方案2】:

    您可以查看Irony。使用它,您可以使用与 bnf 相距不远的语法在 C# 代码中定义您的语法。他们甚至在他们的网站上有一个简单的示例(表达式评估器),这似乎与您想要实现的目标非常接近。

    编辑:在今年的 Lang.Net 研讨会上有一个talk about Irony

    希望这会有所帮助!

    【讨论】:

    • 嗨 - 这是我一直在考虑的一个 - 与 TinyPG 一起。我喜欢 TinyPG,因为它没有任何依赖关系,然而,Irony 目前似乎更活跃。您知道 Irony 在性能方面与其他解决方案相比有多好吗?李
    • 嗨,不,我没有,我只是玩了一下。但作者似乎(非常)有能力,他相信它比较好。他在今年的 Lang.Net 研讨会上谈到了 Irony(我已经编辑了我的答案以包含该演讲的链接)。
    【解决方案3】:

    试试 Vici.Parser: download it here (free) ,这是迄今为止我发现的最灵活的表达式解析器/求值器。

    【讨论】:

    • 感谢 Roel,但这看起来专门用于 C# 语法和代码的后期绑定执行。我更喜欢指定自己的语法的灵活性,也不希望代码由系统执行,而是由我的代码进行评估。再次感谢您抽出宝贵时间。
    【解决方案4】:

    如果可能,请使用 .Net 3.5 表达式。

    编译器会为您解析表达式并为您提供表达式树,您可以根据需要进行分析和使用。不是很简单但可行(实际上所有 IQueryable 接口的实现都是这样做的)。

    【讨论】:

    • 谢谢康斯坦丁 - 你知道任何例子吗?专门提供一些源文本,然后评估树中的表达式?
    【解决方案5】:

    您可以为此使用 .NET 表达式树。这个例子其实很简单。

    Expression<Func<int, int, int, int, bool>> test = (int a, int b, int c, int d) => ((a == b) | (c == 1)) & (c <= d);
    

    然后只看调试器中的“测试”。一切都已经为你解析好了,你可以使用它。

    唯一的问题是在 .NET 3.5 中 Func 中最多只能有 4 个参数。所以,我在一个地方把“e”改成了“c”。在 4.0 中,此限制更改为 16。

    【讨论】:

    • 您好,我不确定这对解析表达式字符串有何帮助。有 Dynamic Linq,但似乎不支持自己的(即 none-c#、none-vb)语言。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    • 2018-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多