我正在尝试向文本编辑器添加代码完成功能。我认为我可以从 Antlr 获得非语义内容辅助提案。
此时,我有几个 ParserRuleContext。我想到达任何类型的 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];
并且我在编辑器上写了一句话:
类 CLAZZ {
公共(public)属性 SOMETHING :字符串;
}
当用户将光标移动到下面的索引并想要获得内容帮助时:
“公共(public)[光标]属性SOMETHING:字符串;
”
内容辅助应获得“最终”和“静态”限定符作为建议。
我使用Antlr解析器来解析这句话。然后我通过使用 Visitor 发现光标位于 ClassContext -> AttributeContext 中。
在visitAttributeContext方法中,我想获取AttributeContext的所有终端,例如[public、protected、private、static、final、unique]。然后我将根据光标位置消除除“static, Final”之外的其他限定符。
最后,我的问题是,如何从任何 ParserRuleContex 获取所有终端节点?或者还有其他办法吗?
注意:语法可能有错误,我是为了这道题发明的。请浏览一下。
最佳答案
“ContentAssist”(在术语“代码完成”下更广为人知)的实现是一项艰巨的任务,您可能必须深入研究 ANTLR 的内部类(至少是 atm)。您所要做的就是遍历由 ANTLR 为每个解析器和词法分析器类生成的 ATN。博客文章中描述了一种方法:Building autocompletion for an editor based on ANTLR 。 LL1Analyzer 使用类似的方法,它是 ANTLR 运行时中的一个类。
但是,两者都只能为您提供词法分析器标记(例如,所有关键字+其他关键字,例如 IDENTIFIER 或 DIGIT)。这意味着你不会得到例如变量引用等。
关于antlr - 获取 ParserRuleContext 的所有预期标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42088388/