鉴于以下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))?
答案 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
会很乐意使用FIRST
和SECOND
令牌,而将15 UNKNOWN_KEYWORD
个令牌留在令牌流。
但是,如果您反复匹配statement
规则,请执行以下操作:
parse
: statement+ EOF
;
然后你最终得到以下解析树:
或此AST:
如果您想将所有UNKNOWN_KEYWORD
令牌分组为1个替代品,则需要执行以下操作:
statement : my_statement
| UNKNOWN_KEYWORD+ -> ^(UNKNOWN)
;
请注意,你的词法分析器中不能组UNKNOWN_KEYWORD
:
UNKNOWN_KEYWORD : .+ ;
因为这会导致词法分析器将整个字符流吞噬到1个UNKNOWN_KEYWORD
令牌中。