我是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,但我还不清楚发生了什么。
答案 0 :(得分:2)
ANTLR词法分析器在使用解析器之前完全分配明确的令牌类型。当一个词法分析器规则可以匹配多于另一个词法分析器规则的字符时,ANTLR始终首选匹配更多字符的规则,而不管词法分析器规则在语法中出现的顺序如何。当两个或多个规则完全匹配相同长度的输入符号(并且没有其他规则匹配超过此数量的输入符号)时,将为语法中首先出现的规则分配一个标记类型。
您的词法分析器包含一个规则DATE
,它匹配除换行符之外的所有字符。由于这始终与行的整个文本匹配,并且您的所有令牌都不跨越多行,因此结果如下:
commit
匹配,则会生成与此输入序列对应的未命名标记。[a-z0-9]+
匹配,则会为该行的整个文本创建COMMITHASH
标记。 DATE
也匹配此输入,但COMMITHASH
首先显示,因此使用它。DATE
标记。即使该行以commit
或COMMITHASH
开头,也会使用DATE
规则,因为它与较长的字符序列匹配。NEWLINE
令牌。您需要执行以下操作之一来解决此问题。确切的策略取决于您尝试解决的更大问题。
DATE
规则,或重写该规则以匹配更具体的日期格式。DATE
令牌的位置。