ANTLR 4.5 - 不匹配的输入'x'期待'x'

Chi*_*ara 31 antlr antlr4

我已经开始使用ANTLR,并注意到它的词法分析规则相当变幻无常.一个非常令人沮丧的例子如下:

grammar output;

test: FILEPATH NEWLINE TITLE ;

FILEPATH: ('A'..'Z'|'a'..'z'|'0'..'9'|':'|'\\'|'/'|' '|'-'|'_'|'.')+ ;
NEWLINE: '\r'? '\n' ;
TITLE: ('A'..'Z'|'a'..'z'|' ')+ ;
Run Code Online (Sandbox Code Playgroud)

这个语法不匹配:

c:\ test.txt
x

奇怪的是,如果我改变TITLETITLE: 'x' ;它仍然失败,这次给出一个错误消息说"不匹配的输入'x'期待'x'"这是非常混乱.更奇怪的是,如果我替换的使用TITLEtestFILEPATH整个事情的作品(虽然FILEPATH将匹配多于我期待相符所以总的来说这是对我并没有有效的解决方案).

我非常困惑为什么ANTLR会给出如此极其奇怪的错误,然后突然出现问题时,没有明显的原因.

Cor*_*onA 56

这似乎是一个常见的误解ANTLR:

ANTLR中的语言处理:

语言处理分为两个严格分开的阶段:

  • Lexing,即将文本分区为标记
  • 解析,即从标记构建解析树

由于lexing必须先解析,因此有一个结果:词法分析器独立于解析器,解析器不能影响lexing.

乐星

在ANTLR中的Lexing工作原理如下:

  • 所有带有大写第一个字符的规则都是词法规则
  • 词法分析器从头开始,并尝试查找与当前输入最匹配的规则
  • 最佳匹配是具有最大长度匹配,即通过将下一个输入字符附加到最大长度匹配而得到的令牌与任何词法分析器规则不匹配
  • 令牌由匹配生成:
    • 如果一个规则匹配最大长度匹配,则相应的令牌被推入令牌流
    • 如果多个规则匹配最大长度匹配,则语法的第一个定义的标记被推送到标记流

示例:您的语法有什么问题

你的语法有两个关键的规则:

FILEPATH: ('A'..'Z'|'a'..'z'|'0'..'9'|':'|'\\'|'/'|' '|'-'|'_'|'.')+ ;
TITLE: ('A'..'Z'|'a'..'z'|' ')+ ;
Run Code Online (Sandbox Code Playgroud)

与TITLE匹配的每个匹配也将与FILEPATH匹配.并且在TITLE之前定义了FILEPATH:因此,您希望成为标题的每个标记都是FILEPATH.

有两个提示:

  • 保持你的词法分析器规则不相符(没有令牌应该匹配另一个的超集).
  • 如果您的令牌故意匹配相同的字符串,那么将它们按正确的顺序排列(在您的情况下这将是足够的).
  • 如果你需要一个解析器驱动的词法分析器,你必须改为另一个解析器生成器:PEG-Parsers或GLR-Parsers会这样做(但当然这会产生其他问题).

  • 现在这很有道理,感谢您的回复!尽管有一个更有用的错误信息会很好,但我知道这可能很难或不合理. (6认同)
  • 来自ANTLR参考的精彩摘要! (2认同)

Blu*_*ber 5

这不是 OP 的直接问题,但对于那些有相同错误消息的人,您可以检查以下内容。


Mismatched Input 'x' expecting 'x'当我引入一个新关键字时,我收到了同样模糊的错误消息。我的原因是我将新关键字放在我的VARNAME词法分析器规则之后,该规则将其指定为变量名而不是新关键字。我通过将关键字放在VARNAME规则之前来修复它。