📄 lex.l
字号:
%{/* * $Id: //pentools/main/datemath/lex.l#5 $ * * written by: Stephen J. Friedl * Software Consultant * Tustin, California USA * steve@unixwiz.net / www.unixwiz.net * * The is the lexer that produces the tokens for the datemath * parser. Our "tokens" are pretty simple stuff, though we do * have to make some judgments about centuries for two-digit * dates. */#include <stdio.h>#include <assert.h>#include <ctype.h>#include <string.h>#include "defs.h"#include "gram.h"#undef input#undef output#undef unputextern jdate_t yylval;int newcentury_cutoff = 40;static int valid_mdy(short const [] , jdate_t *);int yywrap(void){ return 1;}%}D [0-9]+%%"+" return(PLUS);"-" return(MINUS);"*" return(TIMES);"(" return(LPAREN);")" return(RPAREN);"%" return(MOD);"fday" return(FDAY);"lday" return(LDAY);"yymm" return(KYYMM);"year" return(YEAR);"month" return(MONTH);"day" return(DAY);"ndays" return(NDAYS);"week" return(WEEKS);"weeks" return(WEEKS);"doy" return(DOY);"today" { rtoday(&yylval); return(MMDDYY); }"tomorrow" { rtoday(&yylval); yylval++; return(MMDDYY); }"yesterday" { rtoday(&yylval); yylval--; return(MMDDYY); }{D}\/{D}\/{D} { /*------------------------------------------------------ * this is called for mm/dd/yy dates. */ short mdy[3]; if ( sscanf(yytext, "%hd/%hd/%hd", &mdy[MM], &mdy[DD], &mdy[YY]) == 3 && valid_mdy(mdy, &yylval)) { return(MMDDYY); } else { die("\"%s\" is an invalid MM/DD/YY date", yytext); } }{D}\/{D} { short mdy[3]; /*------------------------------------------------------ * This is called for a MM/YY date. */ mdy[DD] = 1; if ( sscanf(yytext, "%hd/%hd", &mdy[MM], &mdy[YY]) == 2 && valid_mdy(mdy, 0)) { mdy[YY] %= 100; yylval = mdy[YY]*100 + mdy[MM]; return(YYMM); } else { die("\"%s\" is an invalid MM/YY date", yytext); } }{D} { short mdy[3]; /*------------------------------------------------------ * this is the handler for a single number. It is possible * that the input could be a date, so we have to be careful * if input is ####, ######, or ########. */ yylval = atol(yytext); if (yyleng == 4) /* YYMM? */ { mdy[MM] = yylval % 100; mdy[DD] = 1; mdy[YY] = yylval / 100; if (valid_mdy(mdy, 0)) return(YYMM); else die("\"%s\" is an invalid YYMM date", yytext); } else if (yyleng == 6) /* mmddyy */ { mdy[MM] = yylval / 10000; mdy[DD] = (yylval / 100) % 100; mdy[YY] = yylval % 100; if (valid_mdy(mdy, &yylval)) return(MMDDYY); else die("\"%s\" is an invalid MMDDYY date", yytext); } else if (yyleng == 8) /* mmdd19yy */ { mdy[MM] = yylval / 1000000; mdy[DD] = (yylval / 10000) % 100; mdy[YY] = yylval % 10000; if (valid_mdy(mdy, &yylval)) return(MMDDYY); else die("\"%s\" is an invalid MMDDYYYY date", yytext); } return(INTEGER); }"/" return(DIV);[a-zA-Z][a-zA-Z0-9]* { die("unknown word \"%s\"", yytext); }[ ]+ ; /* ignore whitespace */%%#if 0/* * output() * * Given a character, handle the lex output function. Here, * "output" is only called for characters that are not specified * by the lexical description, so they are errors. So, we * print a nasty-gram and exit if we find one. */static void output(int c){ if ( isprint(c) ) die("Illegal character: '%c'", c); else if (c < ' ' || c == 0x7f) die("Illegal character: '^%c'", c + '@'); else if (c >= 0x80) die("Illegal character: '0x%02x'", c);}#endifvoid init_scan(char *p){ assert(p != 0); yy_scan_string( strlower(p) );}/* * valid_mdy() * * Return TRUE if the date is valid and FALSE if not. If the * long pointer is provided, stuff the converted Julian date into * it for later use. * * NOTE: if the first token is >100, then we assume this is * a collated date. */static int valid_mdy(const short *mdy, jdate_t *pjdate){jdate_t dummy_jdate;short lmdy[3]; assert(mdy != 0); if ( mdy[0] >= 100 ) { lmdy[YY] = mdy[0]; lmdy[MM] = mdy[1]; lmdy[DD] = mdy[2]; } else { lmdy[MM] = mdy[0]; lmdy[DD] = mdy[1]; lmdy[YY] = mdy[2]; } if (pjdate == 0) pjdate = &dummy_jdate; /*---------------------------------------------------------------- * if the date is between 00 and 99, assume they mean this century * and adjust the date accordingly. */ lmdy[YY] = year_to_yyyy(lmdy[YY]); return rmdyjul(lmdy, pjdate) == 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -