如何创建一个解析日期的antlr4语法
How to create a antlr4 grammar which will parse date
我想使用以下 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”,但它会导致输入不匹配。请帮忙
对于这样的任务,正则表达式是更好的解决方案。但是如果你把它作为一个研究项目,这里是...
重要的是要认识到词法分析器规则的顺序是至关重要的。输入将通过这些规则进行测试,并将使用第一个适用的规则。规则应该从最具体的开始写起,避免冲突。例如,如果你有带变量名和一些关键字的语法,关键字应该在前面,否则它们将被标记为变量。
有很多方法可以解决这个问题,但最好的方法是一个名为 DATE 的词法分析器规则:NUM NUM NUM NUM '-' NUM NUM '-' NUM NUM;您拥有的月份和日期规则不会起作用,因为它们是模棱两可的。词法分析器如何判断输入的两个数字是月还是日?
在我的例子中它有效。我得到一个正确的解析树输入: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 是否有人已经做了我想要的。找到这个图书馆。
这是一个从字符串中解析日期的库。
https://github.com/masasdani/nangka
将此项目添加为您项目的依赖项
<dependency>
<groupId>com.masasdani</groupId>
<artifactId>nangka</artifactId>
<version>0.0.6</version>
</dependency>
示例用法:
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);
}
希望这对像我这样正在搜索的人有所帮助。
我想使用以下 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”,但它会导致输入不匹配。请帮忙
对于这样的任务,正则表达式是更好的解决方案。但是如果你把它作为一个研究项目,这里是...
重要的是要认识到词法分析器规则的顺序是至关重要的。输入将通过这些规则进行测试,并将使用第一个适用的规则。规则应该从最具体的开始写起,避免冲突。例如,如果你有带变量名和一些关键字的语法,关键字应该在前面,否则它们将被标记为变量。
有很多方法可以解决这个问题,但最好的方法是一个名为 DATE 的词法分析器规则:NUM NUM NUM NUM '-' NUM NUM '-' NUM NUM;您拥有的月份和日期规则不会起作用,因为它们是模棱两可的。词法分析器如何判断输入的两个数字是月还是日?
在我的例子中它有效。我得到一个正确的解析树输入: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 是否有人已经做了我想要的。找到这个图书馆。
这是一个从字符串中解析日期的库。
https://github.com/masasdani/nangka
将此项目添加为您项目的依赖项
<dependency>
<groupId>com.masasdani</groupId>
<artifactId>nangka</artifactId>
<version>0.0.6</version>
</dependency>
示例用法:
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);
}
希望这对像我这样正在搜索的人有所帮助。