1

Trying to build a grammar that will parse simple bool expressions.
I am running into an issue when there are multiple expressions.
I need to be able to parse 1..n and/or'ed expressions.

Each example below is a complete expression:

  1. (myitem.isavailable("1234") or myitem.ispresent("1234")) and myitem.isready("1234")
  2. myitem.value > 4 and myitem.value < 10
  3. myitem.value = yes or myotheritem.value = no

Grammar:

@start = conditionalexpression* | expressiontypes;

conditionalexpression = condition expressiontypes;

expressiontypes = expression | functionexpression;

expression = itemname dot property condition value;

functionexpression = itemname dot functionproperty;

itemname = Word;

propertytypes = property | functionproperty;

property = Word;

functionproperty =  Word '(' value ')';

value = Word | QuotedString | Number;

condition = textcondition;

dot = '.';

textcondition = 'or' | 'and' | '<' | '>' | '=';
Regexident
  • 29,441
  • 10
  • 93
  • 100

1 Answers1

1

Developer of ParseKit here.

Here is a ParseKit grammar that matches your example input:

@start = expr;

expr = orExpr;

orExpr = andExpr orTerm*;
orTerm = 'or' andExpr;

  // 'and' should bind more tightly than 'or'
andExpr = relExpr andTerm*;
andTerm = 'and' relExpr;

  // relational expressions should bind more tightly than 'and'/'or'
relExpr = callExpr relTerm*;
relTerm = relOp callExpr;

  // func calls should bind more tightly than relational expressions
callExpr = primaryExpr ('(' argList ')')?;
argList = Empty | atom (',' atom)*;

primaryExpr     = atom | '(' expr ')';
atom            = obj | literal;

  // member access should bind most tightly
obj     = id member*;
member  = ('.' id);

id      = Word;
literal = Number | QuotedString | bool;
bool    = 'yes' | 'no';

relOp   = '<' | '>' | '=';

To give you an idea of how I arrived at this grammar:

  1. I realized that your language is a simple, composable expression langauge.
  2. I remembered that XPath 1.0 is also a relatively simple expression langauge with a easily available/readable grammar.
  3. I visited the XPath 1.0 spec online and quickly scanned the XPath basic language grammar. That served to provide a quick jumping-off point for desinging your language grammar. If you ignore the path expression part of XPath expressions, XPath is a very good template for a basic expression language.

My grammar above successfully parses all of your example inputs (see below). Hope this helps.

[foo, ., bar, (, "hello", ), or, (, bar, or, baz, >, bat, )]foo/./bar/(/"hello"/)/or/(/bar/or/baz/>/bat/)^
[myitem, ., value, >, 4, and, myitem, ., value, <, 10]myitem/./value/>/4/and/myitem/./value/</10^
[myitem, ., value, =, yes, or, myotheritem, ., value, =, no]myitem/./value/=/yes/or/myotheritem/./value/=/no^
Todd Ditchendorf
  • 11,217
  • 14
  • 69
  • 123
  • Being new to this I am missing something. I have the callbacks setup and as I output the assembly I see the pointer move through the list but when it reaches the end of the expression yet it still emits callbacks and the final call back is not the completed assembly. How do I detect when parsing has reached the end of the expression? – user2187880 Mar 21 '13 at 18:31
  • Developer of ParseKit here. I have answered this question previously here: http://stackoverflow.com/a/10046316/34934 – Todd Ditchendorf Mar 21 '13 at 18:53
  • Ignore above - I am getting varying results based on the expression be contained in parens. How do I make the need for outer most parens optional? – user2187880 Mar 21 '13 at 18:59
  • Gotcha!Thanks for the timely responses. – user2187880 Mar 21 '13 at 19:41