ANTLR:标记被识别为规则,而不是类型

时间:2021-07-23 08:12:11

标签: antlr antlr4

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

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

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

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

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

我如何在这里进行?

1 个答案:

答案 0 :(得分:1)

当您在解析器规则中添加文字 '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;