diff options
Diffstat (limited to 'parsetime.yy')
-rw-r--r-- | parsetime.yy | 283 |
1 files changed, 0 insertions, 283 deletions
diff --git a/parsetime.yy b/parsetime.yy deleted file mode 100644 index 36bc08b9..00000000 --- a/parsetime.yy +++ /dev/null @@ -1,283 +0,0 @@ -%{ -#define YYSTYPE struct ledger::intorchar - -#include "times.h" -#include "FlexLexer.h" - -static struct std::tm * timeval; - -namespace { - ledger::moment_t moment; - - struct time_to_leave : std::exception {}; - - yyFlexLexer * lexer; - - inline void yyerror(const char *str) { - throw new ledger::datetime_error(str); - } - - inline int yylex(void) { - return lexer->yylex(); - } - - int month_to_int(const std::string& name) - { - switch (std::toupper(name[0])) { - case 'J': - if (std::tolower(name[1]) == 'a') - return 1; - else if (std::tolower(name[2]) == 'n') - return 6; - else - return 7; - case 'F': - return 2; - case 'M': - if (std::tolower(name[2]) == 'r') - return 3; - else - return 5; - case 'A': - if (std::tolower(name[1]) == 'p') - return 4; - else - return 8; - case 'S': - return 9; - case 'O': - return 10; - case 'N': - return 11; - case 'D': - return 12; - default: - std::cerr << "What?? (" << name << ")" << std::endl; - assert(0); - return -1; - } - } - - void set_mdy(const ledger::intorchar& month, - const ledger::intorchar& day, - const ledger::intorchar& year = ledger::intorchar(), - bool shortyear = false) - { - if (ledger::day_before_month) { - timeval->tm_mon = (day.ival == -1 ? - month_to_int(day.sval) : day.ival) - 1; - timeval->tm_mday = month.ival; - } else { - timeval->tm_mon = (month.ival == -1 ? - month_to_int(month.sval) : month.ival) - 1; - timeval->tm_mday = day.ival; - } - - if (year.ival != -1) - timeval->tm_year = (shortyear ? - (year.ival < 70 ? year.ival + 100 : year.ival) : - year.ival - 1900); - } - - void set_hms(const ledger::intorchar& ampm, - const ledger::intorchar& hour, - const ledger::intorchar& min = ledger::intorchar(), - const ledger::intorchar& sec = ledger::intorchar()) - { - if (! ampm.sval.empty() && - std::tolower(ampm.sval[0]) == 'a' && hour.ival == 12) - timeval->tm_hour = 0; - else if (! ampm.sval.empty() && - std::tolower(ampm.sval[0]) == 'p' && hour.ival == 12) - timeval->tm_hour = 12; - else if (hour.ival < 0 || (ampm.sval.empty() && hour.ival > 23) || - (! ampm.sval.empty() && hour.ival > 12)) - throw ledger::datetime_error("Hour out of range"); - else - timeval->tm_hour += hour.ival; - - if (min.ival < -1 || min.ival > 59) - throw ledger::datetime_error("Minute out of range"); - if (sec.ival < -1 || sec.ival > 59) - throw ledger::datetime_error("Seconds out of range"); - - timeval->tm_min = min.ival == -1 ? 0 : min.ival; - timeval->tm_sec = sec.ival == -1 ? 0 : sec.ival; - } -} - -%} - -%token TOK_FOURNUM -%token TOK_TWONUM -%token TOK_ONENUM -%token TOK_MONTH -%token TOK_AMPM - -%token TOK_SPACE - -%left '/' '-' '.' 'T' - -%% - -input: date -{ - throw time_to_leave(); -}; - -date: absdate opttime -{ - if (timeval->tm_gmtoff != -1) { - boost::posix_time::ptime::time_duration_type offset; - offset = boost::posix_time::seconds(timeval->tm_gmtoff); - moment = boost::posix_time::from_time_t(timegm(timeval)) - offset; - } else { - moment = boost::posix_time::ptime_from_tm(*timeval); - } -}; - -absdate: - isodate -| year '/' morday '/' morday { set_mdy($3, $5, $1); } -| year '-' morday '-' morday { set_mdy($3, $5, $1); } -| year '.' morday '.' morday { set_mdy($3, $5, $1); } -| morday '/' morday '/' year { set_mdy($1, $3, $5); } -| morday '-' morday '-' year { set_mdy($1, $3, $5); } -| morday '.' morday '.' year { set_mdy($1, $3, $5); } -| morday '.' morday { set_mdy($1, $3); } -| morday '/' morday { set_mdy($1, $3); } -| morday '-' morday { set_mdy($1, $3); } -| morday '/' morday '/' TOK_TWONUM { set_mdy($1, $3, $5, true); } -| morday '-' morday '-' TOK_TWONUM { set_mdy($1, $3, $5, true); } -| morday '.' morday '.' TOK_TWONUM { set_mdy($1, $3, $5, true); } -| year TOK_SPACE TOK_MONTH TOK_SPACE morday { set_mdy($3, $5, $1); } -| morday TOK_SPACE TOK_MONTH TOK_SPACE year { set_mdy($3, $1, $5); } -| TOK_MONTH TOK_SPACE morday { set_mdy($1, $3); } -| morday TOK_SPACE TOK_MONTH { set_mdy($3, $1); } -| year '-' TOK_MONTH '-' morday { set_mdy($3, $5, $1); } -| morday '-' TOK_MONTH '-' year { set_mdy($3, $1, $5); } -| TOK_MONTH '-' morday { set_mdy($1, $3); } -| morday '-' TOK_MONTH { set_mdy($3, $1); } -| TOK_MONTH TOK_SPACE morday ',' TOK_SPACE year { set_mdy($1, $3, $6); } -; - -opttime: /* epsilon */ | TOK_SPACE time ; - -time: - onetwo optspace TOK_AMPM { - if (std::tolower($3.sval[0]) == 'p') - timeval->tm_hour = 12; - else - timeval->tm_hour = 0; - - set_hms($3, $1); - } -| - onetwo ':' TOK_TWONUM optampm { - set_hms($4, $1, $3); - } -| - onetwo ':' TOK_TWONUM ':' TOK_TWONUM optampm { - set_hms($6, $1, $3, $5); - } -; - -onetwo: TOK_ONENUM { $$ = $1; } | TOK_TWONUM { $$ = $1; } ; - -optspace: /* epsilon */ | TOK_SPACE ; - -optampm: /* epsilon */ | - optspace TOK_AMPM { - if (std::tolower($2.sval[0]) == 'p') - timeval->tm_hour = 12; - else - timeval->tm_hour = 0; - $$ = $2; - }; - -isodate: - year TOK_FOURNUM optisotime -{ - timeval->tm_year = $1.ival - 1900; - timeval->tm_mon = $2.ival / 100 - 1; - timeval->tm_mday = $3.ival % 100; -}; - -optisotime: /* epsilon */ | - 'T' TOK_FOURNUM TOK_TWONUM optisozone -{ - timeval->tm_hour = $2.ival / 100; - timeval->tm_min = $2.ival % 100; - timeval->tm_sec = $3.ival; -}; - -optisozone: /* epsilon */ | - '-' TOK_FOURNUM { - timeval->tm_gmtoff = - (($2.ival / 100) * 3600 + ($2.ival % 100) * 60); - } -| '+' TOK_FOURNUM { - timeval->tm_gmtoff = (($2.ival / 100) * 3600 + ($2.ival % 100) * 60); - }; - -year: TOK_FOURNUM { $$ = $1; }; - -morday: - TOK_TWONUM { $$ = $1; } -| TOK_ONENUM { $$ = $1; }; - -%% - -int yywrap() -{ - return 1; -} - -ledger::moment_t parse_abs_datetime(std::istream& input) -{ - lexer = new yyFlexLexer(&input); - - struct std::tm temp; - std::memset(&temp, 0, sizeof(struct std::tm)); - temp.tm_year = 2002 - 1900; - temp.tm_gmtoff = -1; - - timeval = &temp; - - // jww (2007-04-19): Catch any boost errors thrown from here and - // push them onto the new error stack scheme. - try { - if (yyparse() == 0) { - delete lexer; - return moment; - } - } - catch (const time_to_leave&) { - delete lexer; - return moment; - } - catch (ledger::datetime_error *) { - delete lexer; - throw; - } - catch (...) { - delete lexer; - throw new ledger::datetime_error("Failed to parse date/time"); - } - delete lexer; - throw new ledger::datetime_error("Failed to parse date/time"); -} - -#ifdef MAIN - -namespace ledger { - bool day_before_month = false; -} - -int main() -{ - yydebug = 1; - std::cout << parse_abs_datetime(std::cin) << std::endl; - return 0; -} - -#endif // MAIN |