    // It is here for incorporating as the basis of a compile() function to do something useful with an AST.
    // For example this generated the code that was manually converted into algol60-indent.h

//\\ B<eof> = 0;
//\\#
//\\ B<ch> = 1;
//\\#
//\\ B<nl> = 2;
//\\#
//\\ P<INITDECS> =
   case P_INITDECS:
#ifdef IN_PARSER

  Basetype   = UNINIT_BASETYPE;
  Signedness = UNINIT_SIGNEDNESS;
  Precision  = UNINIT_PRECISION;
  Proc       = UNINIT_PROC;
  NameInfo   = NO_NAME;           // UNINIT_AN_N
  //IsFormat   = NO_FORMAT;       // UNINIT_ISFORMAT
  Spec       = NO_SPEC;           // UNINIT_SPEC
  IsArray    = SCALAR;            // UNINIT_ISARRAY
  // TO DO: Do I need an "IS_INITIALISED" tag as well?  So far, only reason for
  //        having one would be to suppress the keyword "extern" in declarations
  //        such as "%externalinteger fred = 1" which would otherwise be declared
  //        in C as "extern int fred = 1;" rather than "int fred = 1;" (at least
  //        if declared at the top level.  Placing that declaration within
  //        a nested routine is a separate issue and may be a problem. Exbedding
  //        that declaration to the top level may not be possible due to scoping rules.)
  // NOTE: A data declaration (e.g. %integer I) at the top level of a file of externals
  // or before the begin/endofprogram block is an error in Imp77 and I'm guessing in Imp80.
  Area       = (ctrl_depth() == 0 ? EXTDATA : STACK);  // UNINIT_AREA
  // However a %routine at the same level (as opposed to an %externalroutine) appears to be accepted.
  Linkage    = UNINIT_LINKAGE;    // Ditto? Check with ERCC compiler. Or ask Bob.

#endif
     {                              //\\    ;

     return t[0] = P_mktuple(P_INITDECS, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<USE> =
   case P_USE:
#ifdef IN_PARSER


#endif
     {                              //\\    ;

     return t[0] = P_mktuple(P_USE, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<temp_quiet> =
   case P_temp_quiet:
#ifdef IN_PARSER

  quiet=1;

#endif
     {                              //\\    ;

     return t[0] = P_mktuple(P_temp_quiet, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<end_temp_quiet> =
   case P_end_temp_quiet:
#ifdef IN_PARSER

  quiet=0;

#endif
     {                              //\\    ;

     return t[0] = P_mktuple(P_end_temp_quiet, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<DECLARE> =
   case P_DECLARE:
#ifdef IN_PARSER
     // NOT ONLY OUTPUT THE DECLARATION IN C CODE, BUT ALSO ADD DECLARATION TO SCOPED NAME TABLES.

  // <DECLARE> collects all the pieces that preceded it which were set up during the walk
  // of the CST and uses them to modify the scoped name tables.  It also outputs the
  // declarations on the fly rather than during a subsequent walk of the generated AST.

  // It may be preferable to have this code only create the data structure and add it to the
  // scope tables, leaving the generation of the corresponding C code for the declaration up
  // to a call to 'generate_c' with this data structure as a parameter (eg an AST_DECLARE tuple)

  // One reason for doing so would be to handle initialised declarations better.

  // However it may be essential to create the name tables on the fly as the state of declarations
  // may be needed to steer the parser, though at the moment it is not looking like that is necessary.
  // If it were and if we were to try to postpone the C code generation until the CST was fully
  // converted to an AST, we would have to regenerate the name tables during that tree walk.

  // Until I see a definite need to do otherwise, I'm going to assume that we can postpone the
  // creation of the name tables until the AST is walked.  Note that the reason for these issues
  // is that the ERCC compilers handled a statement at a time but this parser is (currently)
  // parsing the entire program before the AST is interpreted.

  if (quiet) return -1;

  // GENERATE CODE:

  switch (Object) {
  case VAR:
    if (Area == OWN) fprintf(stdout, "static ");
    else if (Area == EXTDATA) {
      // I don't believe that these external data declarations have to come at the top level *unless* they're initialised.
      fprintf(stdout, "extern ");
        /*
              In ISO C, 'extern' does not mean 'not defined in this file', it means
              'visible outside this file'. For instance,

              extern int x(void) { return 1; }
              extern int i3 = 3;

              are both valid ISO C, although they're unusual and the compiler warns
              about the second one.
         */
    } else if (Area == CONSTANT) fprintf(stdout, "const ");
    if (Basetype == RECORD) {

      // If the type was given as a format name then let's use the typedef otherwise
      // we'll need to put the struct definition inline.  And remember when defining
      // a record format, if it refers to itself as a %name field eg to link to a next
      // item, you need to predefine it as "typedef recfm recfm" before you actually
      // typedef the contents of recfm!
      
      fprintf(stdout, "/*pending name*/recfm  ");
    } else if (Basetype == STRINGTYPE) {
      fprintf(stdout, "Imp_String ");
    } else {
      if (Basetype == INTEGER) {
        if (Signedness == UNSIGNED) fprintf(stdout, "unsigned ");
        if (Precision == BYTE) fprintf(stdout, "char ");
        else if (Precision == SHORT) fprintf(stdout, "short int ");
        else if (Precision == WORD) fprintf(stdout, "int ");
        else if (Precision == LONGWORD) fprintf(stdout, "long int ");
        else if (Precision == QUADWORD) fprintf(stdout, "long long int ");
        else if (Precision == ADDR) fprintf(stdout, "void *");
      } else if (Basetype == FLOAT) {
        if (Precision == WORD) fprintf(stdout, "float ");
        else if (Precision == LONGWORD) fprintf(stdout, "double "); 
        else if (Precision == QUADWORD) fprintf(stdout, "long double "); 
        else if (Precision == ADDR) fprintf(stdout, "void *");
      }
    }
    if (NameInfo == OBJECTNAME) fprintf(stdout, "*");
    else if (NameInfo == ARRAYNAME) fprintf(stdout, "**");
    PrintTag(Tag);
    if (IsArray == ARRAY) fprintf(stdout, "[]");
    fprintf(stdout, ";"); // CANNOT OUTPUT ';' HERE IF THIS IS AN INITIALISED DECLARATION!
    break;

  case CODE:
    if (Linkage == EXTPROC) {
      if (Spec == SPEC) {
        fprintf(stdout, "extern ");
      } else {
        // The body of an Imp %externalroutine does not require "extern" in C.
        // An external *spec* does *NOT* have to be at the top level although
        // an external body does.
        /*
              In ISO C, 'extern' does not mean 'not defined in this file', it means
              'visible outside this file'. For instance,

              extern int x(void) { return 1; }
              extern int i3 = 3;

              are both valid ISO C, although they are unusual and the compiler warns
              about the second one.
         */
        // declaration of an externalroutine or function etc *but* only valid if at the top level.  So check.  (TO DO)
      }
    } else if (ctrl_depth() == 0) {
      fprintf(stdout, "static ");
    } else {
      if (Spec == SPEC) fprintf(stdout, "auto "); // GCC requires "auto" for forward references to nested procedures, but not for the procedures themselves.
    }
    if (Proc == ROUTINE) {
      fprintf(stdout, "void ");
    } else if (Basetype == RECORD) {
      fprintf(stdout, "/*pending name*/recfm  ");
    } else if (Basetype == STRINGTYPE) {
      fprintf(stdout, "Imp_String ");
    } else {
      if (Basetype == INTEGER) {
        if (Signedness == UNSIGNED) fprintf(stdout, "unsigned ");
        if (Precision == BYTE) fprintf(stdout, "char ");
        else if (Precision == SHORT) fprintf(stdout, "short int ");
        else if (Precision == WORD) fprintf(stdout, "int ");
        else if (Precision == LONGWORD) fprintf(stdout, "long int ");
        else if (Precision == QUADWORD) fprintf(stdout, "long long int ");
        else if (Precision == ADDR) fprintf(stdout, "void *");
      } else if (Basetype == FLOAT) {
        if (Precision == WORD) fprintf(stdout, "float ");
        else if (Precision == LONGWORD) fprintf(stdout, "double "); 
        else if (Precision == QUADWORD) fprintf(stdout, "long double "); 
        else if (Precision == ADDR) fprintf(stdout, "void *");
      }
    }
    if (NameInfo == OBJECTNAME) fprintf(stdout, "*");
    if (Proc == MAP) fprintf(stdout, "*");
    PrintTag(Tag);
    fprintf(stdout, "(/*to do*/)");
    if (Spec == SPEC) fprintf(stdout, ";"); else fprintf(stdout, " {\n"); // the %end will come much later
    break;

  case RECORDFORMAT:
    break;
  case ARRAYFORMAT:
    break;
  case SWITCHDEFN:
    break;
  case LABELDEFN:
    break;
  case UNINIT_OBJECT:
    break;
  }

    _TypeDecl[TypeDecl_nextfree].Object     =  Object     ;
    _TypeDecl[TypeDecl_nextfree].Basetype   =  Basetype   ;
    _TypeDecl[TypeDecl_nextfree].Signedness =  Signedness ;
    _TypeDecl[TypeDecl_nextfree].Precision  =  Precision  ;
    _TypeDecl[TypeDecl_nextfree].Proc       =  Proc       ;
    _TypeDecl[TypeDecl_nextfree].NameInfo   =  NameInfo   ;
    _TypeDecl[TypeDecl_nextfree].Spec       =  Spec       ;
    _TypeDecl[TypeDecl_nextfree].IsArray    =  IsArray    ;
    _TypeDecl[TypeDecl_nextfree].Area       =  Area       ;
    _TypeDecl[TypeDecl_nextfree].Linkage    =  Linkage    ;
    // TO DO:
    _TypeDecl[TypeDecl_nextfree].arrfm      =  -1         ;
    _TypeDecl[TypeDecl_nextfree].parms      =  -1         ;
    _TypeDecl[TypeDecl_nextfree].recfm      =  -1         ;
    _TypeDecl[TypeDecl_nextfree].strfm      =  -1         ;
    
    _VarDecl[VarDecl_nextfree].varname      = Tag;
    _VarDecl[VarDecl_nextfree].aliasname    = -1;
    _VarDecl[VarDecl_nextfree].c_name       = Tag;
    _VarDecl[VarDecl_nextfree].type         = TypeDecl_nextfree;
    _VarDecl[VarDecl_nextfree].aform        = -1;

//fprintf(stdout, "      /* VarDecl[%d] = {varname=%s tag=%d ", VarDecl_nextfree, Tag2Str(Tag), Tag);
//fprintf(stdout, "Object=%d Basetype=%d Signedness=%d Precision=%d Proc=%d NameInfo=%d Spec=%d IsArray=%d Area=%d Linkage=%d} */\n",
//                        Object,     Basetype,     Signedness,  Precision,  Proc,   NameInfo,  Spec,   IsArray,   Area,   Linkage);

    // DESCRIBE:
    if (Object != LABELDEFN) {
      fprintf(stdout, "  /* ");
      PrintTag(Tag);
      fprintf(stdout, ": TypeDecl=%d VarDecl=%d Object=%s ", TypeDecl_nextfree, VarDecl_nextfree, Object_name[Object]);
      if (Object == CODE) {
        fprintf(stdout, "Proc=%s ", Proc_name[Proc]);
        fprintf(stdout, "Linkage=%s ", Linkage_name[Linkage]);
      } else if (Object == VAR) {
        fprintf(stdout, "Area=%s ", Area_name[Area]);
      }
      if (Object == VAR || (Object == CODE && Proc != ROUTINE) || Object == ARRAYFORMAT) {
        if (Basetype != RECORD && Precision != COMPOUND) fprintf(stdout, "Sign=%s ", Signedness_name[Signedness]);
        fprintf(stdout, "Prec=%s ", Precision_name[Precision]);
        fprintf(stdout, "Type=%s ", Basetype_name[Basetype]);
        fprintf(stdout, "NameInfo=%s ", NameInfo_name[NameInfo]);
      }
      if (Object == VAR) {
        if (Proc != UNINIT_PROC) fprintf(stdout, "Proc=%s ", Proc_name[Proc]);
        //fprintf(stdout, "format=%s ", IsFormat_name[IsFormat]);
        fprintf(stdout, "IsArray=%s ", IsArray_name[IsArray]);
      }
      fprintf(stdout, "Spec=%s ", Spec_name[Spec]);
      fprintf(stdout, "*/\n");
    }
    
    TypeDecl_nextfree += 1;
    VarDecl_nextfree += 1;

    add_entry("decl", Tag2Str(Tag), VarDecl_nextfree-1);


#endif
     {                              //\\    ;

     return t[0] = P_mktuple(P_DECLARE, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<nls> =
   case P_nls:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    <nl> <nls>,
       t[1] = wlit(P(1) /*, L"nl" */);
       t[2] = compile(P(2), depth+1 /* P_nls */);
       return t[0] = P_mktuple(P_nls, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_nls, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<READLINEP> =
   case P_READLINEP:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    <nls>,
       t[1] = compile(P(1), depth+1 /* P_nls */);
       return t[0] = P_mktuple(P_READLINEP, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_READLINEP, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<S> =
   case P_S:
#ifdef IN_PARSER

  // fprintf(stdout, "\n"); // obviously this will need some work re {} blocks...

#endif
     if (alt == 0)               {  //\\    <nl>,
       t[1] = wlit(P(1) /*, L"nl" */);
       return t[0] = P_mktuple(P_S, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ';';
       t[1] = wlit(P(1) /*, L';' */);
       return t[0] = P_mktuple(P_S, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<SET_DOWN_FLAG> =
   case P_SET_DOWN_FLAG:
#ifdef IN_PARSER

  // Set when testing <SPEC> if it *wasn't* a spec.
  DOWN_flag = 1;

#endif
     {                              //\\    ;

     return t[0] = P_mktuple(P_SET_DOWN_FLAG, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<DOWNQ> =
   case P_DOWNQ:
#ifdef IN_PARSER

  // Act on the flag set earlier once we get to the body of the procedure.
  if (DOWN_flag == 1) push_scope_level();
  DOWN_flag = 0;

#endif
     {                              //\\    ;

     return t[0] = P_mktuple(P_DOWNQ, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<DOWN> =
   case P_DOWN:
#ifdef IN_PARSER

  // unconditionally set in a %begin.  Could just put the 'push_scope_level()' in
  // the code for <begin_block> but for now I'll follow the structure of the
  // ERCC compilers and grammar.
  push_scope_level();

#endif
     {                              //\\    ;

     return t[0] = P_mktuple(P_DOWN, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<UP> =
   case P_UP:
#ifdef IN_PARSER

  // called on %end and %endofprogram
  pop_scope_level();

#endif
     {                              //\\    ;

     return t[0] = P_mktuple(P_UP, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<SS> =
   case P_SS:
#ifdef IN_PARSER

#endif
     {                              //\\    <init> <Imp77_stropping> <STATEMENTS> <terminate>;
     t[1] = -1; /* semantic procedure init */;
     t[2] = -1; /* semantic procedure Imp77_stropping */;
     t[3] = compile(P(3), depth+1 /* P_STATEMENTS */);
     t[4] = -1; /* semantic procedure terminate */;
     return t[0] = P_mktuple(P_SS, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<BINOP> =
   case P_BINOP:
#ifdef IN_PARSER

     // Phrase is used to convert an OP into a more useful AST phrase.
     // (the default for char syms is separate items for each char which is unweildy)

     // It would be cleaner to return the OP_xxx enum rather than the string.  Will do so later.
     // (The string is decoded in PushBinOp())
     
     if (alt == 0)               {  //\\    '+',
       t[1] = wstrtopool(L"+");
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t);

     } else if (alt == 1)        {  //\\    '-',
       t[1] = wstrtopool(L"-");
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t);

     } else if (alt == 2)        {  //\\    '&',
       t[1] = wstrtopool(L"&");
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t);

     } else if (alt == 3)        {  //\\    '*' '*' '*' '*',
       t[1] = wstrtopool(L"****");
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t);
       
     } else if (alt == 4)        {  //\\    '*' '*',
       t[1] = wstrtopool(L"**");
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t);

     } else if (alt == 5)        {  //\\    '*',
       t[1] = wstrtopool(L"*");
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t);

     } else if (alt == 6)        {  //\\    '!' '!',
       t[1] = wstrtopool(L"!!");
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t);

     } else if (alt == 7)        {  //\\    '!',
       t[1] = wstrtopool(L"!");
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t);

     } else if (alt == 8)        {  //\\    '/' '/',
       t[1] = wstrtopool(L"//");
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t);

     } else if (alt == 9)        {  //\\    '/',
       t[1] = wstrtopool(L"/");
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t);

     } else if (alt == 10)        {  //\\    '>' '>',
       t[1] = wstrtopool(L">>");
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t);

     } else if (alt == 11)        {  //\\    '<' '<',
       t[1] = wstrtopool(L"<<");
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t);

     } else if (alt == 12)        {  //\\    '.',
       t[1] = wstrtopool(L".");
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t);

     } else if (alt == 13)        {  //\\    '\' '\',
       t[1] = wstrtopool(L"\\\\");
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t);

     } else if (alt == 14)        {  //\\    '\',
       t[1] = wstrtopool(L"\\");
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t);

     } else if (alt == 15)        {  //\\    '^' '^',
       t[1] = wstrtopool(L"^^");                                    // NOTE: soap80 does not recognise ^^, only ****
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t);

     } else                      {  //\\    '^';
       t[1] = wstrtopool(L"^");
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t);

     }
     return -1;

#endif
     if (alt == 0)               {  //\\    '+',
       t[1] = wlit(P(1) /*, L'+' */);
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    '-',
       t[1] = wlit(P(1) /*, L'-' */);
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 2)        {  //\\    '&',
       t[1] = wlit(P(1) /*, L'&' */);
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 3)        {  //\\    '*' '*' '*' '*',
       t[1] = wlit(P(1) /*, L'*' */);
       t[2] = wlit(P(2) /*, L'*' */);
       t[3] = wlit(P(3) /*, L'*' */);
       t[4] = wlit(P(4) /*, L'*' */);
       return t[0] = P_mktuple(P_BINOP, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 4)        {  //\\    '*' '*',
       t[1] = wlit(P(1) /*, L'*' */);
       t[2] = wlit(P(2) /*, L'*' */);
       return t[0] = P_mktuple(P_BINOP, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 5)        {  //\\    '*',
       t[1] = wlit(P(1) /*, L'*' */);
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 6)        {  //\\    '!' '!',
       t[1] = wlit(P(1) /*, L'!' */);
       t[2] = wlit(P(2) /*, L'!' */);
       return t[0] = P_mktuple(P_BINOP, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 7)        {  //\\    '!',
       t[1] = wlit(P(1) /*, L'!' */);
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 8)        {  //\\    '/' '/',
       t[1] = wlit(P(1) /*, L'/' */);
       t[2] = wlit(P(2) /*, L'/' */);
       return t[0] = P_mktuple(P_BINOP, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 9)        {  //\\    '/',
       t[1] = wlit(P(1) /*, L'/' */);
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 10)        {  //\\    '>' '>',
       t[1] = wlit(P(1) /*, L'>' */);
       t[2] = wlit(P(2) /*, L'>' */);
       return t[0] = P_mktuple(P_BINOP, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 11)        {  //\\    '<' '<',
       t[1] = wlit(P(1) /*, L'<' */);
       t[2] = wlit(P(2) /*, L'<' */);
       return t[0] = P_mktuple(P_BINOP, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 12)        {  //\\    '.',
       t[1] = wlit(P(1) /*, L'.' */);
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 13)        {  //\\    '\' '\',
       t[1] = wlit(P(1) /*, L'\\' */);
       t[2] = wlit(P(2) /*, L'\\' */);
       return t[0] = P_mktuple(P_BINOP, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 14)        {  //\\    '\',
       t[1] = wlit(P(1) /*, L'\\' */);
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 15)        {  //\\    '^' '^',
       t[1] = wlit(P(1) /*, L'^' */);
       t[2] = wlit(P(2) /*, L'^' */);
       return t[0] = P_mktuple(P_BINOP, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    '^';
       t[1] = wlit(P(1) /*, L'^' */);
       return t[0] = P_mktuple(P_BINOP, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<OP> =
   case P_OP:
#ifdef IN_PARSER

    PushBinOp(compile(P(1),depth+1)); // TORP
    return -1;

#endif
     {                              //\\    <BINOP>;
     t[1] = compile(P(1), depth+1 /* P_BINOP */);
     return t[0] = P_mktuple(P_OP, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<MONOP> =
   case P_MONOP:
#ifdef IN_PARSER

     if (alt == 4) return -1;
  
     if (alt == 0)               {  //\\    '+',
       t[1] = wstrtopool(L"+");
     } else if (alt == 1)        {  //\\    '-',
       t[1] = wstrtopool(L"-");
     } else if (alt == 2)        {  //\\    '\\',
       t[1] = wstrtopool(L"\\");
     } else if (alt == 3)        {  //\\    '~',
       t[1] = wstrtopool(L"~");
     }
     return t[0] = P_mktuple(P_MONOP, alt, 1/*phrases*/, t);

#endif
     if (alt == 0)               {  //\\    '+',
       t[1] = wlit(P(1) /*, L'+' */);
       return t[0] = P_mktuple(P_MONOP, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    '-',
       t[1] = wlit(P(1) /*, L'-' */);
       return t[0] = P_mktuple(P_MONOP, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 2)        {  //\\    '\',
       t[1] = wlit(P(1) /*, L'\\' */);
       return t[0] = P_mktuple(P_MONOP, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 3)        {  //\\    '~',
       t[1] = wlit(P(1) /*, L'~' */);
       return t[0] = P_mktuple(P_MONOP, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_MONOP, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<UOP> =
   case P_UOP:
#ifdef IN_PARSER

  {
     int Expr = compile(P(1),depth+1);
     if (Expr != -1) PushMonOp(Expr); // TORP
     return -1;
  }

#endif
     {                              //\\    <MONOP>;
     t[1] = compile(P(1), depth+1 /* P_MONOP */);
     return t[0] = P_mktuple(P_UOP, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<ASSOP> =
   case P_ASSOP:
#ifdef IN_PARSER

     if (alt == 0)               {
       t[1] = wstrtopool(L"==");
     } else if (alt == 1)        {
       t[1] = wstrtopool(L"=");
     } else if (alt == 2)        {
       t[1] = wstrtopool(L"<-");
     } else if (alt == 3)        {
       t[1] = wstrtopool(L"->");
     }
     return t[0] = P_mktuple(P_ASSOP, alt, 1/*phrases*/, t);

#endif
     if (alt == 0)               {  //\\    '=' '=',
       t[1] = wlit(P(1) /*, L'=' */);
       t[2] = wlit(P(2) /*, L'=' */);
       return t[0] = P_mktuple(P_ASSOP, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    '=',
       t[1] = wlit(P(1) /*, L'=' */);
       return t[0] = P_mktuple(P_ASSOP, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 2)        {  //\\    '<' '-',
       t[1] = wlit(P(1) /*, L'<' */);
       t[2] = wlit(P(2) /*, L'-' */);
       return t[0] = P_mktuple(P_ASSOP, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    '-' '>';
       t[1] = wlit(P(1) /*, L'-' */);
       t[2] = wlit(P(2) /*, L'>' */);
       return t[0] = P_mktuple(P_ASSOP, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<COMP1> =
   case P_COMP1:
#ifdef IN_PARSER

  {
    // Some work required to distinguish address comparisons and conditional resolution from simple arithmetic comparisons or string comparisons
    const char *C_Comp[] = { "==", ">=", ">", "!=", "!=", "!=", "<=", "<", "*ERROR*", "== &", "!= &", "!= &" };
    fprintf(stdout, " %s ", C_Comp[alt]);
    return -1; // TO DO: return one of several possible AST_something tuples
  }

#endif
     if (alt == 0)               {  //\\    '=',
       t[1] = wlit(P(1) /*, L'=' */);
       return t[0] = P_mktuple(P_COMP1, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    '>' '=',
       t[1] = wlit(P(1) /*, L'>' */);
       t[2] = wlit(P(2) /*, L'=' */);
       return t[0] = P_mktuple(P_COMP1, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 2)        {  //\\    '>',
       t[1] = wlit(P(1) /*, L'>' */);
       return t[0] = P_mktuple(P_COMP1, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 3)        {  //\\    '#',
       t[1] = wlit(P(1) /*, L'#' */);
       return t[0] = P_mktuple(P_COMP1, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 4)        {  //\\    '\' '=',
       t[1] = wlit(P(1) /*, L'\\' */);
       t[2] = wlit(P(2) /*, L'=' */);
       return t[0] = P_mktuple(P_COMP1, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 5)        {  //\\    '<' '>',
       t[1] = wlit(P(1) /*, L'<' */);
       t[2] = wlit(P(2) /*, L'>' */);
       return t[0] = P_mktuple(P_COMP1, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 6)        {  //\\    '<' '=',
       t[1] = wlit(P(1) /*, L'<' */);
       t[2] = wlit(P(2) /*, L'=' */);
       return t[0] = P_mktuple(P_COMP1, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 7)        {  //\\    '<',
       t[1] = wlit(P(1) /*, L'<' */);
       return t[0] = P_mktuple(P_COMP1, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 8)        {  //\\    '-' '>',
       t[1] = wlit(P(1) /*, L'-' */);
       t[2] = wlit(P(2) /*, L'>' */);
       return t[0] = P_mktuple(P_COMP1, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 9)        {  //\\    '=' '=',
       t[1] = wlit(P(1) /*, L'=' */);
       t[2] = wlit(P(2) /*, L'=' */);
       return t[0] = P_mktuple(P_COMP1, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 10)        {  //\\    '#' '#',
       t[1] = wlit(P(1) /*, L'#' */);
       t[2] = wlit(P(2) /*, L'#' */);
       return t[0] = P_mktuple(P_COMP1, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    '\' '=' '=';
       t[1] = wlit(P(1) /*, L'\\' */);
       t[2] = wlit(P(2) /*, L'=' */);
       t[3] = wlit(P(3) /*, L'=' */);
       return t[0] = P_mktuple(P_COMP1, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<COMP2> =
   case P_COMP2:
#ifdef IN_PARSER

#endif
     {                              //\\    <COMP1>;
     t[1] = compile(P(1), depth+1 /* P_COMP1 */);
     return t[0] = P_mktuple(P_COMP2, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<VARNAME> =
   case P_VARNAME:
#ifdef IN_PARSER

  {

    // TO DO: If the name was a perm/prim then it disappears in the output!  We need to handle that by
    // 1) actually declaring the built-in names, and
    // 2) returning something that outputs the name if it wasn't found... (at least during development -
    //    once we're live, the compiler will exit after a "NAME NOT SET" error.)

    // We want to return an AST record with the VarDecl contents
    // (which includes the TypeDecl information)
    char *s;
    VTag = SubPhraseIdx(Ph, 2)&AST_idx_mask;
    // Use the scope tools to find it.
    int VarIDX = lookup("decl", s=Tag2Str(VTag));
    if (VarIDX == -1) {
      fprintf(stderr, "* NAME NOT SET: %s\n", Tag2Str(VTag)); // exit(1);
      // return a literal string somehow.
    }
    t[1] = VarIDX;
    //fprintf(stderr, "Debug: VarIDX returned by looking up %s was %d\n", s, VarIDX);
    free(s); // Sorry. Should use Stringpool.
    return t[0] = P_mktuple(AST_RVALUE, 0/*alt no*/, 1/*phrases*/, t);
  }

#endif
     {                              //\\    <!CONST> «[A-Z][A-Z0-9]*» <USE>;
     t[1] = -1; /* ignore negative guard */;
     t[2] = wlit(P(2));
     t[3] = compile(P(3), depth+1 /* P_USE */);
     return t[0] = P_mktuple(P_VARNAME, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<NAME> =
   case P_NAME:
#ifdef IN_PARSER

  Tag = SubPhraseIdx(Ph, 2)&AST_idx_mask;
  // NO, not yet.  return -1;

#endif
     {                              //\\    <!CONST> «[A-Z][A-Z0-9]*» <DECLARE>;
     t[1] = -1; /* ignore negative guard */;
     t[2] = wlit(P(2));
     t[3] = compile(P(3), depth+1 /* P_DECLARE */);
     return t[0] = P_mktuple(P_NAME, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<BigCharConst> =
   case P_BigCharConst:
#ifdef IN_PARSER

#endif
     {                              //\\    «'([^']|'')*'»;
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_BigCharConst, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<CharConst> =
   case P_CharConst:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    «''''»,
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_CharConst, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    «''»,
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_CharConst, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    «'.'»;
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_CharConst, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<OptExponent> =
   case P_OptExponent:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    '@' <N>,
       t[1] = wlit(P(1) /*, L'@' */);
       t[2] = compile(P(2), depth+1 /* P_N */);
       return t[0] = P_mktuple(P_OptExponent, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_OptExponent, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<OptDecimal> =
   case P_OptDecimal:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    '.' <N>,
       t[1] = wlit(P(1) /*, L'.' */);
       t[2] = compile(P(2), depth+1 /* P_N */);
       return t[0] = P_mktuple(P_OptDecimal, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_OptDecimal, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<LITCONST> =
   case P_LITCONST:
#ifdef IN_PARSER


#endif
     if (alt == 0)               {  //\\    <N> <OptDecimal> <OptExponent>,
       t[1] = compile(P(1), depth+1 /* P_N */);
       t[2] = compile(P(2), depth+1 /* P_OptDecimal */);
       t[3] = compile(P(3), depth+1 /* P_OptExponent */);
       return t[0] = P_mktuple(P_LITCONST, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    <CharConst>,
       t[1] = compile(P(1), depth+1 /* P_CharConst */);
       return t[0] = P_mktuple(P_LITCONST, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 2)        {  //\\    <ALIASTEXT>,
       t[1] = compile(P(1), depth+1 /* P_ALIASTEXT */);
       return t[0] = P_mktuple(P_LITCONST, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 3)        {  //\\    'E' <ALIASTEXT>,
       t[1] = wlit(P(1) /*, L'E' */);
       t[2] = compile(P(2), depth+1 /* P_ALIASTEXT */);
       return t[0] = P_mktuple(P_LITCONST, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    «[MBKXRH]» <BigCharConst>;
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_BigCharConst */);
       return t[0] = P_mktuple(P_LITCONST, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<CONST> =
   case P_CONST:
#ifdef IN_PARSER
  // Pushes an AST_LITERAL:
  // PushConst(compile(P(1),depth+1)); // more complex than that but this will do for basic testing during development.

  // alt=0: symbolic constant
  // alt=1: literal constant
  t[1] = compile(P(1),depth+1);
  PushConst(P_mktuple(AST_RVALUE, 1/*alt no*/, 1/*phrases*/, t));
  
  return -1;

#endif
     {                              //\\    <LITCONST>;
     t[1] = compile(P(1), depth+1 /* P_LITCONST */);
     return t[0] = P_mktuple(P_CONST, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<N> =
   case P_N:
#ifdef IN_PARSER

#endif
     {                              //\\    «[0-9][0-9]*»;
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_N, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<dq> =
   case P_dq:
#ifdef IN_PARSER

#endif
     {                              //\\    '"';
     t[1] = wlit(P(1) /*, L'"' */);
     return t[0] = P_mktuple(P_dq, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<any> =
   case P_any:
#ifdef IN_PARSER

#endif
     {                              //\\    «.»;
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_any, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<stringchars> =
   case P_stringchars:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    <dq> <dq> <stringchars>,
       t[1] = compile(P(1), depth+1 /* P_dq */);
       t[2] = compile(P(2), depth+1 /* P_dq */);
       t[3] = compile(P(3), depth+1 /* P_stringchars */);
       return t[0] = P_mktuple(P_stringchars, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    <!dq> <any> <stringchars>,
       t[1] = -1; /* ignore negative guard */;
       t[2] = compile(P(2), depth+1 /* P_any */);
       t[3] = compile(P(3), depth+1 /* P_stringchars */);
       return t[0] = P_mktuple(P_stringchars, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_stringchars, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<ALIASTEXT> =
   case P_ALIASTEXT:
#ifdef IN_PARSER

#endif
     {                              //\\    <dq> <stringchars> <dq>;
     t[1] = compile(P(1), depth+1 /* P_dq */);
     t[2] = compile(P(2), depth+1 /* P_stringchars */);
     t[3] = compile(P(3), depth+1 /* P_dq */);
     return t[0] = P_mktuple(P_ALIASTEXT, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<semi> =
   case P_semi:
#ifdef IN_PARSER

#endif
     {                              //\\    ';';
     t[1] = wlit(P(1) /*, L';' */);
     return t[0] = P_mktuple(P_semi, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<Comment> =
   case P_Comment:
#ifdef IN_PARSER

  return -1; // suppressing extraneous data during development.  Will want it back later.

#endif
     if (alt == 0)               {  //\\    '!' <TEXT>,
       t[1] = wlit(P(1) /*, L'!' */);
       t[2] = compile(P(2), depth+1 /* P_TEXT */);
       return t[0] = P_mktuple(P_Comment, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    '|' <TEXT>,
       t[1] = wlit(P(1) /*, L'|' */);
       t[2] = compile(P(2), depth+1 /* P_TEXT */);
       return t[0] = P_mktuple(P_Comment, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    "comment" <TEXT>;
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_TEXT */);
       return t[0] = P_mktuple(P_Comment, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<TEXT> =
   case P_TEXT:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    <!S> «.» <TEXT>,
       t[1] = -1; /* ignore negative guard */;
       t[2] = wlit(P(2));
       t[3] = compile(P(3), depth+1 /* P_TEXT */);
       return t[0] = P_mktuple(P_TEXT, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_TEXT, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<VAR> =
   case P_VAR:
#ifdef IN_PARSER

  PushVar(compile(P(1),depth+1)); // more complex than that but this will do for basic testing during development.
  return -1;

#endif
     {                              //\\    <VARNAME> <APP> <Opt_Record_Field>;
     t[1] = compile(P(1), depth+1 /* P_VARNAME */);
     t[2] = compile(P(2), depth+1 /* P_APP */);
     t[3] = compile(P(3), depth+1 /* P_Opt_Record_Field */);
     return t[0] = P_mktuple(P_VAR, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<OPERAND> =
   case P_OPERAND:
#ifdef IN_PARSER


  // shunting yard algorithm.  Note need to distinguish between the use of
  // VAR and CONST in expressions (which are getting the shunting yard treatment)
  // and many other places in the grammar, where they are not.

  // NOTE: parentheses in Imp serve two purposes: 1) overriding the precedence of
  // operators, and 2) forcing the order of evaluation specifically to avoid
  // overflows in intermediate results.  So although we normally output expressions
  // using minimal brackets and only insert them when needed due to differences
  // between Imp and C precedences, we will leave user-supplied parentheses in place
  // when outputting the C version of an expression to explicitly preserve option (2).

  if (alt == 2) {
    // compile the expr and reduce it to a single irreducible object so it is treated
    // like a variable or a constant and its subexpressions are not examined when
    // handling C's operator precedence.

    // Compiling <EXPR> should return an AST_EXPRESSION

    // a + (b + c) is coming out as (a + b + c) - it looks like the TORP
    // is picking up the "a +" that is already on the stack and adding it to
    // the Expr.  I suspect what is needed is to seal a false bottom on the
    // stack so that Expr is constructed independent of anything preceding it.
    // *OR* maybe all the problem is that at this point, the operator is on the
    // operator stack and not the output stack.  Actually that suggests that we
    // need false bottoms on *both* stacks.  Or maybe just to stop evaluating
    // when we get to a "(" on the stack.

    int SaveOperBottom = OperStack_bottom; OperStack_bottom = OperStack_nextfree;
    int SaveDataBottom = DataStack_bottom; DataStack_bottom = DataStack_nextfree;
    int Expr = compile(P(2),depth+1);
    t[1] = Expr;
    DataStack_bottom = SaveDataBottom;
    OperStack_bottom = SaveOperBottom;
    
    int AstTuple = P_mktuple(AST_USER_PARENS, 0, 1, t);
               
    PushParen(L"("); PushExpr(AstTuple); PushParen(L")"); // AstTuple is opaque to the RP code.  It treats it like any atom.
    return -1;
  }
  // otherwise, compile <VAR> or <CONST>, which will push them on the TORP stack

#endif
     if (alt == 0)               {  //\\    <VAR>,
       t[1] = compile(P(1), depth+1 /* P_VAR */);
       return t[0] = P_mktuple(P_OPERAND, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    <CONST>,
       t[1] = compile(P(1), depth+1 /* P_CONST */);
       return t[0] = P_mktuple(P_OPERAND, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    '(' <EXPR> ')';
       t[1] = wlit(P(1) /*, L'(' */);
       t[2] = compile(P(2), depth+1 /* P_EXPR */);
       t[3] = wlit(P(3) /*, L')' */);
       return t[0] = P_mktuple(P_OPERAND, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<CONSTVAR> =
   case P_CONSTVAR:
#ifdef IN_PARSER


  // alt=0: symbolic constant
  // alt=1: literal constant
//  t[1] = compile(P(1),depth+1);
//  PushConst(P_mktuple(AST_RVALUE, 0/*alt no*/, 1/*phrases*/, t));


  PushConst(compile(P(1),depth+1));
  return -1;

#endif
     {                              //\\    <VARNAME>;
     t[1] = compile(P(1), depth+1 /* P_VARNAME */);
     return t[0] = P_mktuple(P_CONSTVAR, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<COPERAND> =
   case P_COPERAND:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    <CONSTVAR>,
       t[1] = compile(P(1), depth+1 /* P_CONSTVAR */);
       return t[0] = P_mktuple(P_COPERAND, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    <CONST>,
       t[1] = compile(P(1), depth+1 /* P_CONST */);
       return t[0] = P_mktuple(P_COPERAND, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    '(' <CEXPR> ')';
       t[1] = wlit(P(1) /*, L'(' */);
       t[2] = compile(P(2), depth+1 /* P_CEXPR */);
       t[3] = wlit(P(3) /*, L')' */);
       return t[0] = P_mktuple(P_COPERAND, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<CEXPR> =
   case P_CEXPR:
#ifdef IN_PARSER

  t[1] = ExPop();
  t[2] = P(1);
  return P_mktuple(AST_EXPRESSION, 0, 2, t);

#endif
     {                              //\\    <CTORP>;
     t[1] = compile(P(1), depth+1 /* P_CTORP */);
     return t[0] = P_mktuple(P_CEXPR, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<CTORP> =
   case P_CTORP:
#ifdef IN_PARSER

#endif
     {                              //\\    <UOP> <COPERAND> <RESTOFCEXPR>;
     t[1] = compile(P(1), depth+1 /* P_UOP */);
     t[2] = compile(P(2), depth+1 /* P_COPERAND */);
     t[3] = compile(P(3), depth+1 /* P_RESTOFCEXPR */);
     return t[0] = P_mktuple(P_CTORP, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<STAROREXPR> =
   case P_STAROREXPR:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    <UOP> <COPERAND> <RESTOFCEXPR>,
       t[1] = compile(P(1), depth+1 /* P_UOP */);
       t[2] = compile(P(2), depth+1 /* P_COPERAND */);
       t[3] = compile(P(3), depth+1 /* P_RESTOFCEXPR */);
       return t[0] = P_mktuple(P_STAROREXPR, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    '*';
       t[1] = wlit(P(1) /*, L'*' */);
       return t[0] = P_mktuple(P_STAROREXPR, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<TORP> =
   case P_TORP:
#ifdef IN_PARSER

#endif
     {                              //\\    <UOP> <OPERAND> <RESTOFEXPR>;
     t[1] = compile(P(1), depth+1 /* P_UOP */);
     t[2] = compile(P(2), depth+1 /* P_OPERAND */);
     t[3] = compile(P(3), depth+1 /* P_RESTOFEXPR */);
     return t[0] = P_mktuple(P_TORP, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<EXPR> =
   case P_EXPR:
#ifdef IN_PARSER

  {
    int Expr;
    t[2] = compile(P(1),depth+1); // walk the CST expression tree to process each atom sequentially left to right, as input to the shunting yard algorithm
    t[1] = ExPop();               // now convert the reverse-polish stack back into an AST tree, with precedence now magically applied.
    Expr = P_mktuple(AST_EXPRESSION, 0, 2, t);

    // We do not print <EXPR>s immediately because a bracketed (<EXPR>) which is a subexpression of a larger <EXPR> has to be reprocessed
    // in order to apply operator precedence.  A consequence of this is that <EXPR>s in other contexts will have to be output via generate_c()
    // at the point of call.
    
    return Expr;
  }

#endif
     {                              //\\    <TORP>;
     t[1] = compile(P(1), depth+1 /* P_TORP */);
     return t[0] = P_mktuple(P_EXPR, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RESTOFEXPR> =
   case P_RESTOFEXPR:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    <OP> <OPERAND> <RESTOFEXPR>,
       t[1] = compile(P(1), depth+1 /* P_OP */);
       t[2] = compile(P(2), depth+1 /* P_OPERAND */);
       t[3] = compile(P(3), depth+1 /* P_RESTOFEXPR */);
       return t[0] = P_mktuple(P_RESTOFEXPR, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_RESTOFEXPR, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RESTOFCEXPR> =
   case P_RESTOFCEXPR:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    <OP> <COPERAND> <RESTOFCEXPR>,
       t[1] = compile(P(1), depth+1 /* P_OP */);
       t[2] = compile(P(2), depth+1 /* P_COPERAND */);
       t[3] = compile(P(3), depth+1 /* P_RESTOFCEXPR */);
       return t[0] = P_mktuple(P_RESTOFCEXPR, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_RESTOFCEXPR, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<APP> =
   case P_APP:
#ifdef IN_PARSER

  if (alt == 0) {
    // drop the '()' which is put back in by AST_PROC_CALL
    generate_c(compile(P(2), depth+1), depth+1);
    compile(P(3), depth+1);
  }
  return -1;

#endif
     if (alt == 0)               {  //\\    '(' <EXPR> <RESTOFAPP> ')',
       t[1] = wlit(P(1) /*, L'(' */);
       t[2] = compile(P(2), depth+1 /* P_EXPR */);
       t[3] = compile(P(3), depth+1 /* P_RESTOFAPP */);
       t[4] = wlit(P(4) /*, L')' */);
       return t[0] = P_mktuple(P_APP, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_APP, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RESTOFAPP> =
   case P_RESTOFAPP:
#ifdef IN_PARSER

  if (alt == 0) {
    fprintf(stdout, ", ");
    generate_c(compile(P(3),depth+1), depth+1);
    compile(P(4), depth+1);
  }
  return -1;

#endif
     if (alt == 0)               {  //\\    ',' <READLINEP> <EXPR> <RESTOFAPP>,
       t[1] = wlit(P(1) /*, L',' */);
       t[2] = compile(P(2), depth+1 /* P_READLINEP */);
       t[3] = compile(P(3), depth+1 /* P_EXPR */);
       t[4] = compile(P(4), depth+1 /* P_RESTOFAPP */);
       return t[0] = P_mktuple(P_RESTOFAPP, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_RESTOFAPP, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<PC_IU> =
   case P_PC_IU:
#ifdef IN_PARSER

  if (alt == 0) {
    fprintf(stdout, "if ");
  } else {
    fprintf(stdout, "unless ");
  }

#endif
     if (alt == 0)               {  //\\    "if",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_PC_IU, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    "unless";
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_PC_IU, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<TOP_LEVEL_CONDITION> =
   case P_TOP_LEVEL_CONDITION:
#ifdef IN_PARSER

  fprintf(stdout, " (");
  compile(P(1), depth+1); compile(P(2), depth+1);
  fprintf(stdout, ") ");
  return -1;

#endif
     {                              //\\    <SC> <RESTOFCOND>;
     t[1] = compile(P(1), depth+1 /* P_SC */);
     t[2] = compile(P(2), depth+1 /* P_RESTOFCOND */);
     return t[0] = P_mktuple(P_TOP_LEVEL_CONDITION, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<CYCPARM> =
   case P_CYCPARM:
#ifdef IN_PARSER

  // %for J = I, -1, 1
  // for (J = I; J < 1; J += -1)
  // if the step is positive use '<', if negative use '>', if unknown use '!='...
  
  fprintf(stdout, "for (");
  generate_c(compile(P(1), depth+1), depth+1);
  fprintf(stdout, " = ");
  generate_c(compile(P(3), depth+1), depth+1); // Actually I'm not sure why <EXPR> just works here. I thought I needded to do the false bottom thing? (TO DO)
  fprintf(stdout, "; ");
  generate_c(compile(P(1), depth+1), depth+1);
  fprintf(stdout, " < ");
  generate_c(compile(P(7), depth+1), depth+1);
  fprintf(stdout, "; ");
  generate_c(compile(P(1), depth+1), depth+1);
  fprintf(stdout, " += ");
  generate_c(compile(P(5), depth+1), depth+1);
  fprintf(stdout, ") ");
  return -1;

#endif
     {                              //\\    <VARNAME> '=' <EXPR> ',' <EXPR> ',' <EXPR>;
     t[1] = compile(P(1), depth+1 /* P_VARNAME */);
     t[2] = wlit(P(2) /*, L'=' */);
     t[3] = compile(P(3), depth+1 /* P_EXPR */);
     t[4] = wlit(P(4) /*, L',' */);
     t[5] = compile(P(5), depth+1 /* P_EXPR */);
     t[6] = wlit(P(6) /*, L',' */);
     t[7] = compile(P(7), depth+1 /* P_EXPR */);
     return t[0] = P_mktuple(P_CYCPARM, alt, 7/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<PC_WUF> =
   case P_PC_WUF:
#ifdef IN_PARSER

  if (alt == 0) {
    fprintf(stdout, "while "); compile(P(2), depth+1);
  } else if (alt == 1) {
    fprintf(stdout, "/*TO DO*/until "); compile(P(2), depth+1);
  } else if (alt == 2) {
    compile(P(2), depth+1);
  }
  return -1;

#endif
     if (alt == 0)               {  //\\    "while" <TOP_LEVEL_CONDITION>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_TOP_LEVEL_CONDITION */);
       return t[0] = P_mktuple(P_PC_WUF, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    "until" <TOP_LEVEL_CONDITION>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_TOP_LEVEL_CONDITION */);
       return t[0] = P_mktuple(P_PC_WUF, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    "for" <CYCPARM>;
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_CYCPARM */);
       return t[0] = P_mktuple(P_PC_WUF, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<ALIAS> =
   case P_ALIAS:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    "alias" <ALIASTEXT>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_ALIASTEXT */);
       return t[0] = P_mktuple(P_ALIAS, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_ALIAS, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<NAMES> =
   case P_NAMES:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    ',' <READLINEP> <NAME> <NAMES> <INITDECS>,
       t[1] = wlit(P(1) /*, L',' */);
       t[2] = compile(P(2), depth+1 /* P_READLINEP */);
       t[3] = compile(P(3), depth+1 /* P_NAME */);
       t[4] = compile(P(4), depth+1 /* P_NAMES */);
       t[5] = compile(P(5), depth+1 /* P_INITDECS */);
       return t[0] = P_mktuple(P_NAMES, alt, 5/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_NAMES, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<FULLTYPE> =
   case P_FULLTYPE:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    "integer",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_FULLTYPE, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_FULLTYPE, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<BTYPE> =
   case P_BTYPE:
#ifdef IN_PARSER

  Basetype = (alt == 0 ? FLOAT : INTEGER);

#endif
     if (alt == 0)               {  //\\    "real",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_BTYPE, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    "integer";
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_BTYPE, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<XTYPE> =
   case P_XTYPE:
#ifdef IN_PARSER

  switch (alt) {
  case 0: Signedness = SIGNED;   Precision = WORD;     Basetype = INTEGER;     break; // integer
  case 1: Signedness = SIGNED;   Precision = WORD;     Basetype = FLOAT;       break; // real
  case 2: Signedness = SIGNED;   Precision = QUADWORD;                         break; // long long (integer | real)
  case 3: Signedness = SIGNED;   Precision = LONGWORD;                         break; // long (integer | real)
  case 4: Signedness = SIGNED;   Precision = BYTE;     Basetype = INTEGER;     break; // byte (integer)?   (no %mite in this variant of Imp)
  case 5: Signedness = SIGNED;   Precision = COMPOUND; Basetype = STRINGTYPE;  break; // string
  case 6: Signedness = UNSIGNED; Precision = SHORT;    Basetype = INTEGER;     break; // half (integer)?
  case 7: Signedness = SIGNED;   Precision = SHORT;    Basetype = INTEGER;     break; // short (integer)?
  case 8: Signedness = SIGNED;   Precision = COMPOUND; Basetype = RECORD;      break; // record
  }
  if (debug_declarations > 1) fprintf(stderr, "[ Sign=%d Prec=%d Type=%d ]", Signedness, Precision, Basetype); 

#endif
     if (alt == 0)               {  //\\    "integer",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_XTYPE, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    "real",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_XTYPE, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 2)        {  //\\    "long" "long" <BTYPE>,
       t[1] = wlit(P(1));
       t[2] = wlit(P(2));
       t[3] = compile(P(3), depth+1 /* P_BTYPE */);
       return t[0] = P_mktuple(P_XTYPE, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 3)        {  //\\    "long" <BTYPE>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_BTYPE */);
       return t[0] = P_mktuple(P_XTYPE, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 4)        {  //\\    "byte" <FULLTYPE>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_FULLTYPE */);
       return t[0] = P_mktuple(P_XTYPE, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 5)        {  //\\    "string" <REPFACT>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_REPFACT */);
       return t[0] = P_mktuple(P_XTYPE, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 6)        {  //\\    "half" <FULLTYPE>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_FULLTYPE */);
       return t[0] = P_mktuple(P_XTYPE, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 7)        {  //\\    "short" <FULLTYPE>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_FULLTYPE */);
       return t[0] = P_mktuple(P_XTYPE, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    "record" '(' <RFREF> ')';
       t[1] = wlit(P(1));
       t[2] = wlit(P(2) /*, L'(' */);
       t[3] = compile(P(3), depth+1 /* P_RFREF */);
       t[4] = wlit(P(4) /*, L')' */);
       return t[0] = P_mktuple(P_XTYPE, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RT> =
   case P_RT:
#ifdef IN_PARSER

  if (alt == 0) {
    Proc = ROUTINE;
    if (debug_declarations > 1) fprintf(stderr, "[Proc=%d]", Proc);
  }

#endif
     if (alt == 0)               {  //\\    "routine",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_RT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    <XTYPE> <FM>;
       t[1] = compile(P(1), depth+1 /* P_XTYPE */);
       t[2] = compile(P(2), depth+1 /* P_FM */);
       return t[0] = P_mktuple(P_RT, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<FM> =
   case P_FM:
#ifdef IN_PARSER

  if (alt == 1) Proc = MAP; else Proc = FN;
  if (debug_declarations > 1) fprintf(stderr, "[Proc=%d]", Proc);

#endif
     if (alt == 0)               {  //\\    "fn",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_FM, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    "map",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_FM, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    "function";
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_FM, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<FPDEL> =
   case P_FPDEL:
#ifdef IN_PARSER


#endif
     if (alt == 0)               {  //\\    <XTYPE> <Opt_AN_N_type> <NAME> <NAMES> <INITDECS>,
       t[1] = compile(P(1), depth+1 /* P_XTYPE */);
       t[2] = compile(P(2), depth+1 /* P_Opt_AN_N_type */);
       t[3] = compile(P(3), depth+1 /* P_NAME */);
       t[4] = compile(P(4), depth+1 /* P_NAMES */);
       t[5] = compile(P(5), depth+1 /* P_INITDECS */);
       return t[0] = P_mktuple(P_FPDEL, alt, 5/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    <RT> <Opt_N_type> <NAME> <NAMES> <INITDECS> <FPP>,
       t[1] = compile(P(1), depth+1 /* P_RT */);
       t[2] = compile(P(2), depth+1 /* P_Opt_N_type */);
       t[3] = compile(P(3), depth+1 /* P_NAME */);
       t[4] = compile(P(4), depth+1 /* P_NAMES */);
       t[5] = compile(P(5), depth+1 /* P_INITDECS */);
       t[6] = compile(P(6), depth+1 /* P_FPP */);
       return t[0] = P_mktuple(P_FPDEL, alt, 6/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    "name" <NAME> <NAMES> <INITDECS>;
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_NAME */);
       t[3] = compile(P(3), depth+1 /* P_NAMES */);
       t[4] = compile(P(4), depth+1 /* P_INITDECS */);
       return t[0] = P_mktuple(P_FPDEL, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<Opt_N_type> =
   case P_Opt_N_type:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    "name",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_Opt_N_type, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_Opt_N_type, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<Opt_AN_N_type> =
   case P_Opt_AN_N_type:
#ifdef IN_PARSER

  switch (alt) {
  case 0: NameInfo = ARRAYNAME;  break;
  case 1: NameInfo = OBJECTNAME; break;
  case 2: NameInfo = NO_NAME;     break;
  }
  if (debug_declarations > 1) fprintf(stderr, "[NameInfo=%d]", NameInfo);

#endif
     if (alt == 0)               {  //\\    "array" "name",
       t[1] = wlit(P(1));
       t[2] = wlit(P(2));
       return t[0] = P_mktuple(P_Opt_AN_N_type, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    "name",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_Opt_AN_N_type, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_Opt_AN_N_type, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<FPP> =
   case P_FPP:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    '(' <FPDEL> <RESTOFFPLIST> ')',
       t[1] = wlit(P(1) /*, L'(' */);
       t[2] = compile(P(2), depth+1 /* P_FPDEL */);
       t[3] = compile(P(3), depth+1 /* P_RESTOFFPLIST */);
       t[4] = wlit(P(4) /*, L')' */);
       return t[0] = P_mktuple(P_FPP, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_FPP, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<Opt_comma> =
   case P_Opt_comma:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    ',',
       t[1] = wlit(P(1) /*, L',' */);
       return t[0] = P_mktuple(P_Opt_comma, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_Opt_comma, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RESTOFFPLIST> =
   case P_RESTOFFPLIST:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    <Opt_comma> <READLINEP> <FPDEL> <RESTOFFPLIST>,
       t[1] = compile(P(1), depth+1 /* P_Opt_comma */);
       t[2] = compile(P(2), depth+1 /* P_READLINEP */);
       t[3] = compile(P(3), depth+1 /* P_FPDEL */);
       t[4] = compile(P(4), depth+1 /* P_RESTOFFPLIST */);
       return t[0] = P_mktuple(P_RESTOFFPLIST, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_RESTOFFPLIST, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<ENDLIST> =
   case P_ENDLIST:
#ifdef IN_PARSER

                      
  // Need a routine to unwind the control stack and show what was expected.
  
  if (alt == 0) {
    // end of program
    if (ctrl_depth() != 1) {
      fprintf(stderr, "\n* Spurious %%ENDOFPROGRAM\n"); exit(1);
    }
    int EXPECTED = pop_ctrl();
    if (EXPECTED != ENDOFPROGRAM) {
      fprintf(stderr, "\n* %%ENDOFPROGRAM not expected here (expecting %s)\n",
             ctrl_debug[EXPECTED]); exit(1);
    }
    if (debug_compiler) fprintf(stderr, "[end of program]");
    fprintf(stdout, "\n  exit(0);\n} /* End of program */\n");
  } else if (alt == 1) {
    // end of perm
    if (debug_compiler) fprintf(stderr, "[end of perm]");
  } else if (alt == 2) {
    // end of file
    if (ctrl_depth() != 0) { // might not be the case for an unbalanced %include file...
      fprintf(stderr, "\n* Spurious %%ENDOFFILE\n"); exit(1);
    }
    if (debug_compiler) fprintf(stderr, "[end of file]");
  } else if (alt == 3) {
    // end of list
    if (debug_compiler) fprintf(stderr, "[end of list]");
  } else if (alt == 4) {
    // %end (begin or Rt/Fn/Map)
    if (ctrl_depth() == 0) {
      fprintf(stderr, "\n* Spurious %%END\n"); exit(1);
    }
    int EXPECTED = pop_ctrl();
    if (EXPECTED != END) {
      fprintf(stderr, "\n* %%END not expected here (expecting %s)\n",
              ctrl_debug[EXPECTED]); exit(1);
    }
    if (debug_compiler) fprintf(stderr, "[end of 'begin' block]");
    fprintf(stdout, "\n} /* End of Rt/Fn/Map */\n");
  }

#endif
     if (alt == 0)               {  //\\    "ofprogram" <UP>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_UP */);
       return t[0] = P_mktuple(P_ENDLIST, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    "ofperm",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_ENDLIST, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 2)        {  //\\    "offile",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_ENDLIST, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 3)        {  //\\    "oflist" <LISTOFF>,
       t[1] = wlit(P(1));
       t[2] = -1; /* semantic procedure LISTOFF */;
       return t[0] = P_mktuple(P_ENDLIST, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    <UP>;
       t[1] = compile(P(1), depth+1 /* P_UP */);
       return t[0] = P_mktuple(P_ENDLIST, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<ARRAYFORMAT> =
   case P_ARRAYFORMAT:
#ifdef IN_PARSER

  if (alt == 0) Object = ARRAYFORMAT;
  //IsFormat = (alt == 0 ? IS_FORMAT : NO_FORMAT );
  //if (debug_declarations > 1) fprintf(stderr, "[format=%d]", IsFormat);

#endif
     if (alt == 0)               {  //\\    "format",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_ARRAYFORMAT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_ARRAYFORMAT, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RESTOFSC> =
   case P_RESTOFSC:
#ifdef IN_PARSER

  return -1; // lt the parent level handle it.

#endif
     if (alt == 0)               {  //\\    <COMP2> <EXPR>,
       t[1] = compile(P(1), depth+1 /* P_COMP2 */);
       t[2] = compile(P(2), depth+1 /* P_EXPR */);
       return t[0] = P_mktuple(P_RESTOFSC, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_RESTOFSC, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<SC> =
   case P_SC:
#ifdef IN_PARSER
 // %not is '!' in C
  if (alt == 0) {
    generate_c(compile(P(1), depth+1), depth+1);          // TO DO: <EXPR>s need false bottom!
    compile(P(2), depth+1);
    generate_c(compile(P(3), depth+1), depth+1);
    int RestofSC = P(4);
    if (P_alt(RestofSC) == 0) {
      int Comp2 = P_P(RestofSC, 1);
      int Expr3 = P_P(RestofSC, 2);
      fprintf(stdout, " && ");
      generate_c(compile(P(3), depth+1), depth+1);
      compile(Comp2, depth+1);
      generate_c(compile(Expr3,depth+1), depth+1);
    }
    compile(P(4), depth+1);
  } else if (alt == 1) {
    compile(P(2), depth+1);
    compile(P(3), depth+1);
  } else {
    fprintf(stdout, "!");  // not sure about priorities for booleans
    fprintf(stdout, "(");
    compile(P(2), depth+1);
    fprintf(stdout, ")");
  }
  return -1;

#endif
     if (alt == 0)               {  //\\    <EXPR> <COMP1> <EXPR> <RESTOFSC>,
       t[1] = compile(P(1), depth+1 /* P_EXPR */);
       t[2] = compile(P(2), depth+1 /* P_COMP1 */);
       t[3] = compile(P(3), depth+1 /* P_EXPR */);
       t[4] = compile(P(4), depth+1 /* P_RESTOFSC */);
       return t[0] = P_mktuple(P_SC, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    '(' <SC> <RESTOFCOND> ')',
       t[1] = wlit(P(1) /*, L'(' */);
       t[2] = compile(P(2), depth+1 /* P_SC */);
       t[3] = compile(P(3), depth+1 /* P_RESTOFCOND */);
       t[4] = wlit(P(4) /*, L')' */);
       return t[0] = P_mktuple(P_SC, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    "not" <SC>;
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_SC */);
       return t[0] = P_mktuple(P_SC, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RESTOFCOND> =
   case P_RESTOFCOND:
#ifdef IN_PARSER

  // TO DO: Only one of them needs to have () added around the other, because the
  //        operator precedences of && and || in C are not equal. (&& is higher than || so we need () around "and" SC's in a RESTOFORC.)
  if (alt == 0) {
    fprintf(stdout, " && ");
    compile(P(2),depth+1);
  } else if (alt == 1) {
    fprintf(stdout, " || ");
    compile(P(2),depth+1);
  }
  return -1;

#endif
     if (alt == 0)               {  //\\    "and" <SC> <RESTOFANDC>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_SC */);
       t[3] = compile(P(3), depth+1 /* P_RESTOFANDC */);
       return t[0] = P_mktuple(P_RESTOFCOND, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    "or" <SC> <RESTOFORC>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_SC */);
       t[3] = compile(P(3), depth+1 /* P_RESTOFORC */);
       return t[0] = P_mktuple(P_RESTOFCOND, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_RESTOFCOND, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RESTOFANDC> =
   case P_RESTOFANDC:
#ifdef IN_PARSER

  if (alt == 0) {
    fprintf(stdout, " && ");
    compile(P(2),depth+1);
    compile(P(3),depth+1);
  }
  return -1;

#endif
     if (alt == 0)               {  //\\    "and" <SC> <RESTOFANDC>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_SC */);
       t[3] = compile(P(3), depth+1 /* P_RESTOFANDC */);
       return t[0] = P_mktuple(P_RESTOFANDC, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_RESTOFANDC, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RESTOFORC> =
   case P_RESTOFORC:
#ifdef IN_PARSER

  if (alt == 0) {
    fprintf(stdout, " || ");
    compile(P(2),depth+1);     // NEED () AROUND THE <SC> IF IT CONTAINS AN "&&"
    compile(P(3),depth+1);
  }
  return -1;

#endif
     if (alt == 0)               {  //\\    "or" <SC> <RESTOFORC>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_SC */);
       t[3] = compile(P(3), depth+1 /* P_RESTOFORC */);
       return t[0] = P_mktuple(P_RESTOFORC, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_RESTOFORC, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<Optional_Assignment> =
   case P_Optional_Assignment:
#ifdef IN_PARSER

  if (debug_compiler) fprintf(stderr, (alt == 1 ? "[procedure call]" : "[assignment]"));

#endif
     if (alt == 0)               {  //\\    <ASSOP> <EXPR>,
       t[1] = compile(P(1), depth+1 /* P_ASSOP */);
       t[2] = compile(P(2), depth+1 /* P_EXPR */);
       return t[0] = P_mktuple(P_Optional_Assignment, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_Optional_Assignment, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<Opt_RtFnMapSpec> =
   case P_Opt_RtFnMapSpec:
#ifdef IN_PARSER

  if (alt == 1) {
    // Procedures of all kinds require a %end
    push_ctrl(END); // we will probably later distinguish between END and PROCEND etc.
    // Spec = NO_SPEC;
  } else Spec = SPEC;
  if (debug_declarations > 1) fprintf(stderr, "[Spec=%d]", Spec);

#endif
     if (alt == 0)               {  //\\    "spec",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_Opt_RtFnMapSpec, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    <SET_DOWN_FLAG>;
       t[1] = compile(P(1), depth+1 /* P_SET_DOWN_FLAG */);
       return t[0] = P_mktuple(P_Opt_RtFnMapSpec, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<VSPECQ> =
   case P_VSPECQ:
#ifdef IN_PARSER

  if (alt == 0) Spec = SPEC;
  if (debug_declarations > 1) fprintf(stderr, "[Spec=%d]", Spec);

#endif
     if (alt == 0)               {  //\\    "spec",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_VSPECQ, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_VSPECQ, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RESTOFBPLIST> =
   case P_RESTOFBPLIST:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    ',' <EXPR> ':' <EXPR> <RESTOFBPLIST>,
       t[1] = wlit(P(1) /*, L',' */);
       t[2] = compile(P(2), depth+1 /* P_EXPR */);
       t[3] = wlit(P(3) /*, L':' */);
       t[4] = compile(P(4), depth+1 /* P_EXPR */);
       t[5] = compile(P(5), depth+1 /* P_RESTOFBPLIST */);
       return t[0] = P_mktuple(P_RESTOFBPLIST, alt, 5/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_RESTOFBPLIST, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<DECLN> =
   case P_DECLN:
#ifdef IN_PARSER

  if (alt == 1) IsArray = ARRAY;

#endif
     if (alt == 0)               {  //\\    <Opt_AN_N_type> <NAME> <NAMES> <INITDECS>,
       t[1] = compile(P(1), depth+1 /* P_Opt_AN_N_type */);
       t[2] = compile(P(2), depth+1 /* P_NAME */);
       t[3] = compile(P(3), depth+1 /* P_NAMES */);
       t[4] = compile(P(4), depth+1 /* P_INITDECS */);
       return t[0] = P_mktuple(P_DECLN, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    "array" <ARRAYFORMAT> <ADECLN>;
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_ARRAYFORMAT */);
       t[3] = compile(P(3), depth+1 /* P_ADECLN */);
       return t[0] = P_mktuple(P_DECLN, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<BPAIR> =
   case P_BPAIR:
#ifdef IN_PARSER

  // TO DO: list of upper/lower bounds

#endif
     {                              //\\    '(' <EXPR> ':' <EXPR> <RESTOFBPLIST> ')';
     t[1] = wlit(P(1) /*, L'(' */);
     t[2] = compile(P(2), depth+1 /* P_EXPR */);
     t[3] = wlit(P(3) /*, L':' */);
     t[4] = compile(P(4), depth+1 /* P_EXPR */);
     t[5] = compile(P(5), depth+1 /* P_RESTOFBPLIST */);
     t[6] = wlit(P(6) /*, L')' */);
     return t[0] = P_mktuple(P_BPAIR, alt, 6/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RESTOFARLIST> =
   case P_RESTOFARLIST:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    ',' <ADECLN>,
       t[1] = wlit(P(1) /*, L',' */);
       t[2] = compile(P(2), depth+1 /* P_ADECLN */);
       return t[0] = P_mktuple(P_RESTOFARLIST, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_RESTOFARLIST, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<ADECLN> =
   case P_ADECLN:
#ifdef IN_PARSER

#endif
     {                              //\\    <NAME> <NAMES> <BPAIR> <RESTOFARLIST>;
     t[1] = compile(P(1), depth+1 /* P_NAME */);
     t[2] = compile(P(2), depth+1 /* P_NAMES */);
     t[3] = compile(P(3), depth+1 /* P_BPAIR */);
     t[4] = compile(P(4), depth+1 /* P_RESTOFARLIST */);
     return t[0] = P_mktuple(P_ADECLN, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<OWNDEC> =
   case P_OWNDEC:
#ifdef IN_PARSER

  if (alt == 1) IsArray = ARRAY; // Must be set to SCALAR somewhere for default.
  if (debug_declarations > 1) fprintf(stderr, "[IsArray=%d]", IsArray);

#endif
     if (alt == 0)               {  //\\    <Opt_AN_N_type> <VSPECQ> <NAME> <ALIAS> <Opt_Const_Init> <RESTOFOWNDEC>,
       t[1] = compile(P(1), depth+1 /* P_Opt_AN_N_type */);
       t[2] = compile(P(2), depth+1 /* P_VSPECQ */);
       t[3] = compile(P(3), depth+1 /* P_NAME */);
       t[4] = compile(P(4), depth+1 /* P_ALIAS */);
       t[5] = compile(P(5), depth+1 /* P_Opt_Const_Init */);
       t[6] = compile(P(6), depth+1 /* P_RESTOFOWNDEC */);
       return t[0] = P_mktuple(P_OWNDEC, alt, 6/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    "array" <ARRAYFORMAT> <NAME> <ALIAS> <BPAIR> <CONSTLIST>;
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_ARRAYFORMAT */);
       t[3] = compile(P(3), depth+1 /* P_NAME */);
       t[4] = compile(P(4), depth+1 /* P_ALIAS */);
       t[5] = compile(P(5), depth+1 /* P_BPAIR */);
       t[6] = compile(P(6), depth+1 /* P_CONSTLIST */);
       return t[0] = P_mktuple(P_OWNDEC, alt, 6/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RESTOFOWNDEC> =
   case P_RESTOFOWNDEC:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    ',' <READLINEP> <NAME> <ALIAS> <Opt_Const_Init> <RESTOFOWNDEC>,
       t[1] = wlit(P(1) /*, L',' */);
       t[2] = compile(P(2), depth+1 /* P_READLINEP */);
       t[3] = compile(P(3), depth+1 /* P_NAME */);
       t[4] = compile(P(4), depth+1 /* P_ALIAS */);
       t[5] = compile(P(5), depth+1 /* P_Opt_Const_Init */);
       t[6] = compile(P(6), depth+1 /* P_RESTOFOWNDEC */);
       return t[0] = P_mktuple(P_RESTOFOWNDEC, alt, 6/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_RESTOFOWNDEC, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<XOWN> =
   case P_XOWN:
#ifdef IN_PARSER

  switch (alt) {
  case 0: Area = OWN;                    break;
  case 1: Area = EXTDATA;                break;
  case 2: Area = EXTDATA;  Spec = SPEC;  break;
  case 3: Area = CONSTANT;               break;
  case 4: Area = CONSTANT;               break;
  }
  if (debug_declarations > 1) fprintf(stderr, "[Area=%d]", Area );

#endif
     if (alt == 0)               {  //\\    "own",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_XOWN, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    "external",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_XOWN, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 2)        {  //\\    "extrinsic",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_XOWN, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 3)        {  //\\    "constant",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_XOWN, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    "const";
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_XOWN, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<CONSTLIST> =
   case P_CONSTLIST:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    '=' <READLINEP> <UOP> <COPERAND> <RESTOFCEXPR> <REPFACT> <ROCL>,
       t[1] = wlit(P(1) /*, L'=' */);
       t[2] = compile(P(2), depth+1 /* P_READLINEP */);
       t[3] = compile(P(3), depth+1 /* P_UOP */);
       t[4] = compile(P(4), depth+1 /* P_COPERAND */);
       t[5] = compile(P(5), depth+1 /* P_RESTOFCEXPR */);
       t[6] = compile(P(6), depth+1 /* P_REPFACT */);
       t[7] = compile(P(7), depth+1 /* P_ROCL */);
       return t[0] = P_mktuple(P_CONSTLIST, alt, 7/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_CONSTLIST, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<ExPop> =
   case P_ExPop:
#ifdef IN_PARSER

  (void)ExPop(); // quick hack because <EXPR> code was generating a *huge* stack, with each initialised array element being on the stack :-/

#endif
     {                              //\\    ;

     return t[0] = P_mktuple(P_ExPop, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<ROCL> =
   case P_ROCL:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    ',' <ExPop> <READLINEP> <UOP> <COPERAND> <RESTOFCEXPR> <REPFACT> <ROCL>,
       t[1] = wlit(P(1) /*, L',' */);
       t[2] = compile(P(2), depth+1 /* P_ExPop */);
       t[3] = compile(P(3), depth+1 /* P_READLINEP */);
       t[4] = compile(P(4), depth+1 /* P_UOP */);
       t[5] = compile(P(5), depth+1 /* P_COPERAND */);
       t[6] = compile(P(6), depth+1 /* P_RESTOFCEXPR */);
       t[7] = compile(P(7), depth+1 /* P_REPFACT */);
       t[8] = compile(P(8), depth+1 /* P_ROCL */);
       return t[0] = P_mktuple(P_ROCL, alt, 8/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_ROCL, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<REPFACT> =
   case P_REPFACT:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    '(' <STAROREXPR> ')',
       t[1] = wlit(P(1) /*, L'(' */);
       t[2] = compile(P(2), depth+1 /* P_STAROREXPR */);
       t[3] = wlit(P(3) /*, L')' */);
       return t[0] = P_mktuple(P_REPFACT, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_REPFACT, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RESTOFNLIST> =
   case P_RESTOFNLIST:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    ',' <CEXPR> <RESTOFNLIST>,
       t[1] = wlit(P(1) /*, L',' */);
       t[2] = compile(P(2), depth+1 /* P_CEXPR */);
       t[3] = compile(P(3), depth+1 /* P_RESTOFNLIST */);
       return t[0] = P_mktuple(P_RESTOFNLIST, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_RESTOFNLIST, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<PC_EVENTQ> =
   case P_PC_EVENTQ:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    "event",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_PC_EVENTQ, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_PC_EVENTQ, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<Opt_EXPR> =
   case P_Opt_EXPR:
#ifdef IN_PARSER

  if (alt == 0) {
    fprintf(stdout, ", ");
    generate_c(compile(P(2),depth+1), depth+1);
  }
  return -1;

#endif
     if (alt == 0)               {  //\\    ',' <EXPR>,
       t[1] = wlit(P(1) /*, L',' */);
       t[2] = compile(P(2), depth+1 /* P_EXPR */);
       return t[0] = P_mktuple(P_Opt_EXPR, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_Opt_EXPR, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RESTOFSWLIST> =
   case P_RESTOFSWLIST:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    ',' <NAME> <NAMES> '(' <EXPR> ':' <EXPR> ')' <RESTOFSWLIST>,
       t[1] = wlit(P(1) /*, L',' */);
       t[2] = compile(P(2), depth+1 /* P_NAME */);
       t[3] = compile(P(3), depth+1 /* P_NAMES */);
       t[4] = wlit(P(4) /*, L'(' */);
       t[5] = compile(P(5), depth+1 /* P_EXPR */);
       t[6] = wlit(P(6) /*, L':' */);
       t[7] = compile(P(7), depth+1 /* P_EXPR */);
       t[8] = wlit(P(8) /*, L')' */);
       t[9] = compile(P(9), depth+1 /* P_RESTOFSWLIST */);
       return t[0] = P_mktuple(P_RESTOFSWLIST, alt, 9/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_RESTOFSWLIST, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RESTOFREPEAT> =
   case P_RESTOFREPEAT:
#ifdef IN_PARSER

  {
  int EXPECTED = pop_ctrl();
  if (EXPECTED != REPEAT && EXPECTED != REPEATUNTIL) {
    fprintf(stderr, "\n* %%REPEAT not expected here (expecting %s)\n", ctrl_debug[EXPECTED]); exit(1);
  }

  if (EXPECTED == REPEATUNTIL) {
    // if this was a %cycle ... %repeat with a possible %until after it, the
    // %cycle could have been emitted as "do {" and this code could be either ") until (cond)" or "} while (1)"
    if (alt == 0) {
      fprintf(stdout, "} until ");
      compile(P(2), depth+1);
      fprintf(stdout, ";");
      if (debug_compiler) fprintf(stderr, "[until condition]");
    } else if (alt == 1) {
      fprintf(stdout, "} while (1);");
    }
  } else if (EXPECTED == REPEAT) {
    if (alt == 0) {
      fprintf(stderr, "* %%UNTIL is not allowed at the end of this cycle.\n"); exit(1);
    }
    fprintf(stdout, "}"); // no semicolon
  }
  return -1;
  }

#endif
     if (alt == 0)               {  //\\    "until" <TOP_LEVEL_CONDITION>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_TOP_LEVEL_CONDITION */);
       return t[0] = P_mktuple(P_RESTOFREPEAT, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_RESTOFREPEAT, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<FINISHELSEQ> =
   case P_FINISHELSEQ:
#ifdef IN_PARSER

  {
    int EXPECTED = pop_ctrl();

    if (alt == 0) {
      fprintf(stdout, " else ");
      if (debug_compiler) fprintf(stderr, "[FINISHELSEQ]");
    } else fprintf(stdout, "\n"); // following a %finish
  }
  // recurse on AFTERELSE

#endif
     if (alt == 0)               {  //\\    "else" <AFTERELSE>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_AFTERELSE */);
       return t[0] = P_mktuple(P_FINISHELSEQ, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_FINISHELSEQ, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<AFTERELSE> =
   case P_AFTERELSE:
#ifdef IN_PARSER

  if (alt == 0) {
    push_ctrl(FINISH);
    fprintf(stdout, "{\n");
    if (debug_compiler) fprintf(stderr, "[afterelse: start]");
    return -1;
  } else if (alt == 1) {
    //push_ctrl(FINISHELSE);
    if (debug_compiler) fprintf(stderr, "[afterelse: if or unless <COND> start]");
    compile(P(1),depth+1);
    compile(P(2),depth+1);
    compile(P(3),depth+1);
    return -1;
  } else {
    if (debug_compiler) fprintf(stderr, "[afterelse: <UI>]");
    // recurse
  }
  // recursively handle alt 2

#endif
     if (alt == 0)               {  //\\    "start",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_AFTERELSE, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    <PC_IU> <TOP_LEVEL_CONDITION> <RESTOFIU>,
       t[1] = compile(P(1), depth+1 /* P_PC_IU */);
       t[2] = compile(P(2), depth+1 /* P_TOP_LEVEL_CONDITION */);
       t[3] = compile(P(3), depth+1 /* P_RESTOFIU */);
       return t[0] = P_mktuple(P_AFTERELSE, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    <UI_BLOCK>;
       t[1] = compile(P(1), depth+1 /* P_UI_BLOCK */);
       return t[0] = P_mktuple(P_AFTERELSE, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<ELSEQ> =
   case P_ELSEQ:
#ifdef IN_PARSER

  if (alt == 0) {
    fprintf(stdout, " else ");
    if (debug_compiler) fprintf(stderr, "[ELSEQ]");
    // recurse
  }

#endif
     if (alt == 0)               {  //\\    "else" <AFTERELSE>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_AFTERELSE */);
       return t[0] = P_mktuple(P_ELSEQ, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_ELSEQ, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RESTOFIU> =
   case P_RESTOFIU:
#ifdef IN_PARSER

  if (alt < 2) {
    push_ctrl(FINISHELSE);
    fprintf(stdout, " {\n");
    if (debug_compiler) fprintf(stderr, "[then start]");
    return -1;
  } else {
    if (debug_compiler) fprintf(stderr, "[then UI]");
    // recursively handle the rest
  }

#endif
     if (alt == 0)               {  //\\    "start",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_RESTOFIU, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    "then" "start",
       t[1] = wlit(P(1));
       t[2] = wlit(P(2));
       return t[0] = P_mktuple(P_RESTOFIU, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    "then" <UI_BLOCK> <ELSEQ>;
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_UI_BLOCK */);
       t[3] = compile(P(3), depth+1 /* P_ELSEQ */);
       return t[0] = P_mktuple(P_RESTOFIU, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<Opt_Record_Field> =
   case P_Opt_Record_Field:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    '_' <VARNAME> <APP> <Opt_Record_Field>,
       t[1] = wlit(P(1) /*, L'_' */);
       t[2] = compile(P(2), depth+1 /* P_VARNAME */);
       t[3] = compile(P(3), depth+1 /* P_APP */);
       t[4] = compile(P(4), depth+1 /* P_Opt_Record_Field */);
       return t[0] = P_mktuple(P_Opt_Record_Field, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_Opt_Record_Field, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<Opt_Const_Init> =
   case P_Opt_Const_Init:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    '=' <UOP> <COPERAND> <RESTOFCEXPR>,
       t[1] = wlit(P(1) /*, L'=' */);
       t[2] = compile(P(2), depth+1 /* P_UOP */);
       t[3] = compile(P(3), depth+1 /* P_COPERAND */);
       t[4] = compile(P(4), depth+1 /* P_RESTOFCEXPR */);
       return t[0] = P_mktuple(P_Opt_Const_Init, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_Opt_Const_Init, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<SEX> =
   case P_SEX:
#ifdef IN_PARSER

  Linkage = alt+1;
  // %routine without one of the above is auto if nested but not sure what at external level if no %external keyword.
  if (debug_declarations > 1) fprintf(stderr, "[Linkage=%d]", Linkage);

#endif
     if (alt == 0)               {  //\\    "external",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_SEX, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    "system",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_SEX, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 2)        {  //\\    "dynamic",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_SEX, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 3)        {  //\\    "prim",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_SEX, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 4)        {  //\\    "perm",
       t[1] = wlit(P(1));
       return t[0] = P_mktuple(P_SEX, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_SEX, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RFSTMNT> =
   case P_RFSTMNT:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    "spec" <NAME> <INITDECS>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_NAME */);
       t[3] = compile(P(3), depth+1 /* P_INITDECS */);
       return t[0] = P_mktuple(P_RFSTMNT, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    <NAME> <INITDECS> '(' <temp_quiet> <RFDEC> <RESTOFRFDEC> <ALTRFDEC> <end_temp_quiet> ')';
       t[1] = compile(P(1), depth+1 /* P_NAME */);
       t[2] = compile(P(2), depth+1 /* P_INITDECS */);
       t[3] = wlit(P(3) /*, L'(' */);
       t[4] = compile(P(4), depth+1 /* P_temp_quiet */);
       t[5] = compile(P(5), depth+1 /* P_RFDEC */);
       t[6] = compile(P(6), depth+1 /* P_RESTOFRFDEC */);
       t[7] = compile(P(7), depth+1 /* P_ALTRFDEC */);
       t[8] = compile(P(8), depth+1 /* P_end_temp_quiet */);
       t[9] = wlit(P(9) /*, L')' */);
       return t[0] = P_mktuple(P_RFSTMNT, alt, 9/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RFREF> =
   case P_RFREF:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    <VARNAME>,
       t[1] = compile(P(1), depth+1 /* P_VARNAME */);
       return t[0] = P_mktuple(P_RFREF, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    <RFDEC> <RESTOFRFDEC> <ALTRFDEC>;
       t[1] = compile(P(1), depth+1 /* P_RFDEC */);
       t[2] = compile(P(2), depth+1 /* P_RESTOFRFDEC */);
       t[3] = compile(P(3), depth+1 /* P_ALTRFDEC */);
       return t[0] = P_mktuple(P_RFREF, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RESTOFRFDEC> =
   case P_RESTOFRFDEC:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    ',' <READLINEP> <RFDEC> <RESTOFRFDEC>,
       t[1] = wlit(P(1) /*, L',' */);
       t[2] = compile(P(2), depth+1 /* P_READLINEP */);
       t[3] = compile(P(3), depth+1 /* P_RFDEC */);
       t[4] = compile(P(4), depth+1 /* P_RESTOFRFDEC */);
       return t[0] = P_mktuple(P_RESTOFRFDEC, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_RESTOFRFDEC, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RFDEC> =
   case P_RFDEC:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    <XTYPE> <RFELMNT>,
       t[1] = compile(P(1), depth+1 /* P_XTYPE */);
       t[2] = compile(P(2), depth+1 /* P_RFELMNT */);
       return t[0] = P_mktuple(P_RFDEC, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    '(' <RFDEC> <RESTOFRFDEC> <ALTRFDEC> ')';
       t[1] = wlit(P(1) /*, L'(' */);
       t[2] = compile(P(2), depth+1 /* P_RFDEC */);
       t[3] = compile(P(3), depth+1 /* P_RESTOFRFDEC */);
       t[4] = compile(P(4), depth+1 /* P_ALTRFDEC */);
       t[5] = wlit(P(5) /*, L')' */);
       return t[0] = P_mktuple(P_RFDEC, alt, 5/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<RFELMNT> =
   case P_RFELMNT:
#ifdef IN_PARSER

  // a declaration of a record field - more restrictive in what it can be compared to regular declarations

#endif
     if (alt == 0)               {  //\\    <Opt_AN_N_type> <NAME> <NAMES> <INITDECS>,
       t[1] = compile(P(1), depth+1 /* P_Opt_AN_N_type */);
       t[2] = compile(P(2), depth+1 /* P_NAME */);
       t[3] = compile(P(3), depth+1 /* P_NAMES */);
       t[4] = compile(P(4), depth+1 /* P_INITDECS */);
       return t[0] = P_mktuple(P_RFELMNT, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    "array" <ADECLN>;
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_ADECLN */);
       return t[0] = P_mktuple(P_RFELMNT, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<ALTRFDEC> =
   case P_ALTRFDEC:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    "or" <RFDEC> <RESTOFRFDEC> <ALTRFDEC>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_RFDEC */);
       t[3] = compile(P(3), depth+1 /* P_RESTOFRFDEC */);
       t[4] = compile(P(4), depth+1 /* P_ALTRFDEC */);
       return t[0] = P_mktuple(P_ALTRFDEC, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_ALTRFDEC, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<ASM> =
   case P_ASM:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    <!semi> <nl> <eof> «.» <ASM>,
       t[1] = -1; /* ignore negative guard */;
       t[2] = wlit(P(2) /*, L"nl" */);
       t[3] = wlit(P(3) /*, L"eof" */);
       t[4] = wlit(P(4));
       t[5] = compile(P(5), depth+1 /* P_ASM */);
       return t[0] = P_mktuple(P_ASM, alt, 5/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_ASM, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<Call_or_Assign_AUI> =
   case P_Call_or_Assign_AUI:
#ifdef IN_PARSER

  {
    int Ass = compile(P(4),depth+1); // <ASSOP><EXPR>, ''
    if (P_alt(Ass) == 0) { // 0 assignment 1 procedure call
      // TO DO: under development
      int LHS = compile(P(1),depth+1);
      // LHS = <VARNAME><APP><Opt_Record_Field>;
      // Using the struct here would reduce the risk of putting a value in the wrong field!
      t[1] = P_P(Ass,1);
      t[2] = LHS;
      t[3] = P_P(Ass,2);
      generate_c(P_mktuple(AST_ASSIGN, 0, 3, t),depth+1);
    } else {

      // procedure call
      
      extern int handle_ast_phrase(int Ph, int depth);
      (void)handle_ast_phrase(compile(P(1),depth+1), depth+1); // <VARNAME> returns AST_RVALUE
      
      fprintf(stdout, "(");
      generate_c(compile(P(2),depth+1), depth+1);
      fprintf(stdout, ")");
      //generate_c(P_mktuple(AST_PROC_CALL, 0, 2, t),depth+1);   // This could be preferred if it worked. Which at the moment it seems not to.
    }
    return -1;
  }

#endif
     {                              //\\    <VARNAME> <APP> <Opt_Record_Field> <Optional_Assignment>;
     t[1] = compile(P(1), depth+1 /* P_VARNAME */);
     t[2] = compile(P(2), depth+1 /* P_APP */);
     t[3] = compile(P(3), depth+1 /* P_Opt_Record_Field */);
     t[4] = compile(P(4), depth+1 /* P_Optional_Assignment */);
     return t[0] = P_mktuple(P_Call_or_Assign_AUI, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<Goto> =
   case P_Goto:
#ifdef IN_PARSER

  fprintf(stdout, "goto ");
  generate_c(compile(P(3),depth+1), depth+1);
  if (0) {                 // if <APP> is not empty, generate code for a jump to a switch statement, otherwise a plain 'goto'...
      fprintf(stdout, "[");
      compile(P(4),depth+1); // NO: needs to be a decimal constant with special handling for negative numbers.
      fprintf(stdout, "/*to do*/]");
  }
  if (debug_compiler) fprintf(stderr, "[go to]");
  return -1;

#endif
     {                              //\\    '-' '>' <VARNAME> <APP>;
     t[1] = wlit(P(1) /*, L'-' */);
     t[2] = wlit(P(2) /*, L'>' */);
     t[3] = compile(P(3), depth+1 /* P_VARNAME */);
     t[4] = compile(P(4), depth+1 /* P_APP */);
     return t[0] = P_mktuple(P_Goto, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<return> =
   case P_return:
#ifdef IN_PARSER

  fprintf(stdout, "return");
  if (debug_compiler) fprintf(stderr, "[return]");

#endif
     {                              //\\    "return";
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_return, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<result> =
   case P_result:
#ifdef IN_PARSER

  fprintf(stdout, "return ");
  // Assop will modify the result, possibly with a cast (for <-) or removing an indirection (for ==)

  // TO DO: possibly needs a new AST_RESULT tuple similar to AST_ASSIGN



  int SaveOperBottom = OperStack_bottom; OperStack_bottom = OperStack_nextfree;
  int SaveDataBottom = DataStack_bottom; DataStack_bottom = DataStack_nextfree;
  int Expr = compile(P(3),depth+1);
  DataStack_bottom = SaveDataBottom;
  OperStack_bottom = SaveOperBottom;

  generate_c(Expr, depth+1);

  if (debug_compiler) fprintf(stderr, "[result]");
  return -1;

#endif
     {                              //\\    "result" <ASSOP> <EXPR>;
     t[1] = wlit(P(1));
     t[2] = compile(P(2), depth+1 /* P_ASSOP */);
     t[3] = compile(P(3), depth+1 /* P_EXPR */);
     return t[0] = P_mktuple(P_result, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<monitor_AUI> =
   case P_monitor_AUI:
#ifdef IN_PARSER

  fprintf(stdout, "assert(FALSE)");
  if (debug_compiler) fprintf(stderr, "[print diagnostics]");
  // go on to handle <AUI> for now.

#endif
     {                              //\\    "monitor";
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_monitor_AUI, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<stop> =
   case P_stop:
#ifdef IN_PARSER

  fprintf(stdout, "exit(0)");
  if (debug_compiler) fprintf(stderr, "[stop program]");
  return -1;

#endif
     {                              //\\    "stop";
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_stop, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<signal> =
   case P_signal:
#ifdef IN_PARSER

  fprintf(stdout, "_imp_signal(");
  compile(P(2),depth+1);
  fprintf(stdout, ", ");
  compile(P(3),depth+1);
  if (0) { // if <OPXPR> is not the null alt
    fprintf(stdout, ", ");
    compile(P(4),depth+1);
    fprintf(stdout, ")");
  }
  if (debug_compiler) fprintf(stderr, "[signal event]");
  return -1;

#endif
     {                              //\\    "signal" <PC_EVENTQ> <CEXPR> <Opt_EXPR>;
     t[1] = wlit(P(1));
     t[2] = compile(P(2), depth+1 /* P_PC_EVENTQ */);
     t[3] = compile(P(3), depth+1 /* P_CEXPR */);
     t[4] = compile(P(4), depth+1 /* P_Opt_EXPR */);
     return t[0] = P_mktuple(P_signal, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<exit> =
   case P_exit:
#ifdef IN_PARSER

  fprintf(stdout, "break");
  if (debug_compiler) fprintf(stderr, "[exit from cycle]");

#endif
     {                              //\\    "exit";
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_exit, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<continue> =
   case P_continue:
#ifdef IN_PARSER

  fprintf(stdout, "continue");
  if (debug_compiler) fprintf(stderr, "[continue at end of cycle]");

#endif
     {                              //\\    "continue";
     t[1] = wlit(P(1));
     return t[0] = P_mktuple(P_continue, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<Unconditional_Instructions> =
   case P_Unconditional_Instructions:
#ifdef IN_PARSER

  if (alt == 0) {
    compile(P(1),depth+1); // <UI> must be encapsulated in a {...} block if more that 1 statement
  } else if (alt == 1) { // PC_IU is just "if" or "unless"
    compile(P(2),depth+1);
    compile(P(3),depth+1);
    compile(P(1),depth+1);
  } else if (alt == 2) { // but PC_WUF is a full while/until/for condition
    compile(P(2),depth+1);
    compile(P(1),depth+1);
  }
  return -1;

#endif
     if (alt == 0)               {  //\\    <UI_BLOCK> <S>,
       t[1] = compile(P(1), depth+1 /* P_UI_BLOCK */);
       t[2] = compile(P(2), depth+1 /* P_S */);
       return t[0] = P_mktuple(P_Unconditional_Instructions, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    <UI_BLOCK> <PC_IU> <TOP_LEVEL_CONDITION> <S>,
       t[1] = compile(P(1), depth+1 /* P_UI_BLOCK */);
       t[2] = compile(P(2), depth+1 /* P_PC_IU */);
       t[3] = compile(P(3), depth+1 /* P_TOP_LEVEL_CONDITION */);
       t[4] = compile(P(4), depth+1 /* P_S */);
       return t[0] = P_mktuple(P_Unconditional_Instructions, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    <UI_BLOCK> <PC_WUF> <S>;
       t[1] = compile(P(1), depth+1 /* P_UI_BLOCK */);
       t[2] = compile(P(2), depth+1 /* P_PC_WUF */);
       t[3] = compile(P(3), depth+1 /* P_S */);
       return t[0] = P_mktuple(P_Unconditional_Instructions, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<UI> =
   case P_UI:
#ifdef IN_PARSER

  if (alt == 0) {
    compile(P(1),depth+1); fprintf(stdout, "; ");
    compile(P(2),depth+1);
    return -1;
  } else {
    compile(P(1),depth+1);
    fprintf(stdout, "; ");
  }
  return -1;

#endif
     if (alt == 0)               {  //\\    <NONFINAL_UI> <AUI>,
       t[1] = compile(P(1), depth+1 /* P_NONFINAL_UI */);
       t[2] = compile(P(2), depth+1 /* P_AUI */);
       return t[0] = P_mktuple(P_UI, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    <NONFINAL_UI>,
       t[1] = compile(P(1), depth+1 /* P_NONFINAL_UI */);
       return t[0] = P_mktuple(P_UI, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    <FINAL_UI>;
       t[1] = compile(P(1), depth+1 /* P_FINAL_UI */);
       return t[0] = P_mktuple(P_UI, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<AUI> =
   case P_AUI:
#ifdef IN_PARSER


#endif
     {                              //\\    "and" <UI>;
     t[1] = wlit(P(1));
     t[2] = compile(P(2), depth+1 /* P_UI */);
     return t[0] = P_mktuple(P_AUI, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<UI_BLOCK> =
   case P_UI_BLOCK:
#ifdef IN_PARSER

  if (alt == 0) {
    fprintf(stdout, "{ ");
    compile(P(1),depth+1); fprintf(stdout, "; ");
    compile(P(2),depth+1);
    fprintf(stdout, " }");
    return -1;
  } else {
    compile(P(1),depth+1); fprintf(stdout, "; ");
  }
  return -1;

#endif
     if (alt == 0)               {  //\\    <NONFINAL_UI> <AUI>,
       t[1] = compile(P(1), depth+1 /* P_NONFINAL_UI */);
       t[2] = compile(P(2), depth+1 /* P_AUI */);
       return t[0] = P_mktuple(P_UI_BLOCK, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    <NONFINAL_UI>,
       t[1] = compile(P(1), depth+1 /* P_NONFINAL_UI */);
       return t[0] = P_mktuple(P_UI_BLOCK, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    <FINAL_UI>;
       t[1] = compile(P(1), depth+1 /* P_FINAL_UI */);
       return t[0] = P_mktuple(P_UI_BLOCK, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<NONFINAL_UI> =
   case P_NONFINAL_UI:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    <Call_or_Assign_AUI>,
       t[1] = compile(P(1), depth+1 /* P_Call_or_Assign_AUI */);
       return t[0] = P_mktuple(P_NONFINAL_UI, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    <monitor_AUI>;
       t[1] = compile(P(1), depth+1 /* P_monitor_AUI */);
       return t[0] = P_mktuple(P_NONFINAL_UI, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<FINAL_UI> =
   case P_FINAL_UI:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    <Goto>,
       t[1] = compile(P(1), depth+1 /* P_Goto */);
       return t[0] = P_mktuple(P_FINAL_UI, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    <return>,
       t[1] = compile(P(1), depth+1 /* P_return */);
       return t[0] = P_mktuple(P_FINAL_UI, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 2)        {  //\\    <result>,
       t[1] = compile(P(1), depth+1 /* P_result */);
       return t[0] = P_mktuple(P_FINAL_UI, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 3)        {  //\\    <stop>,
       t[1] = compile(P(1), depth+1 /* P_stop */);
       return t[0] = P_mktuple(P_FINAL_UI, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 4)        {  //\\    <signal>,
       t[1] = compile(P(1), depth+1 /* P_signal */);
       return t[0] = P_mktuple(P_FINAL_UI, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 5)        {  //\\    <exit>,
       t[1] = compile(P(1), depth+1 /* P_exit */);
       return t[0] = P_mktuple(P_FINAL_UI, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    <continue>;
       t[1] = compile(P(1), depth+1 /* P_continue */);
       return t[0] = P_mktuple(P_FINAL_UI, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<More_STATEMENTS> =
   case P_More_STATEMENTS:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    <STATEMENT> <More_STATEMENTS>,
       t[1] = compile(P(1), depth+1 /* P_STATEMENT */);
       t[2] = compile(P(2), depth+1 /* P_More_STATEMENTS */);
       return t[0] = P_mktuple(P_More_STATEMENTS, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_More_STATEMENTS, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<STATEMENTS> =
   case P_STATEMENTS:
#ifdef IN_PARSER

#endif
     {                              //\\    <STATEMENT> <More_STATEMENTS> <eof>;
     t[1] = compile(P(1), depth+1 /* P_STATEMENT */);
     t[2] = compile(P(2), depth+1 /* P_More_STATEMENTS */);
     t[3] = wlit(P(3) /*, L"eof" */);
     return t[0] = P_mktuple(P_STATEMENTS, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<Labels> =
   case P_Labels:
#ifdef IN_PARSER

  if (debug_compiler || debug_declarations) fprintf(stderr, "[label]");
  int LabelTag;
  compile(P(1),depth+1); LabelTag = Tag;
  if (alt == 0) {
    Object = SWITCHDEFN;
    Basetype = SWITCHLABEL;
    fprintf(stdout, "%s_default:", Tag2Str(LabelTag));
  }  else if (alt == 1) {
    Object = SWITCHDEFN;
    Basetype = SWITCHLABEL;
    fprintf(stdout, "%s_", Tag2Str(LabelTag));
    generate_c(compile(P(4),depth+1),depth+1); // NO: needs to be a decimal constant with special handling for negative numbers.
    fprintf(stdout, ":");
  } else {
    Object = LABELDEFN;
    Basetype = JUMPLABEL;
    fprintf(stdout, "%s: ", Tag2Str(LabelTag));  // TO DO: This outputs a ' ' after the tag.  We should suppress the space at the
                                                 // point where it was added and add any needed spaces at the point of instantiation.
  }
  return -1;


#endif
     if (alt == 0)               {  //\\    <NAME> <INITDECS> '(' '*' ')' ':' <COLON>,
       t[1] = compile(P(1), depth+1 /* P_NAME */);
       t[2] = compile(P(2), depth+1 /* P_INITDECS */);
       t[3] = wlit(P(3) /*, L'(' */);
       t[4] = wlit(P(4) /*, L'*' */);
       t[5] = wlit(P(5) /*, L')' */);
       t[6] = wlit(P(6) /*, L':' */);
       t[7] = -1; /* semantic procedure COLON */;
       return t[0] = P_mktuple(P_Labels, alt, 7/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    <NAME> <INITDECS> '(' <EXPR> ')' ':' <COLON>,
       t[1] = compile(P(1), depth+1 /* P_NAME */);
       t[2] = compile(P(2), depth+1 /* P_INITDECS */);
       t[3] = wlit(P(3) /*, L'(' */);
       t[4] = compile(P(4), depth+1 /* P_EXPR */);
       t[5] = wlit(P(5) /*, L')' */);
       t[6] = wlit(P(6) /*, L':' */);
       t[7] = -1; /* semantic procedure COLON */;
       return t[0] = P_mktuple(P_Labels, alt, 7/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    <NAME> <INITDECS> ':' <COLON>;
       t[1] = compile(P(1), depth+1 /* P_NAME */);
       t[2] = compile(P(2), depth+1 /* P_INITDECS */);
       t[3] = wlit(P(3) /*, L':' */);
       t[4] = -1; /* semantic procedure COLON */;
       return t[0] = P_mktuple(P_Labels, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<If_or_Unless> =
   case P_If_or_Unless:
#ifdef IN_PARSER

  if (debug_compiler) fprintf(stderr, "[if or unless]");

#endif
     {                              //\\    <PC_IU> <TOP_LEVEL_CONDITION> <RESTOFIU> <S>;
     t[1] = compile(P(1), depth+1 /* P_PC_IU */);
     t[2] = compile(P(2), depth+1 /* P_TOP_LEVEL_CONDITION */);
     t[3] = compile(P(3), depth+1 /* P_RESTOFIU */);
     t[4] = compile(P(4), depth+1 /* P_S */);
     return t[0] = P_mktuple(P_If_or_Unless, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<Opt_CYCPARM> =
   case P_Opt_CYCPARM:
#ifdef IN_PARSER

  if (alt == 0) {
    push_ctrl(REPEAT); // for loop
    compile(P(1), depth+1);
  } else if (alt == 1) {
    push_ctrl(REPEATUNTIL); // plain %cycle
    fprintf(stdout, "do ");
  }
  return -1;

#endif
     if (alt == 0)               {  //\\    <CYCPARM>,
       t[1] = compile(P(1), depth+1 /* P_CYCPARM */);
       return t[0] = P_mktuple(P_Opt_CYCPARM, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    ;

       return t[0] = P_mktuple(P_Opt_CYCPARM, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<start_of_cycle> =
   case P_start_of_cycle:
#ifdef IN_PARSER

  if (debug_compiler) fprintf(stderr, "[cycle]");

  if (alt == 0) {
    compile(P(2), depth+1);  // if <Opt_CYCPARM> was empty, we should push_ctrl(REPEATUNTIL);, otherwise...
  } else {
    push_ctrl(REPEAT);       // %until not allowed after %repeat
    compile(P(1), depth+1);
  }
  fprintf(stdout, "{\n");
  return -1;

#endif
     if (alt == 0)               {  //\\    "cycle" <Opt_CYCPARM> <S>,
       t[1] = wlit(P(1));
       t[2] = compile(P(2), depth+1 /* P_Opt_CYCPARM */);
       t[3] = compile(P(3), depth+1 /* P_S */);
       return t[0] = P_mktuple(P_start_of_cycle, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    <PC_WUF> "cycle" <S>;
       t[1] = compile(P(1), depth+1 /* P_PC_WUF */);
       t[2] = wlit(P(2));
       t[3] = compile(P(3), depth+1 /* P_S */);
       return t[0] = P_mktuple(P_start_of_cycle, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<end_of_cycle> =
   case P_end_of_cycle:
#ifdef IN_PARSER

  // <RESTOFREPEAT> handles the control stack and whether a %until is allowed
  compile(P(2), depth+1);
  if (debug_compiler) fprintf(stderr, "[repeat]");
  return -1;

#endif
     {                              //\\    "repeat" <RESTOFREPEAT> <S>;
     t[1] = wlit(P(1));
     t[2] = compile(P(2), depth+1 /* P_RESTOFREPEAT */);
     t[3] = compile(P(3), depth+1 /* P_S */);
     return t[0] = P_mktuple(P_end_of_cycle, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<regular_declaration> =
   case P_regular_declaration:
#ifdef IN_PARSER

  if (debug_compiler) fprintf(stderr, "[auto declaration]");
  Object = VAR;

#endif
     {                              //\\    <INITDECS> <XTYPE> <DECLN> <S>;
     t[1] = compile(P(1), depth+1 /* P_INITDECS */);
     t[2] = compile(P(2), depth+1 /* P_XTYPE */);
     t[3] = compile(P(3), depth+1 /* P_DECLN */);
     t[4] = compile(P(4), depth+1 /* P_S */);
     return t[0] = P_mktuple(P_regular_declaration, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<proc_declaration> =
   case P_proc_declaration:
#ifdef IN_PARSER

  if (debug_compiler) fprintf(stderr, "[procedure declaration]");
  Object = CODE;

#endif
     {                              //\\    <INITDECS> <SEX> <RT> <Opt_RtFnMapSpec> <NAME> <ALIAS> <INITDECS> <DOWNQ> <temp_quiet> <FPP> <end_temp_quiet> <S>;
     t[1] = compile(P(1), depth+1 /* P_INITDECS */);
     t[2] = compile(P(2), depth+1 /* P_SEX */);
     t[3] = compile(P(3), depth+1 /* P_RT */);
     t[4] = compile(P(4), depth+1 /* P_Opt_RtFnMapSpec */);
     t[5] = compile(P(5), depth+1 /* P_NAME */);
     t[6] = compile(P(6), depth+1 /* P_ALIAS */);
     t[7] = compile(P(7), depth+1 /* P_INITDECS */);
     t[8] = compile(P(8), depth+1 /* P_DOWNQ */);
     t[9] = compile(P(9), depth+1 /* P_temp_quiet */);
     t[10] = compile(P(10), depth+1 /* P_FPP */);
     t[11] = compile(P(11), depth+1 /* P_end_temp_quiet */);
     t[12] = compile(P(12), depth+1 /* P_S */);
     return t[0] = P_mktuple(P_proc_declaration, alt, 12/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<own_or_external_declaration> =
   case P_own_or_external_declaration:
#ifdef IN_PARSER

  // if (debug_compiler) fprintf(stderr, "[own/external/const declaration]");
  Object = VAR;

#endif
     {                              //\\    <INITDECS> <XOWN> <XTYPE> <OWNDEC> <S>;
     t[1] = compile(P(1), depth+1 /* P_INITDECS */);
     t[2] = compile(P(2), depth+1 /* P_XOWN */);
     t[3] = compile(P(3), depth+1 /* P_XTYPE */);
     t[4] = compile(P(4), depth+1 /* P_OWNDEC */);
     t[5] = compile(P(5), depth+1 /* P_S */);
     return t[0] = P_mktuple(P_own_or_external_declaration, alt, 5/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<on_event_block> =
   case P_on_event_block:
#ifdef IN_PARSER

  if (debug_compiler) fprintf(stderr, "[on event block]");
  fprintf(stdout, "if (_imp_onevent(/*to do*/)) {\n");
  push_ctrl(FINISH);

#endif
     {                              //\\    "on" <PC_EVENTQ> <CEXPR> <RESTOFNLIST> "start" <S>;
     t[1] = wlit(P(1));
     t[2] = compile(P(2), depth+1 /* P_PC_EVENTQ */);
     t[3] = compile(P(3), depth+1 /* P_CEXPR */);
     t[4] = compile(P(4), depth+1 /* P_RESTOFNLIST */);
     t[5] = wlit(P(5));
     t[6] = compile(P(6), depth+1 /* P_S */);
     return t[0] = P_mktuple(P_on_event_block, alt, 6/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<record_format_declaration> =
   case P_record_format_declaration:
#ifdef IN_PARSER

  if (debug_compiler) fprintf(stderr, "[record format declaration]");
  //IsFormat = IS_FORMAT; // THIS APPEARS TO HAVE BE OVERRIDDEN BY THE TIME IT IS PRINTED.
  Object = RECORDFORMAT;

#endif
     {                              //\\    <INITDECS> "record" "format" <RFSTMNT> <S>;
     t[1] = compile(P(1), depth+1 /* P_INITDECS */);
     t[2] = wlit(P(2));
     t[3] = wlit(P(3));
     t[4] = compile(P(4), depth+1 /* P_RFSTMNT */);
     t[5] = compile(P(5), depth+1 /* P_S */);
     return t[0] = P_mktuple(P_record_format_declaration, alt, 5/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<various_ends> =
   case P_various_ends:
#ifdef IN_PARSER

  if (debug_compiler) fprintf(stderr, "[end of something]");

#endif
     {                              //\\    "end" <ENDLIST> <S>;
     t[1] = wlit(P(1));
     t[2] = compile(P(2), depth+1 /* P_ENDLIST */);
     t[3] = compile(P(3), depth+1 /* P_S */);
     return t[0] = P_mktuple(P_various_ends, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<include_file> =
   case P_include_file:
#ifdef IN_PARSER

  if (debug_compiler) fprintf(stderr, "[push an include file]");
  fprintf(stdout, "\n#include \"...\"\n");

#endif
     {                              //\\    "include" <CONST> <INCLUDE>;
     t[1] = wlit(P(1));
     t[2] = compile(P(2), depth+1 /* P_CONST */);
     t[3] = -1; /* semantic procedure INCLUDE */;
     return t[0] = P_mktuple(P_include_file, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<begin_block> =
   case P_begin_block:
#ifdef IN_PARSER

  if (debug_compiler) fprintf(stderr, "[begin block]");
  if (ctrl_depth() == 0) {
    push_ctrl(ENDOFPROGRAM);
    fprintf(stdout, "\n#include <imp_perms.h>\nint main(int argc, char **argv) {\n");
  } else {
    push_ctrl(END);
    fprintf(stdout, "\n{\n");
  }

#endif
     {                              //\\    "begin" <DOWN> <S>;
     t[1] = wlit(P(1));
     t[2] = compile(P(2), depth+1 /* P_DOWN */);
     t[3] = compile(P(3), depth+1 /* P_S */);
     return t[0] = P_mktuple(P_begin_block, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<switch_declaration> =
   case P_switch_declaration:
#ifdef IN_PARSER

  if (debug_declarations > 1) fprintf(stderr, "[switch declaration]");
  Object = VAR;
  // Will require *either* exbedded code at end of scope block with actual switch statement and gotos,
  // *or* we have to backpatch this declaration with assignment of an array of labels (in the style &&labname)
  // *or* we generate *all* labels at the point of declaration but output the unused ones at the end of
  // the scope block with a jump to the default if given, or an error message if not.

#endif
     {                              //\\    <INITDECS> "switch" <NAME> <NAMES> <INITDECS> '(' <EXPR> ':' <EXPR> ')' <RESTOFSWLIST> <S>;
     t[1] = compile(P(1), depth+1 /* P_INITDECS */);
     t[2] = wlit(P(2));
     t[3] = compile(P(3), depth+1 /* P_NAME */);
     t[4] = compile(P(4), depth+1 /* P_NAMES */);
     t[5] = compile(P(5), depth+1 /* P_INITDECS */);
     t[6] = wlit(P(6) /*, L'(' */);
     t[7] = compile(P(7), depth+1 /* P_EXPR */);
     t[8] = wlit(P(8) /*, L':' */);
     t[9] = compile(P(9), depth+1 /* P_EXPR */);
     t[10] = wlit(P(10) /*, L')' */);
     t[11] = compile(P(11), depth+1 /* P_RESTOFSWLIST */);
     t[12] = compile(P(12), depth+1 /* P_S */);
     return t[0] = P_mktuple(P_switch_declaration, alt, 12/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<list_on> =
   case P_list_on:
#ifdef IN_PARSER

  if (debug_compiler) fprintf(stderr, "[turn on listing]");

#endif
     {                              //\\    "list" <S> <LISTON>;
     t[1] = wlit(P(1));
     t[2] = compile(P(2), depth+1 /* P_S */);
     t[3] = -1; /* semantic procedure LISTON */;
     return t[0] = P_mktuple(P_list_on, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<else> =
   case P_else:
#ifdef IN_PARSER

  {
    if (debug_compiler) fprintf(stderr, "[(finish) else (start)]");
    int EXPECTED = pop_ctrl();
    if (EXPECTED == ELSE || EXPECTED == FINISHELSE) {
      push_ctrl(FINISH);
      fprintf(stdout, "} else {");           // NOTE: a plain "%else" represents "%finish %else %start"
    } else {
      // TO DO:
      
      // And today's exercise is... try to remember how to extract the line/column from the "else" symbol
      // to report the error better :-/
      
      fprintf(stderr, "\n* Spurious %%ELSE\n"); exit(1);
    }
  }

#endif
     {                              //\\    "else" <S>;
     t[1] = wlit(P(1));
     t[2] = compile(P(2), depth+1 /* P_S */);
     return t[0] = P_mktuple(P_else, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<finish_opt_else> =
   case P_finish_opt_else:
#ifdef IN_PARSER

  {
    if (ctrl_depth() == 0) {
      fprintf(stderr, "\n* Spurious %%FINISH\n"); exit(1); // at least until we get around to handling ERCC conditional compilation tests
    }
    int EXPECTED = pop_ctrl();
    fprintf(stdout, "\n}");
    if (EXPECTED == FINISH) {
      push_ctrl(ELSE);
    } else if (EXPECTED == FINISHELSE) {
      push_ctrl(ELSE);
    } else {
      fprintf(stderr, "\n* %%FINISH not expected (expecting %s)\n", ctrl_debug[EXPECTED]); exit(1);
    }
    // recurse on FINISHELSEQ
  }
  if (debug_compiler) fprintf(stderr, "[finish]");

#endif
     {                              //\\    "finish" <FINISHELSEQ> <S>;
     t[1] = wlit(P(1));
     t[2] = compile(P(2), depth+1 /* P_FINISHELSEQ */);
     t[3] = compile(P(3), depth+1 /* P_S */);
     return t[0] = P_mktuple(P_finish_opt_else, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<embedded_assembler> =
   case P_embedded_assembler:
#ifdef IN_PARSER

  fprintf(stdout, "asm(/*to do*/)");
  if (debug_compiler) fprintf(stderr, "[embedded assembly code]");

#endif
     {                              //\\    '*' <ASM> <S>;
     t[1] = wlit(P(1) /*, L'*' */);
     t[2] = compile(P(2), depth+1 /* P_ASM */);
     t[3] = compile(P(3), depth+1 /* P_S */);
     return t[0] = P_mktuple(P_embedded_assembler, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<trusted> =
   case P_trusted:
#ifdef IN_PARSER

  if (debug_compiler) fprintf(stderr, "[trusted program pragma]");

#endif
     {                              //\\    "trustedprogram" <S>;
     t[1] = wlit(P(1));
     t[2] = compile(P(2), depth+1 /* P_S */);
     return t[0] = P_mktuple(P_trusted, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<mainep> =
   case P_mainep:
#ifdef IN_PARSER

  if (debug_compiler) fprintf(stderr, "[use this routine for main()]");

#endif
     {                              //\\    "mainep" <NAME> <INITDECS> <S>;
     t[1] = wlit(P(1));
     t[2] = compile(P(2), depth+1 /* P_NAME */);
     t[3] = compile(P(3), depth+1 /* P_INITDECS */);
     t[4] = compile(P(4), depth+1 /* P_S */);
     return t[0] = P_mktuple(P_mainep, alt, 4/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<control> =
   case P_control:
#ifdef IN_PARSER

  // pragma?
  if (debug_compiler) fprintf(stderr, "[%%control - fine control over compiler options]");

#endif
     {                              //\\    "control" <CONST> <S>;
     t[1] = wlit(P(1));
     t[2] = compile(P(2), depth+1 /* P_CONST */);
     t[3] = compile(P(3), depth+1 /* P_S */);
     return t[0] = P_mktuple(P_control, alt, 3/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<PSEMI> =
   case P_PSEMI:
#ifdef IN_PARSER
 // print a semicolon after certain statements. This is for C's benefit.
  fprintf(stdout, "/*5*/; ");

#endif
     {                              //\\    ;

     return t[0] = P_mktuple(P_PSEMI, alt, 0/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ P<STATEMENT> =
   case P_STATEMENT:
#ifdef IN_PARSER

#endif
     if (alt == 0)               {  //\\    <Labels>,
       t[1] = compile(P(1), depth+1 /* P_Labels */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 1)        {  //\\    <Unconditional_Instructions>,
       t[1] = compile(P(1), depth+1 /* P_Unconditional_Instructions */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 2)        {  //\\    <Comment> <S>,
       t[1] = compile(P(1), depth+1 /* P_Comment */);
       t[2] = compile(P(2), depth+1 /* P_S */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 3)        {  //\\    <If_or_Unless>,
       t[1] = compile(P(1), depth+1 /* P_If_or_Unless */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 4)        {  //\\    <start_of_cycle>,
       t[1] = compile(P(1), depth+1 /* P_start_of_cycle */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 5)        {  //\\    <end_of_cycle>,
       t[1] = compile(P(1), depth+1 /* P_end_of_cycle */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 6)        {  //\\    <regular_declaration>,
       t[1] = compile(P(1), depth+1 /* P_regular_declaration */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 7)        {  //\\    <various_ends>,
       t[1] = compile(P(1), depth+1 /* P_various_ends */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 8)        {  //\\    <record_format_declaration>,
       t[1] = compile(P(1), depth+1 /* P_record_format_declaration */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 9)        {  //\\    <proc_declaration>,
       t[1] = compile(P(1), depth+1 /* P_proc_declaration */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 10)        {  //\\    <own_or_external_declaration>,
       t[1] = compile(P(1), depth+1 /* P_own_or_external_declaration */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 11)        {  //\\    <include_file>,
       t[1] = compile(P(1), depth+1 /* P_include_file */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 12)        {  //\\    <begin_block>,
       t[1] = compile(P(1), depth+1 /* P_begin_block */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 13)        {  //\\    <on_event_block>,
       t[1] = compile(P(1), depth+1 /* P_on_event_block */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 14)        {  //\\    <switch_declaration>,
       t[1] = compile(P(1), depth+1 /* P_switch_declaration */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 15)        {  //\\    <list_on>,
       t[1] = compile(P(1), depth+1 /* P_list_on */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 16)        {  //\\    <else>,
       t[1] = compile(P(1), depth+1 /* P_else */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 17)        {  //\\    <finish_opt_else>,
       t[1] = compile(P(1), depth+1 /* P_finish_opt_else */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 18)        {  //\\    <embedded_assembler> <PSEMI>,
       t[1] = compile(P(1), depth+1 /* P_embedded_assembler */);
       t[2] = compile(P(2), depth+1 /* P_PSEMI */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 19)        {  //\\    <trusted> <PSEMI>,
       t[1] = compile(P(1), depth+1 /* P_trusted */);
       t[2] = compile(P(2), depth+1 /* P_PSEMI */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 20)        {  //\\    <mainep> <PSEMI>,
       t[1] = compile(P(1), depth+1 /* P_mainep */);
       t[2] = compile(P(2), depth+1 /* P_PSEMI */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else if (alt == 21)        {  //\\    <control> <PSEMI>,
       t[1] = compile(P(1), depth+1 /* P_control */);
       t[2] = compile(P(2), depth+1 /* P_PSEMI */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 2/*phrases*/, t); /* (note t[], not T[]) */

     } else                      {  //\\    <S>;
       t[1] = compile(P(1), depth+1 /* P_S */);
       return t[0] = P_mktuple(P_STATEMENT, alt, 1/*phrases*/, t); /* (note t[], not T[]) */

     }
//\\ E
