ANTLR4:输入不匹配

ANTLR4:输入不匹配,antlr4,Antlr4,我是antlr的新手。我想写一个语法来解析以下输入: commit a1b2c3d4 语法如下所示: grammar commit; file : 'commit' COMMITHASH NEWLINE; COMMITHASH : [a-z0-9]+; DATE : ~[\r\n]+; NEWLINE : '\r'?'\n'; 当我尝试使用语法解析上述输入时,它抛出以下异常:: 第1行:0不匹配的输入“提交a1b2c3d4”应为“提交” 注意:我故意添加了日期标记。如果

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

commit a1b2c3d4
语法如下所示:

grammar commit;

file : 'commit' COMMITHASH NEWLINE;

COMMITHASH : [a-z0-9]+;
DATE       : ~[\r\n]+;
NEWLINE    : '\r'?'\n';
当我尝试使用语法解析上述输入时,它抛出以下异常::

第1行:0不匹配的输入“提交a1b2c3d4”应为“提交”

注意:我故意添加了日期标记。如果没有日期标记,它可以正常工作。但是我想知道,当添加日期标记时会发生什么


我已经提到了链接,但还不清楚发生了什么。

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

lexer包含一个规则
DATE
,该规则匹配除换行符以外的所有字符。由于这始终与一行的整个文本相匹配,并且没有任何标记跨越多行,因此结果如下:

  • 如果单行的整个文本与
    commit
    匹配,则将生成与此输入序列对应的未命名标记
  • 如果单行的整个文本与
    [a-z0-9]+
    匹配,则将为该行的整个文本创建一个
    COMMITHASH
    标记<代码>日期也与此输入匹配,但
    COMMITHASH
    首先出现,因此使用它
  • 否则,如果单行至少包含一个字符,则将为该行的整个文本创建一个
    DATE
    标记。即使行以
    commit
    COMMITHASH
    开头,也将使用
    DATE
    规则,因为它匹配更长的字符序列
  • 最后,将为每个换行创建一个
    换行标记
您需要执行以下操作之一来解决此问题。确切的策略取决于您试图解决的更大问题

  • 删除
    日期
    规则,或重写它以匹配更具体的日期格式
  • 使用语义谓词和/或lexer模式限制输入中可能产生
    日期
    标记的位置

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

lexer包含一个规则
DATE
,该规则匹配除换行符以外的所有字符。由于这始终与一行的整个文本相匹配,并且没有任何标记跨越多行,因此结果如下:

  • 如果单行的整个文本与
    commit
    匹配,则将生成与此输入序列对应的未命名标记
  • 如果单行的整个文本与
    [a-z0-9]+
    匹配,则将为该行的整个文本创建一个
    COMMITHASH
    标记<代码>日期
    也与此输入匹配,但
    COMMITHASH
    首先出现,因此使用它
  • 否则,如果单行至少包含一个字符,则将为该行的整个文本创建一个
    DATE
    标记。即使行以
    commit
    COMMITHASH
    开头,也将使用
    DATE
    规则,因为它匹配更长的字符序列
  • 最后,将为每个换行创建一个
    换行标记
您需要执行以下操作之一来解决此问题。确切的策略取决于您试图解决的更大问题

  • 删除
    日期
    规则,或重写它以匹配更具体的日期格式
  • 使用语义谓词和/或lexer模式限制输入中可能产生
    日期
    标记的位置

感谢您的回答,现在我能够理解在上述情况下发生了什么。当我打印出lexer发出的标记时,它变得更加清晰了。对于这个问题以及为感谢您的回答而提出的问题,现在我能够理解在上述情况下发生了什么。当我打印出lexer发出的标记时,它变得更加清晰了。无论是这个问题还是在