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