#java #antlr #antlr4
#java #antlr #antlr4
Вопрос:
Я указал следующую грамматику ANTLR:
expression: ...
| extractor=EXTRACTOR '(' setElementDefinition ',' expression ')' #setExtractorExp
| ... ;
EXTRACTOR: 'select'
| 'choose' ;
Я хотел бы знать, с каким типом извлечения я имею дело при разборе этого выражения.
Один из способов сделать это — сравнить поле extractor со строкой, содержащей тип extractor, например:
@Override
public Expression visitSetExtractorExp(MyParser.SetExtractorExpContext ctx) {
if(ctx.extractor.getText().equals("select")) { ... }
}
Но мне не нравится дублировать имена экстракторов здесь, на случай, если я решу изменить имена экстракторов позже.
Итак, есть ли способ получить доступ к токенам лексера?
Я представляю себе что-то вроде if(ctx.extractor == MyLexer.EXTRACTOR.choose)
.
Ответ №1:
Прямо сейчас у вас EXTRACTOR
есть только один тип, что делает "select"
и "choose"
почти то же самое. Единственный способ провести различие — это сравнение строк, как вы уже делаете. Если вы этого не хотите, сделайте что-то вроде этого:
expression
: ...
| extractor '(' setElementDefinition ',' expression ')' #setExtractorExp
| ...
;
extractor
: SELECT
| CHOOSE
;
SELECT : 'select';
CHOOSE : 'choose';
и в вашем посетителе:
@Override
public Expression visitSetExtractorExp(MyParser.SetExtractorExpContext ctx) {
if(ctx.extractor().start.getType() == MyLexer.SELECT) { ... }
else if(ctx.extractor().start.getType() == MyLexer.CHOOSE) { ... }
}
Таким образом, вам не нужно дублировать (волшебные) строки.