Как создать токен в ANTLR4?

#java #antlr #antlr4

#java #antlr #antlr4

Вопрос:

Это мой grammar.g4 :

 FOO: 'x';
BAR: 'y'
  { /* here! */ };
  

Я хочу, чтобы токены BAR и FOO выдавались, когда входные данные содержат y . Что я должен написать в here! части? Пожалуйста, не предлагайте переписывать грамматику, это всего лишь тестовый образец, мой реальный случай намного сложнее.

Комментарии:

1. Когда вопросы слишком упрощены, я часто заканчиваю тем, что отвечаю на проблему X-Y ( en.wikipedia.org/wiki/XY_problem ). Не могли бы вы объяснить свой реальный случай и привести реальные примеры?

2. @BartKiers посмотрите, как токены генерируются в NEWLINE правиле здесь . Мне нужен аналогичный механизм, но в очень простой форме.

3. Да, я знаю, как это сделать. Я даже написал тот код, на который вы ссылались ;). Я просто хотел увидеть реальный пример использования из вашей реальной грамматики.

4. @BartKiers это маленький мир 🙂 Не могли бы вы привести мне пример приведенного выше кода, пожалуйста? Используя его, я смогу сделать то же самое в своем собственном коде (и многих других пользователей тоже!)

Ответ №1:

Вот краткая демонстрация:

 grammar T;

@lexer::members {
  private java.util.LinkedList<Token> tokens = new java.util.LinkedList<>();

  @Override
  public Token nextToken() {
    return tokens.isEmpty() ? super.nextToken() : tokens.poll();
  }
}

parse
 : foo bar foo EOF
 ;

foo : FOO;
bar : BAR;

FOO : 'x';
BAR : 'y' {this.tokens.offer(new CommonToken(TLexer.FOO, "x"));};

SPACES : [ trn] -> skip;
  

Тест с:

 TLexer lexer = new TLexer(CharStreams.fromString("x y"));
TParser parser = new TParser(new CommonTokenStream(lexer));

System.out.println(parser.parse().toStringTree(parser));
  

который будет печатать:

 (parse (foo x) (bar y) (foo x) <EOF>)