view anagram/agcore/engine.cgs @ 21:1c9dac05d040

Add lint-style FALLTHROUGH annotations to fallthrough cases. (in the parse engine and thus the output code) Document this, because the old output causes warnings with gcc10.
author David A. Holland
date Mon, 13 Jun 2022 00:04:38 -0400
parents 13d2b8934445
children
line wrap: on
line source

copyright
/*
 * AnaGram, A System for Syntax Directed Programming
 * File generated by: %s, built %s
 *
 * 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.
 */
##
broken
This copy of AnaGram appears to have been damaged or miscompiled.
New copies may be obtained via http://www.parsifalsoft.com.
##
header, chain header
#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])
##
function macro defs

AG_GET_KEY_WORD   ag_get_key_word(THISARGC#int ag_k)
AG_RNS            ag_rns(THISARGC#int ag_t, int *ag_sx, int ag_snd)
AG_JNS            ag_jns(THISARGC#int ag_t)
AG_ATX            ag_atx(THISARGC#int ag_t, int *ag_sx, int ag_snd)
AG_CHECK_DEPTH    ag_check_depth(THISARGC#int ag_fl)
AG_VALID          ag_valid(THISARGC#int ag_k)
AG_DEFAULT        ag_default(THISARGC#CONST int *ag_tp)
##
function macro defs old style

AG_GET_KEY_WORD   ag_get_key_word(ag_k) int ag_k;
AG_RNS            ag_rns(ag_t,*ag_sx, ag_snd) int ag_t,*ag_sx,ag_snd;
AG_JNS            ag_jns(ag_t) int ag_t;
AG_ATX            ag_atx(ag_t,*ag_sx,ag_snd) int ag_t,*ag_sx,ag_snd;
AG_CHECK_DEPTH    ag_check_depth(ag_fl) int ag_fl;
AG_VALID          ag_valid(ag_k) int ag_k;
AG_DEFAULT        ag_default(ag_tp) int *ag_tp;
##
pcbHeader

typedef struct %s{
  %s token_number, reduction_token, error_frame_token;
  int input_code;
  %s input_value;
  int line, column;
  int ssx, sn, error_frame_ssx;
  int drt, dssx, dsn;
  int ss[%d];
  %s vs[%d];
  int ag_ap;
  const char *error_message;
  char read_flag;
  char exit_flag;
##
pcbTail
} %s;

#ifndef PRULE_CONTEXT
#define PRULE_CONTEXT(pcb)  (&((pcb).cs[(pcb).ssx]))
#define PERROR_CONTEXT(pcb) ((pcb).cs[(pcb).error_frame_ssx])
#define PCONTEXT(pcb)       ((pcb).cs[(pcb).ssx])
#endif

#ifndef AG_RUNNING_CODE
/* PCB.exit_flag values */
#define AG_RUNNING_CODE         0
#define AG_SUCCESS_CODE         1
#define AG_SYNTAX_ERROR_CODE    2
#define AG_REDUCTION_ERROR_CODE 3
#define AG_STACK_ERROR_CODE     4
#define AG_SEMANTIC_ERROR_CODE  5
#endif
##
wrap decls

#undef  VW
#define VW(i,t) *(t) (&(PCB).vs[(PCB).ssx + (i)])
#undef  VNO
#define VNO new(&(PCB).vs[(PCB).ssx])
#undef  VRO
#define VRO(to,v) ag_replace_object((to) &(PCB).vs[(PCB).ssx], v)
#undef  VWD
#define VWD(i,t) ag_delete_object((t) &(PCB).vs[(PCB).ssx + (i)]);
#undef  VDO
#define VDO(to, v) ag_delete_object((to) &(PCB).vs[(PCB).ssx], v)

template <class NewObject, class OldObject>
static inline void ag_replace_object(AgObjectWrapper<OldObject> *p, const NewObject &o) {
  delete p;
  new(p) AgObjectWrapper<NewObject >(o);
}

template <class Object>
static inline void ag_delete_object(AgObjectWrapper<Object> *p) {
  delete p;
}

template <class NewObject, class OldObject>
static inline const NewObject &ag_delete_object(AgObjectWrapper<OldObject> *p, const NewObject &o) {
  delete p;
  return o;
}
##
wrapper def

#ifndef AG_OBJECT_WRAPPER_DEFINED
#define AG_OBJECT_WRAPPER_DEFINED

#ifndef AG_PLACEMENT_DELETE_REQUIRED
#if _MSC_VER >= 1200 || __INTEL_COMPILER
#define AG_PLACEMENT_DELETE_REQUIRED 1
#endif
#endif

template <class Object>
class AgObjectWrapper {
  Object object;
public:
  void operator delete(void *) {}
  void *operator new(size_t, void *p) { return p;}
#if AG_PLACEMENT_DELETE_REQUIRED
  void operator delete(void *, void *) { }
#endif
  AgObjectWrapper(const Object &o) : object(o) {}
  ~AgObjectWrapper() {}
  operator Object &() {return object;}
};

#endif

##
declarations
#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_shift_accept,
  ag_go_to,
  ag_shift_reduce,
  ag_shift_simple_reduce,
  ag_reduce_form,
  ag_simple_reduce,
  ag_accept,
  ag_syn_error,
  ag_null_go_to,
  ag_skip,
  ag_skip_reduce,
  ag_recover
} ag_parser_action;

##
toupper
#ifndef CONVERT_CASE

static int agConvertCase(int c) {
  if (c >= 'a' && c <= 'z') return c ^ 0x20;
  return c;
}

#define CONVERT_CASE(c) agConvertCase(c)

#endif
##
toupper latin
#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
##
declare macros
AG_OVERFLOW \
AG_TRACE_ERROR\
(PCB).exit_flag = AG_STACK_ERROR_CODE;\
PARSER_STACK_OVERFLOW;

ag_shift_accept               ag_action_1
ag_go_to                      ag_action_2
ag_shift_reduce               ag_action_3
ag_shift_simple_reduce        ag_action_4
ag_reduce_form                ag_action_5
ag_simple_reduce              ag_action_6
ag_accept                     ag_action_7
ag_syn_error                  ag_action_8
ag_null_go_to                 ag_action_9
ag_skip                       ag_action_10
ag_skip_reduce                ag_action_11
ag_recover                    ag_action_12

ag_shift_accept_proc          ag_action_1_proc
ag_go_to_proc                 ag_action_2_proc
ag_shift_reduce_proc          ag_action_3_proc
ag_simple_shift_reduce_proc   ag_action_4_proc
ag_reduce_proc                ag_action_5_proc
ag_simple_reduce_proc         ag_action_6_proc
ag_accept_proc                ag_action_7_proc
ag_error_proc                 ag_action_8_proc
ag_null_go_to_proc            ag_action_9_proc
ag_skip_proc                  ag_action_10_proc
ag_skip_reduce_proc           ag_action_11_proc
ag_recover_proc               ag_action_12_proc

ag_er_shift_accept_proc          ag_action_1_er_proc
ag_er_go_to_proc                 ag_action_2_er_proc
ag_er_shift_reduce_proc          ag_action_3_er_proc
ag_er_simple_shift_reduce_proc   ag_action_4_er_proc

ag_r_shift_accept_proc               ag_action_1_r_proc
ag_r_go_to_proc                      ag_action_2_r_proc
ag_r_simple_shift_reduce_error_proc  ag_action_3_er_proc
ag_s_shift_accept_proc               ag_action_1_s_proc

ag_go_to_error_proc                  ag_action_2_e_proc
ag_simple_shift_reduce_error_proc    ag_action_4_e_proc
ag_simple_reduce_error_proc          ag_action_6_e_proc
ag_skip_reduce_error_proc            ag_action_11_e_proc

ag_r_shift_reduce_proc               ag_action_3_r_proc
ag_r_simple_shift_reduce_proc        ag_action_4_r_proc

ag_s_shift_reduce_proc               ag_action_3_s_proc
##
error trace
#ifndef AG_TRACE_FILE_NAME
#define AG_TRACE_FILE_NAME AG_TRACE_FILE
#endif

STATIC#VOID NEAR#QUAL#ag_trace_error(THISARG) {
  FILE *ag_file = fopen(AG_TRACE_FILE_NAME, "w");
  int i;
  if (ag_file == NULL) return;
  fprintf(ag_file, "%d\n", (PCB).ssx);
  for (i = 0; i < (PCB).ssx; i++) fprintf(ag_file, "%d\n", (PCB).ss[i]);
  fprintf(ag_file, "%d\n", (PCB).sn);
  fprintf(ag_file, "%d\n", (PCB).token_number);
  fclose(ag_file);
}
##
read write counts
AG_READ_COUNTS {
  FILE *ag_file = fopen(AG_COUNT_FILE, "r");
  int i;

  if (ag_file) {
    long ag_file_id;
    fscanf(ag_file, "%ld", &ag_file_id);
    if (ag_file_id == AG_COUNT_FILE_ID) {
      for (i = 0; i < AG_COUNT_FILE_RC; i++)
        fscanf(ag_file,"%u", &(AG_RULE_COUNT[i]));
      fclose(ag_file);
      return;
    }
  }
  for (i = 0; i < AG_COUNT_FILE_RC; i++) AG_RULE_COUNT[i] = 0;
}

AG_WRITE_COUNTS {
  FILE *ag_file = fopen(AG_COUNT_FILE, "w");
  int i;

  if (ag_file == NULL) return;
  fprintf(ag_file, "%ld\n", AG_COUNT_FILE_ID);
  for (i = 0; i < AG_COUNT_FILE_RC; i++)
    fprintf(ag_file,"%u\n", AG_RULE_COUNT[i]);
  fclose(ag_file);
}
##
parse action macros

AG_GT ag_gt_procs_scan
AG_SR ag_s_procs_scan
AG_RD ag_r_procs_scan
AG_INIT_RESYNCH
##
error resynch macros

AG_GT ag_gt_procs_scan
AG_SR ag_s_procs_scan
AG_RD ag_r_procs_scan
AG_ER ag_er_procs_scan
AG_INIT_RESYNCH
##
init col

#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

##
init nocol

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

#ifndef PARSER_STACK_OVERFLOW
#define PARSER_STACK_OVERFLOW {fprintf(stderr, \
  "\nParser stack overflow\n");}
#endif

#ifndef REDUCTION_TOKEN_ERROR
#define REDUCTION_TOKEN_ERROR {fprintf(stderr, \
  "\nReduction token error\n");}
#endif

##

backtrack off

##
backtrack off macros

AG_STACK    AG_SAVE_CONTEXT\
(PCB).ss[(PCB).ssx] = (PCB).sn;

AG_CHKOVFLO if ((PCB).ssx >= AG_PARSER_STACK_SIZE) {\
  AG_TRACE_ERROR\
  (PCB).exit_flag = AG_STACK_ERROR_CODE;\
  PARSER_STACK_OVERFLOW;\
}

AG_PROT     if ((PCB).ssx >= AG_PARSER_STACK_SIZE) {\
  AG_TRACE_ERROR\
  (PCB).exit_flag = AG_STACK_ERROR_CODE;\
  PARSER_STACK_OVERFLOW;\
}

AG_PROTX    if ((PCB).ssx >= AG_PARSER_STACK_SIZE) {\
  AG_TRACE_ERROR\
  (PCB).exit_flag = AG_STACK_ERROR_CODE;\
  PARSER_STACK_OVERFLOW;\
}

AG_SET_BACK
AG_UNDO
AG_CLEAR_BACK
AG_PROT_CONTEXT
AG_UNDO_CONTEXT

##

backtrack on

STATIC#VOID NEAR#QUAL#ag_prot(THISARG) {
  int ag_k;
  ag_k = AG_PARSER_STACK_SIZE - ++(PCB).btsx;
  if (ag_k <= (PCB).ssx) {
    AG_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];
  AG_PROT_CONTEXT
}

STATIC#VOID NEAR#QUAL#ag_undo(THISARG) {
  if ((PCB).drt == -1) return;
  while ((PCB).btsx) {
    int ag_k = AG_PARSER_STACK_SIZE - (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];
    AG_UNDO_CONTEXT
  }
  (PCB).token_number = (AG_TOKEN_TYPE) (PCB).drt;
  (PCB).ssx = (PCB).dssx;
  (PCB).sn = (PCB).dsn;
  (PCB).drt = -1;
}

##

backtrack on macros

AG_CLEAR_BACK (PCB).btsx = 0, (PCB).drt = -1;

AG_SET_BACK if ((PCB).drt == -1) {\
  (PCB).drt=(PCB).token_number;\
  (PCB).dssx=(PCB).ssx;\
  (PCB).dsn=(PCB).sn;\
}

AG_CHKOVFLO if ((PCB).ssx >= AG_PARSER_STACK_SIZE) {\
  AG_TRACE_ERROR\
  (PCB).exit_flag = AG_STACK_ERROR_CODE;\
  PARSER_STACK_OVERFLOW;\
}

AG_STACK AG_SAVE_CONTEXT\
(PCB).ss[(PCB).ssx] = (PCB).sn;

AG_PROT if ((PCB).drt >= 0) ag_prot(PCBARG);\
else if ((PCB).ssx >= AG_PARSER_STACK_SIZE) {\
  AG_TRACE_ERROR\
  (PCB).exit_flag = AG_STACK_ERROR_CODE;\
  PARSER_STACK_OVERFLOW;\
}

AG_PROTX ag_prot(PCBARG);

##

error resynch undo

AG_UNDO int ag_k = ag_sbt[(PCB).sn];\
while (ag_tstt[ag_k] != AG_ERROR && ag_tstt[ag_k]) ag_k++;\
if (ag_tstt[ag_k] == 0) ag_undo(PCBARG);

##

undo macro

AG_UNDO ag_undo(PCBARG);

##

context macros

AG_PROT_CONTEXT  (PCB).cs[ag_k] = (PCB).cs[(PCB).ssx];
AG_UNDO_CONTEXT  (PCB).cs[(PCB).ssx] = (PCB).cs[ag_k];

##

no context macros

AG_PROT_CONTEXT
AG_UNDO_CONTEXT

##

trk char key col, trk char sink key col

#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 NEAR#QUAL#ag_track(THISARG) {
  int ag_k = 0;
  while (ag_k < (PCB).rx) {
    int ag_ch = (PCB).lab[ag_k++];
    switch (ag_ch) {
    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++;
    }
  }
  ag_k = 0;
  while ((PCB).rx < (PCB).fx) (PCB).lab[ag_k++] = (PCB).lab[(PCB).rx++];
  (PCB).fx = ag_k;
  (PCB).rx = 0;
}

##

trk macros char key col, trk macros char sink key col

AG_TRK_PTR ag_track(PCBARG);
AG_INC_PTR {(PCB).rx = 1; ag_track(PCBARG);}
AG_INIT_TRK (PCB).line = FIRST_LINE;\
(PCB).column = FIRST_COLUMN;

##

trk char key, trk char sink key

STATIC#VOID NEAR#QUAL#ag_track(THISARG) {
  int ag_k = 0;
  while ((PCB).rx < (PCB).fx) (PCB).lab[ag_k++] = (PCB).lab[(PCB).rx++];
  (PCB).fx = ag_k;
  (PCB).rx = 0;
}

##

trk macros char key, trk macros char sink key

AG_INC_PTR {(PCB).rx = 1; ag_track(PCBARG);}
AG_TRK_PTR ag_track(PCBARG);
AG_INIT_TRK

##

trk char col, trk char sink col

#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 NEAR#QUAL#ag_track(THISARG) {
  switch ((PCB).input_code) {
  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++;
  }
  (PCB).read_flag = 1;
}

##

trk macros char col, trk macros char sink col

AG_TRK_PTR ag_track(PCBARG);
AG_INC_PTR ag_track(PCBARG);
AG_INIT_TRK (PCB).line = FIRST_LINE;\
(PCB).column = FIRST_COLUMN;

##

trk char, trk token

##

trk macros char, trk macros token

AG_TRK_PTR {if ((PCB).read_flag == 0) (PCB).read_flag = 1;}
AG_INC_PTR {if ((PCB).read_flag == 0) (PCB).read_flag = 1;}
AG_INIT_TRK

##

trk token col

##

trk macros token col
AG_TRK_PTR {if ((PCB).read_flag == 0) (PCB).read_flag = 1;}
AG_INC_PTR {if ((PCB).read_flag == 0) (PCB).read_flag = 1;}
AG_INIT_TRK (PCB).line = FIRST_LINE;\
(PCB).column = FIRST_COLUMN;

##

init char key

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;

#ifndef GET_INPUT
#define GET_INPUT ((PCB).input_code = getchar())
#endif


STATIC#int NEAR#QUAL#ag_look_ahead(THISARG) {
  if ((PCB).rx < (PCB).fx) {
    return CONVERT_CASE((PCB).lab[(PCB).rx++]);
  }
  GET_INPUT;
  (PCB).fx++;
  return CONVERT_CASE((PCB).lab[(PCB).rx++] = (PCB).input_code);
}

STATIC#VOID NEAR#QUAL#AG_GET_KEY_WORD {
  int save_index = (PCB).rx;
  CONST unsigned char *sp;
  int ag_ch;
  while (1) {
    switch (ag_key_act[ag_k]) {
    case ag_cf_end_key:
      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 + ag_look_ahead(PCBARG)]) goto ag_fail;
          (PCB).rx--;
          (PCB).token_number = (AG_TOKEN_TYPE) ag_key_pt[ag_k1 + 1];
          return;
        }
      } while (ag_look_ahead(PCBARG) == ag_ch);
      goto ag_fail;
    case ag_end_key:
      sp = ag_key_ends + ag_key_jmp[ag_k];
      do {
        if ((ag_ch = *sp++) == 0) {
          (PCB).token_number = (AG_TOKEN_TYPE) ag_key_parm[ag_k];
          return;
        }
      } while (ag_look_ahead(PCBARG) == ag_ch);
      /* FALLTHROUGH */
    case ag_no_match_key:
ag_fail:
      (PCB).rx = save_index;
      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 + (ag_ch = ag_look_ahead(PCBARG))]) break;
      save_index = --(PCB).rx;
      (PCB).token_number = (AG_TOKEN_TYPE) ag_key_pt[ag_k1+1];
      break;
    }
    case ag_set_key:
      save_index = (PCB).rx;
      (PCB).token_number = (AG_TOKEN_TYPE) ag_key_parm[ag_k];
      /* FALLTHROUGH */
    case ag_jmp_key:
      ag_k = ag_key_jmp[ag_k];
      ag_ch = ag_look_ahead(PCBARG);
      break;
    case ag_accept_key:
      (PCB).token_number =  (AG_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 + ag_look_ahead(PCBARG)]) (PCB).rx = save_index;
      else {
        (PCB).rx--;
        (PCB).token_number =  (AG_TOKEN_TYPE) ag_key_pt[ag_k1+1];
      }
      return;
    }
    default:
      /* not reachable; here to suppress compiler warnings */
      goto ag_fail;
    }
    if (ag_ch <= 255) while (ag_key_ch[ag_k] < ag_ch) ag_k++;
    if (ag_ch > 255 || ag_key_ch[ag_k] != ag_ch) {
      (PCB).rx = save_index;
      return;
    }
  }
}

##

init macros char key

AG_CHAR     ((PCB).rx < (PCB).fx ? (PCB).lab[(PCB).rx-1] : (PCB).input_code)
AG_INIT_PTR (PCB).rx = (PCB).fx = 0;
AG_RST_PTR  (PCB).rx = 0;

##

init char sink key

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;

##

init macros char sink key

AG_CHAR     ((PCB).rx < (PCB).fx ? (PCB).lab[(PCB).rx-1] : (PCB).input_code)
AG_INIT_PTR (PCB).rx = (PCB).fx = 0;
AG_RST_PTR  (PCB).rx = 0;

##

get char key

AG_GET_TKN if ((PCB).rx < (PCB).fx) {\
  (PCB).input_code = (PCB).lab[(PCB).rx++];\
  (PCB).token_number = (AG_TOKEN_TYPE) AG_TCV((PCB).input_code);}\
else {\
  GET_INPUT;\
  (PCB).lab[(PCB).fx++] = (PCB).input_code;\
  (PCB).token_number = (AG_TOKEN_TYPE) AG_TCV((PCB).input_code);\
  (PCB).rx++;\
}\
if (ag_key_index[(PCB).sn]) {\
  unsigned ag_k = ag_key_index[(PCB).sn];\
  int ag_ch = CONVERT_CASE((PCB).input_code);\
  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(PCBARGC#ag_k);\
  }\
}

##

init char


#ifndef GET_INPUT
#define GET_INPUT ((PCB).input_code = getchar())
#endif

##

init macros char

AG_CHAR     (PCB).input_code;
AG_INIT_PTR (PCB).read_flag = 1;
AG_RST_PTR

##

init char sink

##

init macros char sink

AG_CHAR (PCB).input_code;
AG_INIT_PTR
AG_RST_PTR

##

init token

##

init macros token

AG_INIT_PTR (PCB).read_flag = 1;
AG_RST_PTR

##

init token sink

##

init macros token sink

AG_INIT_PTR
AG_RST_PTR

##

get token sink, get char sink

##

trk token sink, trk char sink

##

trk macros token sink, trk macros char sink

AG_TRK_PTR
AG_INC_PTR
AG_INIT_TRK

##

get char, get token

AG_GET_TKN if ((PCB).read_flag) {\
  (PCB).read_flag = 0;\
  GET_INPUT;\
};\
(PCB).token_number = (AG_TOKEN_TYPE) AG_TCV((PCB).input_code);

##

init ptr key

#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 NEAR#QUAL#AG_GET_KEY_WORD {
  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 = (AG_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 = (AG_TOKEN_TYPE) ag_key_parm[ag_k];
          return;
        }
      } while (CONVERT_CASE(*(PCB).la_ptr++) == ag_ch);
    }
    /* FALLTHROUGH */
    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 = (AG_TOKEN_TYPE) ag_key_pt[ag_k1+1];
      break;
    }
    case ag_set_key:
      ag_save = (int) ((PCB).la_ptr - (PCB).pointer);
      (PCB).token_number = (AG_TOKEN_TYPE) ag_key_parm[ag_k];
      /* FALLTHROUGH */
    case ag_jmp_key:
      ag_k = ag_key_jmp[ag_k];
      break;
    case ag_accept_key:
      (PCB).token_number = (AG_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 = (AG_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);
  }
}

##

init macros ptr key

AG_CHAR    *(PCB).pointer
AG_INIT_PTR (PCB).la_ptr = (PCB).pointer;
AG_RST_PTR  (PCB).la_ptr =  (PCB).pointer;

##

trk ptr key

##

trk macros ptr key

AG_TRK_PTR (PCB).pointer = (PCB).la_ptr;
AG_INC_PTR (PCB).la_ptr = ++(PCB).pointer;
AG_INIT_TRK

##

trk ptr key col

#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 NEAR#QUAL#ag_track(THISARG) {
  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++;
    }
  }
}

##

trk macros ptr key col

AG_TRK_PTR  ag_track(PCBARG);
AG_INIT_TRK (PCB).line = FIRST_LINE;\
(PCB).column = FIRST_COLUMN;

AG_INC_PTR  {(PCB).la_ptr = (PCB).pointer + 1; ag_track(PCBARG);}

##

get ptr key

AG_GET_TKN (PCB).token_number = (AG_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(PCB_TYPE_CAST#PCBARGC#ag_k);\
  }\
}

##

init ptr

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

##

init macros ptr

AG_RST_PTR  (PCB).la_ptr = (PCB).pointer;
AG_INIT_PTR (PCB).la_ptr = (PCB).pointer;
AG_CHAR    *(PCB).pointer

##

trk ptr

##

trk macros ptr

AG_TRK_PTR (PCB).pointer = (PCB).la_ptr;
AG_INC_PTR (PCB).la_ptr = ++(PCB).pointer;
AG_INIT_TRK

##

trk ptr col

#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 NEAR#QUAL#ag_track(THISARG) {
  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++;
    }
  }
}

##

trk macros ptr col

AG_TRK_PTR  ag_track(PCBARG);
AG_INC_PTR  {(PCB).la_ptr = (PCB).pointer + 1; ag_track(PCBARG);}
AG_INIT_TRK (PCB).line = FIRST_LINE;\
(PCB).column = FIRST_COLUMN;

##

get ptr

AG_GET_TKN (PCB).token_number = (AG_TOKEN_TYPE) AG_TCV(INPUT_CODE(*(PCB).la_ptr));\
(PCB).la_ptr++;

##

jns proc

STATIC#int NEAR#QUAL#AG_RNS {
  while (1) {
    int ag_act, ag_k = ag_sbt[ag_snd], ag_lim = ag_sbt[ag_snd+1];
    int ag_p;

    while (ag_k < ag_lim && ag_tstt[ag_k] != ag_t) ag_k++;
    if (ag_k == ag_lim) break;
    ag_act = ag_astt[ag_k];
    ag_p = ag_pstt[ag_k];
    if (ag_act == ag_go_to) return ag_p;
    if (ag_act == ag_skip || ag_act == ag_skip_reduce) {
      (*ag_sx)--;
      return ag_snd;
    }
    if (ag_act != ag_shift_reduce &&
      ag_act != ag_shift_simple_reduce) break;
    *ag_sx -= (ag_fl[ag_p] - 1);
    ag_snd = (PCB).ss[*ag_sx];
    ag_t = ag_ptt[ag_p];
  }
  return 0;
}

STATIC#int NEAR#QUAL#AG_JNS {
  int ag_k;

  ag_k = ag_sbt[(PCB).sn];
  while (ag_tstt[ag_k] != ag_t && ag_tstt[ag_k]) ag_k++;
  while (1) {
    int ag_p = ag_pstt[ag_k];
    int ag_sd;

    switch (ag_astt[ag_k]) {
    case ag_go_to:
      AG_STACK
      return ag_p;
    case ag_skip:
    case ag_skip_reduce:
      return (PCB).ss[(PCB).ssx--];
    case ag_null_go_to:
      AG_STACK
      (PCB).ssx++;
      (PCB).sn = ag_p;
      ag_k = ag_sbt[(PCB).sn];
      while (ag_tstt[ag_k] != ag_t && ag_tstt[ag_k]) ag_k++;
      continue;
    case ag_shift_reduce:
    case ag_shift_simple_reduce:
      ag_sd = ag_fl[ag_p] - 1;
      if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
      else AG_STACK
      ag_t = ag_ptt[ag_p];
      ag_k = ag_sbt[(PCB).sn+1];
      while (ag_tstt[--ag_k] != ag_t);
      continue;
    case ag_reduce_form:
    case ag_simple_reduce:
      if (ag_fl[ag_p]) break;
      (PCB).sn = ag_rns(PCBARGC#ag_ptt[ag_p],&(PCB).ssx, (PCB).sn);
      (PCB).ss[++(PCB).ssx] = (PCB).sn;
      ag_k = ag_sbt[(PCB).sn];
      while (ag_tstt[ag_k] != ag_t && ag_tstt[ag_k]) ag_k++;
      continue;
    }
    break;
  }
  return 0;
}

##

no resynch

AG_RESYNCH (PCB).exit_flag = AG_SYNTAX_ERROR_CODE;\
AG_DIAGNOSE\
SYNTAX_ERROR;\
AG_INC_PTR

##

error resynch token sink mode

STATIC#VOID NEAR#QUAL#ag_error_resynch(THISARG) {
  int ag_k;
  int ag_ssx = (PCB).ssx;

  AG_DIAGNOSE
  SYNTAX_ERROR;
  if ((PCB).exit_flag != AG_RUNNING_CODE) return;
  while (1) {
    ag_k = ag_sbt[(PCB).sn];
    while (ag_tstt[ag_k] != AG_ERROR && ag_tstt[ag_k]) ag_k++;
    if (ag_tstt[ag_k] || (PCB).ssx == 0) break;
    DELETE_OBJECT
  }
  if (ag_tstt[ag_k] == 0) {
    (PCB).sn = (PCB).ss[(PCB).ssx = ag_ssx];
    (PCB).exit_flag = AG_SYNTAX_ERROR_CODE;
    return;
  }
  ag_k = ag_sbt[(PCB).sn];
  while (ag_tstt[ag_k] != AG_ERROR && ag_tstt[ag_k]) ag_k++;
  (PCB).ag_ap = ag_pstt[ag_k];
  (AG_ER[ag_astt[ag_k]])(PCBARG);
  (PCB).ss[(PCB).ssx++] = (PCB).sn;
  (PCB).sn = AG_ERROR_STATE;
  return;
}

STATIC#int NEAR#QUAL#ag_recover_proc(THISARG) {
  int ag_t, ag_k = ag_sbt[(PCB).ss[(PCB).ssx-1]];

  while (ag_tstt[ag_k] != (AG_TSTT_CAST) (PCB).token_number && ag_tstt[ag_k]) ag_k++;
  ag_t = ag_tstt[ag_k];
  if (ag_t && ag_astt[ag_k] != ag_skip){
    (PCB).sn = (PCB).ss[--(PCB).ssx];
    AG_RST_PTR
    return 1;
  }
  if ((PCB).token_number == AG_EOF)
     {(PCB).exit_flag = AG_SYNTAX_ERROR_CODE; return 0;}
  AG_TRK_PTR
  return 0;
}

##

error resynch

STATIC#VOID NEAR#QUAL#ag_error_resynch(THISARG) {
  int ag_k;
  int ag_ssx = (PCB).ssx;

  AG_DIAGNOSE
  SYNTAX_ERROR;
  if ((PCB).exit_flag != AG_RUNNING_CODE) return;
  while (1) {
    ag_k = ag_sbt[(PCB).sn];
    while (ag_tstt[ag_k] != AG_ERROR && ag_tstt[ag_k]) ag_k++;
    if (ag_tstt[ag_k] || (PCB).ssx == 0) break;
    DELETE_OBJECT
  }
  if (ag_tstt[ag_k] == 0) {
    (PCB).sn = PCB.ss[(PCB).ssx = ag_ssx];
    (PCB).exit_flag = AG_SYNTAX_ERROR_CODE;
    return;
  }
  ag_k = ag_sbt[(PCB).sn];
  while (ag_tstt[ag_k] != AG_ERROR && ag_tstt[ag_k]) ag_k++;
  (PCB).ag_ap = ag_pstt[ag_k];
  (AG_ER[ag_astt[ag_k]])(PCBARG);
  while (1) {
    ag_k = ag_sbt[(PCB).sn];
    while (ag_tstt[ag_k] != (AG_TSTT_CAST) (PCB).token_number && ag_tstt[ag_k])
      ag_k++;
    if (ag_tstt[ag_k] && ag_astt[ag_k] != ag_skip) break;
    if ((PCB).token_number == AG_EOF)
       {(PCB).exit_flag = AG_SYNTAX_ERROR_CODE; return;}
    AG_INC_PTR
    AG_GET_TKN
  }
  AG_RST_PTR
}
##

auto resynch macros

AG_GT *(PCB).gt_procs
AG_SR *(PCB).s_procs
AG_RD *(PCB).r_procs

AG_INIT_RESYNCH (PCB).gt_procs = ag_gt_procs_scan;\
(PCB).r_procs = ag_r_procs_scan;\
(PCB).s_procs = ag_s_procs_scan;\
(PCB).ag_error_depth = (PCB).ag_min_depth = (PCB).ag_tmp_depth = 0;\
(PCB).ag_resynch_active = 0;

##

auto resynch defs

  int ag_error_depth, ag_min_depth, ag_tmp_depth;
  int ag_rss[2*AG_PARSER_STACK_SIZE], ag_lrss;

##

auto resynch event defs

  int ag_error_depth, ag_min_depth, ag_tmp_depth;
  int ag_rss[2*AG_PARSER_STACK_SIZE], ag_lrss;
  int ag_rk1, ag_tk1;

##

auto resynch token sink mode

STATIC#int NEAR#QUAL#AG_ATX {
  int ag_k, ag_f;
  int ag_save_btsx = (PCB).btsx;
  int ag_flag = 1;

  while (1) {
    int ag_a;

    (PCB).bts[AG_PARSER_STACK_SIZE - ++(PCB).btsx] = *ag_sx;
    (PCB).ss[AG_PARSER_STACK_SIZE - (PCB).btsx] = (PCB).ss[*ag_sx];
    (PCB).ss[*ag_sx] = ag_snd;
    ag_k = ag_sbt[ag_snd];
    while (ag_tstt[ag_k] != ag_t && ag_tstt[ag_k]) ag_k++;
    ag_a = ag_astt[ag_k];
    if (ag_a == ag_go_to ||
        ag_a == ag_shift_reduce ||
        ag_a == ag_skip ||
        ag_a == ag_skip_reduce ||
        ag_a == ag_shift_accept ||
        ag_a == ag_shift_simple_reduce) break;
    if ((ag_a == ag_reduce_form ||
        ag_a == ag_simple_reduce) &&
        (ag_k = ag_fl[ag_f = ag_pstt[ag_k]]) == 0) {
        ag_snd = ag_rns(PCBARGC#ag_ptt[ag_f],ag_sx, (PCB).ss[*ag_sx]);
        (*ag_sx)++;
        continue;
    }
    if (ag_a == ag_null_go_to) {
      ag_snd = ag_pstt[ag_k];
      (*ag_sx)++;
      continue;
    }
    ag_flag = 0;
    break;
  }
  while ((PCB).btsx > ag_save_btsx) {
    *ag_sx = (PCB).bts[AG_PARSER_STACK_SIZE - (PCB).btsx];
    (PCB).ss[*ag_sx] = (PCB).ss[AG_PARSER_STACK_SIZE - (PCB).btsx--];
  }
  return ag_flag;
}

STATIC#int NEAR#QUAL#ag_tst_tkn(THISARG) {
  int ag_rk, ag_sx, ag_snd;

  for (ag_rk = 0; ag_rk < (PCB).ag_lrss; ag_rk += 2) {
    ag_sx = (PCB).ag_rss[ag_rk];
    if (ag_sx > (PCB).ssx) continue;
    ag_snd = (PCB).ag_rss[ag_rk + 1];
    if (ag_sx > (PCB).ag_min_depth) continue;
    if (ag_atx(PCBARGC#(PCB).token_number, &ag_sx, ag_snd)) break;
  }
  return ag_rk;
}

STATIC#VOID NEAR#QUAL#ag_set_error_procs(THISARG);

STATIC#VOID NEAR#QUAL#ag_auto_resynch(THISARG) {
  int ag_sx;
  MY_DELETE_WRAPPERS
  (PCB).ss[(PCB).ssx] = (PCB).sn;
  if ((PCB).ag_error_depth && (PCB).ag_min_depth >= (PCB).ag_error_depth) {
    (PCB).ssx = (PCB).ag_error_depth;
    (PCB).sn = (PCB).ss[(PCB).ssx];
  }
  else {
    AG_DIAGNOSE
    SYNTAX_ERROR;
    if ((PCB).exit_flag != AG_RUNNING_CODE) return;
    (PCB).ag_error_depth = (PCB).ag_min_depth = 0;
    (PCB).ag_lrss = 0;
    (PCB).ss[ag_sx = (PCB).ssx] = (PCB).sn;
    (PCB).ag_min_depth = (PCB).ag_rss[(PCB).ag_lrss++] = ag_sx;
    (PCB).ag_rss[(PCB).ag_lrss++] = (PCB).sn;
    while (ag_sx && (PCB).ag_lrss < 2*AG_PARSER_STACK_SIZE) {
      int ag_t = 0, ag_x, ag_s, ag_sxs = ag_sx;

      while (ag_sx && (ag_t = ag_ctn[2*(PCB).sn]) == 0) (PCB).sn = (PCB).ss[--ag_sx];
      if (ag_t) (PCB).sn = (PCB).ss[ag_sx -= ag_ctn[2*(PCB).sn +1]];
      else {
        if (ag_sx == 0) (PCB).sn = 0;
        ag_t = ag_ptt[0];
      }
      if ((ag_s = ag_rns(PCBARGC#ag_t, &ag_sx, (PCB).sn)) == 0) break;
      for (ag_x = 0; ag_x < (PCB).ag_lrss; ag_x += 2)
        if ((PCB).ag_rss[ag_x] == ag_sx + 1 && (PCB).ag_rss[ag_x+1] == ag_s) break;
      if (ag_x == (PCB).ag_lrss) {
        (PCB).ag_rss[(PCB).ag_lrss++] = ++ag_sx;
        (PCB).ag_rss[(PCB).ag_lrss++] = (PCB).sn = ag_s;
      }
      else if (ag_sx >= ag_sxs) ag_sx--;
    }
    ag_set_error_procs(PCBARG);
  }
  (PCB).ssx++;
  (PCB).sn = AG_ERROR_STATE;
  (PCB).ag_rk1 = (PCB).ag_lrss;
  return;
}

STATIC#int NEAR#QUAL#ag_recover_proc(THISARG) {
  int ag_k, ag_rk;

  (PCB).ssx--;
  if ((PCB).ag_rk1 == (PCB).ag_lrss) {
    (PCB).ag_rk1 = ag_tst_tkn(PCBARG);
    (PCB).ssx++;
    if ((PCB).token_number == AG_EOF)
      {(PCB).exit_flag = AG_SYNTAX_ERROR_CODE; return 0;}
    (PCB).ag_tk1 = (PCB).token_number;
    AG_TRK_PTR
    return 0;
  }
  ag_rk = ag_tst_tkn(PCBARG);
  if (ag_rk < (PCB).ag_rk1) {
    ag_k = 0;
    AG_TRK_PTR
  }
  else {
    ag_k = 1;
    ag_rk = (PCB).ag_rk1;
    (PCB).token_number = (AG_TOKEN_TYPE) (PCB).ag_tk1;
    AG_RST_PTR
  }
  (PCB).ag_min_depth = (PCB).ssx = (PCB).ag_rss[ag_rk++];
  (PCB).sn = (PCB).ss[(PCB).ssx] = (PCB).ag_rss[ag_rk];
  (PCB).sn = ag_jns(PCBARGC#(PCB).token_number);
  if ((PCB).ag_error_depth == 0 || (PCB).ag_error_depth > (PCB).ssx)
    (PCB).ag_error_depth = (PCB).ssx;
  if (++(PCB).ssx >= AG_PARSER_STACK_SIZE) {
    AG_OVERFLOW
    return 0;
  }
  AG_STACK
  (PCB).ag_tmp_depth = (PCB).ag_min_depth;
  return ag_k;
}

##

auto resynch


STATIC#int NEAR#QUAL#AG_ATX {
  int ag_k, ag_f;
  int ag_save_btsx = (PCB).btsx;
  int ag_flag = 1;

  while (1) {
    int ag_a;

    (PCB).bts[AG_PARSER_STACK_SIZE - ++(PCB).btsx] = *ag_sx;
    (PCB).ss[AG_PARSER_STACK_SIZE - (PCB).btsx] = (PCB).ss[*ag_sx];
    (PCB).ss[*ag_sx] = ag_snd;
    ag_k = ag_sbt[ag_snd];
    while (ag_tstt[ag_k] != ag_t && ag_tstt[ag_k]) ag_k++;
    ag_a = ag_astt[ag_k];
    if (ag_a == ag_go_to ||
        ag_a == ag_shift_reduce ||
        ag_a == ag_skip ||
        ag_a == ag_skip_reduce ||
        ag_a == ag_shift_accept ||
        ag_a == ag_shift_simple_reduce) break;
    if ((ag_a == ag_reduce_form ||
        ag_a == ag_simple_reduce) &&
        (ag_k = ag_fl[ag_f = ag_pstt[ag_k]]) == 0) {
        ag_snd = ag_rns(PCBARGC#ag_ptt[ag_f],ag_sx, (PCB).ss[*ag_sx]);
        (*ag_sx)++;
        continue;
    }
    if (ag_a == ag_null_go_to) {
      ag_snd = ag_pstt[ag_k];
      (*ag_sx)++;
      continue;
    }
    ag_flag = 0;
    break;
  }
  while ((PCB).btsx > ag_save_btsx) {
    *ag_sx = (PCB).bts[AG_PARSER_STACK_SIZE - (PCB).btsx];
    (PCB).ss[*ag_sx] = (PCB).ss[AG_PARSER_STACK_SIZE - (PCB).btsx--];
  }
  return ag_flag;
}


STATIC#int NEAR#QUAL#ag_tst_tkn(THISARG) {
  int ag_rk, ag_sx, ag_snd = (PCB).sn;

  AG_GET_TKN
  for (ag_rk = 0; ag_rk < (PCB).ag_lrss; ag_rk += 2) {
    ag_sx = (PCB).ag_rss[ag_rk];
    if (ag_sx > (PCB).ssx || ag_sx > (PCB).ag_min_depth) continue;
    (PCB).sn = (PCB).ag_rss[ag_rk + 1];
    if (ag_atx(PCBARGC#(PCB).token_number, &ag_sx, (PCB).sn)) break;
  }
  (PCB).sn = ag_snd;
  return ag_rk;
}

STATIC#VOID NEAR#QUAL#ag_set_error_procs(THISARG);

STATIC#VOID NEAR#QUAL#ag_auto_resynch(THISARG) {
  int ag_sx, ag_rk;
  int ag_rk1, ag_rk2, ag_tk1;
  MY_DELETE_WRAPPERS
  (PCB).ss[(PCB).ssx] = (PCB).sn;
  if ((PCB).ag_error_depth && (PCB).ag_min_depth >= (PCB).ag_error_depth) {
    (PCB).ssx = (PCB).ag_error_depth;
    (PCB).sn = (PCB).ss[(PCB).ssx];
  }
  else {
    AG_DIAGNOSE
    SYNTAX_ERROR;
    if ((PCB).exit_flag != AG_RUNNING_CODE) return;
    (PCB).ag_error_depth = (PCB).ag_min_depth = 0;
    (PCB).ag_lrss = 0;
    (PCB).ss[ag_sx = (PCB).ssx] = (PCB).sn;
    (PCB).ag_min_depth = (PCB).ag_rss[(PCB).ag_lrss++] = ag_sx;
    (PCB).ag_rss[(PCB).ag_lrss++] = (PCB).sn;
    while (ag_sx && (PCB).ag_lrss < 2*AG_PARSER_STACK_SIZE) {
      int ag_t = 0, ag_x, ag_s, ag_sxs = ag_sx;

      while (ag_sx && (ag_t = ag_ctn[2*(PCB).sn]) == 0) (PCB).sn = (PCB).ss[--ag_sx];
      if (ag_t) (PCB).sn = (PCB).ss[ag_sx -= ag_ctn[2*(PCB).sn +1]];
      else {
        if (ag_sx == 0) (PCB).sn = 0;
        ag_t = ag_ptt[0];
      }
      if ((ag_s = ag_rns(PCBARGC#ag_t, &ag_sx, (PCB).sn)) == 0) break;
      for (ag_x = 0; ag_x < (PCB).ag_lrss; ag_x += 2)
        if ((PCB).ag_rss[ag_x] == ag_sx + 1 && (PCB).ag_rss[ag_x+1] == ag_s) break;
      if (ag_x == (PCB).ag_lrss) {
        (PCB).ag_rss[(PCB).ag_lrss++] = ++ag_sx;
        (PCB).ag_rss[(PCB).ag_lrss++] = (PCB).sn = ag_s;
      }
      else if (ag_sx >= ag_sxs) ag_sx--;
    }
    ag_set_error_procs(PCBARG);
  }
  AG_RST_PTR
  if ((PCB).ssx > (PCB).ag_min_depth) (PCB).ag_min_depth = (PCB).ssx;
  while (1) {
    ag_rk1 = ag_tst_tkn(PCBARG);
    if ((PCB).token_number == AG_EOF)
      {(PCB).exit_flag = AG_SYNTAX_ERROR_CODE; return;}
    if (ag_rk1 < (PCB).ag_lrss) break;
    AG_INC_PTR
  }
  ag_tk1 = (PCB).token_number;
  AG_TRK_PTR
  ag_rk2 = ag_tst_tkn(PCBARG);
  if (ag_rk2 < ag_rk1) {ag_rk = ag_rk2; AG_TRK_PTR}
  else {ag_rk = ag_rk1; (PCB).token_number = (AG_TOKEN_TYPE) ag_tk1; AG_RST_PTR}
  (PCB).ag_min_depth = (PCB).ssx = (PCB).ag_rss[ag_rk++];
  (PCB).sn = (PCB).ss[(PCB).ssx] = (PCB).ag_rss[ag_rk];
  (PCB).sn = ag_jns(PCBARGC#(PCB).token_number);
  if ((PCB).ag_error_depth == 0 || (PCB).ag_error_depth > (PCB).ssx)
    (PCB).ag_error_depth = (PCB).ssx;
  if (++(PCB).ssx >= AG_PARSER_STACK_SIZE) {
    AG_OVERFLOW
    return;
  }
  AG_STACK
  (PCB).ag_tmp_depth = (PCB).ag_min_depth;
  AG_RST_PTR
  return;
}

##

error parse procs

STATIC#VOID NEAR#QUAL#AG_CHECK_DEPTH {
  int ag_sx = (PCB).ssx - ag_fl;
  if ((PCB).ag_error_depth && ag_sx < (PCB).ag_tmp_depth) (PCB).ag_tmp_depth = ag_sx;
}

STATIC#int NEAR#QUAL#ag_r_simple_shift_reduce_error_proc(THISARG) {
  ag_check_depth(PCBARGC#ag_fl[(PCB).ag_ap] - 1);
  return ag_r_simple_shift_reduce_proc(PCBARG);
}

STATIC#int NEAR#QUAL#ag_go_to_error_proc(THISARG) {
  ag_go_to_proc(PCBARG);
  (PCB).ag_min_depth = (PCB).ag_tmp_depth;
  return 0;
}

STATIC#int NEAR#QUAL#ag_simple_shift_reduce_error_proc(THISARG) {
  ag_check_depth(PCBARGC#ag_fl[(PCB).ag_ap] - 1);
  (PCB).ag_min_depth = (PCB).ag_tmp_depth;
  return ag_simple_shift_reduce_proc(PCBARG);
}

STATIC#int NEAR#QUAL#ag_simple_reduce_error_proc(THISARG) {
  ag_check_depth(PCBARGC#ag_fl[(PCB).ag_ap]);
  return ag_simple_reduce_proc(PCBARG);
}

STATIC#int NEAR#QUAL#ag_skip_reduce_error_proc(THISARG) {
  return ag_skip_proc(PCBARG);
}

STATIC#int (NEAR#*QUAL#ag_r_procs_error[])(THISARG) = {
  ag_r_shift_accept_proc,
  ag_r_go_to_proc,
  ag_r_simple_shift_reduce_error_proc,
  ag_r_simple_shift_reduce_error_proc
};

STATIC#int (NEAR#*QUAL#ag_s_procs_error[])(THISARG) = {
  ag_s_shift_accept_proc,
  ag_r_go_to_proc,
  ag_r_simple_shift_reduce_error_proc,
  ag_r_simple_shift_reduce_error_proc
};

STATIC#int (NEAR#*QUAL#ag_gt_procs_error[])(THISARG) = {
  ag_shift_accept_proc,
  ag_go_to_error_proc,
  ag_simple_shift_reduce_error_proc,
  ag_simple_shift_reduce_error_proc,
  ag_simple_reduce_error_proc,
  ag_simple_reduce_error_proc,
  ag_accept_proc,
  ag_error_proc,
  ag_null_go_to_proc,
  ag_skip_proc,
  ag_skip_reduce_error_proc,
  AG_RECOVER
};

STATIC#VOID NEAR#QUAL#ag_set_error_procs(THISARG) {
  (PCB).gt_procs = ag_gt_procs_error;
  (PCB).r_procs = ag_r_procs_error;
  (PCB).s_procs = ag_s_procs_error;
}

##

diagnose context

{
  int ag_sx, ag_t;

  ag_sx = (PCB).ssx;
  (PCB).ss[ag_sx] = (PCB).sn;
  do {
    while (ag_sx && ag_ctn[2*(ag_snd = (PCB).ss[ag_sx])] == 0) ag_sx--;
    if (ag_sx) {
      ag_t = ag_ctn[2*ag_snd];
      ag_sx -= ag_ctn[2*ag_snd +1];
      ag_snd = (PCB).ss[ag_sx];
    }
    else {
      ag_snd = 0;
      ag_t = ag_ptt[0];
    }
  } while (ag_sx && *TOKEN_NAMES[ag_t]==0);
  if (*TOKEN_NAMES[ag_t] == 0) ag_t = 0;
  (PCB).error_frame_ssx = ag_sx;
  (PCB).error_frame_token = (AG_TOKEN_TYPE) ag_t;
}

##

diagnose defs

#ifndef MISSING_FORMAT
#define MISSING_FORMAT "Missing %s"
#endif
#ifndef UNEXPECTED_FORMAT
#define UNEXPECTED_FORMAT "Unexpected %s"
#endif
#ifndef UNNAMED_TOKEN
#define UNNAMED_TOKEN "input"
#endif

##

diagnose char

STATIC#VOID NEAR#QUAL#ag_diagnose(THISARG) {
  int ag_snd = (PCB).sn;
  int ag_k = ag_sbt[ag_snd];

  if (*TOKEN_NAMES[ag_tstt[ag_k]] && ag_astt[ag_k + 1] == ag_syn_error) {
    sprintf((PCB).ag_msg, MISSING_FORMAT, TOKEN_NAMES[ag_tstt[ag_k]]);
  }
  else if (ag_astt[ag_sbe[(PCB).sn]] == ag_action_8
          && (ag_k = (int) ag_sbe[(PCB).sn] + 1) == (int) ag_sbt[(PCB).sn+1] - 1
          && *TOKEN_NAMES[ag_tstt[ag_k]]) {
    sprintf((PCB).ag_msg, MISSING_FORMAT, TOKEN_NAMES[ag_tstt[ag_k]]);
  }
  else if ((PCB).token_number && *TOKEN_NAMES[(PCB).token_number]) {
    sprintf((PCB).ag_msg, UNEXPECTED_FORMAT, TOKEN_NAMES[(PCB).token_number]);
  }
  else if (isprint(AG_INPUT_CODE) && AG_INPUT_CODE != '\\') {
    char buf[20];
    sprintf(buf, "\'%c\'", (char) AG_INPUT_CODE);
    sprintf((PCB).ag_msg, UNEXPECTED_FORMAT, buf);
  }
  else sprintf((PCB).ag_msg, UNEXPECTED_FORMAT, UNNAMED_TOKEN);
  (PCB).error_message = (PCB).ag_msg;

##

diagnose token

STATIC#VOID NEAR#QUAL#ag_diagnose(THISARG) {
  int ag_snd = (PCB).sn;
  CONST char *ag_p;
  int ag_k = ag_sbt[ag_snd];

  if (*(ag_p = TOKEN_NAMES[ag_tstt[ag_k++]]) != 0 &&
            ag_astt[ag_k] == ag_syn_error) {
    sprintf((PCB).ag_msg, MISSING_FORMAT, ag_p);
  }
  else if ((ag_k = (int) ag_sbe[(PCB).sn] + 1) == (int) ag_sbt[(PCB).sn+1] - 1
          && *TOKEN_NAMES[ag_tstt[ag_k]]) {
    sprintf((PCB).ag_msg, MISSING_FORMAT, TOKEN_NAMES[ag_tstt[ag_k]]);
  }
  else {
    ag_p = TOKEN_NAMES[(PCB).token_number];
    if ((PCB).token_number == 0 || *ag_p == 0) ag_p = UNNAMED_TOKEN;
    sprintf((PCB).ag_msg, UNEXPECTED_FORMAT, ag_p);

  }
  (PCB).error_message = (PCB).ag_msg;

##

reduce loop

##

reduce macros

AG_REDUCE \
AG_COUNT_RULE_P\
(PCB).reduction_token = (AG_TOKEN_TYPE) ag_ptt[(PCB).ag_ap];\
ag_ra(PCBARG);

AG_SIMPLE_REDUCE \
AG_COUNT_RULE_P\
(PCB).reduction_token = (AG_TOKEN_TYPE) ag_ptt[(PCB).ag_ap];

AG_NSR_SR 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] < (AG_TSTT_CAST)(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_SR[ag_astt[ag_t1]])(PCBARG) == 0) break;\
}

AG_NSR_RD 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] < (AG_TSTT_CAST)(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_RD[ag_astt[ag_t1]])(PCBARG) == 0) break;\
}

##

reduce loop vars

  CONST int *ag_dtl;
  int ag_dsn;

##

reduce loop checking

STATIC#AG_TSTT_TYPE LOCUS *QUAL#AG_VALID {
  AG_TSTT_TYPE LOCUS *ag_tp = &ag_tstt[ag_sbt[(PCB).sn+1]];
  while (*--ag_tp != (AG_TSTT_CAST) ag_k) if (*ag_tp == 0) return NULL;
  return ag_tp;
}

int AG_CHANGE_REDUCTION {
  if (!ag_valid(PCBARGC#ag_k)) return 0;
  (PCB).reduction_token = ag_k;
  return 1;
}

STATIC#VOID NEAR#QUAL#AG_DEFAULT {
  (PCB).ag_dsn = (PCB).sn;
  (PCB).ag_dtl = ag_tp;
  while (!ag_valid(PCBARGC#(AG_TOKEN_TYPE) *ag_tp)) ag_tp++;
  (PCB).reduction_token = (AG_TOKEN_TYPE) *ag_tp;
}

##

reduce macros checking

AG_REDUCE \
AG_COUNT_RULE_P\
(PCB).reduction_token = (AG_TOKEN_TYPE) ag_ptt[(PCB).ag_ap];\
ag_ra(PCBARG);

AG_SIMPLE_REDUCE \
AG_COUNT_RULE_P\
(PCB).reduction_token = (AG_TOKEN_TYPE) ag_ptt[(PCB).ag_ap];

AG_NSR_SR 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] < (AG_TSTT_CAST)(PCB).reduction_token) ag_t1 = ag_tx + 1;\
    else ag_t2 = ag_tx;\
  } while (ag_t1 < ag_t2);\
  if (ag_tstt[ag_t1] != (PCB).reduction_token) {\
    (PCB).exit_flag = AG_REDUCTION_ERROR_CODE; AG_TRACE_ERROR\
    REDUCTION_TOKEN_ERROR; break;}\
    (PCB).ag_ap = ag_pstt[ag_t1];\
  if ((AG_SR[ag_astt[ag_t1]])(PCBARG) == 0) break;\
}

AG_NSR_RD 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] < (AG_TSTT_CAST)(PCB).reduction_token) ag_t1 = ag_tx + 1;\
    else ag_t2 = ag_tx;\
  } while (ag_t1 < ag_t2);\
  if (ag_tstt[ag_t1] != (PCB).reduction_token) {\
    (PCB).exit_flag = AG_REDUCTION_ERROR_CODE; AG_TRACE_ERROR\
    REDUCTION_TOKEN_ERROR; break;}\
    (PCB).ag_ap = ag_pstt[ag_t1];\
  if ((AG_RD[ag_astt[ag_t1]])(PCBARG) == 0) break;\
}

##

reduction choices

int AG_CHOICES {
  int ag_k, ag_n;
  if ((PCB).ag_dsn != (PCB).sn) {
    *ag_tp = ag_ptt[(PCB).ag_ap];
    return 1;
  }
  for (ag_k = ag_n = 0; (PCB).ag_dtl[ag_k]; ag_k++) {
    if (!ag_valid(PCBARGC#(AG_TOKEN_TYPE) (PCB).ag_dtl[ag_k])) continue;
    ag_tp[ag_n++] = (PCB).ag_dtl[ag_k];
  }
  return ag_n;
}

##

parse procs

STATIC#int NEAR#QUAL#ag_skip_proc(THISARG) {
  int ag_t = (PCB).token_number;
  AG_COUNT_RULE_P
  AG_CLEAR_BACK
  do {
    AG_COUNT_RULE_P
    AG_TRK_PTR
    AG_GET_TKN
  } while ((PCB).token_number == (AG_TOKEN_TYPE) ag_t);
  AG_RST_PTR
  return 1;
}

STATIC#int NEAR#QUAL#ag_skip_reduce_proc(THISARG) {
  int ag_t = (PCB).token_number;

  AG_COUNT_RULE_P
  AG_CLEAR_BACK
  do {
    AG_GET_VALUE
    (PCB).ssx--;
    AG_TRK_PTR
    ag_ra(PCBARG);
    if ((PCB).exit_flag != AG_RUNNING_CODE) return 0;
    (PCB).ssx++;
    AG_GET_TKN
  }
  while ((PCB).token_number == (AG_TOKEN_TYPE) ag_t);
  AG_RST_PTR
  return 1;
}

STATIC#int NEAR#QUAL#ag_r_shift_reduce_proc(THISARG) {
  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  AG_CLEAR_BACK
  AG_REDUCE
  return (PCB).exit_flag == AG_RUNNING_CODE;
}

STATIC#int NEAR#QUAL#ag_s_shift_reduce_proc(THISARG) {
  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  AG_CLEAR_BACK
  AG_REDUCE
  return (PCB).exit_flag == AG_RUNNING_CODE;
}

STATIC#int NEAR#QUAL#ag_r_simple_shift_reduce_proc(THISARG) {
  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  AG_SIMPLE_REDUCE
  return 1;
}

STATIC#int NEAR#QUAL#ag_go_to_proc(THISARG) {
  AG_CLEAR_BACK
  AG_CHKOVFLO
  AG_GET_VALUE
  AG_STACK
  (PCB).ssx++;
  (PCB).sn = (PCB).ag_ap;
  AG_TRK_PTR
  return 0;
}

STATIC#int NEAR#QUAL#ag_null_go_to_proc(THISARG) {
  AG_SET_BACK
  AG_PROTX
  AG_NULL
  AG_STACK
  (PCB).ssx++;
  (PCB).sn = (PCB).ag_ap;
  AG_RST_PTR
  return (PCB).exit_flag == AG_RUNNING_CODE;
}

STATIC#int NEAR#QUAL#ag_r_go_to_proc(THISARG) {
  (PCB).ssx++;
  (PCB).sn = (PCB).ag_ap;
  return 0;
}

STATIC#int NEAR#QUAL#ag_accept_proc(THISARG) {
  --(PCB).ssx;
  AG_RST_PTR
  AG_COUNT_RULE_Z
  (PCB).exit_flag = AG_SUCCESS_CODE;
  return 0;
}

STATIC#int NEAR#QUAL#ag_shift_accept_proc(THISARG) {
  AG_TRK_PTR
  AG_COUNT_RULE_Z
  (PCB).exit_flag = AG_SUCCESS_CODE;
  return 0;
}

STATIC#int NEAR#QUAL#ag_r_shift_accept_proc(THISARG) {
  AG_COUNT_RULE_Z
  (PCB).exit_flag = AG_SUCCESS_CODE;
  return 0;
}

STATIC#int NEAR#QUAL#ag_s_shift_accept_proc(THISARG) {
  AG_COUNT_RULE_Z
  (PCB).exit_flag = AG_SUCCESS_CODE;
  return 0;
}

STATIC#int NEAR#QUAL#ag_simple_shift_reduce_proc(THISARG) {
  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
  AG_SIMPLE_REDUCE
  AG_CLEAR_BACK
  AG_GET_VALUE
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  else AG_STACK
  AG_TRK_PTR
  AG_NSR_SR
  return 0;
}

STATIC#int NEAR#QUAL#ag_shift_reduce_proc(THISARG) {
  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
  AG_CLEAR_BACK
  AG_GET_VALUE
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  else AG_STACK
  AG_TRK_PTR
  AG_REDUCE
  AG_NSR_SR
  return 0;
}

STATIC#int NEAR#QUAL#ag_error_proc(THISARG) {
  AG_UNDO
  AG_TRACE_ERROR
  AG_RST_PTR
  AG_RESYNCH
  return (PCB).exit_flag == AG_RUNNING_CODE;
}

STATIC#int NEAR#QUAL#ag_reduce_proc(THISARG) {
  int ag_sd = ag_fl[(PCB).ag_ap];
  AG_CLEAR_BACK
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  else {
    AG_STACK
  }
  AG_RST_PTR
  AG_REDUCE
  AG_NSR_RD
  return (PCB).exit_flag == AG_RUNNING_CODE;
}

STATIC#int NEAR#QUAL#ag_simple_reduce_proc(THISARG) {
  int ag_sd = ag_fl[(PCB).ag_ap];
  AG_SIMPLE_REDUCE
  AG_SET_BACK
  if (ag_sd) {
    (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  }
  else {
    AG_PROTX
    AG_NULL
    AG_STACK
  }
  AG_RST_PTR
  AG_NSR_RD
  return (PCB).exit_flag == AG_RUNNING_CODE;
}

##

error token parse procs

STATIC#int NEAR#QUAL#ag_er_go_to_proc(THISARG) {
  AG_CLEAR_BACK
  AG_GET_VALUE
  (PCB).ssx++;
  (PCB).sn = (PCB).ag_ap;
  return 0;
}

STATIC#int NEAR#QUAL#ag_er_shift_accept_proc(THISARG) {
  AG_CLEAR_BACK
  AG_COUNT_RULE_Z
  (PCB).exit_flag = AG_SUCCESS_CODE;
  return 0;
}

STATIC#int NEAR#QUAL#ag_er_simple_shift_reduce_proc(THISARG) {
  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
  AG_CLEAR_BACK
  AG_SIMPLE_REDUCE
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  else (PCB).ss[(PCB).ssx] = (PCB).sn;
  AG_NSR_SR
  return 0;
}

STATIC#int NEAR#QUAL#ag_er_shift_reduce_proc(THISARG) {
  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
  AG_CLEAR_BACK
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  else (PCB).ss[(PCB).ssx] = (PCB).sn;
  AG_REDUCE
  AG_NSR_SR
  return 0;
}

##

parse engine

AG_INIT_PARSE {
  AG_INIT_PTR
  AG_INIT_ERROR_MESSAGE
  AG_INIT_RESYNCH
  (PCB).ss[0] = (PCB).sn = (PCB).ssx = 0;
  (PCB).exit_flag = AG_RUNNING_CODE;
  AG_INIT_TRK
  AG_CLEAR_BACK
}

AG_PARSE {
  AG_INITIALIZE;
  (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;
      AG_GET_TKN
      do {
        unsigned ag_tx = (ag_t1 + ag_t2)/2;
        if (ag_tstt[ag_tx] > (AG_TSTT_CAST)(PCB).token_number)
          ag_t1 = ag_tx + 1;
        else ag_t2 = ag_tx;
      } while (ag_t1 < ag_t2);
      if (ag_tstt[ag_t1] != (AG_TSTT_CAST)(PCB).token_number)
        ag_t1 = ag_sbe[(PCB).sn];
    }
    (PCB).ag_ap = ag_pstt[ag_t1];
    (AG_GT[ag_astt[ag_t1]])(PCB_TYPE_CAST#PCBARG);
  }
}

##

reduce proc defs

STATIC#int NEAR#ag_r_shift_accept_proc(THISARG);
STATIC#int NEAR#ag_r_go_to_proc(THISARG);
STATIC#int NEAR#ag_r_shift_reduce_proc(THISARG);
STATIC#int NEAR#ag_r_simple_shift_reduce_proc(THISARG);
STATIC#int NEAR#ag_s_shift_accept_proc(THISARG);
STATIC#int NEAR#ag_s_shift_reduce_proc(THISARG);
STATIC#int NEAR#ag_shift_accept_proc(THISARG);
STATIC#int NEAR#ag_go_to_proc(THISARG);
STATIC#int NEAR#ag_shift_reduce_proc(THISARG);
STATIC#int NEAR#ag_simple_shift_reduce_proc(THISARG);
STATIC#int NEAR#ag_reduce_proc(THISARG);
STATIC#int NEAR#ag_simple_reduce_proc(THISARG);
STATIC#int NEAR#ag_accept_proc(THISARG);
STATIC#int NEAR#ag_error_proc(THISARG);
STATIC#int NEAR#ag_null_go_to_proc(THISARG);
STATIC#int NEAR#ag_skip_proc(THISARG);
STATIC#int NEAR#ag_skip_reduce_proc(THISARG);
STATIC#int NEAR#AG_RECOVER(THISARG);


STATIC#int (NEAR#*CONST QUAL#ag_r_procs_scan[])(THISARG) = {
  ag_r_shift_accept_proc,
  ag_r_go_to_proc,
  ag_r_shift_reduce_proc,
  ag_r_simple_shift_reduce_proc
};

STATIC#int (NEAR#*CONST QUAL#ag_s_procs_scan[])(THISARG) = {
  ag_s_shift_accept_proc,
  ag_r_go_to_proc,
  ag_s_shift_reduce_proc,
  ag_r_simple_shift_reduce_proc
};

STATIC#int (NEAR#*CONST QUAL#ag_gt_procs_scan[])(THISARG) = {
  ag_shift_accept_proc,
  ag_go_to_proc,
  ag_shift_reduce_proc,
  ag_simple_shift_reduce_proc,
  ag_reduce_proc,
  ag_simple_reduce_proc,
  ag_accept_proc,
  ag_error_proc,
  ag_null_go_to_proc,
  ag_skip_proc,
  ag_skip_reduce_proc,
  AG_RECOVER
};

##

reduce proc error defs

STATIC#int NEAR#ag_er_shift_accept_proc(THISARG);
STATIC#int NEAR#ag_er_go_to_proc(THISARG);
STATIC#int NEAR#ag_er_shift_reduce_proc(THISARG);
STATIC#int NEAR#ag_er_simple_shift_reduce_proc(THISARG);

STATIC#int (NEAR#*CONST QUAL#ag_er_procs_scan[])(THISARG) = {
  ag_er_shift_accept_proc,
  ag_er_go_to_proc,
  ag_er_shift_reduce_proc,
  ag_er_simple_shift_reduce_proc
};



##

chain parse procs

STATIC#int NEAR#QUAL#ag_skip_proc(THISARG) {
  AG_COUNT_RULE_P
  AG_CLEAR_BACK
  AG_TRK_PTR
  return 0;
}

STATIC#int NEAR#QUAL#ag_skip_reduce_proc(THISARG) {
  AG_CLEAR_BACK
  AG_GET_VALUE
  (PCB).ssx--;
  AG_COUNT_RULE_P
  ag_ra(PCBARG);
  (PCB).ssx++;
  AG_TRK_PTR
  return 0;
}

STATIC#int NEAR#QUAL#ag_r_shift_reduce_proc(THISARG) {
  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  AG_CLEAR_BACK
  AG_REDUCE
  return (PCB).exit_flag == AG_RUNNING_CODE;
}

STATIC#int NEAR#QUAL#ag_s_shift_reduce_proc(THISARG) {
  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  AG_CLEAR_BACK
  AG_REDUCE
  return (PCB).exit_flag == AG_RUNNING_CODE;
}

STATIC#int NEAR#QUAL#ag_r_simple_shift_reduce_proc(THISARG) {
  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  AG_SIMPLE_REDUCE
  return 1;
}

STATIC#int NEAR#QUAL#ag_go_to_proc(THISARG) {
  AG_CLEAR_BACK
  AG_CHKOVFLO
  AG_GET_VALUE
  AG_STACK
  (PCB).ssx++;
  (PCB).sn = (PCB).ag_ap;
  AG_TRK_PTR
  return 0;
}

STATIC#int NEAR#QUAL#ag_null_go_to_proc(THISARG) {
  AG_SET_BACK
  AG_PROTX
  AG_STACK
  (PCB).ssx++;
  (PCB).sn = (PCB).ag_ap;
  AG_RST_PTR
  return (PCB).exit_flag == AG_RUNNING_CODE;
}

STATIC#int NEAR#QUAL#ag_r_go_to_proc(THISARG) {
  (PCB).ssx++;
  (PCB).sn = (PCB).ag_ap;
  return 0;
}

STATIC#int NEAR#QUAL#ag_accept_proc(THISARG) {
  --(PCB).ssx;
  AG_COUNT_RULE_Z
  (PCB).exit_flag = AG_SUCCESS_CODE;
  AG_RST_PTR
  return 0;
}

STATIC#int NEAR#QUAL#ag_shift_accept_proc(THISARG) {
  (PCB).exit_flag = AG_SUCCESS_CODE;
  AG_COUNT_RULE_Z
  AG_TRK_PTR
  return 0;
}

STATIC#int NEAR#QUAL#ag_r_shift_accept_proc(THISARG) {
  AG_COUNT_RULE_Z
  (PCB).exit_flag = AG_SUCCESS_CODE;
  return 0;
}

STATIC#int NEAR#QUAL#ag_s_shift_accept_proc(THISARG) {
  AG_COUNT_RULE_Z
  (PCB).exit_flag = AG_SUCCESS_CODE;
  return 0;
}

STATIC#int NEAR#QUAL#ag_simple_shift_reduce_proc(THISARG) {
  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
  AG_SIMPLE_REDUCE
  AG_CLEAR_BACK
  AG_GET_VALUE
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  else AG_STACK
  AG_TRK_PTR
  AG_NSR_SR
  return 0;
}

STATIC#int NEAR#QUAL#ag_shift_reduce_proc(THISARG) {
  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
  AG_CLEAR_BACK
  AG_GET_VALUE
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  else AG_STACK
  AG_TRK_PTR
  AG_REDUCE
  AG_NSR_SR
  return 0;
}

STATIC#int NEAR#QUAL#ag_error_proc(THISARG) {
  AG_UNDO
  AG_TRACE_ERROR
  AG_RST_PTR
  AG_RESYNCH
  return (PCB).exit_flag == AG_RUNNING_CODE;
}

STATIC#int NEAR#QUAL#ag_reduce_proc(THISARG) {
  int ag_sd = ag_fl[(PCB).ag_ap];
  AG_CLEAR_BACK
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  else {
    AG_STACK
  }
  AG_RST_PTR
  AG_REDUCE
  AG_NSR_RD
  return (PCB).exit_flag == AG_RUNNING_CODE;
}

STATIC#int NEAR#QUAL#ag_simple_reduce_proc(THISARG) {
  int ag_sd = ag_fl[(PCB).ag_ap];
  AG_SIMPLE_REDUCE
  AG_SET_BACK
  if (ag_sd) {
    (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  }
  else {
    AG_PROTX
    AG_NULL
    AG_STACK
  }
  AG_RST_PTR
  AG_NSR_RD
  return (PCB).exit_flag == AG_RUNNING_CODE;
}

##

chain error token parse procs

STATIC#int NEAR#QUAL#ag_er_go_to_proc(THISARG) {
  AG_CLEAR_BACK
  AG_GET_VALUE
  (PCB).ssx++;
  (PCB).sn = (PCB).ag_ap;
  return 0;
}

STATIC#int NEAR#QUAL#ag_er_shift_accept_proc(THISARG) {
  AG_CLEAR_BACK
  (PCB).exit_flag = AG_SUCCESS_CODE;
  AG_COUNT_RULE_Z
  return 0;
}

STATIC#int NEAR#QUAL#ag_er_simple_shift_reduce_proc(THISARG) {
  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
  AG_CLEAR_BACK
  AG_SIMPLE_REDUCE
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  else (PCB).ss[(PCB).ssx] = (PCB).sn;
  AG_NSR_SR
  return 0;
}

STATIC#int NEAR#QUAL#ag_er_shift_reduce_proc(THISARG) {
  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
  AG_CLEAR_BACK
  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
  else (PCB).ss[(PCB).ssx] = (PCB).sn;
  AG_REDUCE
  AG_NSR_SR
  return 0;
}

##

chain parse engine


AG_INIT_PARSE {
  unsigned ag_t1;
  ag_t1 = 0;
  AG_INIT_PTR
  AG_INIT_ERROR_MESSAGE
  AG_INIT_RESYNCH
  (PCB).ss[0] = (PCB).sn = (PCB).ssx = 0;
  (PCB).exit_flag = AG_RUNNING_CODE;
  AG_INIT_TRK
  AG_CLEAR_BACK
  while (ag_tstt[ag_t1] == 0) {
    (PCB).ag_ap = ag_pstt[ag_t1];
    (AG_GT[ag_astt[ag_t1]])(PCB_TYPE_CAST#PCBARG);
    ag_t1 = ag_sbt[(PCB).sn];
  }
}

AG_PARSE {
  (PCB).token_number = (AG_TOKEN_TYPE) AG_TCV((PCB).input_code);
  while (1) {
    unsigned ag_t1 = ag_sbt[(PCB).sn];
    unsigned ag_t2 = ag_sbe[(PCB).sn] - 1;
    do {
      unsigned ag_tx = (ag_t1 + ag_t2)/2;
      if (ag_tstt[ag_tx] > (AG_TSTT_CAST)(PCB).token_number)
        ag_t1 = ag_tx + 1;
      else ag_t2 = ag_tx;
    } while (ag_t1 < ag_t2);
    if (ag_tstt[ag_t1] != (AG_TSTT_CAST)(PCB).token_number)
      ag_t1 = ag_sbe[(PCB).sn];
    (PCB).ag_ap = ag_pstt[ag_t1];
    if ((AG_GT[ag_astt[ag_t1]])(PCB_TYPE_CAST#PCBARG) == 0) break;
  }
}

##

chain key parse engine

AG_INIT_PARSE {
  unsigned ag_t1;
  ag_t1 = 0;
  AG_INIT_PTR
  AG_INIT_ERROR_MESSAGE
  AG_INIT_RESYNCH
  (PCB).ss[0] = (PCB).sn = (PCB).ssx = 0;
  (PCB).exit_flag = AG_RUNNING_CODE;
  (PCB).key_sp = NULL;
  (PCB).key_state = 0;
  AG_INIT_TRK
  AG_CLEAR_BACK
  while (ag_tstt[ag_t1] == 0) {
    (PCB).ag_ap = ag_pstt[ag_t1];
    (AG_GT[ag_astt[ag_t1]])(PCB_TYPE_CAST#PCBARG);
    ag_t1 = ag_sbt[(PCB).sn];
  }
}

AG_PARSE {
  (PCB).lab[(PCB).fx++] = (PCB).input_code;
  while ((PCB).exit_flag == AG_RUNNING_CODE) {
    while (1) {
      CONST unsigned char *ag_p;
      int ag_ch;
      if ((PCB).rx >= (PCB).fx) return;
      ag_ch = CONVERT_CASE((PCB).lab[(PCB).rx++]);
      if ((PCB).key_sp) {
        if (ag_ch != *(PCB).key_sp++) {
          (PCB).rx = (PCB).save_index;
          (PCB).key_sp = NULL;
          (PCB).key_state = 0;
          break;
        } else if (*(PCB).key_sp) continue;
        if (ag_key_act[(PCB).key_state] == ag_cf_end_key) {
          int ag_k1;
          int ag_k2;
          if ((PCB).rx >= (PCB).fx) {
            (PCB).rx--;
            (PCB).key_sp--;
            return;
          }
          (PCB).key_sp = NULL;
          ag_k1 = ag_key_parm[(PCB).key_state];
          ag_k2 = ag_key_pt[ag_k1];
          if (ag_key_itt[ag_k2 + CONVERT_CASE((PCB).lab[(PCB).rx])])
            (PCB).rx = (PCB).save_index;
          else {
            (PCB).token_number =  (AG_TOKEN_TYPE) ag_key_pt[ag_k1+1];
            (PCB).key_state = 0;
          }
          break;
        }
        else {
          (PCB).token_number = (AG_TOKEN_TYPE) ag_key_parm[(PCB).key_state];
          (PCB).key_state = 0;
          (PCB).key_sp = NULL;
        }
        break;
      }
      if ((PCB).key_state == 0) {
        (PCB).token_number = (AG_TOKEN_TYPE) AG_TCV(ag_ch);
        if (((PCB).key_state = ag_key_index[(PCB).sn]) == 0) break;
        (PCB).save_index = 1;
      }
      ag_p = &ag_key_ch[(PCB).key_state];
      if (ag_ch <= 255) while (*ag_p < ag_ch) ag_p++;
      if (*ag_p == ag_ch) {
        (PCB).key_state = (int)(ag_p - ag_key_ch);
        switch (ag_key_act[(PCB).key_state]) {
        case ag_cf_set_key: {
          int ag_k1;
          int ag_k2;
          if ((PCB).rx >= (PCB).fx) {
            (PCB).rx--;
            return;
          }
          ag_k1 = ag_key_parm[(PCB).key_state];
          ag_k2 = ag_key_pt[ag_k1];
          (PCB).key_state = ag_key_jmp[(PCB).key_state];
          if (ag_key_itt[ag_k2 + CONVERT_CASE((PCB).lab[(PCB).rx])]) continue;
          (PCB).save_index = (PCB).rx;
          (PCB).token_number = (AG_TOKEN_TYPE) ag_key_pt[ag_k1+1];
          continue;
        }
        case ag_set_key:
          (PCB).save_index = (PCB).rx;
          (PCB).token_number = (AG_TOKEN_TYPE) ag_key_parm[(PCB).key_state];
          /* FALLTHROUGH */
        case ag_jmp_key:
          (PCB).key_state = ag_key_jmp[(PCB).key_state];
          continue;
        case ag_cf_end_key:
        case ag_end_key:
          (PCB).key_sp = ag_key_ends + ag_key_jmp[(PCB).key_state];
          continue;
        case ag_accept_key:
          (PCB).token_number = (AG_TOKEN_TYPE) ag_key_parm[(PCB).key_state];
          (PCB).key_state = 0;
          break;
        case ag_cf_accept_key: {
          int ag_k1;
          int ag_k2;
          if ((PCB).rx >= (PCB).fx) {
            (PCB).rx--;
            return;
          }
          ag_k1 = ag_key_parm[(PCB).key_state];
          ag_k2 = ag_key_pt[ag_k1];
          if (ag_key_itt[ag_k2 + CONVERT_CASE((PCB).lab[(PCB).rx])])
            (PCB).rx = (PCB).save_index;
          else {
            (PCB).token_number = (AG_TOKEN_TYPE) ag_key_pt[ag_k1+1];
            (PCB).key_state = 0;
          }
          break;
        }
        }
        break;
      } else {
        (PCB).rx = (PCB).save_index;
        (PCB).key_state = 0;
        break;
      }
    }

    {
      unsigned ag_t1 = ag_sbt[(PCB).sn];
      unsigned ag_t2 = ag_sbe[(PCB).sn] - 1;
      do {
        unsigned ag_tx = (ag_t1 + ag_t2)/2;
        if (ag_tstt[ag_tx] > (AG_TSTT_CAST)(PCB).token_number)
          ag_t1 = ag_tx + 1;
        else ag_t2 = ag_tx;
      } while (ag_t1 < ag_t2);
      if (ag_tstt[ag_t1] != (PCB).token_number)  ag_t1 = ag_sbe[(PCB).sn];
      (PCB).ag_ap = ag_pstt[ag_t1];
      (AG_GT[ag_astt[ag_t1]])(PCB_TYPE_CAST#PCBARG);
    }
  }
}

##


c plus plus definitions

STATIC#int  NEAR#QUAL#ag_accept_proc(THISARG);
STATIC#int  NEAR#QUAL#AG_ATX;
STATIC#VOID NEAR#QUAL#ag_auto_resynch(THISARG);
STATIC#VOID NEAR#QUAL#AG_CHECK_DEPTH;
STATIC#VOID NEAR#QUAL#AG_DEFAULT;
STATIC#VOID NEAR#QUAL#ag_diagnose(THISARG);
STATIC#int  NEAR#QUAL#ag_error_proc(THISARG);
STATIC#VOID NEAR#QUAL#ag_error_resynch(THISARG);
STATIC#VOID NEAR#QUAL#AG_GET_KEY_WORD;
STATIC#int  NEAR#QUAL#ag_go_to_error_proc(THISARG);
STATIC#int  NEAR#QUAL#ag_go_to_proc(THISARG);
STATIC#int  NEAR#QUAL#AG_JNS;
STATIC#int  NEAR#QUAL#ag_look_ahead(THISARG);
STATIC#int  NEAR#QUAL#ag_null_go_to_proc(THISARG);
STATIC#VOID NEAR#QUAL#ag_prot(THISARG);
STATIC#int  NEAR#QUAL#ag_recover_proc(THISARG);
STATIC#int  NEAR#QUAL#ag_reduce_proc(THISARG);
STATIC#int  NEAR#QUAL#AG_RNS;
STATIC#int  NEAR#QUAL#ag_r_go_to_proc(THISARG);
STATIC#int  NEAR#QUAL#ag_r_shift_accept_proc(THISARG);
STATIC#int  NEAR#QUAL#ag_r_shift_reduce_proc(THISARG);
STATIC#int  NEAR#QUAL#ag_r_simple_shift_reduce_error_proc(THISARG);
STATIC#int  NEAR#QUAL#ag_r_simple_shift_reduce_proc(THISARG);
STATIC#VOID NEAR#QUAL#ag_set_error_procs(THISARG);
STATIC#int  NEAR#QUAL#ag_shift_accept_proc(THISARG);
STATIC#int  NEAR#QUAL#ag_shift_reduce_proc(THISARG);
STATIC#int  NEAR#QUAL#ag_simple_reduce_error_proc(THISARG);
STATIC#int  NEAR#QUAL#ag_simple_reduce_proc(THISARG);
STATIC#int  NEAR#QUAL#ag_simple_shift_reduce_error_proc(THISARG);
STATIC#int  NEAR#QUAL#ag_simple_shift_reduce_proc(THISARG);
STATIC#int  NEAR#QUAL#ag_skip_proc(THISARG);
STATIC#int  NEAR#QUAL#ag_skip_reduce_error_proc(THISARG);
STATIC#int  NEAR#QUAL#ag_skip_reduce_proc(THISARG);
STATIC#int  NEAR#QUAL#ag_s_shift_accept_proc(THISARG);
STATIC#int  NEAR#QUAL#ag_s_shift_reduce_proc(THISARG);
STATIC#VOID NEAR#QUAL#ag_trace_error(THISARG);
STATIC#VOID NEAR#QUAL#ag_track(THISARG);
STATIC#int  NEAR#QUAL#ag_tst_tkn(THISARG);
STATIC#VOID NEAR#QUAL#ag_undo(THISARG);

STATIC#int (NEAR#*QUAL#ag_r_procs_error[])(THISARG);
STATIC#int (NEAR#*QUAL#ag_s_procs_error[])(THISARG);
STATIC#int (NEAR#*QUAL#ag_gt_procs_error[])(THISARG);
STATIC#AG_TSTT_TYPE LOCUS *QUAL#AG_VALID;

##

value proc

%s %s_value(%s) {
  %s returnValue;
  returnValue = %s;
  return returnValue;
}

##

fin
##