试图理解为什么“输入不匹配”ANTLR 错误中的预期标记不包含某些标记

问题描述 投票:0回答:1

刚开始玩 ANTLR 并试图理解我在尝试解析错误输入时收到的错误消息。 这是我的(简单的)语法:

grammar Playground;

stmtList: (expr EOS)+;
expr:
IDENTIFIER ('!' | '^') IDENTIFIER
| expr ('*' | '/') expr
| expr ('+' | '-') expr
| INT
| IDENTIFIER;

MAKE: 'make';
INT: '0' | [1-9] [0-9]*;
IDENTIFIER: [a-zA-Z0-9]+;
EQUAL: '='; // Dummy token that can be recognised
EOS: '\r'? '\n';
WS: [ \t\n\r]+ -> skip;

这是我要解析的文本:

blah=blah

再一次,我知道这段文字与定义的语法不匹配。我得到的错误如下:

第 1:4 行不匹配的输入 '=' 期望 {'*', '/', '+', '-', EOS}

我的问题是——为什么 ANTLR 推荐的预期标记集不包括像 '!' 和 '^' 这样的标记,它们也在 expr 规则的第一个替代项中定义?我觉得我在这里缺少一些基本知识。任何帮助表示赞赏!

我的期望是看到如下所示的错误消息:

第 1:4 行不匹配的输入 '=' 期望 {'!', '^', '*', '/', '+', '-', EOS}

'!' 和 '^' 标记包含在预期的标记集中。

我正在阅读 The Definitive ANTLR 4 Reference,我也尝试使用 ANTLR 的 TestRig 生成令牌。

grun Playground stmtList -tokens
上运行
blah=blah
给我以下输出:

[@0,0:3='blah',<IDENTIFIER>,1:0]
[@1,4:4='=',<'='>,1:4]
[@2,5:8='blah',<IDENTIFIER>,1:5]
[@3,9:9='\n',<EOS>,1:9]
[@4,10:9='<EOF>',<EOF>,2:0]

ANTLR 版本:4.11.1

antlr antlr4
1个回答
0
投票

这是因为您的

IDENTIFIER
规则中有两个以
expr
开头的选项。因此它们都可以与您的第一个标识符匹配。这就是实际发生的事情。第一个
blah
匹配为
IDENTIFIER
并且解析器尝试
expr
中的第一个 alt。这失败了,因为下一个标记是
EQUAL
,所以它尝试下一个以左递归
expr
规则开始的 alt 并再次进行相同的尝试。
expr
匹配
IDENTIFIER
因为你的最后一个 alt,所以下一步是匹配运算符,但都失败了。最后你得到了 2 个左递归 alts 的预期标记,因为它们的第一部分匹配:

如果您删除

expr
规则中的最后一个替代项,结果如您所料:

因为现在没有

expr
与单个
IDENTIFIER
的匹配,所以第一个alt就是用来报错的。

© www.soinside.com 2019 - 2024. All rights reserved.