ANTLR4:输入不匹配

时间:2013-07-18 05:31:44

标签: antlr4

我是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,但我还不清楚发生了什么。

1 个答案:

答案 0 :(得分:2)

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

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

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

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

  • 删除DATE规则,或重写该规则以匹配更具体的日期格式。
  • 使用语义谓词和/或词法分析器模式来限制输入中可能生成DATE令牌的位置。