1 // © Copyright 2021-2022, Scott Gasch
3 // antlr4 -Dlanguage=Python3 ./dateparse_utils.g4
5 // Hi, self. In ANTLR grammars, there are two separate types of symbols: those
6 // for the lexer and those for the parser. The former begin with a CAPITAL
7 // whereas the latter begin with lowercase. The order of the lexer symbols
8 // is the order that the lexer will recognize them in. There's a good tutorial
11 // https://tomassetti.me/antlr-mega-tutorial/
13 // There are also a zillion premade grammars at:
15 // https://github.com/antlr/grammars-v4
17 grammar dateparse_utils;
22 | SPACE* dateExpr SPACE* dtdiv? SPACE* timeExpr
23 | SPACE* timeExpr SPACE* tddiv? SPACE+ dateExpr
28 | baseAndOffsetDateExpr
33 | baseAndOffsetTimeExpr
37 : twentyFourHourTimeExpr
42 twentyFourHourTimeExpr
43 : hour ((SPACE|tdiv)+ minute ((SPACE|tdiv)+ second ((SPACE|tdiv)+ micros)? )? )? SPACE* tzExpr?
47 : hour ((SPACE|tdiv)+ minute ((SPACE|tdiv)+ second ((SPACE|tdiv)+ micros)? )? )? SPACE* ampm SPACE* tzExpr?
50 ampm: ('a'|'am'|'p'|'pm'|'AM'|'PM'|'A'|'P');
53 : monthDayMaybeYearExpr
54 | dayMonthMaybeYearExpr
56 | specialDateMaybeYearExpr
57 | nthWeekdayInMonthMaybeYearExpr
58 | firstLastWeekdayInMonthMaybeYearExpr
59 | deltaDateExprRelativeToTodayImplied
60 | dayName (SPACE|ddiv)+ monthDayMaybeYearExpr (SPACE|ddiv)* singleTimeExpr*
65 : monthExpr (SPACE|ddiv)+ dayOfMonth ((SPACE|ddiv)+ year)?
69 : dayOfMonth (SPACE|ddiv)+ monthName ((SPACE|ddiv)+ year)?
73 : year (SPACE|ddiv)+ monthExpr (SPACE|ddiv)+ dayOfMonth
76 nthWeekdayInMonthMaybeYearExpr
77 : nth SPACE+ dayName SPACE+ ('in'|'of') SPACE+ monthName ((ddiv|SPACE)+ year)?
80 firstLastWeekdayInMonthMaybeYearExpr
81 : firstOrLast SPACE+ dayName (SPACE+ ('in'|'of'))? SPACE+ monthName ((ddiv|SPACE)+ year)?
84 specialDateMaybeYearExpr
85 : (thisNextLast SPACE+)? specialDate ((SPACE|ddiv)+ year)?
88 thisNextLast: (THIS|NEXT|LAST) ;
91 : baseDate SPACE+ deltaPlusMinusExpr
92 | deltaPlusMinusExpr SPACE+ baseDate
95 deltaDateExprRelativeToTodayImplied
96 : nFoosFromTodayAgoExpr
97 | deltaRelativeToTodayExpr
100 deltaRelativeToTodayExpr
101 : thisNextLast SPACE+ deltaUnit
104 nFoosFromTodayAgoExpr
105 : unsignedInt SPACE+ deltaUnit SPACE+ AGO_FROM_NOW
108 baseDate: singleDateExpr ;
110 baseAndOffsetTimeExpr
111 : deltaPlusMinusTimeExpr SPACE+ baseTime
112 | baseTime SPACE+ deltaPlusMinusTimeExpr
115 baseTime: singleTimeExpr ;
118 : nth SPACE+ deltaUnit (SPACE+ deltaBeforeAfter)?
124 deltaPlusMinusTimeExpr
125 : countUnitsBeforeAfterTimeExpr
126 | fractionBeforeAfterTimeExpr
129 countUnitsBeforeAfterTimeExpr
130 : nth (SPACE+ deltaTimeUnit)? SPACE+ deltaTimeBeforeAfter
133 fractionBeforeAfterTimeExpr
134 : deltaTimeFraction SPACE+ deltaTimeBeforeAfter
137 deltaUnit: (YEAR|MONTH|WEEK|DAY|WEEKDAY|WORKDAY) ;
139 deltaTimeUnit: (SECOND|MINUTE|HOUR|WORKDAY) ;
141 deltaBeforeAfter: (BEFORE|AFTER) ;
143 deltaTimeBeforeAfter: (BEFORE|AFTER) ;
150 year: DIGIT DIGIT DIGIT DIGIT ;
152 specialDate: SPECIAL_DATE ;
155 : DIGIT DIGIT? ('st'|'ST'|'nd'|'ND'|'rd'|'RD'|'th'|'TH')?
156 | KALENDS (SPACE+ 'of')?
157 | IDES (SPACE+ 'of')?
158 | NONES (SPACE+ 'of')?
161 firstOrLast: (FIRST|LAST) ;
163 nth: (DASH|PLUS)? DIGIT+ ('st'|'ST'|'nd'|'ND'|'rd'|'RD'|'th'|'TH')? ;
165 unsignedInt: DIGIT+ ;
167 deltaTimeFraction: DELTA_TIME_FRACTION ;
169 specialTimeExpr: specialTime (SPACE+ tzExpr)? ;
171 specialTime: SPECIAL_TIME ;
175 monthName: MONTH_NAME ;
177 monthNumber: DIGIT DIGIT? ;
181 minute: DIGIT DIGIT ;
183 second: DIGIT DIGIT ;
185 micros: DIGIT DIGIT? DIGIT? DIGIT? DIGIT? DIGIT? DIGIT? ;
187 ddiv: (SLASH|DASH|',') ;
191 dtdiv: ('T'|'t'|'at'|'AT'|','|';') ;
193 tddiv: ('on'|'ON'|','|';') ;
200 ntz: (PLUS|DASH) DIGIT DIGIT COLON? DIGIT DIGIT ;
202 ltz: UPPERCASE_STRING ;
204 // ----------------------------------
208 COMMENT: '#' ~[\r\n]* -> skip ;
210 THE: ('the'|'The') SPACE* -> skip ;
222 MONTH_NAME: (JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC) ;
309 WEEKDAY: (SUN|MON|TUE|WED|THU|FRI|SAT) ;
468 | MARTIN_LUTHER_KING_DAY
488 : ('noon'|'Noon'|'midday'|'Midday')
492 : ('midnight'|'Midnight')
497 : ('today'|'Today'|'now'|'Now')
502 : ('yesterday'|'Yesterday')
507 : ('tomorrow'|'Tomorrow')
559 MARTIN_LUTHER_KING_DAY
560 : 'martin luther king day'
561 | 'Martin Luther King Day'
612 | 'indiginous peoples day'
613 | 'indiginous peoples\' day'
616 | 'Indiginous Peoples Day'
617 | 'Indiginous Peoples\' Day'
644 FIRST: ('first'|'First') ;
646 LAST: ('last'|'Last'|'this past') ;
648 THIS: ('this'|'This'|'this coming') ;
650 NEXT: ('next'|'Next') ;
652 AGO_FROM_NOW: (AGO|FROM_NOW) ;
654 AGO: ('ago'|'Ago'|'back'|'Back') ;
656 FROM_NOW: ('from now'|'From Now') ;
658 BEFORE: ('to'|'To'|'before'|'Before'|'til'|'until'|'Until') ;
660 AFTER: ('after'|'After'|'from'|'From'|'past'|'Past') ;
662 DELTA_TIME_FRACTION: ('quarter'|'Quarter'|'half'|'Half') ;
666 IDES: ('ides'|'Ides') ;
668 NONES: ('nones'|'Nones') ;
670 KALENDS: ('kalends'|'Kalends') ;
683 UPPERCASE_STRING: [A-Z]+ ;