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