如何创建将解析日期的antlr4语法
我想使用下面的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;
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);
}