views:

495

answers:

5

Hi

I am looking for a parser that can operate on a query filter. However, I'm not quite sure of the terminology so it's proving hard work. I hope that someone can help me. I've read about 'Recursive descent parsers' but I wonder if these are for full-blown language parsers rather than the logical expression evaluation that I'm looking for.

Ideally, I am looking for .NET code (C#) but also a similar parser that works in T-SQL.

What I want is for something to parse e.g.:

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

Ideally, the operators can be definable (e.g. '<' vs 'lt', '=' vs '==' vs 'eq', etc) and we can specify function-type labels (e.g. (left(x,1)='e')). The parser loads this, obeys order precedence (and ideally handles the lack of any brackets) and then calls-back to my code with expressions to evaluate to a boolean result - e.g. 'a=b'?). I wouldn't expect the parser to understand the custom functions in the expression (though some basic ones would be useful, like string splitting). Splitting the expression (into left- and right-hand parts) would be nice.

It is preferable that the parser asks the minimum number of questions to have to work out the final result - e.g. if one side of an AND is false, there is no point evaluating the other side, and to evaluate the easiest side first (i.e. in the above expression, 'c<=d' should be assumed to be quicker and thus evaluated first.

I can imagine that this is a lot of work to do, however, fairly common. Can anyone give me any pointers? If there aren't parsers that are as flexible as above, are there any basic parsers that I can use as a start?

Many Thanks

Lee

+1  A: 

Take a look at this. ANTLR is a good parser generator and the linked-to article has working code which you may be able to adapt to your needs.

Vinay Sajip
Thanks Vinay. That's really helpful and I've learnt a lot more about parsing, etc since I posted this question. I've been looking at .NET Expression trees also and wonder if this would work? It looks as though there is less flexibility in defining the grammar, but the advantage that it is a part of the framework. The only thing is I cannot find an example of loading a string into a tree, and then being 'called-back' to evaluate indvidual expressions. I'll keep looking, but ANTLR looks like solution at the moment. Thanks, Lee
Lee Atkinson
@Lee: you can write code convert your ANTLR tree to a .Net Expression tree for evaluation using the AST features in ANTLR.
sixlettervariables
A: 

Try Vici.Parser: download it here (free) , it's the most flexible expression parser/evaluator I've found so far.

Roel
Thanks Roel, but this looks specifically for the C# syntax and for late-bound execution of the code. I prefer the flexibility of specifying my own syntax, and also don't want the code to be executed by the system, but evalauted by my code. Once again, thanks for taking the time.
Lee Atkinson
A: 

If it's possible for you, use .Net 3.5 expressions.

Compiler parses your expression for you and gives you expression tree that you can analyze and use as you need. Not very simple but doable (actually all implementations of IQueryable interface do exactly this).

Konstantin Spirin
Thanks Konstantin - are you aware of any examples? Specifically feeding some source text, and then evaluating the expressions in the tree?
Lee Atkinson
+1  A: 

You could check out Irony. With it you define your grammar in C# code using a syntax which is not to far from bnf. They even have a simple example on their site (expression evaluator) which seems to be quite close to what you want to achieve.

Edit: There's been a talk about Irony at this year's Lang.Net symposium.

Hope this helps!

andyp
Hi - this is one I've been considering - along with TinyPG. I like TinyPG since it doesn't have any dependencies, however, Irony seems to be more active at the moment. Do you know how well Irony compares in performance terms to other solutions?Lee
Lee Atkinson
Hi, no I don't, i just played a bit with it. But the author seems to be (very) competent and he's convinced that it compares well. He has spoken about Irony at this year's Lang.Net symposium (i've edited my answer to include a link to that talk).
andyp
A: 

You can use .NET expression trees for this. And the example is actually pretty simple.

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

And then just look at "test" in the debugger. Everything is already parsed for you, you can just use it.

The only problem is that in .NET 3.5 you can have only up to 4 arguments in Func. So, I changed "e" to "c" in one place. In 4.0 this limit is changed to 16.

Alexandra Rusina
HiI'm not sure how this helps to parse an expression string. There is Dynamic Linq, but that doesn't seem to support one's own (i.e. none-c#, none-vb) language.
Lee Atkinson
Oh, sorry. I thought you wanted to parse the actual code.
Alexandra Rusina