ANTLR4:输入不匹配

时间:2013-07-18 12:59:43

标签: antlr4

我想匹配表单::

的输入
commit a1b2c3
Author: Michael <michael@test.com>

commit d3g4
Author: David <david@test.com> 

这是我写的语法:

grammar commit;

file : commitinfo+;

commitinfo : commitdesc authordesc;
commitdesc : 'commit' COMMITHASH NEWLINE;
authordesc : 'Author:' AUTHORNAME '<' EMAIL '>' NEWLINE;

COMMITHASH : [a-z0-9]+;
AUTHORNAME : [a-zA-Z]+;
EMAIL      : [a-zA-Z0-9.@]+;
NEWLINE    : '\r'?'\n';
WHITESPACE : [ \t]->skip;

上述解析器的问题在于,对于上面的输入,它完全匹配。但是当输入变为:

commit c1d2
Author: michael <michael@test.com>

它会抛出如下错误:

第2行:8输入不匹配的'michael'期待AUTHORNAME。

当我打印令牌时,似乎字符串'michael'被令牌COMMITHASH而不是AUTHORNAME匹配。

如何修复上述情况?

1 个答案:

答案 0 :(得分:4)

ANTLR4 根据词法规则的编写顺序匹配词法规则。

'michael'与规则COMMITHASH : [a-z0-9]+ ;之前出现的规则AUTHORNAME匹配,因此您遇到错误。

我可以考虑以下选项来解决您面临的问题:

  • 您可以在ANTLR中使用'mode'功能:在ANTLR 4中,一次激活一个词法分析器模式,该模式规则中最长的non-fragment lexer rule将确定创建哪个令牌。您的语法仅包含默认模式,因此所有词法分析器规则都是活动的,因此“michael”与COMMITHASH匹配,因为匹配的令牌长度与COMMITHASHAUTHORNAME相同但是COMMITHASH出现在AUTHORNAME语法之前。

  • 您可以通过改变它们在语法中出现的方式来改变词法规则。假设您的COMMITHASH规则始终具有与之匹配的数字。按以下方式将AUTHORNAME放在COMMITHASH之前:

    grammar commit;
    ...
    
    AUTHORNAME : [a-zA-Z]+;
    COMMITHASH : [a-z0-9]+;
    ...
    

注意:我强烈认为你的词法分析器规则不清晰。您确定COMMITHASH规则应该是[a-z0-9]+;这意味着'abhdks'这样的令牌也会与您的COMMITHASH规则匹配。但这完全是一个不同的问题。