I tried to create a simple language, which can evaluate if/else if/else statements and some arithmetic operations with predefined constans. The definition is the following:
grammar test; ifStatement : ifPart elseIfPart* elsePart ; ifPart : 'if (' logicalExpression ') then ' retVal=basicElement ; elseIfPart : ' else if (' logicalExpression ') then ' retVal=basicElement ; elsePart : ' else ' retVal=basicElement ; logicalExpression : logicalExpression ' and ' logicalExpression #andLogicalExpression |logicalExpression ' or ' logicalExpression #orLogicalExpression | compareExpression #compareLogicalExpression | '(' logicalExpression ')' #parensLogicalExpression ; compareExpression : basicElement '' basicElement #gt | basicElement '=' basicElement #eq ; basicElement : operation | atomicElement ; operation : operation op=('*'|'/') operation #mulDiv | operation op=('+'|'-') operation #addSub | atomicElement #atomic | '(' operation ')' #operationParens ; atomicElement : INT #decimal | 'resVal1' #reservedVariable | 'resVal2' #reservedVariable ; INT : [-]?[0-9]+('.'[0-9]+)? ; WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines
I generated a Visitor and a created a test sentence, which is the following:
if (3+3=6 or 12*3=37) then 10*10 else 4+1
It returns 5, which is wrong. After some debugging I saw that the visitOrLogicalExpression method is never called, instead of it the visitCompareLogicalExpression is called two times. What is wrong with my language definition?
Thank You in advance!
The language definition was ok. I could fix the mentioned problem by modifying the Visitor
class.
In the visitIfPart
and visitElseIfPart
methods (which process the subtrees of the if
and else if
nodes) I had to change the visitChildren(ctx.logicalExpression())
method to visitLogicalExpression(ctx.logicalExpression())
, thus my code was able to catch the compound logical expressions.