Reputation: 1389
I have the following grammar:
bRules: bRule ( NL bRule )*;
bRule: IF WS lhs WS THEN WS rhs;
lhs: condition (WS AND WS condition)*;
rhs: result (WS AND WS result)*;
condition: parameter WS operator WS value ;
result: parameter WS EQ WS value ;
parameter: STRING;
value: STRING;
IF: 'if';
THEN: 'then';
AND: '&';
NL : [\n\r]*;
WS: [ ]*;
operator: GT|LT|GE|LE|EQ;
GT: '>';
LT: '<';
GE: '>=';
LE: '<=';
EQ: '=';
STRING: [0-9a-zA-Z]+;
My goal is to have rules that look like this:
IF age < 2 THEN status = baby
...
It works mostly, but what doesnt work is that I can use the equals operator '=' on the condition side like this:
IF age = 2 THEN status = baby
Then I get an error message that the operatortype is not supported.
I tried some different things but cannot get it working. Any ideas or suggestions on how to improve my grammar?
Upvotes: 1
Views: 429
Reputation: 170138
Note that you say your input is IF ...
, yet your lexer only handles lower case if
. And there are 2 lexer rules that match zero characters, which is wrong.
Change:
NL : [\n\r]*;
WS: [ ]*;
into:
NL : [\n\r]+;
WS: [ ]+;
Besides that, I cannot reproduce what you describe. When I parse if age = 2 then status = baby
using the grammar you posted, I get the following parse tree:
Also, isn't it more convenient to simply skip
the white spaces instead of littering them all over your parser rules? Something like this instead:
bRules: bRule (NL bRule )* EOF;
bRule: IF lhs THEN rhs;
lhs: condition (AND condition)*;
rhs: result (AND result)*;
condition: parameter operator value ;
result: parameter EQ value ;
...
WS: [ \t]+ -> skip;
Upvotes: 2