Antlr 语法与预期的词法分析器规则不匹配

Antlr grammar not matching expected lexer rule

我正在尝试使用以下规则匹配持续时间字符串,例如 for 30 minutesfor 2 hours

durationPhrase: FOR_STR (MINUTE_DURATION | HOUR_DURATION);

MINUTE_DURATION: NONZERO_NUMBER MINUTE_STR;

HOUR_DURATION: NONZERO_NUMBER HOUR_STR;

MINUTE_STR: 'minute'('s')?;

HOUR_STR: 'hour'('s')?;

FOR_STR: 'for';

NONZERO_NUMBER: [0-9]+;

WS: (' '|[\n\t\r]) -> skip;

使用以下输入:

for 30 minutes

尝试 debug/match durationPhrase 规则时,出现错误:

line 1:4 mismatched input '30' expecting {MINUTE_DURATION, HOUR_DURATION}

但我似乎无法弄清楚“30”匹配的词法分析器规则是什么?我的印象是 "longest" 词法分析器规则会获胜, 将是 MINUTE_DURATION 规则。

是否先匹配 NONZERO_NUMBER?如果是,为什么?

它匹配 NONZERO_NUMBER,因为其他模式都不适用。如果您输入 30minutes,它会匹配 MINUTE_DURATION,但作为标记模式,MINUTE_DURATION 不会匹配 space 字符。

您通过将 -> skip 应用于令牌 WS 来忽略白色 space。这只有在 WS 被识别为令牌后才会发生;即在标记化之后。在标记化过程中,白色space字符只是字符。

如果您制定 MINUTE_DURATIONHOUR_DURATION 语法规则而不是词汇规则,它应该会按预期工作。