Получение всех ожидаемых токенов ParserRuleContext

Я пытаюсь добавить функцию завершения кода в текстовый редактор. Я думал, что могу получить от Antlr предложения по поддержке несемантического контента.

На данный момент у меня есть несколько ParserRuleContexts. Я хочу получить доступ ко всем терминальным узлам любого типа ParserRuleContext.

Например, у меня есть bnf, как показано ниже;

class
'class' name = IDENTIFIER '{' 
attribute*
'}'
;

attribute
( qualifier += 'public' 
| qualifier += 'protected' 
| qualifier += 'private')?
(qualifier += 'static')?
(qualifier += 'final')?
'attribute' name = IDENTIFIER ':' type = IDENTIFIER
('(' qualifier += 'unique' ')')?
;

IDENTIFIER : LETTER (LETTER|DIGIT)*;
LETTER : [a-zA-Z];
DIGIT : [0-9];

И у меня есть предложение, которое написано в редакторе:

class CLAZZ { public attribute SOMETHING : String; }

Когда пользователь наводит курсор на указатель ниже и хочет получить помощь по содержимому:

"public [cursor] attribute SOMETHING : String;"

Вспомогательный контент должен получить квалификаторы «final» и «static» в качестве предложения.

Я использовал парсер Antlr для разбора этого предложения. А потом я понял, что курсор находится в ClassContext -> AttributeContext с помощью Visitor.

В методе visitAttributeContext я хочу получить все терминалы AttributeContext, например [public, protected, private, static, final, unique]. Затем я уберу другие квалификаторы, кроме «static, final» в соответствии с позицией курсора.

В конце концов, мой вопрос: как я могу получить все конечные узлы из любого ParserRuleContex? Или есть другой способ?

Примечание. Грамматика может быть неправильной, я придумал этот вопрос. Пожалуйста, просто просмотрите это.


person Emre Kirmizi    schedule 07.02.2017    source источник


Ответы (1)


Реализация «ContentAssist» (более известная под термином «завершение кода») — нетривиальная задача, и вам, возможно, придется углубиться во внутренние классы ANTLR (по крайней мере, в атм). Что вам нужно сделать, так это пройтись по ATN, сгенерированному ANTLR для каждого из ваших классов парсера и лексера. Один из способов сделать это описан в сообщении блога: Построение автодополнения для редактора на основе ANTLR. Аналогичный подход используется LL1Analyzer, который является классом в среде выполнения ANTLR.

Однако оба могут дать вам только токены лексера (например, все ваши ключевые слова + другие, такие как IDENTIFIER или DIGIT). Это означает, что вы не получите, например. ссылки на переменные и тому подобное.

person Mike Lischke    schedule 08.02.2017
comment
Прежде всего, извините за поздний ответ. И спасибо за ваш ответ. Я изучил пример Томассетти, а также ваш. Согласно моим исследованиям, есть несколько способов сделать эту работу. Но кажется, что единственный общий способ — пройти через ATN. Пока я использую другой способ, но затем я буду использовать общий способ, который вы упомянули. Еще раз спасибо. С наилучшими пожеланиями. - person Emre Kirmizi; 04.03.2017
comment
Тем временем я опубликовал свой движок C3 (Code Completion Core), который может дать вам больше идей. - person Mike Lischke; 04.03.2017