3

是否可以使用 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']。

如果输入是“猫睡着了,那么自动完成列表将是 ['quietly', 'noisily', '.']。

所以 ANTLR3 提供了一种方法来获得以下集合:

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

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

如果用户已经完成了一条规则(这可能很难确定),我认为我需要提供 FIRST 集以及 FOLLOW 集以涵盖所有有效选项。我还认为我需要构造我的语法,以便在规则级别上永远不会出现两个标记。

我会把上面的“firstSubject”规则分解成一些子规则......

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

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

我还没有找到任何有关从规则中检索第一组的信息。

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

任何建议将不胜感激。

4

1 回答 1

6

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

  1. 创建一个特殊的令牌,它代表代码完成感兴趣的位置。

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

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

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

下面介绍AW2对上述步骤的实现。

  1. 在 AW2 中,这是CaretToken,并且它始终具有标记类型CARET_TOKEN_TYPE
  2. 在 AW2 中,这种专门的操作由ForestParser<TParser>接口表示,大部分可重用实现AbstractForestParser<TParser>GrammarForestParser.
  3. 在 AW2 中,此分析主要由GrammarCompletionQuery.TaskImpl.runImpl(BaseDocument).
于 2013-10-30T19:39:42.703 回答