Migration from old pyutilz package name (which, in turn, came from
[pyutils.git] / src / pyutils / datetimez / dateparse_utils.g4
1 // © Copyright 2021-2022, Scott Gasch
2 //
3 // antlr4 -Dlanguage=Python3 ./dateparse_utils.g4
4 //
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
9 // on this shit at:
10 //
11 //    https://tomassetti.me/antlr-mega-tutorial/
12 //
13 // There are also a zillion premade grammars at:
14 //
15 //    https://github.com/antlr/grammars-v4
16
17 grammar dateparse_utils;
18
19 parse
20     : SPACE* dateExpr
21     | SPACE* timeExpr
22     | SPACE* dateExpr SPACE* dtdiv? SPACE* timeExpr
23     | SPACE* timeExpr SPACE* tddiv? SPACE+ dateExpr
24     ;
25
26 dateExpr
27     : singleDateExpr
28     | baseAndOffsetDateExpr
29     ;
30
31 timeExpr
32     : singleTimeExpr
33     | baseAndOffsetTimeExpr
34     ;
35
36 singleTimeExpr
37     : twentyFourHourTimeExpr
38     | twelveHourTimeExpr
39     | specialTimeExpr
40     ;
41
42 twentyFourHourTimeExpr
43     : hour ((SPACE|tdiv)+ minute ((SPACE|tdiv)+ second ((SPACE|tdiv)+ micros)? )? )? SPACE* tzExpr?
44     ;
45
46 twelveHourTimeExpr
47     : hour ((SPACE|tdiv)+ minute ((SPACE|tdiv)+ second ((SPACE|tdiv)+ micros)? )? )? SPACE* ampm SPACE* tzExpr?
48     ;
49
50 ampm: ('a'|'am'|'p'|'pm'|'AM'|'PM'|'A'|'P');
51
52 singleDateExpr
53     : monthDayMaybeYearExpr
54     | dayMonthMaybeYearExpr
55     | yearMonthDayExpr
56     | specialDateMaybeYearExpr
57     | nthWeekdayInMonthMaybeYearExpr
58     | firstLastWeekdayInMonthMaybeYearExpr
59     | deltaDateExprRelativeToTodayImplied
60     | dayName (SPACE|ddiv)+ monthDayMaybeYearExpr (SPACE|ddiv)* singleTimeExpr*
61     | dayName
62     ;
63
64 monthDayMaybeYearExpr
65     : monthExpr (SPACE|ddiv)+ dayOfMonth ((SPACE|ddiv)+ year)?
66     ;
67
68 dayMonthMaybeYearExpr
69     : dayOfMonth (SPACE|ddiv)+ monthName ((SPACE|ddiv)+ year)?
70     ;
71
72 yearMonthDayExpr
73     : year (SPACE|ddiv)+ monthExpr (SPACE|ddiv)+ dayOfMonth
74     ;
75
76 nthWeekdayInMonthMaybeYearExpr
77     : nth SPACE+ dayName SPACE+ ('in'|'of') SPACE+ monthName ((ddiv|SPACE)+ year)?
78     ;
79
80 firstLastWeekdayInMonthMaybeYearExpr
81     : firstOrLast SPACE+ dayName (SPACE+ ('in'|'of'))? SPACE+ monthName ((ddiv|SPACE)+ year)?
82     ;
83
84 specialDateMaybeYearExpr
85     : (thisNextLast SPACE+)? specialDate ((SPACE|ddiv)+ year)?
86     ;
87
88 thisNextLast: (THIS|NEXT|LAST) ;
89
90 baseAndOffsetDateExpr
91     : baseDate SPACE+ deltaPlusMinusExpr
92     | deltaPlusMinusExpr SPACE+ baseDate
93     ;
94
95 deltaDateExprRelativeToTodayImplied
96     : nFoosFromTodayAgoExpr
97     | deltaRelativeToTodayExpr
98     ;
99
100 deltaRelativeToTodayExpr
101     : thisNextLast SPACE+ deltaUnit
102     ;
103
104 nFoosFromTodayAgoExpr
105     : unsignedInt SPACE+ deltaUnit SPACE+ AGO_FROM_NOW
106     ;
107
108 baseDate: singleDateExpr ;
109
110 baseAndOffsetTimeExpr
111     : deltaPlusMinusTimeExpr SPACE+ baseTime
112     | baseTime SPACE+ deltaPlusMinusTimeExpr
113     ;
114
115 baseTime: singleTimeExpr ;
116
117 deltaPlusMinusExpr
118     : nth SPACE+ deltaUnit (SPACE+ deltaBeforeAfter)?
119     ;
120
121 deltaNextLast
122     : (NEXT|LAST) ;
123
124 deltaPlusMinusTimeExpr
125     : countUnitsBeforeAfterTimeExpr
126     | fractionBeforeAfterTimeExpr
127     ;
128
129 countUnitsBeforeAfterTimeExpr
130     : nth (SPACE+ deltaTimeUnit)? SPACE+ deltaTimeBeforeAfter
131     ;
132
133 fractionBeforeAfterTimeExpr
134     : deltaTimeFraction SPACE+ deltaTimeBeforeAfter
135     ;
136
137 deltaUnit: (YEAR|MONTH|WEEK|DAY|WEEKDAY|WORKDAY) ;
138
139 deltaTimeUnit: (SECOND|MINUTE|HOUR|WORKDAY) ;
140
141 deltaBeforeAfter: (BEFORE|AFTER) ;
142
143 deltaTimeBeforeAfter: (BEFORE|AFTER) ;
144
145 monthExpr
146     : monthName
147     | monthNumber
148     ;
149
150 year: DIGIT DIGIT DIGIT DIGIT ;
151
152 specialDate: SPECIAL_DATE ;
153
154 dayOfMonth
155     : DIGIT DIGIT? ('st'|'ST'|'nd'|'ND'|'rd'|'RD'|'th'|'TH')?
156     | KALENDS (SPACE+ 'of')?
157     | IDES (SPACE+ 'of')?
158     | NONES (SPACE+ 'of')?
159     ;
160
161 firstOrLast: (FIRST|LAST) ;
162
163 nth: (DASH|PLUS)? DIGIT+ ('st'|'ST'|'nd'|'ND'|'rd'|'RD'|'th'|'TH')? ;
164
165 unsignedInt: DIGIT+ ;
166
167 deltaTimeFraction: DELTA_TIME_FRACTION ;
168
169 specialTimeExpr: specialTime (SPACE+ tzExpr)? ;
170
171 specialTime: SPECIAL_TIME ;
172
173 dayName: WEEKDAY ;
174
175 monthName: MONTH_NAME ;
176
177 monthNumber: DIGIT DIGIT? ;
178
179 hour: DIGIT DIGIT? ;
180
181 minute: DIGIT DIGIT ;
182
183 second: DIGIT DIGIT ;
184
185 micros: DIGIT DIGIT? DIGIT? DIGIT? DIGIT? DIGIT? DIGIT? ;
186
187 ddiv: (SLASH|DASH|',') ;
188
189 tdiv: (COLON|DOT) ;
190
191 dtdiv: ('T'|'t'|'at'|'AT'|','|';') ;
192
193 tddiv: ('on'|'ON'|','|';') ;
194
195 tzExpr
196     : ntz
197     | ltz
198     ;
199
200 ntz: (PLUS|DASH) DIGIT DIGIT COLON? DIGIT DIGIT ;
201
202 ltz: UPPERCASE_STRING ;
203
204 // ----------------------------------
205
206 SPACE: [ \t\r\n] ;
207
208 COMMENT: '#' ~[\r\n]* -> skip ;
209
210 THE: ('the'|'The') SPACE* -> skip ;
211
212 DASH: '-' ;
213
214 PLUS: '+' ;
215
216 SLASH: '/' ;
217
218 DOT: '.' ;
219
220 COLON: ':' ;
221
222 MONTH_NAME: (JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC) ;
223
224 JAN : 'jan'
225     | 'Jan'
226     | 'JAN'
227     | 'January'
228     | 'january'
229     ;
230
231 FEB : 'feb'
232     | 'Feb'
233     | 'FEB'
234     | 'February'
235     | 'february'
236     ;
237
238 MAR : 'mar'
239     | 'Mar'
240     | 'MAR'
241     | 'March'
242     | 'march'
243     ;
244
245 APR : 'apr'
246     | 'Apr'
247     | 'APR'
248     | 'April'
249     | 'april'
250     ;
251
252 MAY : 'may'
253     | 'May'
254     | 'MAY'
255     ;
256
257 JUN : 'jun'
258     | 'Jun'
259     | 'JUN'
260     | 'June'
261     | 'june'
262     ;
263
264 JUL : 'jul'
265     | 'Jul'
266     | 'JUL'
267     | 'July'
268     | 'july'
269     ;
270
271 AUG : 'aug'
272     | 'Aug'
273     | 'AUG'
274     | 'August'
275     | 'august'
276     ;
277
278 SEP : 'sep'
279     | 'Sep'
280     | 'SEP'
281     | 'sept'
282     | 'Sept'
283     | 'SEPT'
284     | 'September'
285     | 'september'
286     ;
287
288 OCT : 'oct'
289     | 'Oct'
290     | 'OCT'
291     | 'October'
292     | 'october'
293     ;
294
295 NOV : 'nov'
296     | 'Nov'
297     | 'NOV'
298     | 'November'
299     | 'november'
300     ;
301
302 DEC : 'dec'
303     | 'Dec'
304     | 'DEC'
305     | 'December'
306     | 'december'
307     ;
308
309 WEEKDAY: (SUN|MON|TUE|WED|THU|FRI|SAT) ;
310
311 SUN : 'sun'
312     | 'Sun'
313     | 'SUN'
314     | 'suns'
315     | 'Suns'
316     | 'SUNS'
317     | 'sunday'
318     | 'Sunday'
319     | 'sundays'
320     | 'Sundays'
321     ;
322
323 MON : 'mon'
324     | 'Mon'
325     | 'MON'
326     | 'mons'
327     | 'Mons'
328     | 'MONS'
329     | 'monday'
330     | 'Monday'
331     | 'mondays'
332     | 'Mondays'
333     ;
334
335 TUE : 'tue'
336     | 'Tue'
337     | 'TUE'
338     | 'tues'
339     | 'Tues'
340     | 'TUES'
341     | 'tuesday'
342     | 'Tuesday'
343     | 'tuesdays'
344     | 'Tuesdays'
345     ;
346
347 WED : 'wed'
348     | 'Wed'
349     | 'WED'
350     | 'weds'
351     | 'Weds'
352     | 'WEDS'
353     | 'wednesday'
354     | 'Wednesday'
355     | 'wednesdays'
356     | 'Wednesdays'
357     ;
358
359 THU : 'thu'
360     | 'Thu'
361     | 'THU'
362     | 'thur'
363     | 'Thur'
364     | 'THUR'
365     | 'thurs'
366     | 'Thurs'
367     | 'THURS'
368     | 'thursday'
369     | 'Thursday'
370     | 'thursdays'
371     | 'Thursdays'
372     ;
373
374 FRI : 'fri'
375     | 'Fri'
376     | 'FRI'
377     | 'fris'
378     | 'Fris'
379     | 'FRIS'
380     | 'friday'
381     | 'Friday'
382     | 'fridays'
383     | 'Fridays'
384     ;
385
386 SAT : 'sat'
387     | 'Sat'
388     | 'SAT'
389     | 'sats'
390     | 'Sats'
391     | 'SATS'
392     | 'saturday'
393     | 'Saturday'
394     | 'saturdays'
395     | 'Saturdays'
396     ;
397
398 WEEK
399     : 'week'
400     | 'Week'
401     | 'weeks'
402     | 'Weeks'
403     | 'wks'
404     ;
405
406 DAY
407     : 'day'
408     | 'Day'
409     | 'days'
410     | 'Days'
411     ;
412
413 HOUR
414     : 'hour'
415     | 'Hour'
416     | 'hours'
417     | 'Hours'
418     | 'hrs'
419     ;
420
421 MINUTE
422     : 'min'
423     | 'Min'
424     | 'MIN'
425     | 'mins'
426     | 'Mins'
427     | 'MINS'
428     | 'minute'
429     | 'Minute'
430     | 'minutes'
431     | 'Minutes'
432     ;
433
434 SECOND
435     : 'sec'
436     | 'Sec'
437     | 'SEC'
438     | 'secs'
439     | 'Secs'
440     | 'SECS'
441     | 'second'
442     | 'Second'
443     | 'seconds'
444     | 'Seconds'
445     ;
446
447 MONTH
448     : 'month'
449     | 'Month'
450     | 'months'
451     | 'Months'
452     ;
453
454 YEAR
455     : 'year'
456     | 'Year'
457     | 'years'
458     | 'Years'
459     | 'yrs'
460     ;
461
462 SPECIAL_DATE
463     : TODAY
464     | YESTERDAY
465     | TOMORROW
466     | NEW_YEARS_EVE
467     | NEW_YEARS_DAY
468     | MARTIN_LUTHER_KING_DAY
469     | PRESIDENTS_DAY
470     | EASTER
471     | MEMORIAL_DAY
472     | INDEPENDENCE_DAY
473     | LABOR_DAY
474     | COLUMBUS_DAY
475     | VETERANS_DAY
476     | HALLOWEEN
477     | THANKSGIVING_DAY
478     | CHRISTMAS_EVE
479     | CHRISTMAS
480     ;
481
482 SPECIAL_TIME
483     : NOON
484     | MIDNIGHT
485     ;
486
487 NOON
488     : ('noon'|'Noon'|'midday'|'Midday')
489     ;
490
491 MIDNIGHT
492     : ('midnight'|'Midnight')
493     ;
494
495 // today
496 TODAY
497     : ('today'|'Today'|'now'|'Now')
498     ;
499
500 // yeste
501 YESTERDAY
502     : ('yesterday'|'Yesterday')
503     ;
504
505 // tomor
506 TOMORROW
507     : ('tomorrow'|'Tomorrow')
508     ;
509
510 // easte
511 EASTER
512     : 'easter' SUN?
513     | 'Easter' SUN?
514     ;
515
516 // newye
517 NEW_YEARS_DAY
518     : 'new years'
519     | 'New Years'
520     | 'new years day'
521     | 'New Years Day'
522     | 'new year\'s'
523     | 'New Year\'s'
524     | 'new year\'s day'
525     | 'New year\'s Day'
526     ;
527
528 // newyeeve
529 NEW_YEARS_EVE
530     : 'nye'
531     | 'NYE'
532     | 'new years eve'
533     | 'New Years Eve'
534     | 'new year\'s eve'
535     | 'New Year\'s Eve'
536     ;
537
538 // chris
539 CHRISTMAS
540     : 'christmas'
541     | 'Christmas'
542     | 'christmas day'
543     | 'Christmas Day'
544     | 'xmas'
545     | 'Xmas'
546     | 'xmas day'
547     | 'Xmas Day'
548     ;
549
550 // chriseve
551 CHRISTMAS_EVE
552     : 'christmas eve'
553     | 'Christmas Eve'
554     | 'xmas eve'
555     | 'Xmas Eve'
556     ;
557
558 // mlk
559 MARTIN_LUTHER_KING_DAY
560     : 'martin luther king day'
561     | 'Martin Luther King Day'
562     | 'mlk day'
563     | 'MLK Day'
564     | 'MLK day'
565     | 'mlk'
566     | 'MLK'
567     ;
568
569 // memor
570 MEMORIAL_DAY
571     : 'memorial'
572     | 'Memorial'
573     | 'memorial day'
574     | 'Memorial Day'
575     ;
576
577 // indep
578 INDEPENDENCE_DAY
579     : 'independence day'
580     | 'Independence day'
581     | 'Independence Day'
582     ;
583
584 // labor
585 LABOR_DAY
586     : 'labor'
587     | 'Labor'
588     | 'labor day'
589     | 'Labor Day'
590     ;
591
592 // presi
593 PRESIDENTS_DAY
594     : 'presidents\' day'
595     | 'president\'s day'
596     | 'presidents day'
597     | 'presidents'
598     | 'president\'s'
599     | 'presidents\''
600     | 'Presidents\' Day'
601     | 'President\'s Day'
602     | 'Presidents Day'
603     | 'Presidents'
604     | 'President\'s'
605     | 'Presidents\''
606     ;
607
608 // colum
609 COLUMBUS_DAY
610     : 'columbus'
611     | 'columbus day'
612     | 'indiginous peoples day'
613     | 'indiginous peoples\' day'
614     | 'Columbus'
615     | 'Columbus Day'
616     | 'Indiginous Peoples Day'
617     | 'Indiginous Peoples\' Day'
618     ;
619
620 // veter
621 VETERANS_DAY
622     : 'veterans'
623     | 'veterans day'
624     | 'veterans\' day'
625     | 'Veterans'
626     | 'Veterans Day'
627     | 'Veterans\' Day'
628     ;
629
630 // hallo
631 HALLOWEEN
632     : 'halloween'
633     | 'Halloween'
634     ;
635
636 // thank
637 THANKSGIVING_DAY
638     : 'thanksgiving'
639     | 'thanksgiving day'
640     | 'Thanksgiving'
641     | 'Thanksgiving Day'
642     ;
643
644 FIRST: ('first'|'First') ;
645
646 LAST: ('last'|'Last'|'this past') ;
647
648 THIS: ('this'|'This'|'this coming') ;
649
650 NEXT: ('next'|'Next') ;
651
652 AGO_FROM_NOW: (AGO|FROM_NOW) ;
653
654 AGO: ('ago'|'Ago'|'back'|'Back') ;
655
656 FROM_NOW: ('from now'|'From Now') ;
657
658 BEFORE: ('to'|'To'|'before'|'Before'|'til'|'until'|'Until') ;
659
660 AFTER: ('after'|'After'|'from'|'From'|'past'|'Past') ;
661
662 DELTA_TIME_FRACTION: ('quarter'|'Quarter'|'half'|'Half') ;
663
664 DIGIT: ('0'..'9') ;
665
666 IDES: ('ides'|'Ides') ;
667
668 NONES: ('nones'|'Nones') ;
669
670 KALENDS: ('kalends'|'Kalends') ;
671
672 WORKDAY
673     : 'workday'
674     | 'workdays'
675     | 'work days'
676     | 'working days'
677     | 'Workday'
678     | 'Workdays'
679     | 'Work Days'
680     | 'Working Days'
681     ;
682
683 UPPERCASE_STRING: [A-Z]+ ;