ANTLR4 не позволяет реализовать все указанные вами условия. В частности, условие, что правила могут появляться в любом порядке, но только один раз, является чем-то, что едва поддерживается любым синтаксическим анализатором.
Однако вы можете использовать двухэтапный подход. Во-первых, позвольте всем правилам появляться в любом порядке. Готово обычно так:
main: sub*;
sub: a | b | c;
После синтаксического анализа вы можете сделать еще один шаг (обычно у вас будет семантический шаг в любом случае, который также подходит и здесь) и проверить вхождения в сгенерированном дереве разбора. Затем вы можете выдать подробное сообщение об ошибке, сообщающее пользователю, что не разрешено (что сложно, если не невозможно, если вы попытаетесь сделать это в правилах синтаксического анализатора). Подход, изложенный @sprinter, тоже подойдет, но он не даст вам значимого сообщения об ошибке, а просто скажет, что у правила element
нет жизнеспособного alt (что может иметь много причин, а не только повторяющиеся правила).
И с этим вторым шагом вы можете легко применить любое дополнительное условие (особые приказы, правила, которые не должны сочетаться друг с другом и т. Д., Без необходимости изменять вашу грамматику), что вы не можете сделать на этапе разбора (поскольку вы не можете просматривать правила ).