ANTLR 4.5 - 不匹配的输入 'x' 期望 'x'
ANTLR 4.5 - Mismatched Input 'x' expecting 'x'
我已经开始使用 ANTLR 并注意到它的词法分析器规则变化无常。一个极其令人沮丧的例子如下:
grammar output;
test: FILEPATH NEWLINE TITLE ;
FILEPATH: ('A'..'Z'|'a'..'z'|'0'..'9'|':'|'\'|'/'|' '|'-'|'_'|'.')+ ;
NEWLINE: '\r'? '\n' ;
TITLE: ('A'..'Z'|'a'..'z'|' ')+ ;
此语法不会匹配如下内容:
c:\test.txt
x
奇怪的是,如果我将 TITLE
更改为 TITLE: 'x' ;
,这次它仍然会失败,并显示一条错误消息 "mismatched input 'x' expecting 'x'",这非常令人困惑。更奇怪的是,如果我用 FILEPATH
替换 test
中 TITLE
的用法,整个事情就可以了(尽管 FILEPATH
会比我希望匹配的更多,所以一般来说对我来说不是有效的解决方案)。
我非常困惑为什么 ANTLR 会给出如此极其奇怪的错误,然后在随机播放时突然无缘无故地工作。
这似乎是对ANTLR
的普遍误解:
ANTLR 中的语言处理:
语言处理分两个严格分开的阶段完成:
- Lexing,即将文本划分为标记
- 解析,即从标记构建解析树
因为词法分析必须先于解析,所以有一个结果:词法分析器独立于解析器,解析器不能影响词法分析。
乐兴
ANTLR 中的 Lexing 工作方式如下:
- 所有首字母大写的规则都是词法分析器规则
- 词法分析器从头开始并尝试找到与当前输入最匹配的规则
- 最佳匹配是具有最大长度的匹配,即,将下一个输入字符附加到最大长度匹配所产生的标记不与任何词法分析器规则相匹配
- 令牌是从匹配中生成的:
- 如果一个规则匹配最大长度匹配相应的令牌被推入令牌流
- 如果多个规则匹配最大长度匹配语法中第一个定义的标记被推送到标记流
例子:你的语法有什么问题
你的语法有两条关键规则:
FILEPATH: ('A'..'Z'|'a'..'z'|'0'..'9'|':'|'\'|'/'|' '|'-'|'_'|'.')+ ;
TITLE: ('A'..'Z'|'a'..'z'|' ')+ ;
与 TITLE 匹配的每个匹配项也将与 FILEPATH 匹配。并且 FILEPATH 在 TITLE 之前定义:因此您希望成为标题的每个标记都将是一个 FILEPATH。
有两个提示:
- 保持你的词法分析器规则分离(没有标记应该匹配另一个的超集)。
- 如果您的标记有意匹配相同的字符串,则将它们按正确的顺序排列(在您的情况下这就足够了)。
- 如果你需要一个解析器驱动的词法分析器,你必须换成另一个解析器生成器:PEG-Parsers 或 GLR-Parsers 会这样做(当然这会产生其他问题)。
这不是 OP 的直接问题,但对于那些有相同错误消息的人,您可以检查一下。
我在引入新关键字时收到了相同的 Mismatched Input 'x' expecting 'x'
模糊错误消息。对我来说,原因是我在 VARNAME
词法分析器规则之后放置了 new 关键字,该规则将其指定为变量名而不是 new 关键字。我通过将关键字放在 VARNAME
规则之前来修复它。