Вы были близки, это будет работать:
expression1
@init{boolean or = false;}
: e=expression2 (BINOR {or=true;} expression2)* -> {or}? ^(BINOR expression2+)
-> $e
;
Но это предпочтительнее, так как он не использует какой-либо пользовательский код:
grammar T;
options {
output=AST;
}
expression1
: (e=expression2 -> $e) ((BINOR expression2)+ -> ^(BINOR expression2+))?
;
expression2
: NUMBER
;
NUMBER
: '0'..'9'+
;
BINOR
: '|'
;
Парсер, сгенерированный из приведенной выше грамматики, будет анализировать входные данные "3|1|2|6"
в AST:
и ввод "3"
в AST:
Но ваша оригинальная попытка:
expression1
: e=expression2 (BINOR^ e2=expression2)*
;
не создает плоское дерево (при условии, что у вас есть output=AST;
в ваших настройках). Он генерирует следующий AST для "3|1|2|6"
:
Если вы «видите» плоское дерево, я думаю, вы используете интерпретатор в ANTLRWorks, который показывает не AST, а дерево разбора вашего разбора. Интерпретатор также довольно глючит (не обрабатывает предикаты и не оценивает пользовательский код), поэтому лучше его не использовать. Вместо этого используйте отладчик ANTLRWorks, который работает как шарм (изображения из моего ответа взяты из отладчика)!