Извлечение содержимого скрытого комментария, предшествующего определенному правилу или токену (Antlr, Java) - PullRequest
0 голосов
/ 17 сентября 2018

Я новичок в antlr и java, так что это может быть тривиальный вопрос (надеюсь!).Я использую antlr 3.4.У меня есть грамматика для лексера:

lexer grammar MyLexer;

options {
  language = Java;
}    
COMMENT:
    ( '//' ~('\n'|'\r')* '\r'? '\n'
    | '/*' .* '*/'
    ) {$channel=HIDDEN;};

WS: (' '
     | '\t'
     | '\r'
     | '\n'
     ) {$channel=HIDDEN;};
COLLECTION:    'collection';
BRACE_OPEN:    '{';
BRACE_CLOSE:   '}';

и еще одна для парсера:

parser grammar myParser;

options {
  language = Java;
  tokenVocab = myLexer;
}

collection_def
scope {
    MyCollection currentCollection;
}
@init {
    $collection_def::currentCollection = new MyCollection(); 
}
@after {

    // There should be a comment preceding this rule. How to get the content of that comment into the commentContent variable?
    $collection_def::currentCollection.setDescription(commentContent);

    ...
}
  : COLLECTION BRACE_OPEN
      ...

    BRACE_CLOSE;

Лексер отправляет комментарии на скрытый канал.Но я хочу, чтобы синтаксический анализатор извлек текст, содержащийся в комментарии, который предшествует определенному правилу (или определенному токену, поскольку токен COLLECTION появляется только в правиле выше).Например, я хочу, чтобы этот ввод:

/* Text describing the collection */
collection {
  item 1;
  item 2;
}

был проанализирован для объекта MyCollection с его переменной-членом описания, установленной в «Текст, описывающий коллекцию».

Как я могу это сделать?

1 Ответ

0 голосов
/ 17 сентября 2018

Поток токенов содержит все токены, в том числе и на скрытом канале.Каждый токен, который вы получаете из результата парсера (например, через tree.getToken(), если вы используете output = AST), знает свою позицию в потоке токенов (Token.getTokenIndex()).Это информация, которая вам нужна, чтобы найти и прочитать скрытые токены, предшествующие вашему токену.

Все, что вам остается сделать, - это доставить всю эту информацию туда, где вам нужно ее использовать.Один из возможных способов сделать это - получить список токенов (через CommonTokenStream.getTokens(), если вы используете CommonTokenStream между лексером и анализатором) и передать его любому методу, выполняющему обработку комментариев, или выполнить некоторую постобработкурезультат для добавления информации к нему.

...