Очевидно, что поддержка ANTLR4 для (прямой) левой рекурсии не работает, когда предикат появляется перед вызовом леворекурсивного правила. Таким образом, вы можете исправить ошибку, переместив предикат после первого boolExpression
в леворекурсивных альтернативах.
Тем не менее, кажется, что предикаты на самом деле не нужны в первую очередь - по крайней мере, не в том примере, который вы нам показали (или в том, что перед вашим редактированием, насколько я могу судить). Поскольку boolExpression
с типом ограничения INIT
, по-видимому, может соответствовать только boolLiteral
, вы можете просто изменить initDefinition
следующим образом:
initDefinition : t=INIT ':' boolLiteral ;
Тогда boolExpression
всегда будет иметь тип ограничения DERIVE
, и предикаты больше не нужны.
Как правило, если вы хотите разрешить разные альтернативы в нетерминальном x
в зависимости от того, был ли он вызван y
или z
, вам просто нужно иметь несколько версий x
, а затем вызвать одну из y
и другой от z
. Обычно это намного меньше хлопот, чем засорение кода действиями и предикатами.
Точно так же может иметь смысл иметь правило, которое соответствует больше, чем должно, а затем обнаруживать недопустимые выражения на более позднем этапе, вместо того, чтобы пытаться отклонить их на уровне синтаксиса. В частности, новички часто пытаются написать грамматики, которые допускают только хорошо типизированные выражения (отклоняя что-то вроде 1+true
с синтаксической ошибкой) и которые никогда не сработают.