如何创建将解析日期的antlr4语法

如何创建将解析日期的antlr4语法,antlr4,Antlr4,我想使用下面的ANTLR4语法解析一些日期格式 grammar Variables; //varTable : tableNameFormat dateFormat? ; //tableNameFormat: (ID SEPERATOR); dateFormat : YEAR UNDERSCORE MONTH UNDERSCORE TODAY | YEAR ; YEAR : DIGIT DIGIT DIGIT DIGIT;

我想使用下面的ANTLR4语法解析一些日期格式

grammar Variables;
//varTable : tableNameFormat dateFormat? ;
//tableNameFormat: (ID SEPERATOR);
dateFormat : YEAR UNDERSCORE MONTH UNDERSCORE TODAY
       | YEAR
       ;
YEAR : DIGIT DIGIT DIGIT DIGIT;                         // 4-digits YYYY
MONTH : DIGIT DIGIT;                                    // 2-digits MM
TODAY : DIGIT DIGIT ;                                     // 2-digits DD
UNDERSCORE: ('_' | '-' );
fragment
DIGIT : [0-9] ;
ID : [a-zA-Z][a-zA-Z0-9]? ;
WS  : [ \t\r\n]+ -> skip ;

这种语法应该很容易解析“2016-01-01”,但它会导致输入不匹配。请帮助

对于这样的任务,regex是更好的解决方案。但如果你把它作为一个研究项目,这里是

重要的是要认识到lexer规则的顺序是至关重要的。输入将根据这些规则进行测试,并使用第一个适用的规则。规则应该从最具体的角度编写,以避免冲突。例如,如果语法中有变量名和一些关键字,则应首先使用关键字,否则它们将被标记为变量


有很多方法可以解决这个问题,但最好的是一个名为DATE的lexer规则:NUM'-'NUM'-'NUM'-'NUM;你所拥有的月和日规则是不起作用的,因为它们是模棱两可的。lexer如何判断输入的两个数字是月还是日?

在我的例子中,它是有效的。我得到一个正确的parsetree,输入:2016-01-01

grammar date;

dateFormat : year UNDERSCORE month UNDERSCORE today
       | year
       ;

year : DIGIT DIGIT DIGIT DIGIT
     ;

month : DIGIT DIGIT
      ;

today : DIGIT DIGIT 
      ;

UNDERSCORE: ('_' | '-' );
DIGIT : [0-9] ;

但是我会使用
month
类似于
(0[1-9]| 1[0-2])
,因为只有12个月。

我以前从未使用过Antlr,但是当我在GitHub中查看是否有人已经做了我想要的事情时。我找到了这个图书馆

下面是一个从字符串解析日期的库

将此项目添加为项目的依赖项

   <dependency>
        <groupId>com.masasdani</groupId>
        <artifactId>nangka</artifactId>
        <version>0.0.6</version>
    </dependency>

希望这对像我这样正在搜索的人有所帮助。

是的,因为您使用了年、月、日的解析器规则。。。尝试输入它们作为Lexer规则,它将失败。。。我并不是说这种方法不好。只是语法分析器和词法分析器规则之间有区别。你这样做的方式和我得到答案的方式一样。。。但我不想把year用作解析器,我想把year用作lexer问题是你不能。你可以选择年,因为它有4位数长,但如果用作LEXER规则的话,月和日是模棱两可的。2012-01-20将被解析为这些令牌=>YEAR-MONTH-MONTH,这是无效的。但是在我想解析输入并确定哪种日期格式作为输入的情况下,如何使用正则表达式呢??例如,如果输入为“20160101”,则输出应为“YYYYMMDD”;如果输入为“2016-01-01”,则输出应为“YYYY-MM-DD”。对不起,但我不明白。在这里,antlr和regex的用法有什么不同?很抱歉提供了错误的用例。。。。正如我在解析时所想的那样,使用antlr,使用visitor,我可以知道年格式是%Y,月格式是%m,日格式是%d,但是使用regex我该怎么做?现在我似乎明白了。您需要区分3种情况(例如)。20120101、2012-01-01和2012_01_01。你可以用antlr来做,当然,我认为这有点过头了。试试一个正则表达式,检查它是否匹配,然后检查有什么拆分字符,然后再拆分。不知何故,对我来说(只有一种方法)比antlr(几个类)更容易。好吧,是的,正则表达式肯定会更好。。。所以我可以如下解析输入…但是如何检查分割字符<代码>模式模式=模式。编译(\\d{4}['-'.''.'.'.''.'''.'''.''''.''''.''''.''''.''''.'''''.''''.'''.''\\d{2});Matcher Matcher=pattern.Matcher(someInput);if(matcher.find()){//如何检查拆分字符是什么?}
  String exprEn = "a month later, 20-11-90";
    Nangka nangka = new Nangka();
    DateUnit dateUnit = nangka.parse(exprEn);
    for(Date date : dateUnit.getRelatedDates()){
        System.out.println(date);
    }