错误的AST选择

时间:2016-04-28 14:38:44

标签: antlr antlr3

鉴于以下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 选中,而它应该被 UNKNOWN_KEYWORD 选中(即返回的AST是 ^(OPTION $ type?),而它应该是 ^(UNKNOWN))?

1 个答案:

答案 0 :(得分:2)

输入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
 ;

然后你最终得到以下解析树:

enter image description here

或此AST:

enter image description here

如果您想将所有UNKNOWN_KEYWORD令牌分组为1个替代品,则需要执行以下操作:

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

请注意,你的词法分析器中不能UNKNOWN_KEYWORD

UNKNOWN_KEYWORD : .+ ;

因为这会导致词法分析器将整个字符流吞噬到1个UNKNOWN_KEYWORD令牌中。