/*$Log: dateyacc.y,v $ /*Revision 1.1 2002-07-25 08:01:26 arjen /*First checkin, AXE release 0.2 /* * Revision 1.1 84/09/01 15:01:22 wales * Initial revision * * Copyright (c) 1984 by Richard B. Wales * * Purpose: * * YACC parser for "parsedate" routine. * * Usage: * * Called as needed by the "parsedate" routine in "parsedate.c". * Not intended to be called from any other routine. * * Notes: * * Global contents: * * int yyparse () * Parses the date string pointed to by the global variable * "yyinbuf". Sets the appropriate fields in the global data * structure "yyans". The returned value is 1 if there was a * syntax error, 0 if there was no error. * * Local contents: * * None. */ /* ajs * ajs Code added on 850314 to allow goal := year.date '.' time * ajs and year.date := [CC]YYMMDD (YY > 23) * ajs All added lines contain "ajs" for easy searching. * ajs */ %{ #ifdef RCSIDENT static char rcsident[] = "$Header: /cvsroot/lib/AXE/src/dateyacc.y,v 1.1 2002-07-25 08:01:26 arjen Exp $"; #endif RCSIDENT #include #include "parsedate.h" struct parseddate yyans; /* No error routine is needed here. */ #define yyerror(s) %} %union { int IntVal; } %token DAY_NAME %token MONTH_NAME %token NUM9 NUM23 NUM59 NUM99 NUM2359 NUM9999 NUM235959 %token NUM991231 NUM99991231 /* ajs */ %token AMPM %token STD_ZONE DST_ZONE DST_SUFFIX %type DAY_NAME %type MONTH_NAME %type NUM9 NUM23 NUM59 NUM99 NUM2359 NUM9999 NUM235959 %type NUM991231 NUM99991231 /* ajs */ %type AMPM %type STD_ZONE DST_ZONE %type num59 num zone.offset %start goal %% num59: NUM23 | NUM59 ; num: NUM9 | num59 ; goal: date | date dayname | date dayname time | date dayname time year | date dayname year | date dayname year time | date time | date time dayname | date time dayname year | date time year | date time year dayname | date.year | date.year dayname | date.year dayname time | date.year time | date.year time dayname | dayname date | dayname date time | dayname date time year | dayname date.year | dayname date.year time | dayname time date | dayname time date.year | dayname time year.date | dayname year.date | dayname year.date time | dayname year time date | time | time date | time date dayname | time date dayname year | time date.year | time date.year dayname | time dayname date | time dayname date.year | time dayname year.date | time year.date | time year.date dayname | time year dayname date | year.date | year.date dayname | year.date dayname time | year.date time | year.date time dayname | year dayname date | year dayname date time | year dayname time date | year time date | year time date dayname | year time dayname date | NUM2359 { yyans.hour = $1 / 100; yyans.minute = $1 % 100; yyans.second = -1; /* unspecified */ } | dayname | yymmdd '.' time2359 /* ajs */ | yymmdd '.' time /* ajs */ | yymmdd '.' time dayname /* ajs */ | error { extern char *yyinbuf; if (yyans.error == NULL) yyans.error = yyinbuf; } ; dayname: DAY_NAME { yyans.c_weekday = $1; } | DAY_NAME '.' { yyans.c_weekday = $1; } ; date.year: date year | hyphen.date '-' year | num '-' num '-' year { yyans.day = $1; yyans.month = $3; } | slash.date '/' year ; year.date: year date | year '-' hyphen.date | year '-' num '-' num { yyans.day = $5; yyans.month = $3; } | year '/' slash.date | yymmdd /* ajs */ ; /* ajs */ yymmdd: /* ajs */ NUM991231 /* ajs */ { yyans.year = ($1 / 10000) + 1900; /* ajs */ yyans.month = ($1 % 10000) / 100; /* ajs */ yyans.day = ($1 % 100); /* ajs */ } /* ajs */ /*| NUM235959 (leads to parser conflict) */ /* ajs */ | NUM99991231 /* ajs */ { yyans.year = ($1 / 10000); /* ajs */ yyans.month = ($1 % 10000) / 100; /* ajs */ yyans.day = ($1 % 100); /* ajs */ } /* ajs */ ; date: num month.name { yyans.day = $1; } | month.name num { yyans.day = $2; } | num num { yyans.month = $1; yyans.day = $2; } ; hyphen.date: num '-' month.name { yyans.day = $1; } | month.name '-' num { yyans.day = $3; } ; slash.date: num '/' month.name { yyans.day = $1; } | month.name '/' num { yyans.day = $3; } | num '/' num { yyans.month = $1; yyans.day = $3; } ; year: NUM59 /* 2-digit year < 60 : after 2000 */ { yyans.year = 2000 + $1; } | NUM23 { yyans.year = 2000 + $1; } | NUM99 /* precludes two-digit date before 1960 */ { yyans.year = 1900 + $1; } | NUM2359 { yyans.year = $1; } | NUM9999 { yyans.year = $1; } ; month.name: MONTH_NAME { yyans.month = $1; } | MONTH_NAME '.' { yyans.month = $1; } ; time: hour.alone | hour am.pm | hour zone | hour am.pm zone ; hour: NUM2359 { yyans.hour = $1 / 100; yyans.minute = $1 % 100; yyans.second = -1; /* unspecified */ } | hour.alone ; hour.alone: NUM9 ':' num59 { yyans.hour = $1; yyans.minute = $3; yyans.second = -1; /* unspecified */ } | NUM9 '.' num59 { yyans.hour = $1; yyans.minute = $3; yyans.second = -1; /* unspecified */ } | NUM9 ':' num59 ':' num59 { yyans.hour = $1; yyans.minute = $3; yyans.second = $5; } | NUM9 '.' num59 '.' num59 { yyans.hour = $1; yyans.minute = $3; yyans.second = $5; } | NUM23 ':' num59 { yyans.hour = $1; yyans.minute = $3; yyans.second = -1; /* unspecified */ } | NUM23 '.' num59 { yyans.hour = $1; yyans.minute = $3; yyans.second = -1; /* unspecified */ } | NUM23 ':' num59 ':' num59 { yyans.hour = $1; yyans.minute = $3; yyans.second = $5; } | NUM23 '.' num59 '.' num59 { yyans.hour = $1; yyans.minute = $3; yyans.second = $5; } | NUM2359 ':' num59 { yyans.hour = $1 / 100; yyans.minute = $1 % 100; yyans.second = $3; } | NUM2359 '.' num59 { yyans.hour = $1 / 100; yyans.minute = $1 % 100; yyans.second = $3; } | NUM235959 { yyans.hour = $1 / 10000; yyans.minute = ($1 % 10000) / 100; yyans.second = $1 % 100; } ; am.pm: AMPM { if (yyans.hour < 1 || yyans.hour > 12) yyans.hour = -1; /* invalid */ else { if (yyans.hour == 12) yyans.hour = 0; yyans.hour += $1; /* 0 for AM, 12 for PM */ } } ; zone: STD_ZONE { yyans.zone = $1; yyans.dst = 0; } | STD_ZONE DST_SUFFIX { yyans.zone = $1 + 60; yyans.dst = 1; } | '-' STD_ZONE { yyans.zone = $2; yyans.dst = 0; } | '-' STD_ZONE DST_SUFFIX { yyans.zone = $2 + 60; yyans.dst = 1; } | DST_ZONE { yyans.zone = $1; yyans.dst = 1; } | '-' DST_ZONE { yyans.zone = $2; yyans.dst = 1; } | '+' zone.offset { yyans.zone = $2; yyans.dst = 0; } | '-' '+' zone.offset { yyans.zone = $3; yyans.dst = 0; } | '-' zone.offset { yyans.zone = - $2; yyans.dst = 0; } | '-' '-' zone.offset { yyans.zone = - $3; yyans.dst = 0; } ; zone.offset: NUM9 { $$ = 60 * $1; } | NUM9 ':' num59 { $$ = 60 * $1 + $3; } | NUM9 '.' num59 { $$ = 60 * $1 + $3; } | NUM23 { $$ = 60 * $1; } | NUM23 ':' num59 { $$ = 60 * $1 + $3; } | NUM23 '.' num59 { $$ = 60 * $1 + $3; } | NUM2359 { $$ = 60 * ($1 / 100) | ($1 % 100); } ; time2359: /* ajs */ NUM2359 /* ajs */ { yyans.hour = $1 / 100; /* ajs */ yyans.minute = $1 % 100; /* ajs */ yyans.second = -1; /* ajs */ } /* ajs */ ; %%