view tests/agcl/parsifal/good/date_p1.c @ 0:13d2b8934445

Import AnaGram (near-)release tree into Mercurial.
author David A. Holland
date Sat, 22 Dec 2007 17:52:45 -0500
parents
children
line wrap: on
line source

/*
  Date Translator
  Copyright (c) 1995-1999, Parsifal Software
  All Rights Reserved
  See the file COPYING for license and usage terms.

  This program illustrates the use of AnaGram to translate a number of
  different representations of data into a common format. The example
  used shows how to translate any of a number of standard formats for
  entering a date into a single format for further processing.

  The parser illustrated here recognizes six basic date formats, and
  for each, will supply the current year if the year is not given. If
  months are entered by name, they may be spelled out in full, or
  abbreviated in the customary manner. Text may be upper or lower case.
  Spaces or tabs may be used freely between the elements of the dates.
  Some examples of the six formats, as applied to the date June 26,
  1999, are as follows:

    June 26  jun 26    June 26, 1999  JUN 26, 99    jun26,1999
    26 June  26 jun    26 June 1999   26 JUN 99     26jun99
    26-June  26-Jun    26-June-99     26-JUN-1999
    6/26     6/26/99   6/26/1999
    6-26     6-26-99   6-26-1999
    6.26     6.26.99   6-26.1999
    6/26/'99 6-26-'99  6.26.'99
    6/26 '99 6-26 '99  6.26 '99
    26/6     26/6/99   26/6/1999
    26-6     26-6-99   26-6-1999
    26.6     26.6.99   26.6.1999
    26/6 '99 26-6 '99  26.6 '99
    26 vi    26 vi 99  26 vi 1999     26 VI 99      26VI99
    26 vi '99

  If CHKDATE encounters a date of the form 2/3/99, it interrogates a
  switch to determine whether to interpret this in the European manner
  (March 2, 1999) or the American manner (February 3, 1999). Where the
  form is obvious, as in 6/26/98 or 26/6/98 it ignores the switch.

  CHKDATE also recognizes dates consisting of a month and year only.
  Where month and year cannot be distinguished from month and day,
  CHKDATE will assume month and day. When the year is given as a two
  digit number, 0 to 49 are assumed to refer to the coming 21st century
  and 50-99 are 20th century dates.  To force recognition as month and
  year, use an apostrophe or use more than 2 digits for the year:  Aug
  14 is the 14th of the month, Aug '14 is August 2014. For the
  beginning of WWI, use Aug 1914

  CHKDATE operates on a string in memory and stores the month, day and
  year in the variables mon, day, and yr respectively.

  checkDate() sets up the input pointer for CHKDATE and calls it.
  checkDate() then checks for error and adds 2000 to the year if the
  year specified was less than 50, otherwise it adds 1900 to the year
  if the year specified was less than 100. It returns non-zero in case
  of error and zero otherwise.

  main() simply reads a string from stdin, and passes it to
  checkDate(). If there is no error, it prints the date in a standard
  format and loops forever.

*/
/*
 * AnaGram, A System for Syntax Directed Programming
 * File generated by: ...
 *
 * AnaGram Parsing Engine
 * Copyright 1993-2002 Parsifal Software. All Rights Reserved.
 *
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must not
 *    claim that you wrote the original software. If you use this software
 *    in a product, an acknowledgment in the product documentation would be
 *    appreciated but is not required.
 * 2. Altered source versions must be plainly marked as such, and must not be
 *    misrepresented as being the original software.
 * 3. This notice may not be removed or altered from any source distribution.
 */

#ifndef DATE_P1_H
#include "date_p1.h"
#endif

#ifndef DATE_P1_H
#error Mismatched header file
#endif

#include <stdio.h>

#define RULE_CONTEXT (&((PCB).cs[(PCB).ssx]))
#define ERROR_CONTEXT ((PCB).cs[(PCB).error_frame_ssx])
#define CONTEXT ((PCB).cs[(PCB).ssx])



chkdate_pcb_type chkdate_pcb;
#define PCB chkdate_pcb

/*  Line -, date_p1.syn */
#include <time.h>

#define SYNTAX_ERROR

int    days[13]  = {0,31,29,31,30,31,30,31,31,30,31,30,31};
char  *monthName[13] = {NULL, "January", "February", "March", "April",
          "May", "June", "July", "August", "September", "October",
          "November", "December"};
int    mon = 0, day = 0, yr = 0;
int    thisYear;
int    european = 0;
int    matchChar = 0;

void monthDay(int m, int d) {
  if (m <= 12 && d > days[m]) day=0, mon = m, yr = d;
  else if (m > 12 || european ) day = m, mon =d , yr = thisYear;
  else mon=m, day=d, yr=thisYear;
}

void monthDayYear(int m, int d, int y) {
  if (m > 12 || european) day = m, mon = d;
  else mon = m, day = d;
  yr = y;
}

int checkDate(char *input) {
  PCB.pointer = (unsigned char *) input;
  chkdate();
  if (PCB.exit_flag != AG_SUCCESS_CODE) return 1;     /* fail on error */
  if (mon > 12) return 1;
  if (day > days[mon]) return 1;
  if (yr < 50) yr += 2000;
  else if (yr < 100 ) yr += 1900;
  return 0;
}

int main(int argc, char *argv[]) {
  char input[82];
  time_t timeOfDay;
  int k;

  for (k = 1; k < argc; k++) {
    switch (*argv[k]++) {
    case '/':
    case '-':
      if (*argv[k] == 'e') european = 1;
      break;
    }
  }
/*  Determine current year */

  timeOfDay = time(NULL);
  thisYear = localtime(&timeOfDay)->tm_year;

/* Loop forever, reading input strings and converting them */
  while (1) {
    gets(input);
    if (feof(stdin)) break;
    if (checkDate(input)) printf("%-30s Bad date\n", input);
    else if (day) printf("%-30s %s %d, %d\n", input, monthName[mon], day, yr);
    else printf("%-30s %s %d\n", input, monthName[mon], yr);
  }
  return 0;
}

#ifndef CONVERT_CASE

static const char agCaseTable[31] = {
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,    0,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
};

static int agConvertCase(int c) {
  if (c >= 'a' && c <= 'z') return c ^= 0x20;
  if (c >= 0xe0 && c < 0xff) c ^= agCaseTable[c-0xe0];
  return c;
}

#define CONVERT_CASE(c) agConvertCase(c)

#endif


#ifndef TAB_SPACING
#define TAB_SPACING 8
#endif

static void ag_rp_1(int m, int d) {
/* Line -, date_p1.syn */
    if (d > days[m] || d==0) day=0, yr=d;  //  (change to accommodate d = 0, made Dec. 11/99)
    else day=d, mon = m, yr = thisYear;
 
}

#define ag_rp_2(m, y) (day = 0, mon = m, yr = y)

#define ag_rp_3(m, y) (day = 0, mon = m, yr = y)

#define ag_rp_4(m, d, y) (day = d, mon = m, yr = y)

#define ag_rp_5(m, d, y) (day = d, mon = m, yr = y)

#define ag_rp_6(d) (day = d, yr = thisYear)

#define ag_rp_7(d) (day = d, yr = thisYear)

#define ag_rp_8(d, y) (day = d, yr = y)

#define ag_rp_9(d, y) (day = d, yr = y)

#define ag_rp_10(d, y) (day = d, yr = y)

#define ag_rp_11(m, d) (monthDay(m,d))

#define ag_rp_12(m, y) (day = 0, mon=m, yr = y)

#define ag_rp_13(m, d, y) (monthDayYear(m,d,y))

#define ag_rp_14(m, d, y) (monthDayYear(m,d,y))

#define ag_rp_15(d, m) (mon = m, day = d, yr = thisYear)

#define ag_rp_16(d, m, y) (mon = m, day = d, yr = y)

#define ag_rp_17(m, y) (day = 0, mon = m, yr = y)

#define ag_rp_18() (1)

#define ag_rp_19() (2)

#define ag_rp_20() (3)

#define ag_rp_21() (4)

#define ag_rp_22() (5)

#define ag_rp_23() (6)

#define ag_rp_24() (7)

#define ag_rp_25() (8)

#define ag_rp_26() (9)

#define ag_rp_27() (10)

#define ag_rp_28() (11)

#define ag_rp_29() (12)

#define ag_rp_30(c) (matchChar = c)

static void ag_rp_31(int c) {
/* Line -, date_p1.syn */
    if (matchChar != c) PCB.exit_flag = AG_SYNTAX_ERROR_CODE;
 
}

#define ag_rp_32(d) (d-'0')

#define ag_rp_33(n, d) (10*n + d-'0')

#define ag_rp_34() (9)

#define ag_rp_35() (4)

#define ag_rp_36() (1)

#define ag_rp_37() (5)

#define ag_rp_38() (10)

#define ag_rp_39(x) (x+1)


#define READ_COUNTS 
#define WRITE_COUNTS 
#undef V
#define V(i,t) (*t (&(PCB).vs[(PCB).ssx + i]))
#undef VS
#define VS(i) (PCB).vs[(PCB).ssx + i]

#ifndef GET_CONTEXT
#define GET_CONTEXT CONTEXT = (PCB).input_context
#endif

typedef enum {
  ag_action_1,
  ag_action_2,
  ag_action_3,
  ag_action_4,
  ag_action_5,
  ag_action_6,
  ag_action_7,
  ag_action_8,
  ag_action_9,
  ag_action_10,
  ag_action_11,
  ag_action_12
} ag_parser_action;


#ifndef NULL_VALUE_INITIALIZER
#define NULL_VALUE_INITIALIZER = 0
#endif

static int const ag_null_value NULL_VALUE_INITIALIZER;

static const unsigned char ag_rpx[] = {
    0,  0,  1,  2,  3,  4,  5,  6,  7,  0,  0,  8,  0,  0,  9, 10, 11,  0,
    0, 12, 13, 14, 15, 16, 17,  0,  0,  0,  0, 18, 19, 20, 21, 22, 23, 24,
   25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,  0, 36, 37, 38, 39
};

static const unsigned char ag_key_itt[] = {
 0
};

static const unsigned short ag_key_pt[] = {
0
};

static const unsigned char ag_key_ch[] = {
    0, 80, 85,255, 76, 78,255, 65, 85,255, 82, 89,255, 65,255, 65, 68, 70,
   74, 77, 78, 79, 83,255
};

static const unsigned char ag_key_act[] = {
  0,3,3,4,0,0,4,3,2,4,0,0,4,2,4,2,3,3,2,2,3,3,3,4
};

static const unsigned char ag_key_parm[] = {
    0, 22, 26,  0, 25, 24,  0, 16,  0,  0, 21, 23,  0,  0,  0,  0, 30, 20,
    0,  0, 29, 28, 27,  0
};

static const unsigned char ag_key_jmp[] = {
    0,  0,  2,  0,  0,  0,  0, 10,  4,  0,  0,  0,  0, 10,  0,  1,  4,  7,
    7, 13, 12, 15, 18,  0
};

static const unsigned char ag_key_index[] = {
   15, 15, 15,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 15,
    0,  0, 15,  0,  0,  0,  0,  0,  0,  0, 15, 15, 15,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
};

static const unsigned char ag_key_ends[] = {
82,0, 71,0, 69,67,0, 69,66,0, 78,0, 79,86,0, 67,84,0, 
69,80,0, 
};

#define AG_TCV(x) ag_tcv[(x)]

static const unsigned char ag_tcv[] = {
    7,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,
    0,  0,  0, 43,  0,  0,  0,  0, 45, 47, 47, 44, 32, 32, 32, 32, 32, 32,
   32, 32, 32, 32,  0,  0,  0,  0,  0,  0,  0, 37, 37, 37, 37, 37, 37, 37,
   37, 33, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 35, 37, 34, 37,
   37,  0,  0,  0,  0,  0,  0, 37, 37, 37, 37, 37, 37, 37, 37, 33, 37, 37,
   37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 35, 37, 34, 37, 37,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0
};

#ifndef SYNTAX_ERROR
#define SYNTAX_ERROR fprintf(stderr,"%s, line %d, column %d\n", \
  (PCB).error_message, (PCB).line, (PCB).column)
#endif

#ifndef FIRST_LINE
#define FIRST_LINE 1
#endif

#ifndef FIRST_COLUMN
#define FIRST_COLUMN 1
#endif

#ifndef PARSER_STACK_OVERFLOW
#define PARSER_STACK_OVERFLOW {fprintf(stderr, \
   "\nParser stack overflow, line %d, column %d\n",\
   (PCB).line, (PCB).column);}
#endif

#ifndef REDUCTION_TOKEN_ERROR
#define REDUCTION_TOKEN_ERROR {fprintf(stderr, \
    "\nReduction token error, line %d, column %d\n", \
    (PCB).line, (PCB).column);}
#endif


#ifndef INPUT_CODE
#define INPUT_CODE(T) (T)
#endif

typedef enum
  {ag_accept_key, ag_set_key, ag_jmp_key, ag_end_key, ag_no_match_key,
   ag_cf_accept_key, ag_cf_set_key, ag_cf_end_key} key_words;

static void ag_get_key_word(int ag_k) {
  int ag_save = (int) ((PCB).la_ptr - (PCB).pointer);
  const  unsigned char *ag_p;
  int ag_ch;
  while (1) {
    switch (ag_key_act[ag_k]) {
    case ag_cf_end_key: {
      const  unsigned char *sp = ag_key_ends + ag_key_jmp[ag_k];
      do {
        if ((ag_ch = *sp++) == 0) {
          int ag_k1 = ag_key_parm[ag_k];
          int ag_k2 = ag_key_pt[ag_k1];
          if (ag_key_itt[ag_k2 + CONVERT_CASE(*(PCB).la_ptr)]) goto ag_fail;
          (PCB).token_number = (chkdate_token_type) ag_key_pt[ag_k1 + 1];
          return;
        }
      } while (CONVERT_CASE(*(PCB).la_ptr++) == ag_ch);
      goto ag_fail;
    }
    case ag_end_key: {
      const  unsigned char *sp = ag_key_ends + ag_key_jmp[ag_k];
      do {
        if ((ag_ch = *sp++) == 0) {
          (PCB).token_number = (chkdate_token_type) ag_key_parm[ag_k];
          return;
        }
      } while (CONVERT_CASE(*(PCB).la_ptr++) == ag_ch);
    }
    case ag_no_match_key:
ag_fail:
      (PCB).la_ptr = (PCB).pointer + ag_save;
      return;
    case ag_cf_set_key: {
      int ag_k1 = ag_key_parm[ag_k];
      int ag_k2 = ag_key_pt[ag_k1];
      ag_k = ag_key_jmp[ag_k];
      if (ag_key_itt[ag_k2 + CONVERT_CASE(*(PCB).la_ptr)]) break;
      ag_save = (int) ((PCB).la_ptr - (PCB).pointer);
      (PCB).token_number = (chkdate_token_type) ag_key_pt[ag_k1+1];
      break;
    }
    case ag_set_key:
      ag_save = (int) ((PCB).la_ptr - (PCB).pointer);
      (PCB).token_number = (chkdate_token_type) ag_key_parm[ag_k];
    case ag_jmp_key:
      ag_k = ag_key_jmp[ag_k];
      break;
    case ag_accept_key:
      (PCB).token_number = (chkdate_token_type) ag_key_parm[ag_k];
      return;
    case ag_cf_accept_key: {
      int ag_k1 = ag_key_parm[ag_k];
      int ag_k2 = ag_key_pt[ag_k1];
      if (ag_key_itt[ag_k2 + CONVERT_CASE(*(PCB).la_ptr)])
        (PCB).la_ptr = (PCB).pointer + ag_save;
      else (PCB).token_number = (chkdate_token_type) ag_key_pt[ag_k1+1];
      return;
    }
    }
    ag_ch = CONVERT_CASE(*(PCB).la_ptr++);
    ag_p = &ag_key_ch[ag_k];
    if (ag_ch <= 255) while (*ag_p < ag_ch) ag_p++;
    if (ag_ch > 255 || *ag_p != ag_ch) {
      (PCB).la_ptr = (PCB).pointer + ag_save;
      return;
    }
    ag_k = (int) (ag_p - ag_key_ch);
  }
}


#ifndef AG_NEWLINE
#define AG_NEWLINE 10
#endif

#ifndef AG_RETURN
#define AG_RETURN 13
#endif

#ifndef AG_FORMFEED
#define AG_FORMFEED 12
#endif

#ifndef AG_TABCHAR
#define AG_TABCHAR 9
#endif

static void ag_track(void) {
  int ag_k = (int) ((PCB).la_ptr - (PCB).pointer);
  while (ag_k--) {
    switch (*(PCB).pointer++) {
    case AG_NEWLINE:
      (PCB).column = 1, (PCB).line++;
    case AG_RETURN:
    case AG_FORMFEED:
      break;
    case AG_TABCHAR:
      (PCB).column += (TAB_SPACING) - ((PCB).column - 1) % (TAB_SPACING);
      break;
    default:
      (PCB).column++;
    }
  }
}


static void ag_prot(void) {
  int ag_k;
  ag_k = 128 - ++(PCB).btsx;
  if (ag_k <= (PCB).ssx) {
    (PCB).exit_flag = AG_STACK_ERROR_CODE;
    PARSER_STACK_OVERFLOW;
    return;
  }
  (PCB).bts[(PCB).btsx] = (PCB).sn;
  (PCB).bts[ag_k] = (PCB).ssx;
  (PCB).vs[ag_k] = (PCB).vs[(PCB).ssx];
  (PCB).ss[ag_k] = (PCB).ss[(PCB).ssx];
}

static void ag_undo(void) {
  if ((PCB).drt == -1) return;
  while ((PCB).btsx) {
    int ag_k = 128 - (PCB).btsx;
    (PCB).sn = (PCB).bts[(PCB).btsx--];
    (PCB).ssx = (PCB).bts[ag_k];
    (PCB).vs[(PCB).ssx] = (PCB).vs[ag_k];
    (PCB).ss[(PCB).ssx] = (PCB).ss[ag_k];
  }
  (PCB).token_number = (chkdate_token_type) (PCB).drt;
  (PCB).ssx = (PCB).dssx;
  (PCB).sn = (PCB).dsn;
  (PCB).drt = -1;
}


static const unsigned char ag_tstt[] = {
35,34,33,32,30,29,28,27,26,25,24,23,22,21,20,16,1,0,39,40,
1,0,
35,34,33,32,30,29,28,27,26,25,24,23,22,21,20,16,0,2,3,4,5,6,36,41,42,46,
33,0,
35,34,0,
47,44,43,37,35,34,33,32,7,1,0,18,19,
47,44,43,37,35,34,33,32,7,1,0,18,19,
47,44,43,37,35,34,33,32,7,1,0,18,19,
47,44,43,37,35,34,33,32,7,1,0,18,19,
47,44,43,37,35,34,33,32,7,1,0,18,19,
47,44,43,37,35,34,33,32,7,1,0,18,19,
47,44,43,37,35,34,33,32,7,1,0,18,19,
47,44,43,37,35,34,33,32,7,1,0,18,19,
47,44,43,37,35,34,33,32,7,1,0,18,19,
47,44,43,37,35,34,33,32,7,1,0,18,19,
47,44,43,37,35,34,33,32,7,1,0,18,19,
43,32,7,1,0,39,40,
47,45,44,43,35,34,33,32,30,29,28,27,26,25,24,23,22,21,20,16,7,1,0,39,40,
47,44,43,32,7,1,0,39,40,
43,32,0,8,12,
47,44,43,35,34,33,30,29,28,27,26,25,24,23,22,21,20,16,0,2,3,9,11,15,36,38,
  42,46,
44,43,32,0,4,8,9,41,
7,0,
37,35,34,33,0,
32,1,0,39,40,
32,0,4,41,
32,0,4,41,
43,0,8,
43,32,30,29,28,27,26,25,24,23,22,21,20,16,1,0,39,40,
43,32,30,29,28,27,26,25,24,23,22,21,20,16,1,0,39,40,
32,30,29,28,27,26,25,24,23,22,21,20,16,0,2,4,41,42,
44,43,32,7,0,8,9,12,13,
32,0,4,41,
32,0,4,41,
45,44,0,9,10,
32,0,4,41,
47,44,43,0,8,9,14,38,
47,44,0,9,14,38,
32,0,4,41,
32,0,4,41,
32,0,4,41,
32,1,0,39,40,
32,0,4,41,
32,0,4,41,
43,32,0,8,12,
43,32,0,8,12,
32,0,4,41,
32,0,4,41,

};


static unsigned const char ag_astt[438] = {
  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,1,7,1,1,9,5,2,2,1,2,1,1,1,1,1,1,1,2,1,1,1,
  1,7,1,1,1,0,1,1,1,1,1,10,5,2,2,4,5,5,5,1,1,1,1,5,5,5,7,1,2,5,5,5,1,1,1,1,5,
  5,5,7,1,2,5,5,5,1,1,1,1,5,5,5,7,1,2,5,5,5,1,1,1,1,5,5,5,7,1,2,5,5,5,1,1,1,
  1,5,5,5,7,1,2,5,5,5,1,1,1,1,5,5,5,7,1,2,5,5,5,1,1,1,1,5,5,5,7,1,2,5,5,5,1,
  1,1,1,5,5,5,7,1,2,5,5,5,1,1,1,1,5,5,5,7,1,2,5,5,5,1,1,1,1,5,5,5,7,1,2,5,5,
  5,1,1,1,1,5,5,5,7,1,2,5,5,5,1,7,1,3,5,5,5,5,5,5,5,10,5,5,5,5,5,5,5,5,5,5,5,
  5,5,1,7,1,3,5,5,5,5,5,1,7,1,3,1,8,7,1,1,1,1,8,2,2,1,1,1,1,1,1,1,1,2,1,1,1,
  1,7,1,1,2,1,1,1,2,1,1,1,1,2,7,1,1,1,1,3,7,9,9,9,9,5,5,1,7,1,3,2,7,2,1,2,4,
  2,1,1,7,1,5,5,5,5,5,5,5,5,5,5,5,5,5,5,1,7,1,3,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  1,7,1,3,2,1,1,1,1,1,1,1,2,1,1,1,1,5,1,1,1,1,1,1,8,4,7,1,1,1,1,2,7,2,1,2,7,
  2,1,1,1,4,1,1,2,7,2,1,1,1,1,4,1,2,1,2,1,1,4,2,1,2,2,7,2,1,2,7,2,1,2,7,2,1,
  5,1,7,1,3,2,7,2,1,2,7,2,1,1,8,7,1,1,1,8,7,1,1,2,7,2,1,2,7,2,1
};


static const unsigned char ag_pstt[] = {
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,1,2,
59,61,
49,50,4,43,5,6,7,8,9,10,11,33,12,13,14,15,2,21,19,20,0,22,3,17,18,16,
51,47,
46,45,48,
27,27,27,23,23,23,23,27,27,27,5,23,40,
27,27,27,23,23,23,23,27,27,27,6,23,39,
27,27,27,23,23,23,23,27,27,27,7,23,38,
27,27,27,23,23,23,23,27,27,27,8,23,37,
27,27,27,23,23,23,23,27,27,27,9,23,36,
27,27,27,23,23,23,23,27,27,27,10,23,35,
27,27,27,23,23,23,23,27,27,27,11,23,34,
27,27,27,23,23,23,23,27,27,27,12,23,32,
27,27,27,23,23,23,23,27,27,27,13,23,31,
27,27,27,23,23,23,23,27,27,27,14,23,30,
27,27,27,23,23,23,23,27,27,27,15,23,29,
60,60,60,1,16,1,67,
60,60,60,60,60,60,60,44,60,60,60,60,60,60,60,60,60,60,60,60,60,1,17,1,62,
60,60,60,60,60,1,18,1,63,
24,25,19,25,25,
29,28,27,49,50,4,5,6,7,8,9,10,11,33,12,13,14,15,20,31,26,41,30,27,3,41,18,
  16,
28,24,43,21,34,33,32,17,
1,22,
26,26,26,26,28,
60,1,24,1,64,
43,25,24,17,
43,22,23,17,
24,27,35,
60,60,60,60,60,60,60,60,60,60,60,60,60,60,1,28,1,65,
60,60,60,60,60,60,60,60,60,60,60,60,60,60,1,29,1,68,
43,5,6,7,8,9,10,11,33,12,13,14,15,18,37,36,17,18,
28,24,39,7,31,39,38,39,38,
43,32,4,17,
43,33,3,17,
41,28,2,40,42,
43,35,19,17,
29,28,24,16,43,42,44,42,
29,28,8,42,45,42,
43,38,14,17,
43,39,11,17,
43,40,6,17,
60,1,41,1,66,
43,42,5,17,
43,43,21,17,
24,46,44,46,46,
24,47,45,47,47,
43,46,20,17,
43,47,15,17,

};


static const unsigned short ag_sbt[] = {
     0,  20,  22,  48,  50,  53,  66,  79,  92, 105, 118, 131, 144, 157,
   170, 183, 196, 203, 228, 237, 242, 270, 278, 280, 285, 290, 294, 298,
   301, 319, 337, 355, 364, 368, 372, 377, 381, 389, 395, 399, 403, 407,
   412, 416, 420, 425, 430, 434, 438
};


static const unsigned short ag_sbe[] = {
    17,  21,  38,  49,  52,  63,  76,  89, 102, 115, 128, 141, 154, 167,
   180, 193, 200, 225, 234, 239, 260, 273, 279, 284, 287, 291, 295, 299,
   316, 334, 350, 359, 365, 369, 374, 378, 384, 391, 396, 400, 404, 409,
   413, 417, 422, 427, 431, 435, 438
};


static const unsigned char ag_fl[] = {
  2,2,2,3,3,4,4,2,3,0,1,4,0,1,4,6,3,0,1,4,6,5,2,3,3,1,2,0,1,2,2,2,2,1,2,
  2,2,2,2,2,2,1,1,1,2,2,2,1,1,1,1,2,1,1,1,1,1,1,1,2,0,1,2,2,2,2,2,2,2
};

static const unsigned char ag_ptt[] = {
    0,  5,  6,  6,  6,  6,  6,  6,  6, 12, 12,  6, 13, 13,  6,  6,  6, 15,
   15,  6,  6,  6,  6,  6,  6, 18, 18, 19, 19, 42, 42, 42, 42, 42, 42, 42,
   42, 42, 42, 42, 42, 11, 14, 41, 41, 46, 46, 46, 36, 36, 36, 36, 17, 17,
   17, 17, 31, 31, 39, 39, 40, 40,  4,  2,  8,  9, 10,  3, 38
};


static void ag_ra(void)
{
  switch(ag_rpx[(PCB).ag_ap]) {
    case 1: ag_rp_1(VS(0), VS(1)); break;
    case 2: ag_rp_2(VS(0), VS(2)); break;
    case 3: ag_rp_3(VS(0), VS(2)); break;
    case 4: ag_rp_4(VS(0), VS(1), VS(3)); break;
    case 5: ag_rp_5(VS(0), VS(1), VS(3)); break;
    case 6: ag_rp_6(VS(0)); break;
    case 7: ag_rp_7(VS(0)); break;
    case 8: ag_rp_8(VS(0), VS(3)); break;
    case 9: ag_rp_9(VS(0), VS(3)); break;
    case 10: ag_rp_10(VS(0), VS(5)); break;
    case 11: ag_rp_11(VS(0), VS(2)); break;
    case 12: ag_rp_12(VS(0), VS(3)); break;
    case 13: ag_rp_13(VS(0), VS(2), VS(5)); break;
    case 14: ag_rp_14(VS(0), VS(2), VS(4)); break;
    case 15: ag_rp_15(VS(0), VS(1)); break;
    case 16: ag_rp_16(VS(0), VS(1), VS(2)); break;
    case 17: ag_rp_17(VS(0), VS(2)); break;
    case 18: VS(0) = ag_rp_18(); break;
    case 19: VS(0) = ag_rp_19(); break;
    case 20: VS(0) = ag_rp_20(); break;
    case 21: VS(0) = ag_rp_21(); break;
    case 22: VS(0) = ag_rp_22(); break;
    case 23: VS(0) = ag_rp_23(); break;
    case 24: VS(0) = ag_rp_24(); break;
    case 25: VS(0) = ag_rp_25(); break;
    case 26: VS(0) = ag_rp_26(); break;
    case 27: VS(0) = ag_rp_27(); break;
    case 28: VS(0) = ag_rp_28(); break;
    case 29: VS(0) = ag_rp_29(); break;
    case 30: ag_rp_30(VS(0)); break;
    case 31: ag_rp_31(VS(0)); break;
    case 32: VS(0) = ag_rp_32(VS(0)); break;
    case 33: VS(0) = ag_rp_33(VS(0), VS(1)); break;
    case 34: VS(0) = ag_rp_34(); break;
    case 35: VS(0) = ag_rp_35(); break;
    case 36: VS(0) = ag_rp_36(); break;
    case 37: VS(0) = ag_rp_37(); break;
    case 38: VS(0) = ag_rp_38(); break;
    case 39: VS(0) = ag_rp_39(VS(0)); break;
  }
  (PCB).la_ptr = (PCB).pointer;
}

static int ag_action_1_r_proc(void);
static int ag_action_2_r_proc(void);
static int ag_action_3_r_proc(void);
static int ag_action_4_r_proc(void);
static int ag_action_1_s_proc(void);
static int ag_action_3_s_proc(void);
static int ag_action_1_proc(void);
static int ag_action_2_proc(void);
static int ag_action_3_proc(void);
static int ag_action_4_proc(void);
static int ag_action_5_proc(void);
static int ag_action_6_proc(void);
static int ag_action_7_proc(void);
static int ag_action_8_proc(void);
static int ag_action_9_proc(void);
static int ag_action_10_proc(void);
static int ag_action_11_proc(void);
static int ag_action_8_proc(void);


static int (*const  ag_r_procs_scan[])(void) = {
  ag_action_1_r_proc,
  ag_action_2_r_proc,
  ag_action_3_r_proc,
  ag_action_4_r_proc
};

static int (*const  ag_s_procs_scan[])(void) = {
  ag_action_1_s_proc,
  ag_action_2_r_proc,
  ag_action_3_s_proc,
  ag_action_4_r_proc
};

static int (*const  ag_gt_procs_scan[])(void) = {
  ag_action_1_proc,
  ag_action_2_proc,
  ag_action_3_proc,
  ag_action_4_proc,
  ag_action_5_proc,
  ag_action_6_proc,
  ag_action_7_proc,
  ag_action_8_proc,
  ag_action_9_proc,
  ag_action_10_proc,
  ag_action_11_proc,
  ag_action_8_proc
};


static int ag_action_10_proc(void) {
  int ag_t = (PCB).token_number;
  (PCB).btsx = 0, (PCB).drt = -1;
  do {
    ag_track();
    (PCB).token_number = (chkdate_token_type) AG_TCV(INPUT_CODE(*(PCB).la_ptr));
    (PCB).la_ptr++;
    if (ag_key_index[(PCB).sn]) {
      unsigned ag_k = ag_key_index[(PCB).sn];
      int ag_ch = CONVERT_CASE(INPUT_CODE(*(PCB).pointer));
      if (ag_ch <= 255) {
        while (ag_key_ch[ag_k] < ag_ch) ag_k++;
        if (ag_key_ch[ag_k] == ag_ch) ag_get_key_word(ag_k);
      }
    }
  } while ((PCB).token_number == (chkdate_token_type) ag_t);
  (PCB).la_ptr =  (PCB).pointer;
  return 1;
}

static int ag_action_11_proc(void) {
  int ag_t = (PCB).token_number;

  (PCB).btsx = 0, (PCB).drt = -1;
  do {
    (PCB).vs[(PCB).ssx] = *(PCB).pointer;
    (PCB).ssx--;
    ag_track();
    ag_ra();
    if ((PCB).exit_flag != AG_RUNNING_CODE) return 0;
    (PCB).ssx++;
    (PCB).token_number = (chkdate_token_type) AG_TCV(INPUT_CODE(*(PCB).la_ptr));
    (PCB).la_ptr++;
    if (ag_key_index[(PCB).sn]) {
      unsigned ag_k = ag_key_index[(PCB).sn];
      int ag_ch = CONVERT_CASE(INPUT_CODE(*(PCB).pointer));
      if (ag_ch <= 255) {
        while (ag_key_ch[ag_k] < ag_ch) ag_k++;
        if (ag_key_ch[ag_k] == ag_ch) ag_get_key_word(ag_k);
      }
    }
  }
  while ((PCB).token_number == (chkdate_token_type) ag_t);
  (PCB).la_ptr =  (PCB).pointer;
  return 1;
}

static int ag_action_3_r_proc(void) {
  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  (PCB).btsx = 0, (PCB).drt = -1;
  (PCB).reduction_token = (chkdate_token_type) ag_ptt[(PCB).ag_ap];
  ag_ra();
  return (PCB).exit_flag == AG_RUNNING_CODE;
}

static int ag_action_3_s_proc(void) {
  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  (PCB).btsx = 0, (PCB).drt = -1;
  (PCB).reduction_token = (chkdate_token_type) ag_ptt[(PCB).ag_ap];
  ag_ra();
  return (PCB).exit_flag == AG_RUNNING_CODE;
}

static int ag_action_4_r_proc(void) {
  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  (PCB).reduction_token = (chkdate_token_type) ag_ptt[(PCB).ag_ap];
  return 1;
}

static int ag_action_2_proc(void) {
  (PCB).btsx = 0, (PCB).drt = -1;
  if ((PCB).ssx >= 128) {
    (PCB).exit_flag = AG_STACK_ERROR_CODE;
    PARSER_STACK_OVERFLOW;
  }
  (PCB).vs[(PCB).ssx] = *(PCB).pointer;
  (PCB).ss[(PCB).ssx] = (PCB).sn;
  (PCB).ssx++;
  (PCB).sn = (PCB).ag_ap;
  ag_track();
  return 0;
}

static int ag_action_9_proc(void) {
  if ((PCB).drt == -1) {
    (PCB).drt=(PCB).token_number;
    (PCB).dssx=(PCB).ssx;
    (PCB).dsn=(PCB).sn;
  }
  ag_prot();
  (PCB).vs[(PCB).ssx] = ag_null_value;
  (PCB).ss[(PCB).ssx] = (PCB).sn;
  (PCB).ssx++;
  (PCB).sn = (PCB).ag_ap;
  (PCB).la_ptr =  (PCB).pointer;
  return (PCB).exit_flag == AG_RUNNING_CODE;
}

static int ag_action_2_r_proc(void) {
  (PCB).ssx++;
  (PCB).sn = (PCB).ag_ap;
  return 0;
}

static int ag_action_7_proc(void) {
  --(PCB).ssx;
  (PCB).la_ptr =  (PCB).pointer;
  (PCB).exit_flag = AG_SUCCESS_CODE;
  return 0;
}

static int ag_action_1_proc(void) {
  ag_track();
  (PCB).exit_flag = AG_SUCCESS_CODE;
  return 0;
}

static int ag_action_1_r_proc(void) {
  (PCB).exit_flag = AG_SUCCESS_CODE;
  return 0;
}

static int ag_action_1_s_proc(void) {
  (PCB).exit_flag = AG_SUCCESS_CODE;
  return 0;
}

static int ag_action_4_proc(void) {
  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
  (PCB).reduction_token = (chkdate_token_type) ag_ptt[(PCB).ag_ap];
  (PCB).btsx = 0, (PCB).drt = -1;
  (PCB).vs[(PCB).ssx] = *(PCB).pointer;
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  else (PCB).ss[(PCB).ssx] = (PCB).sn;
  ag_track();
  while ((PCB).exit_flag == AG_RUNNING_CODE) {
    unsigned ag_t1 = ag_sbe[(PCB).sn] + 1;
    unsigned ag_t2 = ag_sbt[(PCB).sn+1] - 1;
    do {
      unsigned ag_tx = (ag_t1 + ag_t2)/2;
      if (ag_tstt[ag_tx] < (unsigned char)(PCB).reduction_token) ag_t1 = ag_tx + 1;
      else ag_t2 = ag_tx;
    } while (ag_t1 < ag_t2);
    (PCB).ag_ap = ag_pstt[ag_t1];
    if ((ag_s_procs_scan[ag_astt[ag_t1]])() == 0) break;
  }
  return 0;
}

static int ag_action_3_proc(void) {
  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
  (PCB).btsx = 0, (PCB).drt = -1;
  (PCB).vs[(PCB).ssx] = *(PCB).pointer;
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  else (PCB).ss[(PCB).ssx] = (PCB).sn;
  ag_track();
  (PCB).reduction_token = (chkdate_token_type) ag_ptt[(PCB).ag_ap];
  ag_ra();
  while ((PCB).exit_flag == AG_RUNNING_CODE) {
    unsigned ag_t1 = ag_sbe[(PCB).sn] + 1;
    unsigned ag_t2 = ag_sbt[(PCB).sn+1] - 1;
    do {
      unsigned ag_tx = (ag_t1 + ag_t2)/2;
      if (ag_tstt[ag_tx] < (unsigned char)(PCB).reduction_token) ag_t1 = ag_tx + 1;
      else ag_t2 = ag_tx;
    } while (ag_t1 < ag_t2);
    (PCB).ag_ap = ag_pstt[ag_t1];
    if ((ag_s_procs_scan[ag_astt[ag_t1]])() == 0) break;
  }
  return 0;
}

static int ag_action_8_proc(void) {
  ag_undo();
  (PCB).la_ptr =  (PCB).pointer;
  (PCB).exit_flag = AG_SYNTAX_ERROR_CODE;
  SYNTAX_ERROR;
  {(PCB).la_ptr = (PCB).pointer + 1; ag_track();}
  return (PCB).exit_flag == AG_RUNNING_CODE;
}

static int ag_action_5_proc(void) {
  int ag_sd = ag_fl[(PCB).ag_ap];
  (PCB).btsx = 0, (PCB).drt = -1;
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  else {
    (PCB).ss[(PCB).ssx] = (PCB).sn;
  }
  (PCB).la_ptr =  (PCB).pointer;
  (PCB).reduction_token = (chkdate_token_type) ag_ptt[(PCB).ag_ap];
  ag_ra();
  while ((PCB).exit_flag == AG_RUNNING_CODE) {
    unsigned ag_t1 = ag_sbe[(PCB).sn] + 1;
    unsigned ag_t2 = ag_sbt[(PCB).sn+1] - 1;
    do {
      unsigned ag_tx = (ag_t1 + ag_t2)/2;
      if (ag_tstt[ag_tx] < (unsigned char)(PCB).reduction_token) ag_t1 = ag_tx + 1;
      else ag_t2 = ag_tx;
    } while (ag_t1 < ag_t2);
    (PCB).ag_ap = ag_pstt[ag_t1];
    if ((ag_r_procs_scan[ag_astt[ag_t1]])() == 0) break;
  }
  return (PCB).exit_flag == AG_RUNNING_CODE;
}

static int ag_action_6_proc(void) {
  int ag_sd = ag_fl[(PCB).ag_ap];
  (PCB).reduction_token = (chkdate_token_type) ag_ptt[(PCB).ag_ap];
  if ((PCB).drt == -1) {
    (PCB).drt=(PCB).token_number;
    (PCB).dssx=(PCB).ssx;
    (PCB).dsn=(PCB).sn;
  }
  if (ag_sd) {
    (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  }
  else {
    ag_prot();
    (PCB).vs[(PCB).ssx] = ag_null_value;
    (PCB).ss[(PCB).ssx] = (PCB).sn;
  }
  (PCB).la_ptr =  (PCB).pointer;
  while ((PCB).exit_flag == AG_RUNNING_CODE) {
    unsigned ag_t1 = ag_sbe[(PCB).sn] + 1;
    unsigned ag_t2 = ag_sbt[(PCB).sn+1] - 1;
    do {
      unsigned ag_tx = (ag_t1 + ag_t2)/2;
      if (ag_tstt[ag_tx] < (unsigned char)(PCB).reduction_token) ag_t1 = ag_tx + 1;
      else ag_t2 = ag_tx;
    } while (ag_t1 < ag_t2);
    (PCB).ag_ap = ag_pstt[ag_t1];
    if ((ag_r_procs_scan[ag_astt[ag_t1]])() == 0) break;
  }
  return (PCB).exit_flag == AG_RUNNING_CODE;
}


void init_chkdate(void) {
  (PCB).la_ptr = (PCB).pointer;
  (PCB).error_message = "Syntax Error";
  (PCB).ss[0] = (PCB).sn = (PCB).ssx = 0;
  (PCB).exit_flag = AG_RUNNING_CODE;
  (PCB).line = FIRST_LINE;
  (PCB).column = FIRST_COLUMN;
  (PCB).btsx = 0, (PCB).drt = -1;
}

void chkdate(void) {
  init_chkdate();
  (PCB).exit_flag = AG_RUNNING_CODE;
  while ((PCB).exit_flag == AG_RUNNING_CODE) {
    unsigned ag_t1 = ag_sbt[(PCB).sn];
    if (ag_tstt[ag_t1]) {
      unsigned ag_t2 = ag_sbe[(PCB).sn] - 1;
      (PCB).token_number = (chkdate_token_type) AG_TCV(INPUT_CODE(*(PCB).la_ptr));
      (PCB).la_ptr++;
      if (ag_key_index[(PCB).sn]) {
        unsigned ag_k = ag_key_index[(PCB).sn];
        int ag_ch = CONVERT_CASE(INPUT_CODE(*(PCB).pointer));
        if (ag_ch <= 255) {
          while (ag_key_ch[ag_k] < ag_ch) ag_k++;
          if (ag_key_ch[ag_k] == ag_ch) ag_get_key_word(ag_k);
        }
      }
      do {
        unsigned ag_tx = (ag_t1 + ag_t2)/2;
        if (ag_tstt[ag_tx] > (unsigned char)(PCB).token_number)
          ag_t1 = ag_tx + 1;
        else ag_t2 = ag_tx;
      } while (ag_t1 < ag_t2);
      if (ag_tstt[ag_t1] != (unsigned char)(PCB).token_number)
        ag_t1 = ag_sbe[(PCB).sn];
    }
    (PCB).ag_ap = ag_pstt[ag_t1];
    (ag_gt_procs_scan[ag_astt[ag_t1]])();
  }
}