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
64 : monthExpr (SPACE|ddiv)+ dayOfMonth ((SPACE|ddiv)+ year)?
68 : dayOfMonth (SPACE|ddiv)+ monthName ((SPACE|ddiv)+ year)?
72 : year (SPACE|ddiv)+ monthExpr (SPACE|ddiv)+ dayOfMonth
75 nthWeekdayInMonthMaybeYearExpr
76 : nth SPACE+ dayName SPACE+ ('in'|'of') SPACE+ monthName ((ddiv|SPACE)+ year)?
79 firstLastWeekdayInMonthMaybeYearExpr
80 : firstOrLast SPACE+ dayName (SPACE+ ('in'|'of'))? SPACE+ monthName ((ddiv|SPACE)+ year)?
83 specialDateMaybeYearExpr
84 : (thisNextLast SPACE+)? specialDate ((SPACE|ddiv)+ year)?
87 thisNextLast: (THIS|NEXT|LAST) ;
90 : baseDate SPACE+ deltaPlusMinusExpr
91 | deltaPlusMinusExpr SPACE+ baseDate
94 deltaDateExprRelativeToTodayImplied
95 : nFoosFromTodayAgoExpr
96 | deltaRelativeToTodayExpr
99 deltaRelativeToTodayExpr
100 : thisNextLast SPACE+ deltaUnit
103 nFoosFromTodayAgoExpr
104 : unsignedInt SPACE+ deltaUnit SPACE+ AGO_FROM_NOW
107 baseDate: singleDateExpr ;
109 baseAndOffsetTimeExpr
110 : deltaPlusMinusTimeExpr SPACE+ baseTime
111 | baseTime SPACE+ deltaPlusMinusTimeExpr
114 baseTime: singleTimeExpr ;
117 : nth SPACE+ deltaUnit (SPACE+ deltaBeforeAfter)?
123 deltaPlusMinusTimeExpr
124 : countUnitsBeforeAfterTimeExpr
125 | fractionBeforeAfterTimeExpr
128 countUnitsBeforeAfterTimeExpr
129 : nth (SPACE+ deltaTimeUnit)? SPACE+ deltaTimeBeforeAfter
132 fractionBeforeAfterTimeExpr
133 : deltaTimeFraction SPACE+ deltaTimeBeforeAfter
136 deltaUnit: (YEAR|MONTH|WEEK|DAY|WEEKDAY|WORKDAY) ;
138 deltaTimeUnit: (SECOND|MINUTE|HOUR|WORKDAY) ;
140 deltaBeforeAfter: (BEFORE|AFTER) ;
142 deltaTimeBeforeAfter: (BEFORE|AFTER) ;
149 year: DIGIT DIGIT DIGIT DIGIT ;
151 specialDate: SPECIAL_DATE ;
154 : DIGIT DIGIT? ('st'|'ST'|'nd'|'ND'|'rd'|'RD'|'th'|'TH')?
155 | KALENDS (SPACE+ 'of')?
156 | IDES (SPACE+ 'of')?
157 | NONES (SPACE+ 'of')?
160 firstOrLast: (FIRST|LAST) ;
162 nth: (DASH|PLUS)? DIGIT+ ('st'|'ST'|'nd'|'ND'|'rd'|'RD'|'th'|'TH')? ;
164 unsignedInt: DIGIT+ ;
166 deltaTimeFraction: DELTA_TIME_FRACTION ;
168 specialTimeExpr: specialTime (SPACE+ tzExpr)? ;
170 specialTime: SPECIAL_TIME ;
174 monthName: MONTH_NAME ;
176 monthNumber: DIGIT DIGIT? ;
180 minute: DIGIT DIGIT ;
182 second: DIGIT DIGIT ;
184 micros: DIGIT DIGIT? DIGIT? DIGIT? DIGIT? DIGIT? DIGIT? ;
186 ddiv: (SLASH|DASH|',') ;
190 dtdiv: ('T'|'t'|'at'|'AT'|','|';') ;
192 tddiv: ('on'|'ON'|','|';') ;
199 ntz: (PLUS|DASH) DIGIT DIGIT COLON? DIGIT DIGIT ;
201 ltz: UPPERCASE_STRING ;
203 // ----------------------------------
207 COMMENT: '#' ~[\r\n]* -> skip ;
209 THE: ('the'|'The') SPACE* -> skip ;
221 MONTH_NAME: (JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC) ;
308 WEEKDAY: (SUN|MON|TUE|WED|THU|FRI|SAT) ;
467 | MARTIN_LUTHER_KING_DAY
487 : ('noon'|'Noon'|'midday'|'Midday')
491 : ('midnight'|'Midnight')
496 : ('today'|'Today'|'now'|'Now')
501 : ('yesterday'|'Yesterday')
506 : ('tomorrow'|'Tomorrow')
558 MARTIN_LUTHER_KING_DAY
559 : 'martin luther king day'
560 | 'Martin Luther King Day'
611 | 'indiginous peoples day'
612 | 'indiginous peoples\' day'
615 | 'Indiginous Peoples Day'
616 | 'Indiginous Peoples\' Day'
643 FIRST: ('first'|'First') ;
645 LAST: ('last'|'Last'|'this past') ;
647 THIS: ('this'|'This'|'this coming') ;
649 NEXT: ('next'|'Next') ;
651 AGO_FROM_NOW: (AGO|FROM_NOW) ;
653 AGO: ('ago'|'Ago'|'back'|'Back') ;
655 FROM_NOW: ('from now'|'From Now') ;
657 BEFORE: ('to'|'To'|'before'|'Before'|'til'|'until'|'Until') ;
659 AFTER: ('after'|'After'|'from'|'From'|'past'|'Past') ;
661 DELTA_TIME_FRACTION: ('quarter'|'Quarter'|'half'|'Half') ;
665 IDES: ('ides'|'Ides') ;
667 NONES: ('nones'|'Nones') ;
669 KALENDS: ('kalends'|'Kalends') ;
682 UPPERCASE_STRING: [A-Z]+ ;