2017-02-07 18 views
1

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

На данный момент у меня есть несколько 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? Или есть другой способ?

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

ответ

0

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

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

+0

Прежде всего, извините за поздний ответ. И спасибо за ваш ответ. Я рассмотрел пример [Tomassetti's] (https://tomassetti.me/autocompletion-editor-antlr/), а также [ваш] (http://www.soft-gems.net/index.php/tools/47- универсальный код завершение, используя-ANTLR). Согласно моим исследованиям, есть несколько способов сделать эту работу. Но, похоже, единственный общий способ - пройти через ATN. В настоящее время я использую другой способ, но потом я буду использовать общий способ, о котором вы говорили. Еще раз спасибо. С наилучшими пожеланиями. –

+0

Тем временем я опубликовал модем [C3 (Code Completion Core)] (https://www.npmjs.com/package/antlr4-c3), который может дать вам больше идей. –