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

时间:2018-06-23 16:00:33

标签: antlr grammar antlr4

我正在重新学习一些基本的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...不会解析,因为虽然12HOUR匹配,但20和解析器也一样期望NONZERO_NUMBER失败了。

line 1:20 mismatched input '20' expecting NONZERO_NUMBER

如果我将持续时间值更改为有意不匹配HOUR规则,就可以了:

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

在尝试其他/较早的规则之前,是否有任何方法可以“说服”词法分析器来尝试匹配 expected 标记(为解析器定义)?

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

旁注:我意识到还有其他奇怪之处,例如事件名称只能是一个单词,但是我一次要解决一个问题。

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 个答案:

答案 0 :(得分:3)

尝试在词法分析器中执行解析器的工作通常是一个错误。如果词法分析器仅识别整数,则解析器将毫无问题地整理出如何解释数字。您可以在动作或谓词中拒绝类似8:63的时间。

答案 1 :(得分:0)

  

在尝试其他/较早的规则之前,是否有任何方法可以“说服”词法分析器来尝试匹配 expected 标记(为解析器定义)?

不,您不能说服lexer匹配期望的令牌,因为lexer没有任何期望(通常,它对常规语法进行操作,而解析器对上下文无关的语法进行操作)。词法分析器和解析器独立运行 * ,理论上您可以先运行词法分析器而无需任何解析器,然后再在词法分析器输出上启动解析器。


*在ANTLR 3中有一个例外,我也找不到对ANTLR 4是否适用-ANTLR 3解析器和词法分析器共享一个org.antlr.runtime.RecognizerSharedState实例。但是,使用此方法影响词法分析器与令牌的匹配方式仍会存在风险,因为您无法直接控制词法分析器何时对特定输入进行标记化(即,由于某些解析器规则,它可以进行前瞻性处理,并在获得输入之前对输入进行标记化并在解析器中对其进行尝试,并尝试对其进行影响。)