Some help getting started

May 2, 2014 at 9:10 PM
Hi guys,

I have started playing with Irony, and it looks quite easy to work with. But since I am not used to working woth parsers and compilers, there is some terminology, that I need to understand first.

I am not quite sure what the difference between a Terminal and a NonTerminal is, and when I need which.

What I want to do is to take an input string, and transform that into a linq expression. The string is based on the MongoDb query grammer, but I am not trying to implement the full MongoDb query language. I just think the syntax fits my needs.

The input string could look like this:
name$eq:Roman,age$gt:10
Which means that name equals Roman and age is greater than 10, and should eventually be translated to this:
Expression<Func<Person, bool>> personFilter = person => person.Name == "Roman" && person.Age > 10;
The input string is always on a single line as it is passed in through a URL QueryString, and that of course also means I need to do a lot of validation, such as making sure the properties actually exist and allow a certain boolean operator.

This is where I thought Irony would be really helpful. I have written my first little grammer, and it sort of parses what I want. It only parses one single binary expression. I can't really figure out how to make it parse each expression separated by commas.
public MongoQueryGrammer()
        {
            var identifier = TerminalFactory.CreateCSharpIdentifier("identifier");
            var value = new DsvLiteral("value", TypeCode.String);
            var expression = new NonTerminal("expression");
            var binexpr = new NonTerminal("binexpr");
            var binoperator = new NonTerminal("binoperator");

            expression.Rule = binexpr;
            binexpr.Rule = identifier + binoperator + value;
            binoperator.Rule = ToTerm("$eq:") | "$lt:" | "$le:" | "$gt:" | "$ge:";
            Root = expression;
        }
Hope someone has a few hints that will get me started on this... or at least tell me that I am crazy, and this totally not a valid usecase for Irony.
May 2, 2014 at 10:37 PM
Ok, so parsing a list of expressions wasn't that hard. After googling a bit I found that MakePlusRule is what is needed:
        public MongoQueryGrammer()
        {

            var expressionList = new NonTerminal("expressionList");

            var identifier = TerminalFactory.CreateCSharpIdentifier("identifier");
            var value = new DsvLiteral("value", TypeCode.String);
            var expression = new NonTerminal("expression");
            var binexpr = new NonTerminal("binexpr");
            var binoperator = new NonTerminal("binoperator");

            expressionList.Rule = MakePlusRule(expressionList, null, expression);

            expression.Rule = binexpr;
            binexpr.Rule = identifier + binoperator + value;
            binoperator.Rule = ToTerm("$eq:") | "$lt:" | "$le:" | "$gt:" | "$ge:";
            Root = expressionList;
        }
Next up is how to actually translate this into a Linq Expression...
May 12, 2014 at 9:05 PM
Just an FYI.

MakePlusRule - 1 or more occurrence

MakeStarRule - 0 or more occurrence

The plus and star concepts are similar to regular expressions.

-MindCore