%{ /*- * date parser and calculator; * * caller must define and initialize, by call of jg_init(): * struct jul_greg jg * which has the Gregorian and Julian date information, modified by yyparse(); * * J. A. Rupley, Tucson, Arizona */ #include #include #include "jul_greg.h" extern struct jul_greg jg; %} %union { long julian; int val; } %start result %token MONTH DAY NUMBER UNIT PUNC MINUS TODAY ERROR %token JULIAN %% /* * result formulations return new values of date info, in struct jul_grep jg, * calculated through actions associated with productions following. */ result : /* empty */ /* no action */ | error { YYABORT; } | date_type /* no action */ | diff_type { return (2); /* flag -- date difference returned */ } ; diff_type : date_type MINUS { $$ = jg.j; if(jg_init(&jg)) return yyerror((char *)0); /* reinitialize */ } date_type { jg.j = $3 - jg.j; } ; date_type : date /* no action */ | date_type NUMBER UNIT /* modify date by NUMBER of day/week/mon/yr */ { if (jg_update($2, $3)) return yyerror((char *)0); } | date_type NUMBER DAY /* date for Nth weekDAY in date_type's month */ { if (jg_nth_day($2, $3)) return yyerror((char *)0); } ; date : TODAY /* reinitialize */ { if(jg_init(&jg)) return yyerror((char *)0); } | MONTH NUMBER /* month dd, */ { jg.m = $1; jg.d = $2; if (jg_update(0, 0)) return yyerror((char *)0); } | MONTH NUMBER PUNC NUMBER /* month dd, yy[yy] */ { jg.m = $1; jg.d = $2; jg.y = (($4 < 100) ? (2000 + $4) : $4); if (jg_update(0, 0)) return yyerror((char *)0); } | NUMBER PUNC NUMBER /* mm/dd */ { jg.m = $1; jg.d = $3; if (jg_update(0, 0)) return yyerror((char *)0); } | NUMBER PUNC NUMBER PUNC NUMBER /* mm/dd/yy[yy] */ { jg.m = $1; jg.d = $3; jg.y = (($5 < 100) ? (2000 + $5) : $5); if (jg_update(0, 0)) return yyerror((char *)0); } | DAY /* date for weekDAY of current week */ { jg_update($1 - jg.wd, 'd'); } | MONTH NUMBER DAY /* date for Nth weekDAY in month=MONTH */ { jg.m = $1; if (jg_nth_day($2, $3)) return yyerror((char *)0); } | NUMBER NUMBER DAY /* date for Nth weekDAY in month=NUMBER */ { jg.m = $1; if (jg_nth_day($2, $3)) return yyerror((char *)0); } | JULIAN /* convert julian to gregorian */ { jg_jdate($1); } ; %% /* end of grammar */ int yyerror(s) char *s; { extern char yytext[]; fprintf(stderr, "parser error: near token %s \n", yytext); if (s) fprintf(stderr, "%s\n", s); return 1; }