12a09a4cb18f9b1196707758fb269dc344fce3b0
[AXE.git] / src / dateyacc.y
1 /*$Log: dateyacc.y,v $
2 /*Revision 1.1  2002-07-25 08:01:26  arjen
3 /*First checkin, AXE release 0.2
4 /*
5  * Revision 1.1  84/09/01  15:01:22  wales
6  * Initial revision
7  * 
8  * Copyright (c) 1984 by Richard B. Wales
9  *
10  * Purpose:
11  *
12  *     YACC parser for "parsedate" routine.
13  *
14  * Usage:
15  *
16  *     Called as needed by the "parsedate" routine in "parsedate.c".
17  *     Not intended to be called from any other routine.
18  *
19  * Notes:
20  *
21  * Global contents:
22  *
23  *     int yyparse ()
24  *         Parses the date string pointed to by the global variable
25  *         "yyinbuf".  Sets the appropriate fields in the global data
26  *         structure "yyans".  The returned value is 1 if there was a
27  *         syntax error, 0 if there was no error.
28  *
29  * Local contents:
30  *
31  *     None.
32  */
33
34 /* ajs
35  * ajs  Code added on 850314 to allow   goal      := year.date '.' time
36  * ajs                          and     year.date := [CC]YYMMDD (YY > 23)
37  * ajs  All added lines contain "ajs" for easy searching.
38  * ajs  */
39
40 %{
41 #ifdef RCSIDENT
42 static char rcsident[] = "$Header: /cvsroot/lib/AXE/src/dateyacc.y,v 1.1 2002-07-25 08:01:26 arjen Exp $";
43 #endif RCSIDENT
44
45 #include <stdio.h>
46 #include "parsedate.h"
47 struct parseddate yyans;
48
49 /* No error routine is needed here. */
50 #define yyerror(s)
51 %}
52
53 %union {
54     int IntVal;
55 }
56
57 %token  DAY_NAME
58 %token  MONTH_NAME
59 %token  NUM9 NUM23 NUM59 NUM99 NUM2359 NUM9999 NUM235959
60 %token  NUM991231 NUM99991231                           /* ajs */
61 %token  AMPM
62 %token  STD_ZONE DST_ZONE DST_SUFFIX
63
64 %type   <IntVal>        DAY_NAME
65 %type   <IntVal>        MONTH_NAME
66 %type   <IntVal>        NUM9 NUM23 NUM59 NUM99 NUM2359 NUM9999 NUM235959
67 %type   <IntVal>        NUM991231 NUM99991231           /* ajs */
68 %type   <IntVal>        AMPM
69 %type   <IntVal>        STD_ZONE DST_ZONE
70 %type   <IntVal>        num59 num zone.offset
71
72 %start  goal
73 %%
74
75 num59:
76     NUM23
77   | NUM59
78   ;
79
80 num:
81     NUM9
82   | num59
83   ;
84
85 goal:
86     date
87   | date dayname
88   | date dayname time
89   | date dayname time year
90   | date dayname year
91   | date dayname year time
92   | date time
93   | date time dayname
94   | date time dayname year
95   | date time year
96   | date time year dayname
97   | date.year
98   | date.year dayname
99   | date.year dayname time
100   | date.year time
101   | date.year time dayname
102   | dayname date
103   | dayname date time
104   | dayname date time year
105   | dayname date.year
106   | dayname date.year time
107   | dayname time date
108   | dayname time date.year
109   | dayname time year.date
110   | dayname year.date
111   | dayname year.date time
112   | dayname year time date
113   | time
114   | time date
115   | time date dayname
116   | time date dayname year
117   | time date.year
118   | time date.year dayname
119   | time dayname date
120   | time dayname date.year
121   | time dayname year.date
122   | time year.date
123   | time year.date dayname
124   | time year dayname date
125   | year.date
126   | year.date dayname
127   | year.date dayname time
128   | year.date time
129   | year.date time dayname
130   | year dayname date
131   | year dayname date time
132   | year dayname time date
133   | year time date
134   | year time date dayname
135   | year time dayname date
136   | NUM2359
137         { yyans.hour   = $1 / 100;
138           yyans.minute = $1 % 100;
139           yyans.second = -1;            /* unspecified */
140         }
141   | dayname
142   | yymmdd '.' time2359                 /* ajs */
143   | yymmdd '.' time                     /* ajs */
144   | yymmdd '.' time dayname             /* ajs */
145   | error
146         { extern char *yyinbuf;
147           if (yyans.error == NULL) yyans.error = yyinbuf;
148         }
149   ;
150
151 dayname:
152     DAY_NAME
153         { yyans.c_weekday = $1; }
154   | DAY_NAME '.'
155         { yyans.c_weekday = $1; }
156   ;
157
158 date.year:
159     date year
160   | hyphen.date '-' year
161   | num '-' num '-' year
162         { yyans.day = $1; yyans.month = $3; }
163   | slash.date '/' year
164   ;
165
166 year.date:
167     year date
168   | year '-' hyphen.date
169   | year '-' num '-' num
170         { yyans.day = $5; yyans.month = $3; }
171   | year '/' slash.date
172   | yymmdd                                      /* ajs */
173   ;
174                                                 /* ajs */
175 yymmdd:                                         /* ajs */
176     NUM991231                                   /* ajs */
177         { yyans.year  = ($1 / 10000) + 1900;    /* ajs */
178           yyans.month = ($1 % 10000) / 100;     /* ajs */
179           yyans.day   = ($1 % 100);             /* ajs */
180         }                                       /* ajs */
181 /*| NUM235959   (leads to parser conflict) */   /* ajs */
182   | NUM99991231                                 /* ajs */
183         { yyans.year  = ($1 / 10000);           /* ajs */
184           yyans.month = ($1 % 10000) / 100;     /* ajs */
185           yyans.day   = ($1 % 100);             /* ajs */
186         }                                       /* ajs */
187   ;
188
189 date:
190     num month.name
191         { yyans.day = $1; }
192   | month.name num
193         { yyans.day = $2; }
194   | num num
195         { yyans.month = $1; yyans.day = $2; }
196   ;
197
198 hyphen.date:
199     num '-' month.name
200         { yyans.day = $1; }
201   | month.name '-' num
202         { yyans.day = $3; }
203   ;
204
205 slash.date:
206     num '/' month.name
207         { yyans.day = $1; }
208   | month.name '/' num
209         { yyans.day = $3; }
210   | num '/' num
211         { yyans.month = $1; yyans.day = $3; }
212   ;
213
214 year:
215     NUM59             /*  2-digit year < 60 : after 2000 */
216         { yyans.year = 2000 + $1; }
217   | NUM23
218         { yyans.year = 2000 + $1; }
219   | NUM99               /* precludes two-digit date before 1960 */
220         { yyans.year = 1900 + $1; }
221   | NUM2359
222         { yyans.year = $1; }
223   | NUM9999
224         { yyans.year = $1; }
225   ;
226
227 month.name:
228     MONTH_NAME
229         { yyans.month = $1; }
230   | MONTH_NAME '.'
231         { yyans.month = $1; }
232   ;
233
234 time:
235     hour.alone
236   | hour am.pm
237   | hour zone
238   | hour am.pm zone
239   ;
240
241 hour:
242     NUM2359
243         { yyans.hour   = $1 / 100;
244           yyans.minute = $1 % 100;
245           yyans.second = -1;            /* unspecified */
246         }
247   | hour.alone
248   ;
249
250 hour.alone:
251     NUM9 ':' num59
252         { yyans.hour   = $1;
253           yyans.minute = $3;
254           yyans.second = -1;            /* unspecified */
255         }
256   | NUM9 '.' num59
257         { yyans.hour   = $1;
258           yyans.minute = $3;
259           yyans.second = -1;            /* unspecified */
260         }
261   | NUM9 ':' num59 ':' num59
262         { yyans.hour   = $1;
263           yyans.minute = $3;
264           yyans.second = $5;
265         }
266   | NUM9 '.' num59 '.' num59
267         { yyans.hour   = $1;
268           yyans.minute = $3;
269           yyans.second = $5;
270         }
271   | NUM23 ':' num59
272         { yyans.hour   = $1;
273           yyans.minute = $3;
274           yyans.second = -1;            /* unspecified */
275         }
276   | NUM23 '.' num59
277         { yyans.hour   = $1;
278           yyans.minute = $3;
279           yyans.second = -1;            /* unspecified */
280         }
281   | NUM23 ':' num59 ':' num59
282         { yyans.hour   = $1;
283           yyans.minute = $3;
284           yyans.second = $5;
285         }
286   | NUM23 '.' num59 '.' num59
287         { yyans.hour   = $1;
288           yyans.minute = $3;
289           yyans.second = $5;
290         }
291   | NUM2359 ':' num59
292         { yyans.hour   = $1 / 100;
293           yyans.minute = $1 % 100;
294           yyans.second = $3;
295         }
296   | NUM2359 '.' num59
297         { yyans.hour   = $1 / 100;
298           yyans.minute = $1 % 100;
299           yyans.second = $3;
300         }
301   | NUM235959
302         { yyans.hour   = $1 / 10000;
303           yyans.minute = ($1 % 10000) / 100;
304           yyans.second = $1 % 100;
305         }
306   ;
307
308 am.pm:
309     AMPM
310         { if (yyans.hour < 1 || yyans.hour > 12)
311             yyans.hour = -1;            /* invalid */
312           else
313           { if (yyans.hour == 12) yyans.hour = 0;
314             yyans.hour += $1;           /* 0 for AM, 12 for PM */
315         } }
316   ;
317
318 zone:
319     STD_ZONE
320         { yyans.zone = $1; yyans.dst = 0; }
321   | STD_ZONE DST_SUFFIX
322         { yyans.zone = $1 + 60; yyans.dst = 1; }
323   | '-' STD_ZONE
324         { yyans.zone = $2; yyans.dst = 0; }
325   | '-' STD_ZONE DST_SUFFIX
326         { yyans.zone = $2 + 60; yyans.dst = 1; }
327   | DST_ZONE
328         { yyans.zone = $1; yyans.dst = 1; }
329   | '-' DST_ZONE
330         { yyans.zone = $2; yyans.dst = 1; }
331   | '+' zone.offset
332         { yyans.zone = $2; yyans.dst = 0; }
333   | '-' '+' zone.offset
334         { yyans.zone = $3; yyans.dst = 0; }
335   | '-' zone.offset
336         { yyans.zone = - $2; yyans.dst = 0; }
337   | '-' '-' zone.offset
338         { yyans.zone = - $3; yyans.dst = 0; }
339   ;
340
341 zone.offset:
342     NUM9
343         { $$ = 60 * $1; }
344   | NUM9 ':' num59
345         { $$ = 60 * $1 + $3; }
346   | NUM9 '.' num59
347         { $$ = 60 * $1 + $3; }
348   | NUM23
349         { $$ = 60 * $1; }
350   | NUM23 ':' num59
351         { $$ = 60 * $1 + $3; }
352   | NUM23 '.' num59
353         { $$ = 60 * $1 + $3; }
354   | NUM2359
355         { $$ = 60 * ($1 / 100) | ($1 % 100); }
356   ;
357
358 time2359:                               /* ajs */
359     NUM2359                             /* ajs */
360         { yyans.hour   = $1 / 100;      /* ajs */
361           yyans.minute = $1 % 100;      /* ajs */
362           yyans.second = -1;            /* ajs */
363         }                               /* ajs */
364   ;
365
366 %%