首页 文章

Antlr词法分析器匹配意外的规则

提问于
浏览
1

我正在重新学习一些基本的Antlr并尝试编写语法来生成待办事项:

Meeting at 12pm for 20 minutes

我遇到的问题是,特别是三个词法分析器规则“不匹配”取决于它们使用的上下文:

HOUR: [0-9]|'1'[0-9]|'2'[0-3];
MINUTE: [0-5][0-9];
NONZERO_NUMBER: [1-9][0-9]*;

在某些情况下,我希望 12 匹配 HOUR 规则,有时我希望它匹配 MINUTE 等,但解析器规则似乎无法影响词法分析器对上下文敏感 .

例如,上面的字符串( Read Books... )不解析,因为 12 匹配为 HOUR20 也是如此,并且解析器期望 NONZERO_NUMBER 因此失败 .

line 1:20 mismatched input '20' expecting NONZERO_NUMBER

如果我将持续时间值更改为 intentionally not 匹配 HOUR 规则,则可以:

Meeting at 12pm for 120 minutes // Note 120 minutes doesn't match HOUR or MINUTE

在尝试其他/早期规则之前,有没有办法让词法分析器尝试匹配预期的令牌(如解析器所定义)?

为清晰起见,这是我的完整语法:

旁注:我意识到还有其他奇怪的事情,比如一个事件名称只能是一个单词,但我一次只能处理一个问题 .

grammar Sprint;

event: eventName timePhrase? durationPhrase?;

durationPhrase: 'for' duration;

timePhrase: 'at' time;

duration: (NONZERO_NUMBER MINUTE_STR) | (NONZERO_NUMBER HOUR_STR);

time: ((HOUR ':' MINUTE) | (HOUR)) AMPM?;

eventName: WORD;

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

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

HOUR: [0-9]|'1'[0-9]|'2'[0-3];

MINUTE: [0-5][0-9];

NONZERO_NUMBER: [1-9][0-9]*;

AMPM: ('A'|'a'|'P'|'p')('M'|'m');

WORD: ('a'..'z' | 'A'..'Z')+;

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

2 回答

  • 3

    尝试在词法分析器中完成解析器的工作通常是错误的 . 如果词法分析器只识别整数,那么解析器就可以解决如何解释数字的问题 . 您可以在动作或谓词中拒绝8:63等时间 .

  • 0

    在尝试其他/早期规则之前,有没有办法“说服”词法分析器尝试匹配预期的令牌(如解析器所定义)?

    不,你无法说服lexer匹配预期的令牌,因为词法分析器没有任何期望(正式地,它在常规语法上运行,而解析器在无上下文语法上运行) . 词法分析器和解析器独立运行*,理论上你可以在没有任何解析器的情况下首先运行词法分析器,然后在词法分析器输出上启动解析器 .


    *在ANTLR 3中有一个例外,我无法确定ANTLR 4是否也是如此 - ANTLR 3解析器和词法分析器共享一个 org.antlr.runtime.RecognizerSharedState 实例 . 然而,使用它来影响词法分析器与标记匹配的方式仍然存在风险,因为你没有直接控制词法分析器何时标记特定输入(即,由于某些解析器规则它可以做一个先行,并在你得到之前标记化输入在解析器中并试图影响它) .

相关问题