⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 getdate.y

📁 sloedgy open sip stack source code
💻 Y
📖 第 1 页 / 共 2 页
字号:
%{
/*
**  Originally written by Steven M. Bellovin <smb@research.att.com> while
**  at the University of North Carolina at Chapel Hill.  Later tweaked by
**  a couple of people on Usenet.  Completely overhauled by Rich $alz
**  <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
**
**  Major hack to coerce it into use with the Equivalence Portable
**  Windows Library.
**
**  This grammar has 10 shift/reduce conflicts.
**
**  This code is in the public domain and has no copyright.
*/
/* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */
/* SUPPRESS 288 on yyerrlab *//* Label unused */


#include <time.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

#ifndef EOF
#include <stdio.h>
#endif


#ifdef _WIN32
#ifdef _MSC_VER
#pragma warning(disable:4131 4701 4996)
#endif
#define STDAPICALLTYPE __stdcall
#define MSDOS
#else
#define STDAPICALLTYPE
#endif


extern int  STDAPICALLTYPE PTimeGetChar(void * stream);
extern void STDAPICALLTYPE PTimeUngetChar(void * stream, int c);
int STDAPICALLTYPE PTimeGetDateOrder();
int STDAPICALLTYPE PTimeIsMonthName(const char *, int, int);
int STDAPICALLTYPE PTimeIsDayName(const char *, int, int);


#define EPOCH		1970
#define HOUR(x)		((time_t)(x) * 60)
#define SECSPERDAY	(24L * 60L * 60L)


/*
**  An entry in the lexical lookup table.
*/
typedef struct _TABLE {
    char	*name;
    int		type;
    time_t	value;
} TABLE;


/*
**  Daylight-savings mode:  on, off, or not yet known.
*/
typedef enum _DSTMODE {
    DSTon, DSToff, DSTmaybe
} DSTMODE;

/*
**  Meridian:  am, pm, or 24-hour style.
*/
typedef enum _MERIDIAN {
    MERam, MERpm, MER24
} MERIDIAN;


/*
**  Global variables.  We could get rid of most of these by using a good
**  union as the yacc stack.  (This routine was originally written before
**  yacc had the %union construct.)  Maybe someday; right now we only use
**  the %union very rarely.
*/
struct Variables {
    void	*yyInput;
    DSTMODE	yyDSTmode;
    time_t	yyDayOrdinal;
    time_t	yyDayNumber;
    int	yyHaveDate;
    int	yyHaveDay;
    int	yyHaveRel;
    int	yyHaveTime;
    int	yyHaveZone;
    time_t	yyTimezone;
    time_t	yyDay;
    time_t	yyHour;
    time_t	yyMinutes;
    time_t	yyMonth;
    time_t	yySeconds;
    time_t	yyYear;
    MERIDIAN	yyMeridian;
    time_t	yyRelMonth;
    time_t	yyRelSeconds;
};

#define VARIABLE ((struct Variables*)parseParam)


#define YYPURE		1
#define YYLEX_PARAM	VARIABLE->yyInput
#define YYPARSE_PARAM	parseParam

#define yyparse		PTime_yyparse
#define yylex		PTime_yylex
#define yyerror		PTime_yyerror

static int yyparse(void *); 
static int yylex();

#ifdef __GNUC__
static int yyerror();
#else
static void yyerror();
#endif


static void SetPossibleDate(struct Variables*, time_t, time_t, time_t);


%}

%pure_parser

%union {
    time_t		Number;
    enum _MERIDIAN	Meridian;
}

%token	tAGO tDAY tDAYZONE tID tMERIDIAN tMINUTE_UNIT tMONTH tMONTH_UNIT
%token	tSNUMBER tUNUMBER t4DIGITNUMBER t6DIGITNUMBER
%token	tSEC_UNIT tZONE tMILZONE tDST

%type	<Number>	tDAY tDAYZONE tMINUTE_UNIT tMONTH tMONTH_UNIT
%type	<Number>	tSNUMBER tUNUMBER t4DIGITNUMBER t6DIGITNUMBER unumber
%type	<Number>	tSEC_UNIT tZONE tMILZONE
%type	<Meridian>	tMERIDIAN o_merid

%%

spec	: /* NULL */
	| spec item
	;

item	: time {
	    VARIABLE->yyHaveTime++;
	}
	| zone {
	    VARIABLE->yyHaveZone++;
	}
	| date {
	    VARIABLE->yyHaveDate++;
	}
	| day {
	    VARIABLE->yyHaveDay++;
	}
	| rel {
	    VARIABLE->yyHaveRel++;
	}
	| number
	;

time	: tUNUMBER tMERIDIAN {
	    VARIABLE->yyHour = $1;
	    VARIABLE->yyMinutes = 0;
	    VARIABLE->yySeconds = 0;
	    VARIABLE->yyMeridian = $2;
	}
        | t4DIGITNUMBER tSNUMBER {
	    VARIABLE->yyHour = $1/100;
	    VARIABLE->yyMinutes = $1%100;
	    VARIABLE->yySeconds = 0;
	    VARIABLE->yyMeridian = MER24;
	    VARIABLE->yyDSTmode = DSToff;
	    VARIABLE->yyTimezone = - ($2 % 100 + ($2 / 100) * 60);
        }
        | t6DIGITNUMBER tSNUMBER {
	    VARIABLE->yyHour = $1/10000;
	    VARIABLE->yyMinutes = ($1/100)%100;
	    VARIABLE->yySeconds = $1 % 100;
	    VARIABLE->yyMeridian = MER24;
	    VARIABLE->yyDSTmode = DSToff;
	    VARIABLE->yyTimezone = - ($2 % 100 + ($2 / 100) * 60);
        }
	|  unumber ':' unumber o_merid {
	    VARIABLE->yyHour = $1;
	    VARIABLE->yyMinutes = $3;
	    VARIABLE->yySeconds = 0;
	    VARIABLE->yyMeridian = $4;
	}
	| unumber ':' unumber tSNUMBER {
	    VARIABLE->yyHour = $1;
	    VARIABLE->yyMinutes = $3;
	    VARIABLE->yyMeridian = MER24;
	    VARIABLE->yyDSTmode = DSToff;
	    VARIABLE->yyTimezone = - ($4 % 100 + ($4 / 100) * 60);
	}
	| unumber ':' unumber ':' unumber o_merid {
	    VARIABLE->yyHour = $1;
	    VARIABLE->yyMinutes = $3;
	    VARIABLE->yySeconds = $5;
	    VARIABLE->yyMeridian = $6;
	}
	| unumber ':' unumber ':' unumber tSNUMBER {
	    VARIABLE->yyHour = $1;
	    VARIABLE->yyMinutes = $3;
	    VARIABLE->yySeconds = $5;
	    VARIABLE->yyMeridian = MER24;
	    VARIABLE->yyDSTmode = DSToff;
	    VARIABLE->yyTimezone = - ($6 % 100 + ($6 / 100) * 60);
	}
	;

zone	: tZONE {
	    VARIABLE->yyTimezone = $1;
	    VARIABLE->yyDSTmode = DSToff;
	}
	| tDAYZONE {
	    VARIABLE->yyTimezone = $1;
	    VARIABLE->yyDSTmode = DSTon;
	}
	|
	  tZONE tDST {
	    VARIABLE->yyTimezone = $1;
	    VARIABLE->yyDSTmode = DSTon;
	}
        | tMILZONE {
            if (VARIABLE->yyHaveTime > 0) {
	      VARIABLE->yyTimezone = $1;
	      VARIABLE->yyDSTmode = DSToff;
            }
            else
              VARIABLE->yyHaveZone--;
        }
	;

day	: tDAY {
	    VARIABLE->yyDayOrdinal = 1;
	    VARIABLE->yyDayNumber = $1;
	}
	| tDAY ',' {
	    VARIABLE->yyDayOrdinal = 1;
	    VARIABLE->yyDayNumber = $1;
	}
	| unumber tDAY {
	    VARIABLE->yyDayOrdinal = $1;
	    VARIABLE->yyDayNumber = $2;
	}
	;

date	: unumber '/' unumber {
	    SetPossibleDate(VARIABLE, $1, $3, VARIABLE->yyYear);
	}
	| unumber '/' unumber '/' unumber {
	    SetPossibleDate(VARIABLE, $1, $3, $5);
	}
	| unumber tSNUMBER tSNUMBER {
	    /* ISO 8601 format.  yyyy-mm-dd.  */
	    if ($1 > 31) {
		VARIABLE->yyYear = $1;
		VARIABLE->yyMonth = -$2;
		VARIABLE->yyDay = -$3;
	    }
	    else
		SetPossibleDate(VARIABLE, $1, -$2, -$3);
	}
	| unumber tMONTH tSNUMBER {
	    /* e.g. 17-JUN-1992.  */
	    VARIABLE->yyDay = $1;
	    VARIABLE->yyMonth = $2;
	    VARIABLE->yyYear = -$3;
	}
	| tMONTH unumber {
	    VARIABLE->yyMonth = $1;
	    VARIABLE->yyDay = $2;
	}
	| tMONTH unumber ',' unumber {
	    VARIABLE->yyMonth = $1;
	    VARIABLE->yyDay = $2;
	    VARIABLE->yyYear = $4;
	}
	| unumber tMONTH {
	    VARIABLE->yyMonth = $2;
	    VARIABLE->yyDay = $1;
	}
	| unumber tMONTH unumber {
	    VARIABLE->yyMonth = $2;
	    VARIABLE->yyDay = $1;
	    VARIABLE->yyYear = $3;
	}
	;

rel	: relunit tAGO {
	    VARIABLE->yyRelSeconds = -VARIABLE->yyRelSeconds;
	    VARIABLE->yyRelMonth = -VARIABLE->yyRelMonth;
	}
	| relunit
	;

relunit	: unumber tMINUTE_UNIT {
	    VARIABLE->yyRelSeconds += $1 * $2 * 60L;
	}
	| tSNUMBER tMINUTE_UNIT {
	    VARIABLE->yyRelSeconds += $1 * $2 * 60L;
	}
	| tMINUTE_UNIT {
	    VARIABLE->yyRelSeconds += $1 * 60L;
	}
	| tSNUMBER tSEC_UNIT {
	    VARIABLE->yyRelSeconds += $1;
	}
	| unumber tSEC_UNIT {
	    VARIABLE->yyRelSeconds += $1;
	}
	| tSEC_UNIT {
	    VARIABLE->yyRelSeconds++;
	}
	| tSNUMBER tMONTH_UNIT {
	    VARIABLE->yyRelMonth += $1 * $2;
	}
	| unumber tMONTH_UNIT {
	    VARIABLE->yyRelMonth += $1 * $2;
	}
	| tMONTH_UNIT {
	    VARIABLE->yyRelMonth += $1;
	}
	;

unumber : tUNUMBER {
	    $$ = $1;
	}
        | t4DIGITNUMBER {
	    $$ = $1;
	}
        | t6DIGITNUMBER {
	    $$ = $1;
	}
        ;

number	: tUNUMBER {
	    if (VARIABLE->yyHaveTime && VARIABLE->yyHaveDate && !VARIABLE->yyHaveRel)
		VARIABLE->yyYear = $1;
	    else {
		if($1>240000) {
		    VARIABLE->yyHaveDate++;
		    VARIABLE->yyDay= ($1)%100;
		    VARIABLE->yyMonth= ($1/100)%100;
		    VARIABLE->yyYear = $1/10000;
		}
		else {
		    VARIABLE->yyHaveTime++;
		    if ($1 < 10000) {
		    	VARIABLE->yyHour = $1 / 100;
		    	VARIABLE->yyMinutes = $1 % 100;
		        VARIABLE->yySeconds = 0;
		    }
		    else {
	                VARIABLE->yyHour = $1/10000;
	                VARIABLE->yyMinutes = ($1/100)%100;
	                VARIABLE->yySeconds = $1 % 100;
                    }
		    VARIABLE->yyMeridian = MER24;
	        }
	    }
	}
        | t4DIGITNUMBER {
	    if (VARIABLE->yyHaveTime && VARIABLE->yyHaveDate && !VARIABLE->yyHaveRel)
		VARIABLE->yyYear = $1;
	    else {
	        VARIABLE->yyHaveTime++;
	        VARIABLE->yyHour = $1/100;
	        VARIABLE->yyMinutes = $1%100;
	        VARIABLE->yySeconds = 0;
	        VARIABLE->yyMeridian = MER24;
            }
        }
        | t6DIGITNUMBER {
	    if (!VARIABLE->yyHaveDate && $1>240000) {
		VARIABLE->yyHaveDate++;
		VARIABLE->yyDay= ($1)%100;
		VARIABLE->yyMonth= ($1/100)%100;
		VARIABLE->yyYear = $1/10000;
	    }
	    else if (!VARIABLE->yyHaveTime) {
	        VARIABLE->yyHaveTime++;
	        VARIABLE->yyHour = $1/10000;
	        VARIABLE->yyMinutes = ($1/100)%100;
	        VARIABLE->yySeconds = $1 % 100;
	        VARIABLE->yyMeridian = MER24;
            }
        }
	;

o_merid	: /* NULL */ {
	    $$ = MER24;
	}
	| tMERIDIAN {
	    $$ = $1;
	}
	;

%%

/* Month and day table. */
static TABLE const MonthDayTable[] = {
    { "january",	tMONTH,  1 },
    { "february",	tMONTH,  2 },
    { "march",		tMONTH,  3 },
    { "april",		tMONTH,  4 },
    { "may",		tMONTH,  5 },
    { "june",		tMONTH,  6 },
    { "july",		tMONTH,  7 },
    { "august",		tMONTH,  8 },
    { "september",	tMONTH,  9 },
    { "sept",		tMONTH,  9 },
    { "october",	tMONTH, 10 },
    { "november",	tMONTH, 11 },
    { "december",	tMONTH, 12 },
    { "sunday",		tDAY, 0 },
    { "monday",		tDAY, 1 },
    { "tuesday",	tDAY, 2 },
    { "tues",		tDAY, 2 },
    { "wednesday",	tDAY, 3 },
    { "wednes",		tDAY, 3 },
    { "thursday",	tDAY, 4 },
    { "thur",		tDAY, 4 },
    { "thurs",		tDAY, 4 },
    { "friday",		tDAY, 5 },
    { "saturday",	tDAY, 6 },
    { NULL }
};

/* Time units table. */
static TABLE const UnitsTable[] = {
    { "year",		tMONTH_UNIT,	12 },
    { "month",		tMONTH_UNIT,	1 },
    { "fortnight",	tMINUTE_UNIT,	14 * 24 * 60 },
    { "week",		tMINUTE_UNIT,	7 * 24 * 60 },
    { "day",		tMINUTE_UNIT,	1 * 24 * 60 },
    { "hour",		tMINUTE_UNIT,	60 },
    { "minute",		tMINUTE_UNIT,	1 },
    { "min",		tMINUTE_UNIT,	1 },
    { "second",		tSEC_UNIT,	1 },
    { "sec",		tSEC_UNIT,	1 },
    { NULL }
};

/* Assorted relative-time words. */
static TABLE const OtherTable[] = {
    { "tomorrow",	tMINUTE_UNIT,	1 * 24 * 60 },
    { "yesterday",	tMINUTE_UNIT,	-1 * 24 * 60 },
    { "today",		tMINUTE_UNIT,	0 },
    { "now",		tMINUTE_UNIT,	0 },
    { "last",		tUNUMBER,	-1 },
    { "this",		tMINUTE_UNIT,	0 },
    { "next",		tUNUMBER,	2 },
    { "first",		tUNUMBER,	1 },
/*  { "second",		tUNUMBER,	2 }, */
    { "third",		tUNUMBER,	3 },
    { "fourth",		tUNUMBER,	4 },
    { "fifth",		tUNUMBER,	5 },
    { "sixth",		tUNUMBER,	6 },
    { "seventh",	tUNUMBER,	7 },
    { "eighth",		tUNUMBER,	8 },
    { "ninth",		tUNUMBER,	9 },
    { "tenth",		tUNUMBER,	10 },
    { "eleventh",	tUNUMBER,	11 },
    { "twelfth",	tUNUMBER,	12 },
    { "ago",		tAGO,	1 },
    { NULL }
};

/* The timezone table. */
/* Some of these are commented out because a time_t can't store a float. */
static TABLE const TimezoneTable[] = {
    { "gmt",	tZONE,     HOUR( 0) },	/* Greenwich Mean */
    { "ut",	tZONE,     HOUR( 0) },	/* Universal (Coordinated) */
    { "utc",	tZONE,     HOUR( 0) },
    { "wet",	tZONE,     HOUR( 0) },	/* Western European */
    { "bst",	tDAYZONE,  HOUR( 0) },	/* British Summer */
    { "wat",	tZONE,     HOUR( 1) },	/* West Africa */
    { "at",	tZONE,     HOUR( 2) },	/* Azores */
#if	0
    /* For completeness.  BST is also British Summer, and GST is
     * also Guam Standard. */
    { "bst",	tZONE,     HOUR( 3) },	/* Brazil Standard */
    { "gst",	tZONE,     HOUR( 3) },	/* Greenland Standard */
#endif
#if 0
    { "nft",	tZONE,     HOUR(3.5) },	/* Newfoundland */
    { "nst",	tZONE,     HOUR(3.5) },	/* Newfoundland Standard */
    { "ndt",	tDAYZONE,  HOUR(3.5) },	/* Newfoundland Daylight */
#endif
    { "ast",	tZONE,     HOUR( 4) },	/* Atlantic Standard */
    { "adt",	tDAYZONE,  HOUR( 4) },	/* Atlantic Daylight */
    { "est",	tZONE,     HOUR( 5) },	/* Eastern Standard */
    { "edt",	tDAYZONE,  HOUR( 5) },	/* Eastern Daylight */
    { "cst",	tZONE,     HOUR( 6) },	/* Central Standard */
    { "cdt",	tDAYZONE,  HOUR( 6) },	/* Central Daylight */
    { "mst",	tZONE,     HOUR( 7) },	/* Mountain Standard */
    { "mdt",	tDAYZONE,  HOUR( 7) },	/* Mountain Daylight */
    { "pst",	tZONE,     HOUR( 8) },	/* Pacific Standard */
    { "pdt",	tDAYZONE,  HOUR( 8) },	/* Pacific Daylight */
    { "yst",	tZONE,     HOUR( 9) },	/* Yukon Standard */
    { "ydt",	tDAYZONE,  HOUR( 9) },	/* Yukon Daylight */
    { "hst",	tZONE,     HOUR(10) },	/* Hawaii Standard */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -