Antlr解析器歧义文字

Antlr parser ambiguous literal

我有这样的语法:

grammar a;
rule : cccc direction;
cccc: Char Char Char Char;
direction: Digit Digit Digit 'V' Digit Digit Digit;

Char : [A-Z];
Digit: [0-9];
WS: [ \t\n\r=] ->skip;

我想要解析器字符串“AVBC 120V230”,但我得到了提示:

line 1:1 extraneous input 'V' expecting Char
line 1:5 missing Char at '1'

我该怎么办?谢谢。

当在解析器规则中使用文字标记时('V' 在你的情况下),ANTLR 会像这样处理完整的语法:

grammar a;
rule : cccc direction;
cccc: Char Char Char Char;
direction: Digit Digit Digit T__0 Digit Digit Digit;

T__0 : 'V';
Char : [A-Z];
Digit: [0-9];
WS: [ \t\n\r] ->skip; // you included the `=` here: I assumed it was a typo

并且 ANTLR 将始终为输入 V 创建一个 T__0。这意味着 V 永远不会被标记为 Char 标记。如果您希望 V 也成为 Char,您需要在解析器规则中移动它:

grammar a;
rule : cccc direction;
cccc: ch ch ch ch;
direction: Digit Digit Digit V Digit Digit Digit;
ch : V | Char;

V : 'V';
Char : [A-Z];
Digit: [0-9];
WS: [ \t\n\r] ->skip;

并且您的输入 AVBC 120V230 已正确解析:

请注意,我不知道您的语言是什么样的,但是让词法分析器只标记单个 bytes/chars 并将它们粘合在解析器规则中似乎有点奇怪。虽然这是可能的,但在 ANTLR 中,您通常会定义更多内容的标记。从你的例子中,我会说定义一个 IdentifierDirection 标记更合适:

rule : cccc direction;
cccc: Identifier;
direction: Direction;

Identifier : [A-Z]+;
Direction : [0-9] [0-9] [0-9] 'V' [0-9] [0-9] [0-9];
WS: [ \t\n\r] ->skip;