ANTLR:令牌被识别为规则,而不是类型

ANTLR: token recognized as rule, instead of type

我有以下非常简单的 ANTLR 语法:

SPACE                    : [ ]+ -> skip;
NUMBER                   : ('0'..'9')+;

event                    : '1' '|' identifier EOF;
identifier               : NUMBER;

想法是解析格式为 1 | <number> 的所有输入。

这适用于例如输入 1 | 50。但是 1 | 1 失败了。我相信我明白发生了什么:第二个 1 被识别为规则 event 而不是规则 identifier,但我不确定如何解决这个问题。

我该如何继续?

当您在解析器规则中添加文字 '1' 时,ANTLR 将隐式为此创建词法分析器规则。所以规则:

event                    : '1' '|' identifier EOF;
NUMBER                   : ('0'..'9')+;

真的是这样的:

event                    : T_0 T_1 identifier EOF;
T_0                      : '1';
T_1                      : '|';
NUMBER                   : ('0'..'9')+;

并且 ANTLR 的词法分析器将始终以下列方式创建标记:

  1. 尝试为每个词法分析器规则匹配尽可能多的字符
  2. 只要有 2 个或更多词法分析器规则匹配相同的字符,就让第一个定义的“赢”

因此,对于输入 1,令牌 T_0 将始终被创建(第 2 点适用)。对于输入 11,令牌 NUMBER 将始终被创建(第 1 点适用)。

换句话说:输入 1 永远不会变成 NUMBER 标记。如果需要,请执行以下操作:

SPACE                    : [ ]+ -> skip;
ONE                      : '1';
NUMBER                   : ('0'..'9')+;

event                    : ONE '|' identifier EOF;
identifier               : number;
number                   : ONE | NUMBER;