ANTLR4 词法分析器规则无法按预期工作



我想写一个关于月份和年份的词法分析规则,规则是(用正则表达式(:

"hello"[0-9]{1,2}"ever"([0-9]{2}([0-9]{2})?)?
">

hello"和"ever"文本仅用于调试。

也就是说,月份是一两位数,年份是两位数或四位数。更重要的是,年份部分可以绕过。

如: 八月 2015 ->hello08ever2015 或 hello8ever2015 或 hello8ever15 或 hello8ever 或 hello08ever; 2015 年 10 月 -> hello10ever2015 或 hello10ever15 或 hello10ever;

我的词法分析规则如下(ANTLR4(:

grammar Hello;
r  : 'hello' TimeDate 'ever' TimeYear? ;        
TimeDate : Digit Digit?;
TimeYear : TwoDigit TwoDigit?;
TwoDigit : Digit Digit;
Digit : [0-9] ;             
WS : [ trn]+ -> skip ; // skip spaces, tabs, newlines

但它似乎不起作用。以下是我测试的一些日志:

C:antlrworkspacedemo>java org.antlr.v4.runtime.misc.TestRig Hello r -tree -gui
hello20ever2014
^Z
(r hello 20 ever 2014)
C:antlrworkspacedemo>grun Hello r -tree -gui
C:antlrworkspacedemo>java org.antlr.v4.runtime.misc.TestRig Hello r -tree -gui
hello2ever20
^Z
(r hello 2 ever)
C:antlrworkspacedemo>grun Hello r -tree -gui
C:antlrworkspacedemo>java org.antlr.v4.runtime.misc.TestRig Hello r -tree -gui
hello20ever14
^Z
(r hello 20 ever)
C:antlrworkspacedemo>grun Hello r -tree -gui
C:antlrworkspacedemo>java org.antlr.v4.runtime.misc.TestRig Hello r -tree -gui
hello2ever2014
^Z
(r hello 2 ever 2014)

对于输入:Hello2ever20,它无法识别年份部分"20";对于输入:hello20ever14,它无法识别年份部分"14";

任何人都可以在这方面提供帮助???

谢谢!!

您必须意识到 ANTLR 的词法分析器规则是根据它们在语法文件中的位置匹配的。词法分析器不会"侦听"解析器在解析器规则中的某个位置可能需要什么。词法分析器尝试匹配尽可能多的字符,当 2 个(或更多(规则匹配相同数量的字符时,首先定义的规则将获胜。

在您的情况下,这意味着15将始终标记为TimeDate,而不是标记为TimeYear,因为两个规则都匹配15但首先定义TimeDate2015将被标记为TimeYear,因为没有其他规则与 4 位数字匹配。

解决方案是将TimeYear更改为解析器规则:

timeYear
 : TimeDate TimeDate?
 ;

最新更新