Antlr lexer匹配意外规则
我正在学习一些基本的Antlr,并尝试编写语法来生成todo项:Antlr lexer匹配意外规则,antlr,grammar,antlr4,Antlr,Grammar,Antlr4,我正在学习一些基本的Antlr,并尝试编写语法来生成todo项: Meeting at 12pm for 20 minutes 我遇到的问题是,根据使用的上下文,三个lexer规则尤其“不匹配”: HOUR: [0-9]|'1'[0-9]|'2'[0-3]; MINUTE: [0-5][0-9]; NONZERO_NUMBER: [1-9][0-9]*; 在某些情况下,我希望12匹配HOUR规则,而在其他情况下,我希望它匹配MINUTE,等等,但解析器规则似乎无法影响词法器的上下文敏感性 例
Meeting at 12pm for 20 minutes
我遇到的问题是,根据使用的上下文,三个lexer规则尤其“不匹配”:
HOUR: [0-9]|'1'[0-9]|'2'[0-3];
MINUTE: [0-5][0-9];
NONZERO_NUMBER: [1-9][0-9]*;
在某些情况下,我希望12
匹配HOUR
规则,而在其他情况下,我希望它匹配MINUTE
,等等,但解析器规则似乎无法影响词法器的上下文敏感性
例如,上面的字符串(readbooks…
)不进行解析,因为当12
作为HOUR
匹配时,20
也是如此,而解析器期望非零编号
因此失败
line 1:20 mismatched input '20' expecting NONZERO_NUMBER
如果我故意将持续时间值更改为而不匹配小时
规则,则可以:
Meeting at 12pm for 120 minutes // Note 120 minutes doesn't match HOUR or MINUTE
在尝试其他/更早的规则之前,有没有办法“说服”词法分析器尝试匹配预期的标记(如为解析器定义的)
以下是我的完整语法:
旁注:我意识到还有其他奇怪之处,比如事件名称只能是一个单词,但我一次只解决一个问题
试图在lexer中完成解析器的工作通常是错误的。如果lexer只识别整数,那么解析器将不会对如何解释数字产生任何问题。您可以在动作或谓词中拒绝8:63这样的时间 在尝试其他/更早的规则之前,有没有办法“说服”词法分析器尝试匹配预期的标记(如为解析器定义的) 不,您无法说服lexer匹配期望的标记,因为lexer没有任何期望(形式上,它在常规语法上运行,而解析器在上下文无关语法上运行)。lexer和解析器独立运行*,理论上,您可以先运行lexer而不使用任何解析器,然后在lexer输出上启动解析器
*在ANTLR 3中有一个例外,我无法确定ANTLR 4是否也是如此——ANTLR 3解析器和lexer共享一个
org.ANTLR.runtime.RecognizerSharedState
实例。然而,使用它来影响lexer如何匹配标记仍然是有风险的,因为您无法直接控制lexer何时标记特定的输入(即,它可以根据一些解析器规则进行前瞻,并在您在解析器中访问输入并尝试影响它之前标记输入)
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;