view anagram/agcore/engine.cgs @ 14:a02e9434072e

Fix friend declaration for gcc10. XXX: did not check it against the IBM compiler, might end up needing XXX: to be conditional.
author David A. Holland
date Tue, 31 May 2022 00:59:42 -0400
parents 13d2b8934445
children 1c9dac05d040
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);
    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];
    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);
    }
    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];
    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];
        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
##