从ANTLR4解析器获取第一个并遵循元数据

时间:2013-10-30 18:17:24

标签: antlr3 antlr4

是否可以使用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'](请注意,我必须检索FIRST而不是规则句子的FOLLOW,因为基本规则的后续内容始终如一EOF)。

如果输入为“The”,则自动完成列表将为['small','orange','cat','dog']。

如果输入是“猫睡了,自动完成列表将['安静','吵闹','。']。

因此,ANTLR3提供了一种获取以下内容的方法:

BitSet followSet = state.following[state._fsp];

这很有效。我可以在我的解析器中嵌入一些逻辑,这样当解析器调用用户所在的规则时,它会检索该规则的以下内容,然后将它们提供给用户。但是,这对于嵌套规则也不起作用(例如,基本规则,因为跟随集忽略并且子规则如下所示)。

我认为如果用户已完成规则(这可能很难确定)以及覆盖所有有效选项的FOLLOW集,我需要提供FIRST集。我还认为我需要构建我的语法,这样两个令牌永远不会在规则级别后续。

我会将上述“firstSubject”规则划分为一些子规则......

firstSubject:
    'The'(adjective)? CAT | DOG;

firstSubject:
     the (adjective)?  CAT | DOG;
the:
     'the'; 

我还没有找到有关从规则中检索FIRST集的任何信息。

ANTLR4似乎在生成的解析器级别上大大改变了它的工作方式,所以此时我不确定是否应继续使用ANTLR3或跳转到ANTLR4。

任何建议都将不胜感激。

1 个答案:

答案 0 :(得分:6)

ANTLRWorks 2(AW2)执行类似的操作,我将在此处描述。如果您引用AW2的源代码,请记住它仅在LGPL许可下发布。

  1. 创建一个特殊标记,表示代码完成所需的位置。

    • 在某些方面,此令牌的行为与EOF相似。特别是,ParserATNSimulator 从不使用此令牌;决定始终在达成或达到之前作出决定。
    • 在其他方面,此令牌非常独特。特别是,如果令牌位于标识符或关键字处,则将其视为令牌类型为“模糊”,并允许匹配该语言的任何标识符或关键字。对于ANTLR 4语法,如果插入符号位于用户键入g的位置,则解析器将允许该标记与规则名称或关键字grammar匹配。
  2. 创建一个专门的ATN解释器,它可以返回所有可能导致插入符号的解析树,而无需查看插入符号的任何决定,也不会限制插入符号的确切令牌类型。

  3. 对于每个可能的解析树,在解析器规则中匹配的插入符号的上下文中评估您的代码完成。

  4. 步骤3中找到的所有结果的并集是完整有效代码完成结果集的超集,可以在IDE中显示。

  5. 以下描述了AW2对上述步骤的实现。

    1. 在AW2中,这是CaretToken,它始终具有令牌类型CARET_TOKEN_TYPE
    2. 在AW2中,此专用操作由ForestParser<TParser>接口表示,其中大部分可重用实现位于AbstractForestParser<TParser>,专门用于解析ANTLR 4语法以在GrammarForestParser中完成代码。< / LI>
    3. 在AW2中,此分析主要由GrammarCompletionQuery.TaskImpl.runImpl(BaseDocument)执行。