0

我是antlr的新手。我想编写一个语法来解析以下输入:

commit a1b2c3d4

语法如下::

grammar commit;

file : 'commit' COMMITHASH NEWLINE;

COMMITHASH : [a-z0-9]+;
DATE       : ~[\r\n]+;
NEWLINE    : '\r'?'\n';

当我尝试使用语法解析上述输入时,它会引发以下异常::

第 1:0 行不匹配的输入 'commit a1b2c3d4' 期望 'commit'

注意:我有意添加了 DATE 令牌。没有 DATE 令牌,它可以正常工作。但我想知道,添加 DATE 令牌时会发生什么。

我已经提到了链接Antlr4: Mismatched input但仍不清楚发生了什么。

4

1 回答 1

3

ANTLR 词法分析器在使用解析器之前完全分配明确的标记类型。当一个词法分析器规则可以匹配比另一个词法分析器规则更多的字符时,ANTLR 总是首选匹配更多字符的规则,而不管词法分析器规则在语法中出现的顺序如何。当两个或更多规则匹配完全相同长度的输入符号(并且没有其他规则匹配超过此数量的输入符号)时,将为语法中首先出现的规则分配一个标记类型。

您的词法分析器包含一个DATE匹配除换行符之外的所有字符的规则。由于这始终匹配一行的整个文本,并且您的任何标记都不跨越多行,因此结果如下:

  • 如果单行的整个文本都匹配commit,则将生成与此输入序列对应的未命名标记。
  • 如果单行的整个文本匹配[a-z0-9]+COMMITHASH将为该行的整个文本创建一个标记。DATE也匹配此输入,但COMMITHASH首先出现因此被使用。
  • 否则,如果单行包含至少一个字符,DATE则会为该行的整个文本创建一个标记。即使该行以commit或 a开头,也会使用COMMITHASH该规则,因为它匹配更长的字符序列。DATE
  • 最后,NEWLINE将为每个换行符创建一个令牌。

您需要执行以下操作之一来解决问题。确切的策略取决于您要解决的更大问题。

  • 删除DATE规则,或重写它以匹配更具体的日期格式。
  • 使用语义谓词和/或词法分析器模式来限制输入中DATE可能产生标记的位置。
于 2013-07-18T06:00:36.947 回答