错误的 AST 选择

Wrong AST selection

给定以下 ANTLR v3 语法:

tokens
{
   OPTION;
   UNKNOWN;
}

statement : my_statement
          | UNKNOWN_KEYWORD -> ^(UNKNOWN)
          ;

my_statement : FIRST SECOND type = THIRD? -> ^(OPTION $type?);


FIRST : 'my';

SECOND : 'keyword';

THIRD: 'best';

UNKNOWN_KEYWORD : .;

为什么当字符串 "my keyword this_is_garbage" 被解析时,它被 my_statement 提取,而它应该被 提取=15=]UNKNOWN_KEYWORD(即返回的 AST 是 ^(OPTION $type?) 而它应该是 ^ (未知))?

输入 my keyword this_is_garbage 将被标记如下(假设隐藏空格):

FIRST              'my'
SECOND             'keyword'
UNKNOWN_KEYWORD    't'
UNKNOWN_KEYWORD    'h'
...
UNKNOWN_KEYWORD    'e'

即,一个 FIRST 个令牌,一个 SECOND 个令牌,然后是 15 个 UNKNOWN_KEYWORD 个令牌。

如果您现在尝试匹配 statement,规则 my_statement 将很乐意消耗 FIRSTSECOND 标记,留下 15 个 UNKNOWN_KEYWORD 标记在令牌流中。

但是,如果您像这样重复匹配 statement 规则:

parse
 : statement+ EOF
 ;

那么您将得到以下解析树:

或这个 AST:

如果您想将所有 UNKNOWN_KEYWORD 个标记组合成 1 个备选方案,您需要执行以下操作:

statement : my_statement
          | UNKNOWN_KEYWORD+ -> ^(UNKNOWN)
          ;

请注意,您不能在您的词法分析器中对 UNKNOWN_KEYWORD 进行分组:

UNKNOWN_KEYWORD : .+ ;

因为这会导致词法分析器将整个字符流吞噬成 1 个 UNKNOWN_KEYWORD 标记。