是否可以使用 ANTLR4 从规则中提取第一个和后续集合?我在 ANTLR3 中对此进行了一些尝试,但没有找到令人满意的解决方案,但如果有人有任一版本的信息,将不胜感激。
我想解析用户输入的用户光标位置,然后提供自动完成的可能选项列表。目前,我对部分输入的自动完成令牌不感兴趣。我想在解析过程中的某个时候显示所有可能的以下标记。
例如:
sentence:
subjects verb (adverb)? '.' ;
subjects:
firstSubject (otherSubjects)* ;
firstSubject:
'The' (adjective)? noun ;
otherSubjects:
'and the' (adjective)? noun;
adjective:
'small' | 'orange' ;
noun:
CAT | DOG ;
verb:
'slept' | 'ate' | 'walked' ;
adverb:
'quietly' | 'noisily' ;
CAT : 'cat';
DOG : 'dog';
鉴于上面的语法...
如果用户尚未键入任何内容,则自动完成列表将是['The'](请注意,我必须检索规则句子的第一个而不是FOLLOW,因为基本规则的跟随始终是EOF)。
如果输入为"The",则自动完成列表将为 ["小"、"橙色"、"猫"、"狗"]。
如果输入是"猫睡了,则自动完成列表将为['安静','吵闹','。
因此,ANTLR3 提供了一种方法来获取以下一组
:BitSet followSet = state.following[state._fsp];
这很好用。我可以在我的解析器中嵌入一些逻辑,以便当解析器调用用户所在的规则时,它会检索该规则的以下内容,然后将它们提供给用户。但是,这不适用于嵌套规则(例如,基本规则,因为跟随集忽略而子规则跟随,这是应该的)。
如果用户完成了规则(这可能很难确定),我想我需要提供第一个集以及涵盖所有有效选项的 FOLLOW 集。我还认为我需要构建我的语法,以便在规则级别上永远不会有两个标记。
我会将上述"第一主题"规则分解为一些子规则......
从
firstSubject:
'The'(adjective)? CAT | DOG;
自
firstSubject:
the (adjective)? CAT | DOG;
the:
'the';
我还没有找到任何关于从规则中检索第一个集的信息。
ANTLR4 似乎在生成的解析器级别上彻底改变了它与 FOLLOW 一起工作的方式,所以在这一点上,我不确定我是否应该继续使用 ANTLR3 或跳转到 ANTLR4。
任何建议将不胜感激。
ANTLRWorks 2 (AW2) 执行类似的操作,我将在这里描述。如果您引用 AW2 的源代码,请记住它仅在 LGPL 许可证下发布。
-
创建一个特殊令牌,该令牌表示代码完成的感兴趣位置。
- 在某些方面,此令牌的行为类似于
EOF
。特别是,ParserATNSimulator
从不使用此令牌;决策总是在达成时或之前做出的。 - 在其他方面,这个令牌是非常独特的。特别是,如果令牌位于标识符或关键字处,则将其视为令牌类型为"模糊",并允许匹配该语言的任何标识符或关键字。对于 ANTLR 4 语法,如果插入符号标记位于用户键入
g
的位置,则解析器将允许该标记与规则名称或关键字grammar
匹配。
- 在某些方面,此令牌的行为类似于
-
创建一个专门的 ATN 解释器,该解释器可以返回导致插入符号令牌的所有可能的解析树,而无需查看插入符号以获取任何决策,也不会限制插入符号令牌的确切令牌类型。
-
对于每个可能的分析树,请在分析器规则中匹配的任何插入符号标记的上下文中评估代码完成情况。
-
步骤 3 中找到的所有结果的并集是完整有效代码完成结果集的超集,可以在 IDE 中呈现。
下面介绍了AW2对上述步骤的实现。
- 在AW2中,这是
CaretToken
,并且它始终具有令牌类型CARET_TOKEN_TYPE
。 - 在AW2中,这种专门的操作由
ForestParser<TParser>
接口表示,大多数可重用的实现都是AbstractForestParser<TParser>
的,专门用于解析ANTLR 4语法以在GrammarForestParser
中完成代码。 - 在AW2中,此分析主要由
GrammarCompletionQuery.TaskImpl.runImpl(BaseDocument)
执行。