Метод посетителя Antlr никогда не вызывается

Я попытался создать простой язык, который может оценивать операторы if / else if / else и некоторые арифметические операции с предопределенными константами. Определение следующее:

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

Я создал посетителя и создал тестовое предложение, которое выглядит следующим образом:

    if (3+3=6 or 12*3=37) then 10*10 else 4+1

Он возвращает 5, что неверно. После некоторой отладки я увидел, что метод visitOrLogicalExpression никогда не вызывается, вместо него дважды вызывается visitCompareLogicalExpression. Что не так с моим определением языка?

Заранее спасибо!


person László Halász    schedule 17.12.2014    source источник
comment
Неужели вы не получаете хотя бы предупреждений по грамматике? Ваше логическое выражение кажется неправильным (леворекурсивное без охранников).   -  person Gábor Bakos    schedule 17.12.2014
comment
Такие жетоны ' else if (' просто неправильны. Это должно быть 3 токена: 'else', 'if' и '('.   -  person Bart Kiers    schedule 17.12.2014
comment
@ GáborBakos Antlr4 позволяет использовать прямые леворекурсивные правила (левая рекурсия только в одном правиле).   -  person Mephy    schedule 17.12.2014
comment
@Mephy Cool. Я не знал об этом. Спасибо за исправление.   -  person Gábor Bakos    schedule 17.12.2014


Ответы (1)


Определение языка было в порядке. Я мог бы исправить упомянутую проблему, изменив класс Visitor.

В методах visitIfPart и visitElseIfPart (которые обрабатывают поддеревья узлов if и else if) мне пришлось изменить метод visitChildren(ctx.logicalExpression()) на visitLogicalExpression(ctx.logicalExpression()), поэтому мой код смог уловить составные логические выражения.

person László Halász    schedule 18.12.2014