Добавить альтернативу грамматическому правилу antlr2 для группы, которая является необязательной частью ряда правил более высокого уровня
Я смотрю на добавление альтернатив / восстановления парсера к грамматике языка Groovy: https://github.com/apache/groovy/blob/master/src/main/antlr2/org/codehaus/groovy/antlr/groovy.g
Как я могу добавить альтернативу annotationMemberValuePairs, которая не заставляет парсер выходить из правил более высокого уровня, где аннотации являются необязательными?
Я хочу иметь возможность поддерживать неполные аннотации, подобные этим, для целей поддержки контента (завершение кода):
@
@Tag(a)
@Tag(a=)
@Tag(a=v,)
Я сделал модификации, которые поддерживают все, кроме последнего. Но завершающая запятая дает мне припадки, потому что аннотации необязательны перед кучей правил более высокого уровня, таких как оператор пакета, оператор импорта, объявления типов, объявления методов и т. Д.
annotation! {Token first = LT(1);}
: AT! i:identifier nls! ( LPAREN! ( args:annotationArguments )? RPAREN! )?
{#annotation = #(create(ANNOTATION,"ANNOTATION",first,LT(1)),i,args);}
// GRECLIPSE add -- allow freestanding '@' for content assist
| AT! nls!
{#annotation = #(create(ANNOTATION,"ANNOTATION",first,LT(1)),missingIdentifier(first,LT(1)),null);}
// GRECLIPSE end
;
annotationsInternal
: (
options{generateAmbigWarnings=false;}:
{break; /* go out of the ()* loop*/}
AT "interface"
|
annotation nls!
)*
;
annotationsOpt {Token first = LT(1);}
: (
// See comment above on hushing warnings.
options{generateAmbigWarnings=false;}:
annotationsInternal
)?
{#annotationsOpt = #(create(ANNOTATIONS,"ANNOTATIONS",first,LT(1)),#annotationsOpt);}
;
annotationArguments
: v:annotationMemberValueInitializer
{Token itkn = new Token(IDENT,"value"); AST i; #i = #(create(IDENT,"value",itkn,itkn));
#annotationArguments = #(create(ANNOTATION_MEMBER_VALUE_PAIR,"ANNOTATION_MEMBER_VALUE_PAIR",LT(1),LT(1)),i,v);}
| annotationMemberValuePairs
;
annotationMemberValuePairs
: annotationMemberValuePair ( COMMA! nls! annotationMemberValuePair )*
;
annotationMemberValuePair! {Token first = LT(1);}
: i:annotationIdent ( ASSIGN! nls! ( v:annotationMemberValueInitializer )? )?
{#annotationMemberValuePair = #(create(ANNOTATION_MEMBER_VALUE_PAIR,"ANNOTATION_MEMBER_VALUE_PAIR",first,LT(1)),i,v);}
;
annotationIdent
: IDENT
| keywordPropertyNames
;
annotationMemberValueInitializer
: conditionalExpression[0] | annotation
;
Поэтому, когда я добавляю альтернативу annotationMemberValuePairs следующим образом:
: annotationMemberValuePair ( COMMA! nls! ( annotationMemberValuePair | RPAREN! {rewind(mark()-1);}) )*
Альтернатива работает только для объявлений типов, которые находятся внизу стека возможностей, все из которых имеют необязательные аннотации в ведущей позиции.