sveri
sveri

Reputation: 1389

antlr4 equals / assignment ambiguity

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

Answers (1)

Bart Kiers
Bart Kiers

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:

enter image description here

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

Related Questions