%{ /* * lex(1) specification for tokens for the Unidata units package, udunits. */ #ifndef _XOPEN_SOURCE # define _XOPEN_SOURCE #endif #ifndef _ANSI_C_SOURCE # define _ANSI_C_SOURCE #endif #include #include #include #include #include #include #include #include #include #include "udunits.h" #include "utprivate.h" /* private definitions */ #include "utparse.h" /* #include "udunits.h" before this one */ #include "utscan.h" %} space ([ \t]) integer ([+-]?[0-9]+) exp ([eE][+-]?[0-9]+) real ([+-]?[0-9]*("."[0-9]*{exp}?|{exp})) year ([+-]?[0-9]{1,4}) month (0?[1-9]|1[0-2]) day (0?[1-9]|[1-2][0-9]|30|31) hour ([0-1]?[0-9]|2[0-3]) minute ([0-5]?[0-9]) second (({minute}|60)("."[0-9]*)?) name (%|[a-zA-Z][a-zA-Z_]*([0-9]+[a-zA-Z_]+)*) %Start shift_seen date_seen time_seen %% "#".* { /* comment */ ; } {space}*("@"|after|AFTER|from|FROM|since|SINCE|ref|REF){space}* { BEGIN shift_seen; return SHIFT; } {space}*(per|PER|"/"){space}* { BEGIN 0; return DIVIDE; } "-"|"."|"*"|{space}+ { BEGIN 0; return MULTIPLY; } "^"|"**" { BEGIN 0; return EXPONENT; } {year}"-"{month}"-"{day}T?{space}* { int year; int month; int day; (void) sscanf((char*)yytext, "%d-%d-%d", &year, &month, &day); yylval.rval = utencdate(year, month, day); BEGIN date_seen; return DATE; } now{space}* { time_t now; struct tm *tp; errno = 0; if (time(&now) == -1) { (void) fprintf(stderr, "udunits(3): Can't get current time. %s\n", strerror(errno)); return ERR; } if ((tp = gmtime(&now)) == NULL) { (void) fprintf(stderr, "udunits(3): can't get UTC time\n"); return ERR; } yylval.rval = utencdate(1900+tp->tm_year, 1+tp->tm_mon, tp->tm_mday) + utencclock(tp->tm_hour, tp->tm_min, (double)tp->tm_sec); BEGIN 0; return REAL; } {hour}(":"{minute}(":"{second})?)?{space}* { int hour; int minute = 0; double second = 0.0; (void) sscanf((char*)yytext, "%d:%d:%lf", &hour, &minute, &second); yylval.rval = utencclock(hour, minute, second); BEGIN time_seen; return TIME; } [0-2][0-9][0-5][0-9]{space}* { int hour; int minute; (void) sscanf((char*)yytext, "%2d%2d", &hour, &minute); if (hour >= 24 || minute >= 60) return ERR; yylval.rval = utencclock(hour, minute, 0.0); BEGIN time_seen; return TIME; } ([0-9][0-5][0-9]){space}* { int hour; int minute; (void) sscanf((char*)yytext, "%1d%2d", &hour, &minute); if (minute >= 60) return ERR; yylval.rval = utencclock(hour, minute, 0.0); BEGIN time_seen; return TIME; } UTC{space}* { yylval.rval = 0; BEGIN 0; return ZONE; } ([+-]?{hour}":"{minute}){space}* { int hour; int minute; (void) sscanf((char*)yytext, "%d:%d", &hour, &minute); if (hour < 0) minute = -minute; yylval.rval = utencclock(hour, minute, 0.0); BEGIN 0; return ZONE; } ([+-]?{hour}":"?){space}* { int hour; (void) sscanf((char*)yytext, "%d", &hour); yylval.rval = utencclock(hour, 0, 0.0); BEGIN 0; return ZONE; } ([+-]{hour}{minute}){space}* { int zone; int hour; int minute; (void) sscanf((char*)yytext, "%d", &zone); minute = zone < 0 ? -(-zone % 100) : zone % 100; hour = (zone - minute) / 100; yylval.rval = utencclock(hour, minute, 0.0); BEGIN 0; return ZONE; } {name} { if (strlen((char*)yytext) > UT_NAMELEN-1) (void) fprintf(stderr, "udunits(3): Name `%s' too long; truncated\n", yytext); (void) strncpy(yylval.name, (char*)yytext, UT_NAMELEN-1); yylval.name[UT_NAMELEN-1] = 0; BEGIN 0; return NAME; } {integer} { int status; errno = 0; yylval.ival = atol((char*)yytext); if (errno == 0) { status = INT; } else { (void) fputs("udunits(3): Invalid integer\n", stderr); status = ERR; } BEGIN 0; return status; } {real} { int status; errno = 0; yylval.rval = atof((char*)yytext); if (errno == 0) { status = REAL; } else { (void) fputs("udunits(3): Invalid real\n", stderr); status = ERR; } BEGIN 0; return status; } ")" { BEGIN 0; return yytext[0]; } . { return yytext[0]; } %% void utLexReset() { BEGIN 0; }