Динамический приоритет операторов и ассоциативность в ANTLR4?
Я работал над грамматикой antlr4 для нотации Z (версия ISO UTF), и спецификация требует фазы lex, а затем "двухфазного" анализа. сначала вы помещаете его в набор токенов NAME (или DECORWORD), а затем анализируете полученные токены по правилам operatorTemplate в грамматике синтаксического анализатора спецификации, заменяете соответствующие токены, а затем, наконец, анализируете новый измененный поток токенов, чтобы получить AST.
у меня выше работает, но я не могу понять, как динамически установить приоритет и ассоциативность правил синтаксического анализатора, поэтому деревья синтаксического анализа неверны.
синтаксис оператора выглядит следующим образом (числа имеют приоритет):
-generic 5 rightassoc (_ → _)
-function 65 rightassoc (_ ◁ _)
я не вижу API для установки ассоциативности на правило, поэтому я попытался с семантическими предикатами, что-то вроде:
expression:
: {ZSupport.isLeftAssociative()}? expression I expression
| <assoc=right> expression i expression
;
или же
expression:
: {ZSupport.isLeftAssociative()}? expression i expression
| <assoc=right> {ZSupport.isRightAssociative()}? expression I expression
;
но потом я получаю "Следующие наборы правил взаимно леворекурсивны [выражение]"
это можно сделать?
1 ответ
Я смог сделать это, переместив семантический предикат:
expression:
: expression {ZSupport.isLeftAssociative()}? I expression
| <assoc=right> expression I expression
;
У меня сложилось впечатление, что это не сработает, основываясь на этом обсуждении: /questions/27199783/semanticheskie-predikatyi-antlr4-zavisyaschie-ot-konteksta-ne-rabotayut/27199784#27199784
... но, похоже, он работает правильно во всех моих тестовых случаях...