head	1.12;
access;
symbols;
locks
	gtoal:1.12; strict;
comment	@ * @;


1.12
date	2022.02.19.02.47.42;	author gtoal;	state Exp;
branches;
next	1.11;

1.11
date	2022.02.17.21.14.01;	author gtoal;	state Exp;
branches;
next	1.10;

1.10
date	2022.02.17.06.26.56;	author gtoal;	state Exp;
branches;
next	1.9;

1.9
date	2022.02.16.20.28.07;	author gtoal;	state Exp;
branches;
next	1.8;

1.8
date	2022.02.15.22.30.57;	author gtoal;	state Exp;
branches;
next	1.7;

1.7
date	2022.02.15.00.46.37;	author gtoal;	state Exp;
branches;
next	1.6;

1.6
date	2022.02.13.07.51.20;	author gtoal;	state Exp;
branches;
next	1.5;

1.5
date	2022.02.11.07.13.17;	author gtoal;	state Exp;
branches;
next	1.4;

1.4
date	2022.02.11.03.48.03;	author gtoal;	state Exp;
branches;
next	1.3;

1.3
date	2022.02.11.03.02.25;	author gtoal;	state Exp;
branches;
next	1.2;

1.2
date	2022.02.09.20.13.51;	author gtoal;	state Exp;
branches;
next	1.1;

1.1
date	2022.02.08.18.08.14;	author gtoal;	state Exp;
branches;
next	;


desc
@imp80
@


1.12
log
@*** empty log message ***
@
text
@//\\ # This is an extended grammar which now accepts constructs from multiple versions of Imp
//\\ # - it was primarily based on a correct Imp80 grammar, then modified to add Imp77 constructs
//\\ # followed by features from Pdp15 Imp, old Emas "Imp9", and Hamish's 68000 extensions, etc
//\\ # The original base grammar was:
//\\ #   https://history.dcs.ed.ac.uk/archive/os/emas/emas2/compilers/imp80/imp80ps04.txt
//\\ #
//\\ # Since this accepts multiple dialects, I'm tempted to call it "PImp", short for "Polyglot Imp"...
//\\ #
//\\ # There is good info re the phrase structure grammar to be found at
//\\ # http://www.ancientgeek.org.uk/EMAS/EMAS_Manuals/IMP/A_Syntactic_and_Semantic_Definition_of_the_IMP_Language.pdf
//\\ #
//\\ # Built-in Phrases used by the line reconstruction phase:
//\\ #
//\\ # stropped letter (%a %b etc)
//\\ B<stropped> = 0;
//\\ #
//\\ # single-quoted string
//\\ B<sqstring> = 1;
//\\ #
//\\ # double-quoted string
//\\ B<dqstring> = 2;
//\\ #
//\\ B<NL> = 3;
//\\ #
//\\ B<char> = 4;
//\\ #
//\\ # All parsers need an <EOF> phrase.
//\\ #
//\\ B<EOF> = 5;

//\\ C<immediate> = {
//\\ // WARNING: currently parse-time phrases are not being handled properly
//\\ //          by compile(). Are they set to -1 or skipped completely?
//\\ #define INCLUDE_AST_DEBUG "show_imp_ast.c"
//\\ int kw(int AST_op, int idx, int ap)
//\\ {
//\\   int data[4];
//\\ 
//\\   int i;
//\\ 
//\\   char *k = keyword(idx);
//\\ 
//\\   data[1] =  idx;
//\\ 
//\\   data[2] = A[ap+3]; // index of c[] array element
//\\   data[3] = strlen(k);
//\\ 
//\\   return mktuple(AST_op, 1, 3, data);
//\\ 
//\\ }
//\\ // variables used in line_reconstruction() moved here so they are available to semantic code in grammar.
//\\ #define STROPPED_KEYWORDS 1  /* alters behaviour of parse() */
//\\ int at_startofstatement = TRUE;
//\\ 
//\\ int saved = TRUE;
//\\ 
//\\ int at_startofline = TRUE;
//\\ 
//\\ int in_keyword = FALSE;
//\\ 
//\\ int in_alphanumeric = FALSE;
//\\ 
//\\ };

//\\ #
//\\ # We have one semantic phrase in this grammar:
//\\ #
//\\ # OK, this is slightly trickier than you might expect... you can't place the <COLON> immediate code after the ':'
//\\ # because the parser pre-fetches the next token in order to compare against <COLON> even though <COLON> doesn't
//\\ # actually examine any text.  So... we put the test *before* the ':', and *UNDO* its actions in the following
//\\ # alternative if the ':' was not matched.
//\\ #
//\\ # Anyway, the outcome is that if a <COLON> is followed by a '!' comment, that comment is handled by the
//\\ # line reconstruction code and is *not* passed back to the parser a character at a time as it was previously doing!
//\\ #
//\\ # This in turn solves the problem of line reconstruction finding a ' or a " in the comment and gobbling up characters
//\\ # - possibly over multiple line - until it hits a matching quote.  PHEW.  It took a long time to get here!
//\\ #

//\\ P<LABEL-COLON> = 
//\\    <immediate:saved = at_startofstatement; at_startofstatement = TRUE; return TRUE;> ':',
//\\    <immediate:at_startofstatement = saved; return FALSE;>;

case P_LABEL_COLON:
  if (alt == 0)        {
    T[1] = -1; // successful semantic call  
    T[2] = lit(AST__LIT, ':', A[ap+1]);
    T[0] = mktuple(AST_LABEL_COLON, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[1] = -1; // successful semantic call
    T[0] = mktuple(AST_LABEL_COLON, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ ##P<LABEL-COLON> =
//\\ ##   ':';
//\\ # SS is the primary entry point.
//\\ #

//\\ P<SS> = 
//\\    <EXTERNALS> <LAST-ITEMS-IN-FILE>;

case P_SS:
  T[1] = build_ast(A[ap+0], depth+1); // <EXTERNALS>
  T[2] = build_ast(A[ap+1], depth+1); // <LAST-ITEMS-IN-FILE>
  return mktuple(AST_SS, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);


//\\ #
//\\ # I'm taking the long way to handle alphanumerics and variable names, for now
//\\ # At some point (soon) I hope to add regular expression matching, to shorten
//\\ # these rules and speed up parsing.  But this works, quite reliably.
//\\ #
//\\ ## P<letter> = "[A-Z]";
//\\ #

//\\ P<letter> = 
//\\    'A',
//\\    'B',
//\\    'C',
//\\    'D',
//\\    'E',
//\\    'F',
//\\    'G',
//\\    'H',
//\\    'I',
//\\    'J',
//\\    'K',
//\\    'L',
//\\    'M',
//\\    'N',
//\\    'O',
//\\    'P',
//\\    'Q',
//\\    'R',
//\\    'S',
//\\    'T',
//\\    'U',
//\\    'V',
//\\    'W',
//\\    'X',
//\\    'Y',
//\\    'Z';

case P_letter:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, 'A', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, 'B', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, 'C', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 3) {  
    T[1] = lit(AST__LIT, 'D', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 4) {  
    T[1] = lit(AST__LIT, 'E', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 5) {  
    T[1] = lit(AST__LIT, 'F', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*5*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 6) {  
    T[1] = lit(AST__LIT, 'G', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*6*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 7) {  
    T[1] = lit(AST__LIT, 'H', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*7*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 8) {  
    T[1] = lit(AST__LIT, 'I', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*8*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 9) {  
    T[1] = lit(AST__LIT, 'J', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*9*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 10) {  
    T[1] = lit(AST__LIT, 'K', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*10*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 11) {  
    T[1] = lit(AST__LIT, 'L', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*11*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 12) {  
    T[1] = lit(AST__LIT, 'M', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*12*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 13) {  
    T[1] = lit(AST__LIT, 'N', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*13*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 14) {  
    T[1] = lit(AST__LIT, 'O', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*14*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 15) {  
    T[1] = lit(AST__LIT, 'P', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*15*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 16) {  
    T[1] = lit(AST__LIT, 'Q', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*16*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 17) {  
    T[1] = lit(AST__LIT, 'R', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*17*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 18) {  
    T[1] = lit(AST__LIT, 'S', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*18*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 19) {  
    T[1] = lit(AST__LIT, 'T', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*19*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 20) {  
    T[1] = lit(AST__LIT, 'U', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*20*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 21) {  
    T[1] = lit(AST__LIT, 'V', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*21*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 22) {  
    T[1] = lit(AST__LIT, 'W', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*22*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 23) {  
    T[1] = lit(AST__LIT, 'X', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*23*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 24) {  
    T[1] = lit(AST__LIT, 'Y', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*24*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = lit(AST__LIT, 'Z', A[ap+0]);
    T[0] = mktuple(AST_letter, alt /*25*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ ## P<digit> = "[0-9]";
//\\ #

//\\ P<digit> = 
//\\    '0',
//\\    '1',
//\\    '2',
//\\    '3',
//\\    '4',
//\\    '5',
//\\    '6',
//\\    '7',
//\\    '8',
//\\    '9';

case P_digit:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '0', A[ap+0]);
    T[0] = mktuple(AST_digit, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '1', A[ap+0]);
    T[0] = mktuple(AST_digit, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '2', A[ap+0]);
    T[0] = mktuple(AST_digit, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 3) {  
    T[1] = lit(AST__LIT, '3', A[ap+0]);
    T[0] = mktuple(AST_digit, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 4) {  
    T[1] = lit(AST__LIT, '4', A[ap+0]);
    T[0] = mktuple(AST_digit, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 5) {  
    T[1] = lit(AST__LIT, '5', A[ap+0]);
    T[0] = mktuple(AST_digit, alt /*5*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 6) {  
    T[1] = lit(AST__LIT, '6', A[ap+0]);
    T[0] = mktuple(AST_digit, alt /*6*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 7) {  
    T[1] = lit(AST__LIT, '7', A[ap+0]);
    T[0] = mktuple(AST_digit, alt /*7*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 8) {  
    T[1] = lit(AST__LIT, '8', A[ap+0]);
    T[0] = mktuple(AST_digit, alt /*8*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = lit(AST__LIT, '9', A[ap+0]);
    T[0] = mktuple(AST_digit, alt /*9*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<alphanumeric> = 
//\\    <letter>,
//\\    <digit>;

case P_alphanumeric:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <letter>
    T[0] = mktuple(AST_alphanumeric, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <digit>
    T[0] = mktuple(AST_alphanumeric, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<opt-letter-or-digit-seq> = 
//\\    <letter> <opt-letter-or-digit-seq>,
//\\    <digit> <opt-letter-or-digit-seq>,
//\\   ;

case P_opt_letter_or_digit_seq:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <letter>
    T[2] = build_ast(A[ap+1], depth+1); // <opt-letter-or-digit-seq>
    T[0] = mktuple(AST_opt_letter_or_digit_seq, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <digit>
    T[2] = build_ast(A[ap+1], depth+1); // <opt-letter-or-digit-seq>
    T[0] = mktuple(AST_opt_letter_or_digit_seq, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_opt_letter_or_digit_seq, alt /*2*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ #More than one newline (or semicolon)

//\\ P<BLANKS> = 
//\\    <S> <BLANKS>,
//\\   ;

case P_BLANKS:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <S>
    T[2] = build_ast(A[ap+1], depth+1); // <BLANKS>
    T[0] = mktuple(AST_BLANKS, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_BLANKS, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # The last items in a file.
//\\ # the final EOF below is only for begin/endofprogram which *can* be followed by code but shouldn't

//\\ P<LAST-ITEMS-IN-FILE> = 
//\\    "end" "of" "file" <BLANKS> <EOF>,
//\\    "end" "of" "perm" <BLANKS> <EOF>,
//\\    "end" "of" "prim" <BLANKS> <EOF>,
//\\    <BLANKS> <EOF>;

case P_LAST_ITEMS_IN_FILE:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_end, A[ap+0]);  
    T[2] = kw(AST__KW, KW_of, A[ap+1]);  
    T[3] = kw(AST__KW, KW_file, A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <BLANKS>
    T[5] = bip(AST_EOF, A[ap+4]);
    T[0] = mktuple(AST_LAST_ITEMS_IN_FILE, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_end, A[ap+0]);  
    T[2] = kw(AST__KW, KW_of, A[ap+1]);  
    T[3] = kw(AST__KW, KW_perm, A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <BLANKS>
    T[5] = bip(AST_EOF, A[ap+4]);
    T[0] = mktuple(AST_LAST_ITEMS_IN_FILE, alt /*1*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 2) {  
    T[1] = kw(AST__KW, KW_end, A[ap+0]);  
    T[2] = kw(AST__KW, KW_of, A[ap+1]);  
    T[3] = kw(AST__KW, KW_prim, A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <BLANKS>
    T[5] = bip(AST_EOF, A[ap+4]);
    T[0] = mktuple(AST_LAST_ITEMS_IN_FILE, alt /*2*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <BLANKS>
    T[2] = bip(AST_EOF, A[ap+1]);
    T[0] = mktuple(AST_LAST_ITEMS_IN_FILE, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<program> = 
//\\    "programme",
//\\    "program";

case P_program:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_programme, A[ap+0]);
    T[0] = mktuple(AST_program, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_program, A[ap+0]);
    T[0] = mktuple(AST_program, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # I haven't specified any phrases to be external-only.  There might be some,
//\\ # but I'll leave it to compile() to reject them.

//\\ P<EXTERNALS> = 
//\\    <EXTERNAL-OR-INTERNAL> <EXTERNALS>,
//\\   ;

case P_EXTERNALS:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <EXTERNAL-OR-INTERNAL>
    T[2] = build_ast(A[ap+1], depth+1); // <EXTERNALS>
    T[0] = mktuple(AST_EXTERNALS, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_EXTERNALS, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # I cleaned up label handling, we can afford the overhead of backtracking over one <NAME>...
//\\ # - this isn't the 70's any more.  Labels are not valid outside blocks.

//\\ P<INTERNALS> = 
//\\    <OPT-LABEL-DEFINITION> <INTERNAL> <INTERNALS>,
//\\    <OPT-LABEL-DEFINITION>;

case P_INTERNALS:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <OPT-LABEL-DEFINITION>
    T[2] = build_ast(A[ap+1], depth+1); // <INTERNAL>
    T[3] = build_ast(A[ap+2], depth+1); // <INTERNALS>
    T[0] = mktuple(AST_INTERNALS, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <OPT-LABEL-DEFINITION>
    T[0] = mktuple(AST_INTERNALS, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # top-level begin/end block can either be %begin/%endofprogram,
//\\ # or %begin/%end/%endoffile.  However in some cases things can
//\\ # be placed between the %end and the %endoffile.
//\\ #
//\\ # I've also seen %routine xxx/%endofprogram in FMACS/BOOT.imp
//\\ #
//\\ # There's a %begin/%end without an %endoffile in FMACS/FIRST4.imp

//\\ P<outer-level-end> = 
//\\    "end" "of" <program>,
//\\    "end";

case P_outer_level_end:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_end, A[ap+0]);  
    T[2] = kw(AST__KW, KW_of, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <program>
    T[0] = mktuple(AST_outer_level_end, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_end, A[ap+0]);
    T[0] = mktuple(AST_outer_level_end, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # these are allowed at the external level and also inside procedures/main program.
//\\ # The phrases that are internal-only include these as the final alternative,
//\\ # hence why the empty statement can only occur as the last item in this list.
//\\ #
//\\ # If using this grammar as a 'SOAP' replacement, you'll want to allow syntactically
//\\ # incorrect statements also, and if so, those should be handled here after the <S> rule.
//\\ #

//\\ P<EXTERNAL-OR-INTERNAL> = 
//\\    "begin" <S> <INTERNALS> <outer-level-end> <S>,
//\\    <Percent-SEX> <RT> <spec> <NAME> <Opt-ALIAS> <FPP> <S>,
//\\    <Percent-SEX> <RT> <NAME> <Opt-ALIAS> <FPP> <S> <INTERNALS> <outer-level-end> <S>,
//\\    <OPT-68K> <Percent-SEX> <RT> <NAME> <Opt-ALIAS> <FPP> <S>,
//\\    <DECLARATION-S>,
//\\    "record" "format" <RECFMT-spec-OR-BODY> <S>,
//\\    "switch" <NAME> <Opt-NAME-LIST> '(' <EXPR> ':' <EXPR> ')' <REST-OF-SWLIST> <S>,
//\\    "include" <STR-CONST>,
//\\    "option" <STR-CONST>,
//\\    "from" <NAME> "include" <NAME> <Opt-NAME-LIST>,
//\\    "end" "of" "list" <S>,
//\\    "list" <S>,
//\\    "end" "of" "mcode" <S>,
//\\    "mcode" <S>,
//\\    "trusted" "program" <S>,
//\\    "main" "ep" <NAME> <S>,
//\\    "control" <INT-CONST> <S>,
//\\    "diagnose" <INT-CONST> <S>,
//\\    "reals" "long",
//\\    "reals" "normal",
//\\    <COMMENT>,
//\\    <S>;

case P_EXTERNAL_OR_INTERNAL:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_begin, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <S>
    T[3] = build_ast(A[ap+2], depth+1); // <INTERNALS>
    T[4] = build_ast(A[ap+3], depth+1); // <outer-level-end>
    T[5] = build_ast(A[ap+4], depth+1); // <S>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <Percent-SEX>
    T[2] = build_ast(A[ap+1], depth+1); // <RT>
    T[3] = build_ast(A[ap+2], depth+1); // <spec>
    T[4] = build_ast(A[ap+3], depth+1); // <NAME>
    T[5] = build_ast(A[ap+4], depth+1); // <Opt-ALIAS>
    T[6] = build_ast(A[ap+5], depth+1); // <FPP>
    T[7] = build_ast(A[ap+6], depth+1); // <S>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*1*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <Percent-SEX>
    T[2] = build_ast(A[ap+1], depth+1); // <RT>
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-ALIAS>
    T[5] = build_ast(A[ap+4], depth+1); // <FPP>
    T[6] = build_ast(A[ap+5], depth+1); // <S>
    T[7] = build_ast(A[ap+6], depth+1); // <INTERNALS>
    T[8] = build_ast(A[ap+7], depth+1); // <outer-level-end>
    T[9] = build_ast(A[ap+8], depth+1); // <S>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*2*/, /*phrases*/ 9, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9]*/);
  } else if (alt == 3) {
    T[1] = build_ast(A[ap+0], depth+1); // <OPT-68K>
    T[2] = build_ast(A[ap+1], depth+1); // <Percent-SEX>
    T[3] = build_ast(A[ap+2], depth+1); // <RT>
    T[4] = build_ast(A[ap+3], depth+1); // <NAME>
    T[5] = build_ast(A[ap+4], depth+1); // <Opt-ALIAS>
    T[6] = build_ast(A[ap+5], depth+1); // <FPP>
    T[7] = build_ast(A[ap+6], depth+1); // <S>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*3*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else if (alt == 4) {
    T[1] = build_ast(A[ap+0], depth+1); // <DECLARATION-S>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 5) {  
    T[1] = kw(AST__KW, KW_record, A[ap+0]);  
    T[2] = kw(AST__KW, KW_format, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <RECFMT-spec-OR-BODY>
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*5*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 6) {  
    T[1] = kw(AST__KW, KW_switch, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-NAME-LIST>  
    T[4] = lit(AST__LIT, '(', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <EXPR>  
    T[6] = lit(AST__LIT, ':', A[ap+5]);
    T[7] = build_ast(A[ap+6], depth+1); // <EXPR>  
    T[8] = lit(AST__LIT, ')', A[ap+7]);
    T[9] = build_ast(A[ap+8], depth+1); // <REST-OF-SWLIST>
    T[10] = build_ast(A[ap+9], depth+1); // <S>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*6*/, /*phrases*/ 10, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9], T[10]*/);
  } else if (alt == 7) {  
    T[1] = kw(AST__KW, KW_include, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <STR-CONST>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*7*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 8) {  
    T[1] = kw(AST__KW, KW_option, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <STR-CONST>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*8*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 9) {  
    T[1] = kw(AST__KW, KW_from, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>  
    T[3] = kw(AST__KW, KW_include, A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <NAME>
    T[5] = build_ast(A[ap+4], depth+1); // <Opt-NAME-LIST>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*9*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 10) {  
    T[1] = kw(AST__KW, KW_end, A[ap+0]);  
    T[2] = kw(AST__KW, KW_of, A[ap+1]);  
    T[3] = kw(AST__KW, KW_list, A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*10*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 11) {  
    T[1] = kw(AST__KW, KW_list, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <S>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*11*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 12) {  
    T[1] = kw(AST__KW, KW_end, A[ap+0]);  
    T[2] = kw(AST__KW, KW_of, A[ap+1]);  
    T[3] = kw(AST__KW, KW_mcode, A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*12*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 13) {  
    T[1] = kw(AST__KW, KW_mcode, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <S>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*13*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 14) {  
    T[1] = kw(AST__KW, KW_trusted, A[ap+0]);  
    T[2] = kw(AST__KW, KW_program, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*14*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 15) {  
    T[1] = kw(AST__KW, KW_main, A[ap+0]);  
    T[2] = kw(AST__KW, KW_ep, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*15*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 16) {  
    T[1] = kw(AST__KW, KW_control, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <INT-CONST>
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*16*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 17) {  
    T[1] = kw(AST__KW, KW_diagnose, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <INT-CONST>
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*17*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 18) {  
    T[1] = kw(AST__KW, KW_reals, A[ap+0]);  
    T[2] = kw(AST__KW, KW_long, A[ap+1]);
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*18*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 19) {  
    T[1] = kw(AST__KW, KW_reals, A[ap+0]);  
    T[2] = kw(AST__KW, KW_normal, A[ap+1]);
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*19*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 20) {
    T[1] = build_ast(A[ap+0], depth+1); // <COMMENT>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*20*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <S>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*21*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # These are all extensions used by 68000 Imp.
//\\ #
//\\ # %begin
//\\ # %recordformat f(%byte ldte,lsap,rdte,rsap)
//\\ # @@#ldte %record(f)cur
//\\ # ( I have no idea what "@@#ldte " means. )
//\\ #
//\\ # @@400(a5) %record(*)%namearray in(0:7)
//\\ # @@16_3F00-192 %routine         closeinput
//\\ # @@724(a5) %integername heapfront
//\\ #
//\\ # '@@' <68K-code-address> before a routine name is an external spec in 68000 Imp, and
//\\ # <Opt-68K-code-address> after an external %spec is a perm routine spec in 68000 Imp.
//\\ # as in: %integerfnspec(16_1124) REM(%integer a,b)  { found in APM-gdmr/I/GGPERM.imp }
//\\ #

//\\ P<OPT-68K> = 
//\\    '@@' <68K-stuff>,
//\\   ;

case P_OPT_68K:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '@@', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <68K-stuff>
    T[0] = mktuple(AST_OPT_68K, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_OPT_68K, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<68K-stuff> = 
//\\    '-' <INT-CONST> '(' <NAME> ')',
//\\    <INT-CONST> '(' <NAME> ')',
//\\    <INT-CONST> '-' <INT-CONST>,
//\\    <INT-CONST>,
//\\    '#' <NAME>;

case P_68K_stuff:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '-', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <INT-CONST>  
    T[3] = lit(AST__LIT, '(', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <NAME>  
    T[5] = lit(AST__LIT, ')', A[ap+4]);
    T[0] = mktuple(AST_68K_stuff, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <INT-CONST>  
    T[2] = lit(AST__LIT, '(', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>  
    T[4] = lit(AST__LIT, ')', A[ap+3]);
    T[0] = mktuple(AST_68K_stuff, alt /*1*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <INT-CONST>  
    T[2] = lit(AST__LIT, '-', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <INT-CONST>
    T[0] = mktuple(AST_68K_stuff, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 3) {
    T[1] = build_ast(A[ap+0], depth+1); // <INT-CONST>
    T[0] = mktuple(AST_68K_stuff, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = lit(AST__LIT, '#', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[0] = mktuple(AST_68K_stuff, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];



//\\ # this is for 68000 Imp:
//\\ #
//\\ # %externalrealfnspecalias READ %alias "readreal"
//\\ # %externalintegerfnspecalias READ
//\\ # I have no idea what a "specalias" is :-(
//\\ #
//\\ # %integerarrayspec(16_C00000) frame(0:32767)
//\\ # %integerfnspec(16_1124) REM(%integer a,b)
//\\ # %bytespec(16_7fffc)status
//\\ #
//\\ # I think these extensions are also covered with a *different* extension in the same compiler :-(
//\\ # i.e.
//\\ #   @@16_7fffc %byte status  ???
//\\ #

//\\ P<spec> = 
//\\    "specalias",
//\\    "spec" <Opt-68K-code-address>;

case P_spec:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_specalias, A[ap+0]);
    T[0] = mktuple(AST_spec, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_spec, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-68K-code-address>
    T[0] = mktuple(AST_spec, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<Opt-68K-code-address> = 
//\\    '(' <INT-CONST> ')',
//\\   ;

case P_Opt_68K_code_address:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '(', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <INT-CONST>  
    T[3] = lit(AST__LIT, ')', A[ap+2]);
    T[0] = mktuple(AST_Opt_68K_code_address, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_Opt_68K_code_address, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<OPT-spec> = 
//\\    <spec>,
//\\   ;

case P_OPT_spec:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <spec>
    T[0] = mktuple(AST_OPT_spec, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_OPT_spec, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # All labels come through here.  Because of an interaction with comments,
//\\ # we use some parse-time code in phrase <LABEL-COLON> to modify how line reconstruction
//\\ # handles the comments.  btw Numeric labels are a historical form...

//\\ P<OPT-LABEL-DEFINITION> = 
//\\    <NAME> '(' <CEXPR> ')' <LABEL-COLON> <OPT-LABEL-DEFINITION>,
//\\    <NAME> '(' '*' ')' <LABEL-COLON> <OPT-LABEL-DEFINITION>,
//\\    <NAME> <LABEL-COLON> <OPT-LABEL-DEFINITION>,
//\\    <DIGIT-SEQ> <LABEL-COLON> <OPT-LABEL-DEFINITION>,
//\\   ;

case P_OPT_LABEL_DEFINITION:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>  
    T[2] = lit(AST__LIT, '(', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <CEXPR>  
    T[4] = lit(AST__LIT, ')', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <LABEL-COLON>
    T[6] = build_ast(A[ap+5], depth+1); // <OPT-LABEL-DEFINITION>
    T[0] = mktuple(AST_OPT_LABEL_DEFINITION, alt /*0*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>  
    T[2] = lit(AST__LIT, '(', A[ap+1]);  
    T[3] = lit(AST__LIT, '*', A[ap+2]);  
    T[4] = lit(AST__LIT, ')', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <LABEL-COLON>
    T[6] = build_ast(A[ap+5], depth+1); // <OPT-LABEL-DEFINITION>
    T[0] = mktuple(AST_OPT_LABEL_DEFINITION, alt /*1*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>
    T[2] = build_ast(A[ap+1], depth+1); // <LABEL-COLON>
    T[3] = build_ast(A[ap+2], depth+1); // <OPT-LABEL-DEFINITION>
    T[0] = mktuple(AST_OPT_LABEL_DEFINITION, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 3) {
    T[1] = build_ast(A[ap+0], depth+1); // <DIGIT-SEQ>
    T[2] = build_ast(A[ap+1], depth+1); // <LABEL-COLON>
    T[3] = build_ast(A[ap+2], depth+1); // <OPT-LABEL-DEFINITION>
    T[0] = mktuple(AST_OPT_LABEL_DEFINITION, alt /*3*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_OPT_LABEL_DEFINITION, alt /*4*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # fault statements can only appear in the outer block of a program;
//\\ # they cannot appear in external routines.  This should be checked
//\\ # by the compile() procedure.

//\\ P<FAULT-S> = 
//\\    "fault" <FAULT-ACTION> <MORE-FAULTS> <S>;

case P_FAULT_S:
  T[1] = kw(AST__KW, KW_fault, A[ap+0]);
  T[2] = build_ast(A[ap+1], depth+1); // <FAULT-ACTION>
  T[3] = build_ast(A[ap+2], depth+1); // <MORE-FAULTS>
  T[4] = build_ast(A[ap+3], depth+1); // <S>
  return mktuple(AST_FAULT_S, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);



//\\ P<FAULT-LIST> = 
//\\    <DIGIT-SEQ> <MORE-NUMBERS>;

case P_FAULT_LIST:
  T[1] = build_ast(A[ap+0], depth+1); // <DIGIT-SEQ>
  T[2] = build_ast(A[ap+1], depth+1); // <MORE-NUMBERS>
  return mktuple(AST_FAULT_LIST, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<MORE-NUMBERS> = 
//\\    ',' <DIGIT-SEQ> <MORE-NUMBERS>,
//\\   ;

case P_MORE_NUMBERS:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <DIGIT-SEQ>
    T[3] = build_ast(A[ap+2], depth+1); // <MORE-NUMBERS>
    T[0] = mktuple(AST_MORE_NUMBERS, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_MORE_NUMBERS, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<FAULT-ACTION> = 
//\\    <FAULT-LIST> '-' '>' <LABEL>;

case P_FAULT_ACTION:
  T[1] = build_ast(A[ap+0], depth+1); // <FAULT-LIST>
  T[2] = lit(AST__LIT, '-', A[ap+1]);
  T[3] = lit(AST__LIT, '>', A[ap+2]);
  T[4] = build_ast(A[ap+3], depth+1); // <LABEL>
  return mktuple(AST_FAULT_ACTION, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);



//\\ P<MORE-FAULTS> = 
//\\    ',' <FAULT-ACTION> <MORE-FAULTS>,
//\\   ;

case P_MORE_FAULTS:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <FAULT-ACTION>
    T[3] = build_ast(A[ap+2], depth+1); // <MORE-FAULTS>
    T[0] = mktuple(AST_MORE_FAULTS, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_MORE_FAULTS, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # The "spec" form below is for old EMAS Imp procedure parameters:
//\\ #
//\\ # %routine integrate(%realname y, %real a,b, %integer n, %c
//\\ #                    %realfn f)
//\\ #   %spec f(%real x)
//\\ #
//\\ # the fully-qualified form (%realfnspec f(%real x)) is also valid but comes in via the <EXTERNAL> route.
//\\ #
//\\ # There are other types of %spec related to parameters to procedures as well -
//\\ # %recordspec for sure.  Not so sure if there is an arrayspec.
//\\ # They are only allowed in the body of a procedure.
//\\ #
//\\ # (Btw in the older compilers, all declarations in a block had to precede any code.)
//\\ #
//\\ # strictly speaking the <UI> <REST-OF-SS1> form, <UI> "while" <SC>, should only
//\\ # allow a single <UI>, not the <UI> <AUI> form. (EMAS Imp)
//\\ # (page 4.4 of https://history.dcs.ed.ac.uk/archive/docs/Edinburgh_IMP_Language_Manual.pdf )

//\\ P<INTERNAL> = 
//\\    <NESTED-BLOCK>,
//\\    <UI> <REST-OF-SS1>,
//\\    '*' <UCI>,
//\\    <CYCLE-S>,
//\\    <IF-S>,
//\\    <FAULT-S>,
//\\    "on" <OPT-event> <EVENT-LIST> <REST-OF-NAME-LIST> "start" <S> <INTERNALS> "finish" <S>,
//\\    "spec" <NAME> <FPP> <S>,
//\\    <EXTERNAL-OR-INTERNAL>;

case P_INTERNAL:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <NESTED-BLOCK>
    T[0] = mktuple(AST_INTERNAL, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <UI>
    T[2] = build_ast(A[ap+1], depth+1); // <REST-OF-SS1>
    T[0] = mktuple(AST_INTERNAL, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '*', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <UCI>
    T[0] = mktuple(AST_INTERNAL, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 3) {
    T[1] = build_ast(A[ap+0], depth+1); // <CYCLE-S>
    T[0] = mktuple(AST_INTERNAL, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 4) {
    T[1] = build_ast(A[ap+0], depth+1); // <IF-S>
    T[0] = mktuple(AST_INTERNAL, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 5) {
    T[1] = build_ast(A[ap+0], depth+1); // <FAULT-S>
    T[0] = mktuple(AST_INTERNAL, alt /*5*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 6) {  
    T[1] = kw(AST__KW, KW_on, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-event>
    T[3] = build_ast(A[ap+2], depth+1); // <EVENT-LIST>
    T[4] = build_ast(A[ap+3], depth+1); // <REST-OF-NAME-LIST>  
    T[5] = kw(AST__KW, KW_start, A[ap+4]);
    T[6] = build_ast(A[ap+5], depth+1); // <S>
    T[7] = build_ast(A[ap+6], depth+1); // <INTERNALS>  
    T[8] = kw(AST__KW, KW_finish, A[ap+7]);
    T[9] = build_ast(A[ap+8], depth+1); // <S>
    T[0] = mktuple(AST_INTERNAL, alt /*6*/, /*phrases*/ 9, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9]*/);
  } else if (alt == 7) {  
    T[1] = kw(AST__KW, KW_spec, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <FPP>
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[0] = mktuple(AST_INTERNAL, alt /*7*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <EXTERNAL-OR-INTERNAL>
    T[0] = mktuple(AST_INTERNAL, alt /*8*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # unlike with old-style parsers, the whole of the block content ends up in an AST item.
//\\ #
//\\ # Unfortunately there is a problem caused by 68000 Imp: some files contain only
//\\ # begin/end with no endoffile.  Some are begin/end;endoffile instead of begin/endofprogram
//\\ # A few are routine blah/endofprogram !
//\\ # One had begin/endofprogram followed by more routines.
//\\ # (and see elsewhere for 68000's external routine specs which are of the form
//\\ #   @@address %routine blah
//\\ #  - with no %spec keyword, but no routine body either..)
//\\ #

//\\ P<NESTED-BLOCK> = 
//\\    "begin" <S> <INTERNALS> "end" <S>;

case P_NESTED_BLOCK:
  T[1] = kw(AST__KW, KW_begin, A[ap+0]);
  T[2] = build_ast(A[ap+1], depth+1); // <S>
  T[3] = build_ast(A[ap+2], depth+1); // <INTERNALS>
  T[4] = kw(AST__KW, KW_end, A[ap+3]);
  T[5] = build_ast(A[ap+4], depth+1); // <S>
  return mktuple(AST_NESTED_BLOCK, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);


//\\ # compound statements - blah %and blah %and blah - a short form of startfinish block

//\\ P<AUI> = 
//\\    "and" <UI>,
//\\   ;

case P_AUI:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_and, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <UI>
    T[0] = mktuple(AST_AUI, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_AUI, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<OPT-ASSIGN> = 
//\\    '-' '>' <STRING-RESOLUTION-EXPR>,
//\\    <ASSOP> <EXPR>,
//\\   ;

case P_OPT_ASSIGN:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '-', A[ap+0]);  
    T[2] = lit(AST__LIT, '>', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <STRING-RESOLUTION-EXPR>
    T[0] = mktuple(AST_OPT_ASSIGN, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <ASSOP>
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>
    T[0] = mktuple(AST_OPT_ASSIGN, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_OPT_ASSIGN, alt /*2*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # the compound statement form ends in UIs which change control flow, ie
//\\ # you cannot say: %if whatever %then blah %and ->lab %and this will never happen
//\\ # tempted to add %caption here ;-)  But that may be a step too far.
//\\ # "%monitor 9" would be trapped by "%fault 9 -> lab"

//\\ P<UI> = 
//\\    <NAME> <Opt-PARAMETERS-OR-POINTERINDEX> <Opt-RECORDFIELD> <OPT-ASSIGN> <AUI>,
//\\    "print" "text" <sqstring> <AUI>,
//\\    '-' '>' <LABEL>,
//\\    "return",
//\\    "true",
//\\    "false",
//\\    "result" <ASSOP> <EXPR>,
//\\    "monitorstop",
//\\    "monitor" <DIGIT-SEQ> <AUI>,
//\\    "monitor" <AUI>,
//\\    "stop",
//\\    "signal" <OPT-event> <CEXPR> <OPEXPR2>,
//\\    "exit",
//\\    "continue";

case P_UI:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-PARAMETERS-OR-POINTERINDEX>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-RECORDFIELD>
    T[4] = build_ast(A[ap+3], depth+1); // <OPT-ASSIGN>
    T[5] = build_ast(A[ap+4], depth+1); // <AUI>
    T[0] = mktuple(AST_UI, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_print, A[ap+0]);  
    T[2] = kw(AST__KW, KW_text, A[ap+1]);
    T[3] = bip(AST_sqstring, A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <AUI>
    T[0] = mktuple(AST_UI, alt /*1*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '-', A[ap+0]);  
    T[2] = lit(AST__LIT, '>', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <LABEL>
    T[0] = mktuple(AST_UI, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 3) {  
    T[1] = kw(AST__KW, KW_return, A[ap+0]);
    T[0] = mktuple(AST_UI, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 4) {  
    T[1] = kw(AST__KW, KW_true, A[ap+0]);
    T[0] = mktuple(AST_UI, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 5) {  
    T[1] = kw(AST__KW, KW_false, A[ap+0]);
    T[0] = mktuple(AST_UI, alt /*5*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 6) {  
    T[1] = kw(AST__KW, KW_result, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <ASSOP>
    T[3] = build_ast(A[ap+2], depth+1); // <EXPR>
    T[0] = mktuple(AST_UI, alt /*6*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 7) {  
    T[1] = kw(AST__KW, KW_monitorstop, A[ap+0]);
    T[0] = mktuple(AST_UI, alt /*7*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 8) {  
    T[1] = kw(AST__KW, KW_monitor, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <DIGIT-SEQ>
    T[3] = build_ast(A[ap+2], depth+1); // <AUI>
    T[0] = mktuple(AST_UI, alt /*8*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 9) {  
    T[1] = kw(AST__KW, KW_monitor, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <AUI>
    T[0] = mktuple(AST_UI, alt /*9*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 10) {  
    T[1] = kw(AST__KW, KW_stop, A[ap+0]);
    T[0] = mktuple(AST_UI, alt /*10*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 11) {  
    T[1] = kw(AST__KW, KW_signal, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-event>
    T[3] = build_ast(A[ap+2], depth+1); // <CEXPR>
    T[4] = build_ast(A[ap+3], depth+1); // <OPEXPR2>
    T[0] = mktuple(AST_UI, alt /*11*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 12) {  
    T[1] = kw(AST__KW, KW_exit, A[ap+0]);
    T[0] = mktuple(AST_UI, alt /*12*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_continue, A[ap+0]);
    T[0] = mktuple(AST_UI, alt /*13*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<LABEL> = 
//\\    <NAME> '(' <EXPR> ')',
//\\    <NAME>,
//\\    <DIGIT-SEQ>;

case P_LABEL:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>  
    T[2] = lit(AST__LIT, '(', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <EXPR>  
    T[4] = lit(AST__LIT, ')', A[ap+3]);
    T[0] = mktuple(AST_LABEL, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>
    T[0] = mktuple(AST_LABEL, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <DIGIT-SEQ>
    T[0] = mktuple(AST_LABEL, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # prim and perm added by gt

//\\ P<FILE-END-TYPE> = 
//\\    "file",
//\\    "prim",
//\\    "perm";

case P_FILE_END_TYPE:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_file, A[ap+0]);
    T[0] = mktuple(AST_FILE_END_TYPE, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_prim, A[ap+0]);
    T[0] = mktuple(AST_FILE_END_TYPE, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_perm, A[ap+0]);
    T[0] = mktuple(AST_FILE_END_TYPE, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # I added an old record declaration syntax for examples out of ai2logo.i
//\\ #
//\\ # %OWNRECORDARRAY INDEX42( 0:1022)           (PIC DIR)
//\\ #
//\\ # %SYSTEMROUTINESPEC FINFO(%STRING(15) S,%INTEGER LEV,%C
//\\ #    %RECORDNAME R, %INTEGERNAME FLAG)
//\\ #
//\\ # %RECORD R(F)
//\\ #
//\\ # I'm not sure where/if this is handled:
//\\ #
//\\ # %record(f)%array portinfo(1:31)
//\\ #
//\\ # I need to get the old Imp manuals out and check a couple of things, in particular
//\\ #   %recordformatspec and %arrayformatspec ...
//\\ #
//\\ # The grammar below allows some initialisations that the compilers don't support
//\\ # but it's cleaner to reject them in compile()
//\\ #
//\\ # I had to add initialisations with pointers for these examples from
//\\ # 68000 Imp: %bytename b == length(s)
//\\ # %ownrecord(i tc f)%namearray tc refs(1:maxtc) == nil(*)
//\\ #
//\\ # These are 68000 syntax which is rejected by Imp77:
//\\ # %conststring(1) %array(1:max params) parameters="B","W","L"
//\\ # %string(255) %array(0:maxfiles) list
//\\ #
//\\ # The equivalent Imp77 syntax would be
//\\ #
//\\ # %conststring(1) %array parameters(1:max params)="B","W","L"
//\\ # %string(255) %array list(0:maxfiles)
//\\ #
//\\ # Finally here's a one-off hack for a construct I've only seen *once*
//\\ # in APM-gdmr/I/PRIM22.imp ...
//\\ # %constchar                    snl=char<10>
//\\ #

//\\ P<DECLARATION-S> = 
//\\    <OPT-68K> <XOWN> <XTYPE> <OWNDEC> <S>,
//\\    <OPT-68K> <XTYPE> <DECLN> <S>,
//\\    <OPT-68K> <OPT-XOWN> "record" "array" <RADEC> <REST-OF-RADEC> <S>,
//\\    <OPT-68K> <OPT-XOWN> "record" <RDEC> <REST-OF-RDEC> <S>,
//\\    "const" "char" <NAME> '=' 'C' 'H' 'A' 'R' '<' <INT-CONST> '>' <S>;

case P_DECLARATION_S:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <OPT-68K>
    T[2] = build_ast(A[ap+1], depth+1); // <XOWN>
    T[3] = build_ast(A[ap+2], depth+1); // <XTYPE>
    T[4] = build_ast(A[ap+3], depth+1); // <OWNDEC>
    T[5] = build_ast(A[ap+4], depth+1); // <S>
    T[0] = mktuple(AST_DECLARATION_S, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <OPT-68K>
    T[2] = build_ast(A[ap+1], depth+1); // <XTYPE>
    T[3] = build_ast(A[ap+2], depth+1); // <DECLN>
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[0] = mktuple(AST_DECLARATION_S, alt /*1*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <OPT-68K>
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-XOWN>  
    T[3] = kw(AST__KW, KW_record, A[ap+2]);  
    T[4] = kw(AST__KW, KW_array, A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <RADEC>
    T[6] = build_ast(A[ap+5], depth+1); // <REST-OF-RADEC>
    T[7] = build_ast(A[ap+6], depth+1); // <S>
    T[0] = mktuple(AST_DECLARATION_S, alt /*2*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else if (alt == 3) {
    T[1] = build_ast(A[ap+0], depth+1); // <OPT-68K>
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-XOWN>  
    T[3] = kw(AST__KW, KW_record, A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <RDEC>
    T[5] = build_ast(A[ap+4], depth+1); // <REST-OF-RDEC>
    T[6] = build_ast(A[ap+5], depth+1); // <S>
    T[0] = mktuple(AST_DECLARATION_S, alt /*3*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_const, A[ap+0]);  
    T[2] = kw(AST__KW, KW_char, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>  
    T[4] = lit(AST__LIT, '=', A[ap+3]);  
    T[5] = lit(AST__LIT, 'C', A[ap+4]);  
    T[6] = lit(AST__LIT, 'H', A[ap+5]);  
    T[7] = lit(AST__LIT, 'A', A[ap+6]);  
    T[8] = lit(AST__LIT, 'R', A[ap+7]);  
    T[9] = lit(AST__LIT, '<', A[ap+8]);
    T[10] = build_ast(A[ap+9], depth+1); // <INT-CONST>  
    T[11] = lit(AST__LIT, '>', A[ap+10]);
    T[12] = build_ast(A[ap+11], depth+1); // <S>
    T[0] = mktuple(AST_DECLARATION_S, alt /*4*/, /*phrases*/ 12, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9], T[10], T[11], T[12]*/);
  }
  return T[0];




//\\ P<OPT-XOWN> = 
//\\    <XOWN>,
//\\   ;

case P_OPT_XOWN:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <XOWN>
    T[0] = mktuple(AST_OPT_XOWN, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_OPT_XOWN, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # old-style record array declaration

//\\ P<RADEC> = 
//\\    <NAME> <Opt-NAME-LIST> <BPAIR> '(' <RECFMT-REF> ')';

case P_RADEC:
  T[1] = build_ast(A[ap+0], depth+1); // <NAME>
  T[2] = build_ast(A[ap+1], depth+1); // <Opt-NAME-LIST>
  T[3] = build_ast(A[ap+2], depth+1); // <BPAIR>
  T[4] = lit(AST__LIT, '(', A[ap+3]);
  T[5] = build_ast(A[ap+4], depth+1); // <RECFMT-REF>
  T[6] = lit(AST__LIT, ')', A[ap+5]);
  return mktuple(AST_RADEC, alt /*0*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);



//\\ P<REST-OF-RADEC> = 
//\\    ',' <RADEC>,
//\\   ;

case P_REST_OF_RADEC:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <RADEC>
    T[0] = mktuple(AST_REST_OF_RADEC, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_RADEC, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # old-style record declaration

//\\ P<RDEC> = 
//\\    <NAME> <Opt-NAME-LIST> '(' <RECFMT-REF> ')';

case P_RDEC:
  T[1] = build_ast(A[ap+0], depth+1); // <NAME>
  T[2] = build_ast(A[ap+1], depth+1); // <Opt-NAME-LIST>
  T[3] = lit(AST__LIT, '(', A[ap+2]);
  T[4] = build_ast(A[ap+3], depth+1); // <RECFMT-REF>
  T[5] = lit(AST__LIT, ')', A[ap+4]);
  return mktuple(AST_RDEC, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);



//\\ P<REST-OF-RDEC> = 
//\\    ',' <RDEC> <REST-OF-RDEC>,
//\\   ;

case P_REST_OF_RDEC:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <RDEC>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-RDEC>
    T[0] = mktuple(AST_REST_OF_RDEC, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_RDEC, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # %on %event * %start or %on %event 1,2,3,etc %start

//\\ P<EVENT-LIST> = 
//\\    '*',
//\\    <CEXPR>;

case P_EVENT_LIST:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '*', A[ap+0]);
    T[0] = mktuple(AST_EVENT_LIST, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <CEXPR>
    T[0] = mktuple(AST_EVENT_LIST, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # Added old-style while/until for: %UNTIL NEXTINSYM=NL %THEN %CYCLE
//\\ # and %WHILE NEXTINSYM#NL %THEN SKIPINSYM

//\\ P<CYCLE-S> = 
//\\    "cycle" <Opt-CYCPARM> <S> <INTERNALS> "repeat" <Opt-UNTIL> <S>,
//\\    <Percent-WUF> "cycle" <S> <INTERNALS> "repeat" <Opt-UNTIL> <S>,
//\\    <Percent-WU> "then" "cycle" <S> <INTERNALS> "repeat" <Opt-UNTIL> <S>,
//\\    <Percent-WU> "then" <UI>;

case P_CYCLE_S:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_cycle, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-CYCPARM>
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[4] = build_ast(A[ap+3], depth+1); // <INTERNALS>  
    T[5] = kw(AST__KW, KW_repeat, A[ap+4]);
    T[6] = build_ast(A[ap+5], depth+1); // <Opt-UNTIL>
    T[7] = build_ast(A[ap+6], depth+1); // <S>
    T[0] = mktuple(AST_CYCLE_S, alt /*0*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <Percent-WUF>  
    T[2] = kw(AST__KW, KW_cycle, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[4] = build_ast(A[ap+3], depth+1); // <INTERNALS>  
    T[5] = kw(AST__KW, KW_repeat, A[ap+4]);
    T[6] = build_ast(A[ap+5], depth+1); // <Opt-UNTIL>
    T[7] = build_ast(A[ap+6], depth+1); // <S>
    T[0] = mktuple(AST_CYCLE_S, alt /*1*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <Percent-WU>  
    T[2] = kw(AST__KW, KW_then, A[ap+1]);  
    T[3] = kw(AST__KW, KW_cycle, A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[5] = build_ast(A[ap+4], depth+1); // <INTERNALS>  
    T[6] = kw(AST__KW, KW_repeat, A[ap+5]);
    T[7] = build_ast(A[ap+6], depth+1); // <Opt-UNTIL>
    T[8] = build_ast(A[ap+7], depth+1); // <S>
    T[0] = mktuple(AST_CYCLE_S, alt /*2*/, /*phrases*/ 8, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <Percent-WU>  
    T[2] = kw(AST__KW, KW_then, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <UI>
    T[0] = mktuple(AST_CYCLE_S, alt /*3*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  }
  return T[0];




//\\ P<IF-S> = 
//\\    <Percent-IU> <CONDITION> <THEN-S>;

case P_IF_S:
  T[1] = build_ast(A[ap+0], depth+1); // <Percent-IU>
  T[2] = build_ast(A[ap+1], depth+1); // <CONDITION>
  T[3] = build_ast(A[ap+2], depth+1); // <THEN-S>
  return mktuple(AST_IF_S, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);


//\\ # /home/gtoal/gtoal.com/athome/edinburgh/APM-gdmr/I/LIB.imp
//\\ # contains:
//\\ #          %elseif 'A'<=sym<='Z' %start
//\\ #
//\\ # which is a form of Hamish's that is equivalent to
//\\ #
//\\ #  %finish %else %if 'A'<=sym<='Z' %start
//\\ #
//\\ # or the more concise
//\\ #
//\\ #  %else %if 'A'<=sym<='Z'
//\\ #
//\\ # An identical issue is: %elsestart
//\\ # in APM-gdmr/ETHER/PROFILE.imp
//\\ #

//\\ P<FINISH-S> = 
//\\    "else" <Percent-IU> <CONDITION> <Opt-start> <S> <INTERNALS> <FINISH-S>,
//\\    "else" <Opt-start> <S> <INTERNALS> "finish" <S>,
//\\    "finish" <Opt-ELSE-S>;

case P_FINISH_S:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_else, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Percent-IU>
    T[3] = build_ast(A[ap+2], depth+1); // <CONDITION>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-start>
    T[5] = build_ast(A[ap+4], depth+1); // <S>
    T[6] = build_ast(A[ap+5], depth+1); // <INTERNALS>
    T[7] = build_ast(A[ap+6], depth+1); // <FINISH-S>
    T[0] = mktuple(AST_FINISH_S, alt /*0*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_else, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-start>
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[4] = build_ast(A[ap+3], depth+1); // <INTERNALS>  
    T[5] = kw(AST__KW, KW_finish, A[ap+4]);
    T[6] = build_ast(A[ap+5], depth+1); // <S>
    T[0] = mktuple(AST_FINISH_S, alt /*1*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_finish, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-ELSE-S>
    T[0] = mktuple(AST_FINISH_S, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<Opt-start> = 
//\\    "start",
//\\   ;

case P_Opt_start:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_start, A[ap+0]);
    T[0] = mktuple(AST_Opt_start, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_Opt_start, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # see the comments on <FINISH-S> above.

//\\ P<Opt-ELSE-S> = 
//\\    "else" "start" <S> <INTERNALS> "finish" <S>,
//\\    "else" <IF-S>,
//\\    "else" <UI> <S>,
//\\    <S>;

case P_Opt_ELSE_S:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_else, A[ap+0]);  
    T[2] = kw(AST__KW, KW_start, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[4] = build_ast(A[ap+3], depth+1); // <INTERNALS>  
    T[5] = kw(AST__KW, KW_finish, A[ap+4]);
    T[6] = build_ast(A[ap+5], depth+1); // <S>
    T[0] = mktuple(AST_Opt_ELSE_S, alt /*0*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_else, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <IF-S>
    T[0] = mktuple(AST_Opt_ELSE_S, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 2) {  
    T[1] = kw(AST__KW, KW_else, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <UI>
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[0] = mktuple(AST_Opt_ELSE_S, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <S>
    T[0] = mktuple(AST_Opt_ELSE_S, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<THEN-S> = 
//\\    <OPT-then> "start" <S> <INTERNALS> <FINISH-S>,
//\\    "then" <UI> <Opt-ELSE-S>;

case P_THEN_S:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <OPT-then>  
    T[2] = kw(AST__KW, KW_start, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[4] = build_ast(A[ap+3], depth+1); // <INTERNALS>
    T[5] = build_ast(A[ap+4], depth+1); // <FINISH-S>
    T[0] = mktuple(AST_THEN_S, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_then, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <UI>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-ELSE-S>
    T[0] = mktuple(AST_THEN_S, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  }
  return T[0];




//\\ P<OPT-then> = 
//\\    "then",
//\\   ;

case P_OPT_then:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_then, A[ap+0]);
    T[0] = mktuple(AST_OPT_then, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_OPT_then, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<OPT-start> = 
//\\    "start",
//\\   ;

case P_OPT_start:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_start, A[ap+0]);
    T[0] = mktuple(AST_OPT_start, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_OPT_start, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<S> = 
//\\    <NL>,
//\\    ';';

case P_S:
  if (alt == 0)        {
    T[1] = bip(AST_NL, A[ap+0]);
    T[0] = mktuple(AST_S, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = lit(AST__LIT, ';', A[ap+0]);
    T[0] = mktuple(AST_S, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # Most comments are handled in the line reconstruction phase.
//\\ # Comments starting with %COMMENT are an exception.
//\\ # Some older compilers treated '!' comments like %COMMENT,
//\\ # with "%c" at the end of a comment causing continuation!
//\\ # This phrase does not allow ';' in a comment to terminate
//\\ # the comment, but some versions of Imp (I think PDP15)
//\\ # did, so that will have to be handled with a command-line
//\\ # option and a parse-time phrase if it ever is needed.
//\\ #

//\\ P<COMMENT> = 
//\\    "comment" <Parsed-OldStyle-Comment>,
//\\    '!' <Parsed-OldStyle-Comment>;

case P_COMMENT:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_comment, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Parsed-OldStyle-Comment>
    T[0] = mktuple(AST_COMMENT, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {  
    T[1] = lit(AST__LIT, '!', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Parsed-OldStyle-Comment>
    T[0] = mktuple(AST_COMMENT, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<Parsed-OldStyle-Comment> = 
//\\    <char> <Parsed-OldStyle-Comment>,
//\\    <dqstring> <Parsed-OldStyle-Comment>,
//\\    <sqstring> <Parsed-OldStyle-Comment>,
//\\    <letter> <Parsed-OldStyle-Comment>,
//\\    <digit> <Parsed-OldStyle-Comment>,
//\\    <stropped> <Parsed-OldStyle-Comment>,
//\\    <NL>;

case P_Parsed_OldStyle_Comment:
  if (alt == 0)        {
    T[1] = bip(AST_char, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Parsed-OldStyle-Comment>
    T[0] = mktuple(AST_Parsed_OldStyle_Comment, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {
    T[1] = bip(AST_dqstring, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Parsed-OldStyle-Comment>
    T[0] = mktuple(AST_Parsed_OldStyle_Comment, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 2) {
    T[1] = bip(AST_sqstring, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Parsed-OldStyle-Comment>
    T[0] = mktuple(AST_Parsed_OldStyle_Comment, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 3) {
    T[1] = build_ast(A[ap+0], depth+1); // <letter>
    T[2] = build_ast(A[ap+1], depth+1); // <Parsed-OldStyle-Comment>
    T[0] = mktuple(AST_Parsed_OldStyle_Comment, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 4) {
    T[1] = build_ast(A[ap+0], depth+1); // <digit>
    T[2] = build_ast(A[ap+1], depth+1); // <Parsed-OldStyle-Comment>
    T[0] = mktuple(AST_Parsed_OldStyle_Comment, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 5) {
    T[1] = bip(AST_stropped, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Parsed-OldStyle-Comment>
    T[0] = mktuple(AST_Parsed_OldStyle_Comment, alt /*5*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[1] = bip(AST_NL, A[ap+0]);
    T[0] = mktuple(AST_Parsed_OldStyle_Comment, alt /*6*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<NL-or-SEMI> = 
//\\    <NL>,
//\\    <semi>;

case P_NL_or_SEMI:
  if (alt == 0)        {
    T[1] = bip(AST_NL, A[ap+0]);
    T[0] = mktuple(AST_NL_or_SEMI, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <semi>
    T[0] = mktuple(AST_NL_or_SEMI, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<semi> = 
//\\    ';';

case P_semi:
  T[1] = lit(AST__LIT, ';', A[ap+0]);
  return mktuple(AST_semi, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);


//\\ # <DIGIT-SEQ> '_' <DIGIT-SEQ>, and  <DIGIT-SEQ> '_' <NAME>, added by gt
//\\ # <NAME> <sqstring> is really X'....' but type checking stops me matching 'X'
//\\ # VERY hacky stopgap just to get stuff to parse. Needs proper syntax
//\\ # which needs the ability to recognise individual digits and letters
//\\ # rather than the current typed 'alphanumeric' hack in line_reconstruction ...
//\\ # Doesn't handle %real well, and indeed not at all if containing an '@@' sign.
//\\ # E"ebcdic" etc also not handled.  Hamish's 40_XXX comes in here.
//\\ #
//\\ ## P<basedconst> =  "[0-9][0-9]*_[0-9A-Z][0-9A-Z]*"
//\\ #

//\\ P<INT-CONST> = 
//\\    <DIGIT-SEQ> '_' <alphanumeric-SEQ>,
//\\    <DIGIT-SEQ>,
//\\    <OLDSTYLE-BASE>;

case P_INT_CONST:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <DIGIT-SEQ>  
    T[2] = lit(AST__LIT, '_', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <alphanumeric-SEQ>
    T[0] = mktuple(AST_INT_CONST, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <DIGIT-SEQ>
    T[0] = mktuple(AST_INT_CONST, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <OLDSTYLE-BASE>
    T[0] = mktuple(AST_INT_CONST, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<alphanumeric-SEQ> = 
//\\    <alphanumeric> <Opt-alphanumeric-SEQ>;

case P_alphanumeric_SEQ:
  T[1] = build_ast(A[ap+0], depth+1); // <alphanumeric>
  T[2] = build_ast(A[ap+1], depth+1); // <Opt-alphanumeric-SEQ>
  return mktuple(AST_alphanumeric_SEQ, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<Opt-alphanumeric-SEQ> = 
//\\    <alphanumeric> <Opt-alphanumeric-SEQ>,
//\\   ;

case P_Opt_alphanumeric_SEQ:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <alphanumeric>
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-alphanumeric-SEQ>
    T[0] = mktuple(AST_Opt_alphanumeric_SEQ, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_Opt_alphanumeric_SEQ, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<STR-CONST> = 
//\\    <OPT-DQ-LETTER> <dqstring>,
//\\    <sqstring>;

case P_STR_CONST:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <OPT-DQ-LETTER>
    T[2] = bip(AST_dqstring, A[ap+1]);
    T[0] = mktuple(AST_STR_CONST, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[1] = bip(AST_sqstring, A[ap+0]);
    T[0] = mktuple(AST_STR_CONST, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # current line reconstruction doesn't support this. Letters come through as part of <alphanumeric>s.

//\\ P<OPT-DQ-LETTER> = 
//\\    'E',
//\\   ;

case P_OPT_DQ_LETTER:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, 'E', A[ap+0]);
    T[0] = mktuple(AST_OPT_DQ_LETTER, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_OPT_DQ_LETTER, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<NUMERIC-CONST> = 
//\\    <INT-CONST>,
//\\    <REAL-CONST>;

case P_NUMERIC_CONST:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <INT-CONST>
    T[0] = mktuple(AST_NUMERIC_CONST, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <REAL-CONST>
    T[0] = mktuple(AST_NUMERIC_CONST, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # <CONST> is somewhat generic and should be replaced with the more specific version when possible

//\\ P<CONST> = 
//\\    <INT-CONST>,
//\\    <REAL-CONST>,
//\\    <STR-CONST>;

case P_CONST:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <INT-CONST>
    T[0] = mktuple(AST_CONST, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <REAL-CONST>
    T[0] = mktuple(AST_CONST, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <STR-CONST>
    T[0] = mktuple(AST_CONST, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # <sqstring> has to be checked for length and content depending on prefix.
//\\ #
//\\ ## P<lettercharconst> = <squote> <schar> <squote> |
//\\ ##   "[RHX]" <squote> <hexchars> <squote> |
//\\ ##   "B" <squote> <binchars> <squote> |
//\\ ##   "K" <squote> <octchars> <squote> |
//\\ ##   "[CMD]" <squote> <mchars> <squote>;
//\\ #

//\\ P<OLDSTYLE-BASE> = 
//\\    <letter> <sqstring>;

case P_OLDSTYLE_BASE:
  T[1] = build_ast(A[ap+0], depth+1); // <letter>
  T[2] = bip(AST_sqstring, A[ap+1]);
  return mktuple(AST_OLDSTYLE_BASE, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);


//\\ # Note: a <DIGIT-SEQ> can be both an integer constant and a real constant.
//\\ # Imp77 supports constants like this: %constlongreal PI = 16_3.243F6A89
//\\ # which are not handled here yet.
//\\ #
//\\ ## P<realconst> = "[0-9][0-9]*\.[0-9][0-9]*E[0-9][0-9]*" |
//\\ ##                "[0-9][0-9]*\.[0-9][0-9]*" |
//\\ ##                "[0-9][0-9]*@@[0-9][0-9]*"
//\\ #

//\\ P<REAL-CONST> = 
//\\    <DIGIT-SEQ> <OPT-FRACPT> <OPT-EXPONENT>,
//\\    <FRACPT> <OPT-EXPONENT>;

case P_REAL_CONST:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <DIGIT-SEQ>
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-FRACPT>
    T[3] = build_ast(A[ap+2], depth+1); // <OPT-EXPONENT>
    T[0] = mktuple(AST_REAL_CONST, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <FRACPT>
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-EXPONENT>
    T[0] = mktuple(AST_REAL_CONST, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<FRACPT> = 
//\\    '.' <DIGIT-SEQ>;

case P_FRACPT:
  T[1] = lit(AST__LIT, '.', A[ap+0]);
  T[2] = build_ast(A[ap+1], depth+1); // <DIGIT-SEQ>
  return mktuple(AST_FRACPT, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<OPT-FRACPT> = 
//\\    <FRACPT>,
//\\   ;

case P_OPT_FRACPT:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <FRACPT>
    T[0] = mktuple(AST_OPT_FRACPT, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_OPT_FRACPT, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<OPT-Plus-Minus> = 
//\\    '+',
//\\    '-',
//\\   ;

case P_OPT_Plus_Minus:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '+', A[ap+0]);
    T[0] = mktuple(AST_OPT_Plus_Minus, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '-', A[ap+0]);
    T[0] = mktuple(AST_OPT_Plus_Minus, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_OPT_Plus_Minus, alt /*2*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<OPT-EXPONENT> = 
//\\    '@@' <OPT-Plus-Minus> <DIGIT-SEQ>,
//\\   ;

case P_OPT_EXPONENT:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '@@', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-Plus-Minus>
    T[3] = build_ast(A[ap+2], depth+1); // <DIGIT-SEQ>
    T[0] = mktuple(AST_OPT_EXPONENT, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_OPT_EXPONENT, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<DIGIT-SEQ> = 
//\\    <digit> <rest-of-number>;

case P_DIGIT_SEQ:
  T[1] = build_ast(A[ap+0], depth+1); // <digit>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-number>
  return mktuple(AST_DIGIT_SEQ, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-number> = 
//\\    <DIGIT-SEQ>,
//\\   ;

case P_rest_of_number:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <DIGIT-SEQ>
    T[0] = mktuple(AST_rest_of_number, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_number, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<NAME> = 
//\\    <letter> <!SQUO-STRING> <opt-letter-or-digit-seq>;

case P_NAME:
  T[1] = build_ast(A[ap+0], depth+1); // <letter>
  T[2] = -1; // <!SQUO-STRING>
  T[3] = build_ast(A[ap+2], depth+1); // <opt-letter-or-digit-seq>
  return mktuple(AST_NAME, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);


//\\ ## P<NAME> =
//\\ ##    <alphanumeric> <!SQUO-STRING> <rest-of-name>;
//\\ ## P<rest-of-name> =
//\\ ##    <NAME>,
//\\ ##   ;

//\\ P<SQUO-STRING> = 
//\\    <sqstring>;

case P_SQUO_STRING:
  T[1] = bip(AST_sqstring, A[ap+0]);
  return mktuple(AST_SQUO_STRING, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);


//\\ # A UCI is a machine code instruction.
//\\ # (Hamish's PDP15 imp machine code syntax (which is not introduced by '*') is definitely not supported.)
//\\ #
//\\ # Machine-specific machine-code removed. May cause problems with ';' and quoted chars in machine code
//\\ #

//\\ P<UCI> = 
//\\    <NL-or-SEMI>,
//\\    <char> <UCI>,
//\\    <dqstring> <UCI>,
//\\    <sqstring> <UCI>,
//\\    <stropped> <UCI>;

case P_UCI:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <NL-or-SEMI>
    T[0] = mktuple(AST_UCI, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {
    T[1] = bip(AST_char, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <UCI>
    T[0] = mktuple(AST_UCI, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 2) {
    T[1] = bip(AST_dqstring, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <UCI>
    T[0] = mktuple(AST_UCI, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 3) {
    T[1] = bip(AST_sqstring, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <UCI>
    T[0] = mktuple(AST_UCI, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[1] = bip(AST_stropped, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <UCI>
    T[0] = mktuple(AST_UCI, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];



//\\ # Imp does not let you mix and/or without explicit brackets. They do not have a precedence relationship

//\\ P<REST-OF-COND> = 
//\\    "and" <SC> <REST-OF-ANDC>,
//\\    "or" <SC> <REST-OF-ORC>,
//\\   ;

case P_REST_OF_COND:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_and, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-ANDC>
    T[0] = mktuple(AST_REST_OF_COND, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_or, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-ORC>
    T[0] = mktuple(AST_REST_OF_COND, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_COND, alt /*2*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<REST-OF-ANDC> = 
//\\    "and" <SC> <REST-OF-ANDC>,
//\\   ;

case P_REST_OF_ANDC:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_and, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-ANDC>
    T[0] = mktuple(AST_REST_OF_ANDC, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_ANDC, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<REST-OF-ORC> = 
//\\    "or" <SC> <REST-OF-ORC>,
//\\   ;

case P_REST_OF_ORC:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_or, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-ORC>
    T[0] = mktuple(AST_REST_OF_ORC, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_ORC, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<CONDITION> = 
//\\    <SC> <REST-OF-COND>;

case P_CONDITION:
  T[1] = build_ast(A[ap+0], depth+1); // <SC>
  T[2] = build_ast(A[ap+1], depth+1); // <REST-OF-COND>
  return mktuple(AST_CONDITION, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);


//\\ # <NAME> <OPT-ACTUAL-PARAMETERS> added by gt for predicates
//\\ # RESTOFSC handles double-sided conditions such as '0' <= ch <= '9'

//\\ P<SC> = 
//\\    <STRING-RESOLUTION>,
//\\    <EXPR> <COMP> <EXPR> <OPT-DOUBLE-SIDED>,
//\\    <NAME> <OPT-ACTUAL-PARAMETERS>,
//\\    '(' <CONDITION> ')',
//\\    "not" <SC>;

case P_SC:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <STRING-RESOLUTION>
    T[0] = mktuple(AST_SC, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <EXPR>
    T[2] = build_ast(A[ap+1], depth+1); // <COMP>
    T[3] = build_ast(A[ap+2], depth+1); // <EXPR>
    T[4] = build_ast(A[ap+3], depth+1); // <OPT-DOUBLE-SIDED>
    T[0] = mktuple(AST_SC, alt /*1*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-ACTUAL-PARAMETERS>
    T[0] = mktuple(AST_SC, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 3) {  
    T[1] = lit(AST__LIT, '(', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <CONDITION>  
    T[3] = lit(AST__LIT, ')', A[ap+2]);
    T[0] = mktuple(AST_SC, alt /*3*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_not, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[0] = mktuple(AST_SC, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<OPT-DOUBLE-SIDED> = 
//\\    <COMP> <EXPR>,
//\\   ;

case P_OPT_DOUBLE_SIDED:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <COMP>
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>
    T[0] = mktuple(AST_OPT_DOUBLE_SIDED, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_OPT_DOUBLE_SIDED, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<STRING-RESOLUTION> = 
//\\    <STRING-EXPR> '-' '>' <STRING-RESOLUTION-EXPR>;

case P_STRING_RESOLUTION:
  T[1] = build_ast(A[ap+0], depth+1); // <STRING-EXPR>
  T[2] = lit(AST__LIT, '-', A[ap+1]);
  T[3] = lit(AST__LIT, '>', A[ap+2]);
  T[4] = build_ast(A[ap+3], depth+1); // <STRING-RESOLUTION-EXPR>
  return mktuple(AST_STRING_RESOLUTION, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);


//\\ # Current Imp77 restricts string resolution to -> a.("test").b  with a and b being optional.
//\\ # Older Emas implementations allowed multiple parts I'm fairly sure, eg -> a.("match1").b.("match2").c
//\\ #
//\\ # Also, behaviour changed re initial ("match") with no assignment variable before it -
//\\ # used to be that "match" had to start the string, but now there can be text before
//\\ # it, and a null match has to be coded as -> a.("match").b %and a = ""
//\\ #
//\\ # So if we need to distinguish between these variations, do it in compile()
//\\ #

//\\ P<STRING-RESOLUTION-EXPR> = 
//\\    <STR-MATCH> <OPT-STR-ASSIGN>,
//\\    <STR-ASSIGN> <OPT-STR-MATCH>;

case P_STRING_RESOLUTION_EXPR:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <STR-MATCH>
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-STR-ASSIGN>
    T[0] = mktuple(AST_STRING_RESOLUTION_EXPR, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <STR-ASSIGN>
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-STR-MATCH>
    T[0] = mktuple(AST_STRING_RESOLUTION_EXPR, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<STRING-LVALUE> = 
//\\    <NAME> <Opt-PARAMETERS-OR-POINTERINDEX> <Opt-RECORDFIELD-OR-POINTERINDEX>;

case P_STRING_LVALUE:
  T[1] = build_ast(A[ap+0], depth+1); // <NAME>
  T[2] = build_ast(A[ap+1], depth+1); // <Opt-PARAMETERS-OR-POINTERINDEX>
  T[3] = build_ast(A[ap+2], depth+1); // <Opt-RECORDFIELD-OR-POINTERINDEX>
  return mktuple(AST_STRING_LVALUE, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);



//\\ P<STRING-RVALUE> = 
//\\    <STRING-LVALUE>,
//\\    <STR-CONST>;

case P_STRING_RVALUE:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <STRING-LVALUE>
    T[0] = mktuple(AST_STRING_RVALUE, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <STR-CONST>
    T[0] = mktuple(AST_STRING_RVALUE, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # No bracketed expressions, only '.' operator allowed, although once again,
//\\ # Hamish has an idiosyncratic extension where strings in a printstring are
//\\ # separated by semi-colons - I think it is some approximation to C's printf?
//\\ #

//\\ P<STRING-EXPR> = 
//\\    <STRING-RVALUE> <REST-OF-STRING-EXPR>;

case P_STRING_EXPR:
  T[1] = build_ast(A[ap+0], depth+1); // <STRING-RVALUE>
  T[2] = build_ast(A[ap+1], depth+1); // <REST-OF-STRING-EXPR>
  return mktuple(AST_STRING_EXPR, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<REST-OF-STRING-EXPR> = 
//\\    '.' <STRING-RVALUE> <REST-OF-STRING-EXPR>,
//\\   ;

case P_REST_OF_STRING_EXPR:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '.', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <STRING-RVALUE>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-STRING-EXPR>
    T[0] = mktuple(AST_REST_OF_STRING_EXPR, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_STRING_EXPR, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<STR-MATCH> = 
//\\    '(' <STRING-EXPR> ')';

case P_STR_MATCH:
  T[1] = lit(AST__LIT, '(', A[ap+0]);
  T[2] = build_ast(A[ap+1], depth+1); // <STRING-EXPR>
  T[3] = lit(AST__LIT, ')', A[ap+2]);
  return mktuple(AST_STR_MATCH, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);



//\\ P<STR-ASSIGN> = 
//\\    <STRING-LVALUE>;

case P_STR_ASSIGN:
  T[1] = build_ast(A[ap+0], depth+1); // <STRING-LVALUE>
  return mktuple(AST_STR_ASSIGN, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);


//\\ # ping-pong.  Can't allow -> (a).b.c.(d) or -> a.(b).(c).d

//\\ P<OPT-STR-ASSIGN> = 
//\\    '.' <STR-ASSIGN> <OPT-STR-MATCH>,
//\\   ;

case P_OPT_STR_ASSIGN:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '.', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <STR-ASSIGN>
    T[3] = build_ast(A[ap+2], depth+1); // <OPT-STR-MATCH>
    T[0] = mktuple(AST_OPT_STR_ASSIGN, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_OPT_STR_ASSIGN, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<OPT-STR-MATCH> = 
//\\    '.' <STR-MATCH> <OPT-STR-ASSIGN>,
//\\   ;

case P_OPT_STR_MATCH:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '.', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <STR-MATCH>
    T[3] = build_ast(A[ap+2], depth+1); // <OPT-STR-ASSIGN>
    T[0] = mktuple(AST_OPT_STR_MATCH, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_OPT_STR_MATCH, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # Ordering is important, eg '##' must come before '#'
//\\ #
//\\ # I really pity people who use the sort of grammar that requires
//\\ # eliminating shift-reduce conflicts before they can parse anything :-)
//\\ #

//\\ P<COMP> = 
//\\    '=' '=',
//\\    '=',
//\\    <NOT-EQUALS-ADDRESS>,
//\\    <NOT-EQUALS>,
//\\    '<' '=',
//\\    '<',
//\\    '>' '=',
//\\    '>';

case P_COMP:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_COMP, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);
    T[0] = mktuple(AST_COMP, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <NOT-EQUALS-ADDRESS>
    T[0] = mktuple(AST_COMP, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 3) {
    T[1] = build_ast(A[ap+0], depth+1); // <NOT-EQUALS>
    T[0] = mktuple(AST_COMP, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 4) {  
    T[1] = lit(AST__LIT, '<', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_COMP, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 5) {  
    T[1] = lit(AST__LIT, '<', A[ap+0]);
    T[0] = mktuple(AST_COMP, alt /*5*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 6) {  
    T[1] = lit(AST__LIT, '>', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_COMP, alt /*6*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {  
    T[1] = lit(AST__LIT, '>', A[ap+0]);
    T[0] = mktuple(AST_COMP, alt /*7*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # '<>' is a really obscure form but it definitely used to be used.  I'll
//\\ # post a reference as soon as I locate one.
//\\ #

//\\ P<NOT-EQUALS> = 
//\\    '#',
//\\    '\\' '=',
//\\    '<' '>';

case P_NOT_EQUALS:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '#', A[ap+0]);
    T[0] = mktuple(AST_NOT_EQUALS, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '\\', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_NOT_EQUALS, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {  
    T[1] = lit(AST__LIT, '<', A[ap+0]);  
    T[2] = lit(AST__LIT, '>', A[ap+1]);
    T[0] = mktuple(AST_NOT_EQUALS, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<NOT-EQUALS-ADDRESS> = 
//\\    '#' '#',
//\\    '\\' '=' '=';

case P_NOT_EQUALS_ADDRESS:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '#', A[ap+0]);  
    T[2] = lit(AST__LIT, '#', A[ap+1]);
    T[0] = mktuple(AST_NOT_EQUALS_ADDRESS, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {  
    T[1] = lit(AST__LIT, '\\', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);  
    T[3] = lit(AST__LIT, '=', A[ap+2]);
    T[0] = mktuple(AST_NOT_EQUALS_ADDRESS, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  }
  return T[0];



//\\ # Procedure application, i.e. actual parameters to routine or function call

//\\ P<OPT-ACTUAL-PARAMETERS> = 
//\\    '(' <EXPR> <REST-OF-ACTUAL-PARAMETERS> ')',
//\\   ;

case P_OPT_ACTUAL_PARAMETERS:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '(', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-ACTUAL-PARAMETERS>  
    T[4] = lit(AST__LIT, ')', A[ap+3]);
    T[0] = mktuple(AST_OPT_ACTUAL_PARAMETERS, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[0] = mktuple(AST_OPT_ACTUAL_PARAMETERS, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<REST-OF-ACTUAL-PARAMETERS> = 
//\\    ',' <EXPR> <REST-OF-ACTUAL-PARAMETERS>,
//\\   ;

case P_REST_OF_ACTUAL_PARAMETERS:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-ACTUAL-PARAMETERS>
    T[0] = mktuple(AST_REST_OF_ACTUAL_PARAMETERS, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_ACTUAL_PARAMETERS, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # handling precedence withh the grammar rather than Edinburgh-style in the AST. Tradeoff of speed for simplicity.
//\\ # CEXPR not handled yet

//\\ P<EXPR> = 
//\\    <MEDIUMPREC-EXPR> <REST-OF-EXPR>;

case P_EXPR:
  T[1] = build_ast(A[ap+0], depth+1); // <MEDIUMPREC-EXPR>
  T[2] = build_ast(A[ap+1], depth+1); // <REST-OF-EXPR>
  return mktuple(AST_EXPR, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<REST-OF-EXPR> = 
//\\    <OP-LOW> <MEDIUMPREC-EXPR> <REST-OF-EXPR>,
//\\   ;

case P_REST_OF_EXPR:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <OP-LOW>
    T[2] = build_ast(A[ap+1], depth+1); // <MEDIUMPREC-EXPR>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-EXPR>
    T[0] = mktuple(AST_REST_OF_EXPR, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_EXPR, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<MEDIUMPREC-EXPR> = 
//\\    <HIGHPREC-EXPR> <REST-OF-MEDIUMPREC-EXPR>;

case P_MEDIUMPREC_EXPR:
  T[1] = build_ast(A[ap+0], depth+1); // <HIGHPREC-EXPR>
  T[2] = build_ast(A[ap+1], depth+1); // <REST-OF-MEDIUMPREC-EXPR>
  return mktuple(AST_MEDIUMPREC_EXPR, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<REST-OF-MEDIUMPREC-EXPR> = 
//\\    <OP-MED> <HIGHPREC-EXPR> <REST-OF-MEDIUMPREC-EXPR>,
//\\   ;

case P_REST_OF_MEDIUMPREC_EXPR:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <OP-MED>
    T[2] = build_ast(A[ap+1], depth+1); // <HIGHPREC-EXPR>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-MEDIUMPREC-EXPR>
    T[0] = mktuple(AST_REST_OF_MEDIUMPREC_EXPR, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_MEDIUMPREC_EXPR, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<HIGHPREC-EXPR> = 
//\\    <RIGHT-ASSOC-EXPR> <REST-OF-HIGHPREC-EXPR>;

case P_HIGHPREC_EXPR:
  T[1] = build_ast(A[ap+0], depth+1); // <RIGHT-ASSOC-EXPR>
  T[2] = build_ast(A[ap+1], depth+1); // <REST-OF-HIGHPREC-EXPR>
  return mktuple(AST_HIGHPREC_EXPR, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<REST-OF-HIGHPREC-EXPR> = 
//\\    <OP-HIGH-LEFTASSOC> <RIGHT-ASSOC-EXPR> <REST-OF-HIGHPREC-EXPR>,
//\\   ;

case P_REST_OF_HIGHPREC_EXPR:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <OP-HIGH-LEFTASSOC>
    T[2] = build_ast(A[ap+1], depth+1); // <RIGHT-ASSOC-EXPR>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-HIGHPREC-EXPR>
    T[0] = mktuple(AST_REST_OF_HIGHPREC_EXPR, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_HIGHPREC_EXPR, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<RIGHT-ASSOC-EXPR> = 
//\\    <REST-OF-RIGHTASSOC-EXPR> <UNARY-EXPR>;

case P_RIGHT_ASSOC_EXPR:
  T[1] = build_ast(A[ap+0], depth+1); // <REST-OF-RIGHTASSOC-EXPR>
  T[2] = build_ast(A[ap+1], depth+1); // <UNARY-EXPR>
  return mktuple(AST_RIGHT_ASSOC_EXPR, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<REST-OF-RIGHTASSOC-EXPR> = 
//\\    <RIGHTASSOC-EXPR-with-OP> <REST-OF-RIGHTASSOC-EXPR>,
//\\   ;

case P_REST_OF_RIGHTASSOC_EXPR:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <RIGHTASSOC-EXPR-with-OP>
    T[2] = build_ast(A[ap+1], depth+1); // <REST-OF-RIGHTASSOC-EXPR>
    T[0] = mktuple(AST_REST_OF_RIGHTASSOC_EXPR, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_RIGHTASSOC_EXPR, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<RIGHTASSOC-EXPR-with-OP> = 
//\\    <UNARY-EXPR> <OP-HIGH-RIGHTASSOC>;

case P_RIGHTASSOC_EXPR_with_OP:
  T[1] = build_ast(A[ap+0], depth+1); // <UNARY-EXPR>
  T[2] = build_ast(A[ap+1], depth+1); // <OP-HIGH-RIGHTASSOC>
  return mktuple(AST_RIGHTASSOC_EXPR_with_OP, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<UNARY-EXPR> = 
//\\    <Opt-UNARY-OP> <OPERAND>;

case P_UNARY_EXPR:
  T[1] = build_ast(A[ap+0], depth+1); // <Opt-UNARY-OP>
  T[2] = build_ast(A[ap+1], depth+1); // <OPERAND>
  return mktuple(AST_UNARY_EXPR, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);


//\\ # These pointer arithmetic elements are for Hamish's PDP9/15 Imp (old): INDP == INDEX0++P
//\\ # and for Hamish's 68000 Imp:     %if tp[1]_mode # litmode %then lo = minint %else lo = tp[1]_val
//\\ # I hope this grammar definition causes the right precedence level...
//\\ #
//\\ # They can also be used in LVALUEs.

//\\ P<Opt-PARAMETERS-OR-POINTERINDEX> = 
//\\    '[' <EXPR> ']',
//\\    '+' '+' <EXPR>,
//\\    '-' '-' <EXPR>,
//\\    <OPT-ACTUAL-PARAMETERS>;

case P_Opt_PARAMETERS_OR_POINTERINDEX:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '[', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>  
    T[3] = lit(AST__LIT, ']', A[ap+2]);
    T[0] = mktuple(AST_Opt_PARAMETERS_OR_POINTERINDEX, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '+', A[ap+0]);  
    T[2] = lit(AST__LIT, '+', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <EXPR>
    T[0] = mktuple(AST_Opt_PARAMETERS_OR_POINTERINDEX, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '-', A[ap+0]);  
    T[2] = lit(AST__LIT, '-', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <EXPR>
    T[0] = mktuple(AST_Opt_PARAMETERS_OR_POINTERINDEX, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <OPT-ACTUAL-PARAMETERS>
    T[0] = mktuple(AST_Opt_PARAMETERS_OR_POINTERINDEX, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<Opt-RECORDFIELD> = 
//\\    '_' <NAME> <Opt-PARAMETERS-OR-POINTERINDEX> <Opt-RECORDFIELD>,
//\\   ;

case P_Opt_RECORDFIELD:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '_', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-PARAMETERS-OR-POINTERINDEX>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-RECORDFIELD>
    T[0] = mktuple(AST_Opt_RECORDFIELD, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[0] = mktuple(AST_Opt_RECORDFIELD, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<Opt-RECORDFIELD-OR-POINTERINDEX> = 
//\\    '_' <NAME> <Opt-PARAMETERS-OR-POINTERINDEX> <Opt-RECORDFIELD-OR-POINTERINDEX>,
//\\   ;

case P_Opt_RECORDFIELD_OR_POINTERINDEX:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '_', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-PARAMETERS-OR-POINTERINDEX>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-RECORDFIELD-OR-POINTERINDEX>
    T[0] = mktuple(AST_Opt_RECORDFIELD_OR_POINTERINDEX, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[0] = mktuple(AST_Opt_RECORDFIELD_OR_POINTERINDEX, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # The old form of modulus (!X!) is for really ancient compilers such as Hamish's Pdp15 Imp.
//\\ # Unfortunately there are obscure cases where an ambiguous parse results:
//\\ #
//\\ #  putact(condop!!polarity!!1+polarity<<7,item,0)
//\\ #
//\\ # Does that mean
//\\ #   putact(condop !!  polarity   !!  1 + polarity<<7, item, 0)
//\\ # or
//\\ #   putact(condop !  !polarity!  !   1 + polarity<<7, item, 0)
//\\ #
//\\ # I need to check but I *hope* that the grammar here causes the first of the above to be selected.
//\\ # If not, we'll need a command-line option here to force the version of Imp being used.
//\\ #
//\\ # I just hope that there's no version of Imp that ever supported factorials with a postfix '!'
//\\ #

//\\ P<OPERAND> = 
//\\    <NAME> <Opt-PARAMETERS-OR-POINTERINDEX> <Opt-RECORDFIELD-OR-POINTERINDEX>,
//\\    <CONST>,
//\\    '(' <EXPR> ')',
//\\    '|' <EXPR> '|',
//\\    '!' <EXPR> '!';

case P_OPERAND:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-PARAMETERS-OR-POINTERINDEX>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-RECORDFIELD-OR-POINTERINDEX>
    T[0] = mktuple(AST_OPERAND, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <CONST>
    T[0] = mktuple(AST_OPERAND, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '(', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>  
    T[3] = lit(AST__LIT, ')', A[ap+2]);
    T[0] = mktuple(AST_OPERAND, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 3) {  
    T[1] = lit(AST__LIT, '|', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>  
    T[3] = lit(AST__LIT, '|', A[ap+2]);
    T[0] = mktuple(AST_OPERAND, alt /*3*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {  
    T[1] = lit(AST__LIT, '!', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>  
    T[3] = lit(AST__LIT, '!', A[ap+2]);
    T[0] = mktuple(AST_OPERAND, alt /*4*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  }
  return T[0];



//\\ # <OP> is only used in <CEXPR>s now and will be removed entirely
//\\ # once CEXPRs are recoded to use the same grammar as EXPRs.
//\\ #
//\\ # *However* I am considering doing away with CEXPRs altogether,
//\\ # and just using <EXPR> everywhere, in conjunction with a parse-time
//\\ # test to check whether any of the terms were in fact *not* constants.
//\\ #
//\\ # Also... it's not obvious if we could in fact use EXPRs everywhere *without*
//\\ # the overhead of having to organise the code/name tables so that they
//\\ # can be checked for being constants at parse time, and merely reject
//\\ # them from the compile() procedure instead?  This would be possible
//\\ # as long as there are no parse ambiguities caused by checking after
//\\ # parsing. I know that's a problem in C but Imp's simpler syntax
//\\ # might let us get away with it!
//\\ #
//\\ # Note that none of these options eliminates the possibility of implementing
//\\ # conditional compilation the EMAS Imp80 way using
//\\ #
//\\ # %if <CEXPR> %start
//\\ #   ! conditional code
//\\ # %finish
//\\ #
//\\ # (Though I've always had questions about that on EMAS if there's a
//\\ #  label inside the block - the ability to use that construct for
//\\ #  conditional compilation depends on whether that label is ever
//\\ #  jumped to from code outside the block! - doing it properly requires
//\\ #  full flow control analysis and a transitive closure on the flow graph!)
//\\ #

//\\ P<OP> = 
//\\    <OP-HIGH-LEFTASSOC>,
//\\    <OP-HIGH-RIGHTASSOC>,
//\\    <OP-MED>,
//\\    <OP-LOW>;

case P_OP:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <OP-HIGH-LEFTASSOC>
    T[0] = mktuple(AST_OP, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <OP-HIGH-RIGHTASSOC>
    T[0] = mktuple(AST_OP, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <OP-MED>
    T[0] = mktuple(AST_OP, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <OP-LOW>
    T[0] = mktuple(AST_OP, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # highest precedence, left-associative

//\\ P<OP-HIGH-LEFTASSOC> = 
//\\    '<' '<',
//\\    '>' '>';

case P_OP_HIGH_LEFTASSOC:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '<', A[ap+0]);  
    T[2] = lit(AST__LIT, '<', A[ap+1]);
    T[0] = mktuple(AST_OP_HIGH_LEFTASSOC, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {  
    T[1] = lit(AST__LIT, '>', A[ap+0]);  
    T[2] = lit(AST__LIT, '>', A[ap+1]);
    T[0] = mktuple(AST_OP_HIGH_LEFTASSOC, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];



//\\ # highest precedence, right-associative (only exponentiation)
//\\ #
//\\ # I found this expression the 68000 Imp compiler:
//\\ #
//\\ #           y = |r|+0.5/10.0\{^}m;  !modulus, rounded
//\\ #
//\\ # which I parse as:
//\\ #
//\\ #           y = |r|+( 0.5 / (10.0\{^}m));  !modulus, rounded
//\\ #
//\\ # I presume this is a clever way to round the last digit of a decimal,
//\\ # but damn, how it works is beyond me.
//\\ # Typical Hamish code! Brilliant (I presume) but obscure and uncommented.
//\\ #

//\\ P<OP-HIGH-RIGHTASSOC> = 
//\\    <INTEGER-EXP>,
//\\    <REAL-EXP>;

case P_OP_HIGH_RIGHTASSOC:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <INTEGER-EXP>
    T[0] = mktuple(AST_OP_HIGH_RIGHTASSOC, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <REAL-EXP>
    T[0] = mktuple(AST_OP_HIGH_RIGHTASSOC, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<INTEGER-EXP> = 
//\\    '*' '*' '*' '*',
//\\    '\\' '\\',
//\\    '^' '^';

case P_INTEGER_EXP:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '*', A[ap+0]);  
    T[2] = lit(AST__LIT, '*', A[ap+1]);  
    T[3] = lit(AST__LIT, '*', A[ap+2]);  
    T[4] = lit(AST__LIT, '*', A[ap+3]);
    T[0] = mktuple(AST_INTEGER_EXP, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '\\', A[ap+0]);  
    T[2] = lit(AST__LIT, '\\', A[ap+1]);
    T[0] = mktuple(AST_INTEGER_EXP, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {  
    T[1] = lit(AST__LIT, '^', A[ap+0]);  
    T[2] = lit(AST__LIT, '^', A[ap+1]);
    T[0] = mktuple(AST_INTEGER_EXP, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<REAL-EXP> = 
//\\    '*' '*',
//\\    '\\',
//\\    '^';

case P_REAL_EXP:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '*', A[ap+0]);  
    T[2] = lit(AST__LIT, '*', A[ap+1]);
    T[0] = mktuple(AST_REAL_EXP, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '\\', A[ap+0]);
    T[0] = mktuple(AST_REAL_EXP, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = lit(AST__LIT, '^', A[ap+0]);
    T[0] = mktuple(AST_REAL_EXP, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # middle-precedence operators.  All left-associative.

//\\ P<OP-MED> = 
//\\    '*',
//\\    '/' '/',
//\\    '/',
//\\    '&';

case P_OP_MED:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '*', A[ap+0]);
    T[0] = mktuple(AST_OP_MED, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '/', A[ap+0]);  
    T[2] = lit(AST__LIT, '/', A[ap+1]);
    T[0] = mktuple(AST_OP_MED, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '/', A[ap+0]);
    T[0] = mktuple(AST_OP_MED, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = lit(AST__LIT, '&', A[ap+0]);
    T[0] = mktuple(AST_OP_MED, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # lowest precedence operators.  All left-associative.

//\\ P<OP-LOW> = 
//\\    '+',
//\\    '-',
//\\    '!' '!',
//\\    '!',
//\\    '.';

case P_OP_LOW:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '+', A[ap+0]);
    T[0] = mktuple(AST_OP_LOW, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '-', A[ap+0]);
    T[0] = mktuple(AST_OP_LOW, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '!', A[ap+0]);  
    T[2] = lit(AST__LIT, '!', A[ap+1]);
    T[0] = mktuple(AST_OP_LOW, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 3) {  
    T[1] = lit(AST__LIT, '!', A[ap+0]);
    T[0] = mktuple(AST_OP_LOW, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = lit(AST__LIT, '.', A[ap+0]);
    T[0] = mktuple(AST_OP_LOW, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # You would think that unary operators always have the highest precedence,
//\\ # but not so - here's a tricky one...
//\\ #
//\\ # I = -1 >> 1
//\\ #
//\\ # This always has the value 0, regardless of integer size, because a unary minus
//\\ # in front of a constant is *NOT* interpreted as a negative constant, but rather
//\\ # the positive constant preceded by a unary negation operator.
//\\ #
//\\ # It gets worse... unary negation is implemented as binary subtraction with
//\\ # an inserted '0' left operand, i.e.
//\\ #
//\\ # 0 - 1 >> 1
//\\ #
//\\ # Shifts have higher precedence than subtraction, so this becomes:
//\\ #
//\\ # 0 - (1 >> 1)
//\\ #
//\\ # which evaluates to 0.
//\\ #
//\\ # The 68000 Imp compiler includes this statement which I hope is correct! dict(firstpos)_val = -cad>>1
//\\ #
//\\ # Some versions of Imp (I think Imp80) forbid a unary '+' before constants,
//\\ # so A + +3 would be illegal (although A + -3 would not)
//\\ #
//\\ # and none of this applies to binary-not (\) so \3 really is higher
//\\ # priority than '>>' and \3 >> 1 does what you would expect.  I hope.
//\\ #

//\\ P<Opt-UNARY-OP> = 
//\\    '+',
//\\    '-',
//\\    <UNARY-NOT>,
//\\   ;

case P_Opt_UNARY_OP:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '+', A[ap+0]);
    T[0] = mktuple(AST_Opt_UNARY_OP, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '-', A[ap+0]);
    T[0] = mktuple(AST_Opt_UNARY_OP, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <UNARY-NOT>
    T[0] = mktuple(AST_Opt_UNARY_OP, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_Opt_UNARY_OP, alt /*3*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # fortunately unary backslash is unambiguous with ERCC style exponentiation binary operator

//\\ P<UNARY-NOT> = 
//\\    '\\',
//\\    '~';

case P_UNARY_NOT:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '\\', A[ap+0]);
    T[0] = mktuple(AST_UNARY_NOT, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = lit(AST__LIT, '~', A[ap+0]);
    T[0] = mktuple(AST_UNARY_NOT, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<Percent-IU> = 
//\\    "if",
//\\    "unless";

case P_Percent_IU:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_if, A[ap+0]);
    T[0] = mktuple(AST_Percent_IU, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_unless, A[ap+0]);
    T[0] = mktuple(AST_Percent_IU, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # rest of %switch list
//\\ # This reminds me, isn't there an optional %label declaration in Imp?  Haven't seen an example yet,
//\\ # I need to check the manuals to make sure I'm not confusing this with C...

//\\ P<REST-OF-SWLIST> = 
//\\    ',' <NAME> <Opt-NAME-LIST> '(' <EXPR> ':' <EXPR> ')' <REST-OF-SWLIST>,
//\\   ;

case P_REST_OF_SWLIST:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-NAME-LIST>  
    T[4] = lit(AST__LIT, '(', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <EXPR>  
    T[6] = lit(AST__LIT, ':', A[ap+5]);
    T[7] = build_ast(A[ap+6], depth+1); // <EXPR>  
    T[8] = lit(AST__LIT, ')', A[ap+7]);
    T[9] = build_ast(A[ap+8], depth+1); // <REST-OF-SWLIST>
    T[0] = mktuple(AST_REST_OF_SWLIST, alt /*0*/, /*phrases*/ 9, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_SWLIST, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<Opt-NAME-LIST> = 
//\\    ',' <NAME> <Opt-NAME-LIST>,
//\\   ;

case P_Opt_NAME_LIST:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-NAME-LIST>
    T[0] = mktuple(AST_Opt_NAME_LIST, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_Opt_NAME_LIST, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<REST-OF-NAME-LIST> = 
//\\    ',' <CEXPR> <REST-OF-NAME-LIST>,
//\\   ;

case P_REST_OF_NAME_LIST:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <CEXPR>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-NAME-LIST>
    T[0] = mktuple(AST_REST_OF_NAME_LIST, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_NAME_LIST, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # Still to handle operator precedence etc for <CEXPR>s the same way as for <EXPR>s.
//\\ # However it is such a major duplication of effort that it might be much easier to
//\\ # just use <EXPR>s and have a semantic test for constantcy.
//\\ # The problem is the ambiguity of <NAMES>.  And you don't want any of the decorated
//\\ # forms of a name (records, function calls, pointers, maybe even rejecting const
//\\ # array elements?) - just simple literals and const integer operands.

//\\ P<CEXPR> = 
//\\    <Opt-UNARY-OP> <COPERAND> <REST-OF-CEXPR>;

case P_CEXPR:
  T[1] = build_ast(A[ap+0], depth+1); // <Opt-UNARY-OP>
  T[2] = build_ast(A[ap+1], depth+1); // <COPERAND>
  T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-CEXPR>
  return mktuple(AST_CEXPR, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);



//\\ P<REST-OF-CEXPR> = 
//\\    <OP> <COPERAND> <REST-OF-CEXPR>,
//\\   ;

case P_REST_OF_CEXPR:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <OP>
    T[2] = build_ast(A[ap+1], depth+1); // <COPERAND>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-CEXPR>
    T[0] = mktuple(AST_REST_OF_CEXPR, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_CEXPR, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<COPERAND> = 
//\\    <NAME>,
//\\    <CONST>,
//\\    '(' <CEXPR> ')',
//\\    '|' <CEXPR> '|',
//\\    '!' <CEXPR> '!';

case P_COPERAND:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>
    T[0] = mktuple(AST_COPERAND, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <CONST>
    T[0] = mktuple(AST_COPERAND, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '(', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <CEXPR>  
    T[3] = lit(AST__LIT, ')', A[ap+2]);
    T[0] = mktuple(AST_COPERAND, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 3) {  
    T[1] = lit(AST__LIT, '|', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <CEXPR>  
    T[3] = lit(AST__LIT, '|', A[ap+2]);
    T[0] = mktuple(AST_COPERAND, alt /*3*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {  
    T[1] = lit(AST__LIT, '!', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <CEXPR>  
    T[3] = lit(AST__LIT, '!', A[ap+2]);
    T[0] = mktuple(AST_COPERAND, alt /*4*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  }
  return T[0];




//\\ P<OPT-event> = 
//\\    "event",
//\\   ;

case P_OPT_event:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_event, A[ap+0]);
    T[0] = mktuple(AST_OPT_event, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_OPT_event, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<FPP> = 
//\\    '(' <FORMAL-PARAMETER-DECLARATION> <REST-OF-FORMAL-PARAMETER-LIST> ')',
//\\   ;

case P_FPP:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '(', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <FORMAL-PARAMETER-DECLARATION>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-FORMAL-PARAMETER-LIST>  
    T[4] = lit(AST__LIT, ')', A[ap+3]);
    T[0] = mktuple(AST_FPP, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[0] = mktuple(AST_FPP, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<REST-OF-FORMAL-PARAMETER-LIST> = 
//\\    <Opt-Comma> <FORMAL-PARAMETER-DECLARATION> <REST-OF-FORMAL-PARAMETER-LIST>,
//\\   ;

case P_REST_OF_FORMAL_PARAMETER_LIST:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-Comma>
    T[2] = build_ast(A[ap+1], depth+1); // <FORMAL-PARAMETER-DECLARATION>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-FORMAL-PARAMETER-LIST>
    T[0] = mktuple(AST_REST_OF_FORMAL_PARAMETER_LIST, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_FORMAL_PARAMETER_LIST, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # %routine y (%integer %name %array (1) %name b)
//\\ # %routine r10(%integer%array%name a(1:10),%integer k)

//\\ P<FORMAL-PARAMETER-DECLARATION> = 
//\\    <XTYPE> <OPT-arrayname> <NAME> <OPT-68K-Bounds> <Opt-NAME-LIST>,
//\\    <RT> <OPT-name> <NAME> <Opt-NAME-LIST> <FPP>,
//\\    "name" <Opt-68K-reg> <NAME> <Opt-NAME-LIST>;

case P_FORMAL_PARAMETER_DECLARATION:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <XTYPE>
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-arrayname>
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>
    T[4] = build_ast(A[ap+3], depth+1); // <OPT-68K-Bounds>
    T[5] = build_ast(A[ap+4], depth+1); // <Opt-NAME-LIST>
    T[0] = mktuple(AST_FORMAL_PARAMETER_DECLARATION, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <RT>
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-name>
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-NAME-LIST>
    T[5] = build_ast(A[ap+4], depth+1); // <FPP>
    T[0] = mktuple(AST_FORMAL_PARAMETER_DECLARATION, alt /*1*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_name, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-68K-reg>
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-NAME-LIST>
    T[0] = mktuple(AST_FORMAL_PARAMETER_DECLARATION, alt /*2*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  }
  return T[0];



//\\ # More Hamish idiosyncracy!:
//\\ #
//\\ # @@16_1114%record(*)%map ZNEW(%name(d0) v)
//\\ #  - APM-gdmr/I/VPERM19.imp
//\\ #      d0 being a register
//\\ #

//\\ P<Opt-68K-reg> = 
//\\    '(' <NAME> ')',
//\\   ;

case P_Opt_68K_reg:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '(', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>  
    T[3] = lit(AST__LIT, ')', A[ap+2]);
    T[0] = mktuple(AST_Opt_68K_reg, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_Opt_68K_reg, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<OPT-name> = 
//\\    "name",
//\\   ;

case P_OPT_name:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_name, A[ap+0]);
    T[0] = mktuple(AST_OPT_name, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_OPT_name, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # added predicate - gt

//\\ P<RT> = 
//\\    "routine",
//\\    "predicate",
//\\    <XTYPE> <FN-MAP>;

case P_RT:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_routine, A[ap+0]);
    T[0] = mktuple(AST_RT, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_predicate, A[ap+0]);
    T[0] = mktuple(AST_RT, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <XTYPE>
    T[2] = build_ast(A[ap+1], depth+1); // <FN-MAP>
    T[0] = mktuple(AST_RT, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];



//\\ # note map is equivalent to "name function"

//\\ P<FN-MAP> = 
//\\    <FN>,
//\\    "map";

case P_FN_MAP:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <FN>
    T[0] = mktuple(AST_FN_MAP, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_map, A[ap+0]);
    T[0] = mktuple(AST_FN_MAP, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<FN> = 
//\\    "fn",
//\\    "function";

case P_FN:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_fn, A[ap+0]);
    T[0] = mktuple(AST_FN, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_function, A[ap+0]);
    T[0] = mktuple(AST_FN, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # Confirmed that label is used.  Found one in 68000 code for labels used in embeddded machine code:
//\\ # %label f1,f2,f3,f4,f5,f6,f7,b0,b1,b2,b3,b4,b5,b6,b7,end
//\\ #
//\\ # "long long" would be added here if we supported 64 bit ints or 128bit reals...
//\\ # Okain "long" added here by making <BTYPE> optional.
//\\ # (BTYPE being integer/real/longreal)
//\\ #

//\\ P<BASE-XTYPE> = 
//\\    "integer",
//\\    "real",
//\\    "label",
//\\    "long" <Opt-BTYPE>,
//\\    "byte" <Opt-INTEGER>,
//\\    "mite" <Opt-INTEGER>,
//\\    "short" <Opt-INTEGER>,
//\\    "half" <Opt-INTEGER>,
//\\    "string" <REPFACT>,
//\\    "record" <Opt-RFREF>;

case P_BASE_XTYPE:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_integer, A[ap+0]);
    T[0] = mktuple(AST_BASE_XTYPE, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_real, A[ap+0]);
    T[0] = mktuple(AST_BASE_XTYPE, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = kw(AST__KW, KW_label, A[ap+0]);
    T[0] = mktuple(AST_BASE_XTYPE, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 3) {  
    T[1] = kw(AST__KW, KW_long, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-BTYPE>
    T[0] = mktuple(AST_BASE_XTYPE, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 4) {  
    T[1] = kw(AST__KW, KW_byte, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-INTEGER>
    T[0] = mktuple(AST_BASE_XTYPE, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 5) {  
    T[1] = kw(AST__KW, KW_mite, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-INTEGER>
    T[0] = mktuple(AST_BASE_XTYPE, alt /*5*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 6) {  
    T[1] = kw(AST__KW, KW_short, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-INTEGER>
    T[0] = mktuple(AST_BASE_XTYPE, alt /*6*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 7) {  
    T[1] = kw(AST__KW, KW_half, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-INTEGER>
    T[0] = mktuple(AST_BASE_XTYPE, alt /*7*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 8) {  
    T[1] = kw(AST__KW, KW_string, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <REPFACT>
    T[0] = mktuple(AST_BASE_XTYPE, alt /*8*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_record, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-RFREF>
    T[0] = mktuple(AST_BASE_XTYPE, alt /*9*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];



//\\ # does %record(i tc f)%name match <XTYPE>?
//\\ #
//\\ # Courtesy of Hamish, two more language extensions:
//\\ #
//\\ # Two <OPT-68K-qualifier>s to allow one or both of %writeonly %volatile %byte %integer device
//\\ #

//\\ P<XTYPE> = 
//\\    <OPT-68K-qualifier> <BASE-XTYPE> <OPT-name>;

case P_XTYPE:
  T[1] = build_ast(A[ap+0], depth+1); // <OPT-68K-qualifier>
  T[2] = build_ast(A[ap+1], depth+1); // <BASE-XTYPE>
  T[3] = build_ast(A[ap+2], depth+1); // <OPT-name>
  return mktuple(AST_XTYPE, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);



//\\ P<68K-memptr> = 
//\\    "read" "only" <68K-memptr>,
//\\    "write" "only" <68K-memptr>,
//\\    "volatile" <68K-memptr>,
//\\   ;

case P_68K_memptr:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_read, A[ap+0]);  
    T[2] = kw(AST__KW, KW_only, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <68K-memptr>
    T[0] = mktuple(AST_68K_memptr, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_write, A[ap+0]);  
    T[2] = kw(AST__KW, KW_only, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <68K-memptr>
    T[0] = mktuple(AST_68K_memptr, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 2) {  
    T[1] = kw(AST__KW, KW_volatile, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <68K-memptr>
    T[0] = mktuple(AST_68K_memptr, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_68K_memptr, alt /*3*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<OPT-68K-qualifier> = 
//\\    <68K-register>,
//\\    <68K-memptr>,
//\\   ;

case P_OPT_68K_qualifier:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <68K-register>
    T[0] = mktuple(AST_OPT_68K_qualifier, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <68K-memptr>
    T[0] = mktuple(AST_OPT_68K_qualifier, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_OPT_68K_qualifier, alt /*2*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # C-like register qualifiers (Hamish, again)
//\\ # %register(a2)%integer r1,r2
//\\ # %register(a2)%byte%name bn
//\\ # %register(a3)%short%name sn

//\\ P<68K-register> = 
//\\    "register" '(' <NAME> ')';

case P_68K_register:
  T[1] = kw(AST__KW, KW_register, A[ap+0]);
  T[2] = lit(AST__LIT, '(', A[ap+1]);
  T[3] = build_ast(A[ap+2], depth+1); // <NAME>
  T[4] = lit(AST__LIT, ')', A[ap+3]);
  return mktuple(AST_68K_register, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);


//\\ # '*' added by gt for recordformat(*)
//\\ # () moved from point of call to here to support old style "%recordname fred" without format. (Uses a formatspec instead)

//\\ P<Opt-RFREF> = 
//\\    '(' <RECFMT-REF> ')',
//\\    '(' '*' ')',
//\\   ;

case P_Opt_RFREF:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '(', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <RECFMT-REF>  
    T[3] = lit(AST__LIT, ')', A[ap+2]);
    T[0] = mktuple(AST_Opt_RFREF, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '(', A[ap+0]);  
    T[2] = lit(AST__LIT, '*', A[ap+1]);  
    T[3] = lit(AST__LIT, ')', A[ap+2]);
    T[0] = mktuple(AST_Opt_RFREF, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_Opt_RFREF, alt /*2*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # RF in the rules below is short for Record Format

//\\ P<RECFMT-REF> = 
//\\    <NAME>,
//\\    <RECFMT-DEC> <REST-OF-RECFMT-DEC> <ALT-RECFMT-DEC>;

case P_RECFMT_REF:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>
    T[0] = mktuple(AST_RECFMT_REF, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <RECFMT-DEC>
    T[2] = build_ast(A[ap+1], depth+1); // <REST-OF-RECFMT-DEC>
    T[3] = build_ast(A[ap+2], depth+1); // <ALT-RECFMT-DEC>
    T[0] = mktuple(AST_RECFMT_REF, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  }
  return T[0];



//\\ # Imp variant record. NOT the same as C's which is per field.  This is per record.
//\\ # Still to check: a ( ... %or ... ) subgroup in a record definition, where the ...
//\\ # represents several declarations, with the whole ( ... ) group being a part
//\\ # of an enclosing record.
//\\ #

//\\ P<ALT-RECFMT-DEC> = 
//\\    "or" <RECFMT-DEC> <REST-OF-RECFMT-DEC> <ALT-RECFMT-DEC>,
//\\   ;

case P_ALT_RECFMT_DEC:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_or, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <RECFMT-DEC>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-RECFMT-DEC>
    T[4] = build_ast(A[ap+3], depth+1); // <ALT-RECFMT-DEC>
    T[0] = mktuple(AST_ALT_RECFMT_DEC, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[0] = mktuple(AST_ALT_RECFMT_DEC, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<REST-OF-RECFMT-DEC> = 
//\\    ',' <RECFMT-DEC> <REST-OF-RECFMT-DEC>,
//\\   ;

case P_REST_OF_RECFMT_DEC:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <RECFMT-DEC>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-RECFMT-DEC>
    T[0] = mktuple(AST_REST_OF_RECFMT_DEC, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_RECFMT_DEC, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<RECFMT-DEC> = 
//\\    <XTYPE> <RECFMT-ELMNT>,
//\\    '(' <RECFMT-DEC> <REST-OF-RECFMT-DEC> <ALT-RECFMT-DEC> ')';

case P_RECFMT_DEC:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <XTYPE>
    T[2] = build_ast(A[ap+1], depth+1); // <RECFMT-ELMNT>
    T[0] = mktuple(AST_RECFMT_DEC, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {  
    T[1] = lit(AST__LIT, '(', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <RECFMT-DEC>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-RECFMT-DEC>
    T[4] = build_ast(A[ap+3], depth+1); // <ALT-RECFMT-DEC>  
    T[5] = lit(AST__LIT, ')', A[ap+4]);
    T[0] = mktuple(AST_RECFMT_DEC, alt /*1*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  }
  return T[0];



//\\ # Now "name" has been removed from <OPT-arrayname-or-name>, check at the point
//\\ # of invocation, that "name" still works, now it as been added to <XTYPE>...
//\\ #

//\\ P<RECFMT-ELMNT> = 
//\\    <OPT-arrayname> <NAME> <Opt-NAME-LIST>,
//\\    "array" <ADECLN-in-record>;

case P_RECFMT_ELMNT:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <OPT-arrayname>
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-NAME-LIST>
    T[0] = mktuple(AST_RECFMT_ELMNT, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_array, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <ADECLN-in-record>
    T[0] = mktuple(AST_RECFMT_ELMNT, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];



//\\ # Array declaration

//\\ P<ADECLN-in-record> = 
//\\    <NAME> <Opt-NAME-LIST> <BPAIR> <REST-OF-ARLIST-in-record>;

case P_ADECLN_in_record:
  T[1] = build_ast(A[ap+0], depth+1); // <NAME>
  T[2] = build_ast(A[ap+1], depth+1); // <Opt-NAME-LIST>
  T[3] = build_ast(A[ap+2], depth+1); // <BPAIR>
  T[4] = build_ast(A[ap+3], depth+1); // <REST-OF-ARLIST-in-record>
  return mktuple(AST_ADECLN_in_record, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);



//\\ P<REST-OF-ARLIST-in-record> = 
//\\    ',' <ADECLN-in-record>,
//\\   ;

case P_REST_OF_ARLIST_in_record:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <ADECLN-in-record>
    T[0] = mktuple(AST_REST_OF_ARLIST_in_record, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_ARLIST_in_record, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<LOWERBOUND> = 
//\\    <EXPR>,
//\\    <BASE-XTYPE> <NAME>;

case P_LOWERBOUND:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <EXPR>
    T[0] = mktuple(AST_LOWERBOUND, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <BASE-XTYPE>
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[0] = mktuple(AST_LOWERBOUND, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];



//\\ # Another Hamishism... %integer %array %name fred(1:*)
//\\ # which in Imp77 would be %integer %array (1) fred
//\\ # (reject the '*' in other contexts)
//\\ #

//\\ P<UPPERBOUND> = 
//\\    '*',
//\\    <EXPR>,
//\\    <BASE-XTYPE> <NAME>;

case P_UPPERBOUND:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '*', A[ap+0]);
    T[0] = mktuple(AST_UPPERBOUND, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <EXPR>
    T[0] = mktuple(AST_UPPERBOUND, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <BASE-XTYPE>
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[0] = mktuple(AST_UPPERBOUND, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];



//\\ # List of lower/upper bound pairs, for array declarations.

//\\ P<BPAIR> = 
//\\    '(' <LOWERBOUND> ':' <UPPERBOUND> <REST-OF-BPLIST> ')';

case P_BPAIR:
  T[1] = lit(AST__LIT, '(', A[ap+0]);
  T[2] = build_ast(A[ap+1], depth+1); // <LOWERBOUND>
  T[3] = lit(AST__LIT, ':', A[ap+2]);
  T[4] = build_ast(A[ap+3], depth+1); // <UPPERBOUND>
  T[5] = build_ast(A[ap+4], depth+1); // <REST-OF-BPLIST>
  T[6] = lit(AST__LIT, ')', A[ap+5]);
  return mktuple(AST_BPAIR, alt /*0*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);



//\\ P<BPAIR68K> = 
//\\    '(' <LOWERBOUND> ':' <UPPERBOUND> <REST-OF-BPLIST68K> ')';

case P_BPAIR68K:
  T[1] = lit(AST__LIT, '(', A[ap+0]);
  T[2] = build_ast(A[ap+1], depth+1); // <LOWERBOUND>
  T[3] = lit(AST__LIT, ':', A[ap+2]);
  T[4] = build_ast(A[ap+3], depth+1); // <UPPERBOUND>
  T[5] = build_ast(A[ap+4], depth+1); // <REST-OF-BPLIST68K>
  T[6] = lit(AST__LIT, ')', A[ap+5]);
  return mktuple(AST_BPAIR68K, alt /*0*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);


//\\ # Multi-dimensional arrays

//\\ P<REST-OF-BPLIST> = 
//\\    ',' <EXPR> ':' <EXPR> <REST-OF-BPLIST>,
//\\   ;

case P_REST_OF_BPLIST:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>  
    T[3] = lit(AST__LIT, ':', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <EXPR>
    T[5] = build_ast(A[ap+4], depth+1); // <REST-OF-BPLIST>
    T[0] = mktuple(AST_REST_OF_BPLIST, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_BPLIST, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<REST-OF-BPLIST68K> = 
//\\    ',' <LOWERBOUND> ':' <UPPERBOUND> <REST-OF-BPLIST68K>,
//\\   ;

case P_REST_OF_BPLIST68K:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <LOWERBOUND>  
    T[3] = lit(AST__LIT, ':', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <UPPERBOUND>
    T[5] = build_ast(A[ap+4], depth+1); // <REST-OF-BPLIST68K>
    T[0] = mktuple(AST_REST_OF_BPLIST68K, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_BPLIST68K, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # <Opt-DIMENSIONS> added to handle:
//\\ #
//\\ # %routine y (%integer %name %array (1) %name b)
//\\ #
//\\ # and <OPT-68K-Bounds> added to handle:
//\\ #
//\\ # %routine extract params(%string(255) %name in,out,
//\\ #    %integer %array(1:max params) %name params)
//\\ #

//\\ P<OPT-arrayname> = 
//\\    "array" <Opt-DIMENSIONS> "name",
//\\    "array" <OPT-68K-Bounds> "name",
//\\   ;

case P_OPT_arrayname:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_array, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-DIMENSIONS>  
    T[3] = kw(AST__KW, KW_name, A[ap+2]);
    T[0] = mktuple(AST_OPT_arrayname, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_array, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-68K-Bounds>  
    T[3] = kw(AST__KW, KW_name, A[ap+2]);
    T[0] = mktuple(AST_OPT_arrayname, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_OPT_arrayname, alt /*2*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # for the example from 68000 Imp,
//\\ # %routine y (%integer %name %array (1) %name b)

//\\ P<Opt-DIMENSIONS> = 
//\\    '(' <INT-CONST> ')',
//\\   ;

case P_Opt_DIMENSIONS:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '(', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <INT-CONST>  
    T[3] = lit(AST__LIT, ')', A[ap+2]);
    T[0] = mktuple(AST_Opt_DIMENSIONS, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_Opt_DIMENSIONS, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<Opt-INTEGER> = 
//\\    "integer",
//\\   ;

case P_Opt_INTEGER:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_integer, A[ap+0]);
    T[0] = mktuple(AST_Opt_INTEGER, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_Opt_INTEGER, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # "42(2)" is equivalent to "42, 42".  (*) means 'as many more are needed to fill the array' so must come last.
//\\ # However it looks like <REPFACT> is also used as the string length indicator?!

//\\ P<REPFACT> = 
//\\    '(' <Opt-STAROREXPR> ')',
//\\   ;

case P_REPFACT:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '(', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-STAROREXPR>  
    T[3] = lit(AST__LIT, ')', A[ap+2]);
    T[0] = mktuple(AST_REPFACT, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_REPFACT, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<Opt-STAROREXPR> = 
//\\    <STAROREXPR>,
//\\   ;

case P_Opt_STAROREXPR:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <STAROREXPR>
    T[0] = mktuple(AST_Opt_STAROREXPR, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_Opt_STAROREXPR, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # Used in switch label.  (*) marks a catch-all. (like default: in C)
//\\ # Or at least SHOULD be used in switch label.  Looks like it isn't... just used in <REPFACT>?

//\\ P<STAROREXPR> = 
//\\    <Opt-UNARY-OP> <COPERAND> <REST-OF-CEXPR>,
//\\    '*';

case P_STAROREXPR:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-UNARY-OP>
    T[2] = build_ast(A[ap+1], depth+1); // <COPERAND>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-CEXPR>
    T[0] = mktuple(AST_STAROREXPR, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {  
    T[1] = lit(AST__LIT, '*', A[ap+0]);
    T[0] = mktuple(AST_STAROREXPR, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # Opt- added here to allow plain "%long" as a declaration at <XTYPE>

//\\ P<Opt-BTYPE> = 
//\\    "real",
//\\    "integer",
//\\    "long" "real",
//\\   ;

case P_Opt_BTYPE:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_real, A[ap+0]);
    T[0] = mktuple(AST_Opt_BTYPE, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_integer, A[ap+0]);
    T[0] = mktuple(AST_Opt_BTYPE, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = kw(AST__KW, KW_long, A[ap+0]);  
    T[2] = kw(AST__KW, KW_real, A[ap+1]);
    T[0] = mktuple(AST_Opt_BTYPE, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_Opt_BTYPE, alt /*3*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<Opt-Comma> = 
//\\    ',',
//\\   ;

case P_Opt_Comma:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[0] = mktuple(AST_Opt_Comma, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_Opt_Comma, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<Opt-ALIAS> = 
//\\    "alias" <TEXTTEXT>,
//\\   ;

case P_Opt_ALIAS:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_alias, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <TEXTTEXT>
    T[0] = mktuple(AST_Opt_ALIAS, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_Opt_ALIAS, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<TEXTTEXT> = 
//\\    <dqstring>;

case P_TEXTTEXT:
  T[1] = bip(AST_dqstring, A[ap+0]);
  return mktuple(AST_TEXTTEXT, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);


//\\ # if we add a "C" type (to reverse the order of parameter evaluation) it would be done here.
//\\ # I don't think you would write %permroutine since they are built in to the compiler, but
//\\ # depending on how the compiler is implemented, you might, and if so they would be added here.
//\\ # I do have a vague recollection of perm routines being matched up with internal code using
//\\ # a file or declarations containing magic numbers, eg something like:
//\\ # %perm (5) %routine write(%integer n, sp)
//\\ # - but that may be a manufactured memory!
//\\ #

//\\ P<Percent-SEX> = 
//\\    "system",
//\\    "external",
//\\    "dynamic",
//\\    "prim",
//\\   ;

case P_Percent_SEX:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_system, A[ap+0]);
    T[0] = mktuple(AST_Percent_SEX, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_external, A[ap+0]);
    T[0] = mktuple(AST_Percent_SEX, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = kw(AST__KW, KW_dynamic, A[ap+0]);
    T[0] = mktuple(AST_Percent_SEX, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 3) {  
    T[1] = kw(AST__KW, KW_prim, A[ap+0]);
    T[0] = mktuple(AST_Percent_SEX, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_Percent_SEX, alt /*4*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<RECFMT-spec-OR-BODY> = 
//\\    "spec" <NAME>,
//\\    <NAME> '(' <RECFMT-DEC> <REST-OF-RECFMT-DEC> <ALT-RECFMT-DEC> ')';

case P_RECFMT_spec_OR_BODY:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_spec, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[0] = mktuple(AST_RECFMT_spec_OR_BODY, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>  
    T[2] = lit(AST__LIT, '(', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <RECFMT-DEC>
    T[4] = build_ast(A[ap+3], depth+1); // <REST-OF-RECFMT-DEC>
    T[5] = build_ast(A[ap+4], depth+1); // <ALT-RECFMT-DEC>  
    T[6] = lit(AST__LIT, ')', A[ap+5]);
    T[0] = mktuple(AST_RECFMT_spec_OR_BODY, alt /*1*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  }
  return T[0];



//\\ # 68000 Imp has a non-standard syntax for some array declarations, eg
//\\ #
//\\ # %conststring(1) %array(1:max params) parameters="B","W","L"
//\\ # %string(255) %array(0:maxfiles) list
//\\ #
//\\ # The equivalent Imp77 syntax would be
//\\ #
//\\ # %conststring(1) %array parameters(1:max params)="B","W","L"
//\\ # %string(255) %array list(0:maxfiles)
//\\ #
//\\ # Putting bounds after a %name is also from the 68000:
//\\ #
//\\ #    %integer%array%name an10(1:10)
//\\ #
//\\ # which is likely the same as
//\\ #
//\\ #    %integer%array(1)%name an10
//\\ #
//\\ #  in Imp77.  We just haven't been told the lower bound...
//\\ #
//\\ # meanwhile this broke: %string (64) %array %format sform1(0 : 1022)
//\\ #
//\\ # I'm not sure if there is any significant difference nowadays between own declarations and non-own declarations...
//\\ # the used to be distinguished by allowing initialisations... maybe worth merging the definitions now?

//\\ P<DECLN> = 
//\\    <OPT-arrayname> <OPT-spec> <NAME-or-STAR-68K> <OPT-68K-Bounds> <Opt-Init-assign> <Opt-Assign-NAME-LIST>,
//\\    "array" <OPT-spec> <OPT-format> <NAME> <Opt-NAME-LIST> <BPAIR> <REST-OF-ARLIST>,
//\\    "array" <BPAIR> <OPT-spec> <OPT-format> <NAME> <Opt-NAME-LIST> <REST-OF-ARLIST-68K>;

case P_DECLN:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <OPT-arrayname>
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-spec>
    T[3] = build_ast(A[ap+2], depth+1); // <NAME-or-STAR-68K>
    T[4] = build_ast(A[ap+3], depth+1); // <OPT-68K-Bounds>
    T[5] = build_ast(A[ap+4], depth+1); // <Opt-Init-assign>
    T[6] = build_ast(A[ap+5], depth+1); // <Opt-Assign-NAME-LIST>
    T[0] = mktuple(AST_DECLN, alt /*0*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_array, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-spec>
    T[3] = build_ast(A[ap+2], depth+1); // <OPT-format>
    T[4] = build_ast(A[ap+3], depth+1); // <NAME>
    T[5] = build_ast(A[ap+4], depth+1); // <Opt-NAME-LIST>
    T[6] = build_ast(A[ap+5], depth+1); // <BPAIR>
    T[7] = build_ast(A[ap+6], depth+1); // <REST-OF-ARLIST>
    T[0] = mktuple(AST_DECLN, alt /*1*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_array, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <BPAIR>
    T[3] = build_ast(A[ap+2], depth+1); // <OPT-spec>
    T[4] = build_ast(A[ap+3], depth+1); // <OPT-format>
    T[5] = build_ast(A[ap+4], depth+1); // <NAME>
    T[6] = build_ast(A[ap+5], depth+1); // <Opt-NAME-LIST>
    T[7] = build_ast(A[ap+6], depth+1); // <REST-OF-ARLIST-68K>
    T[0] = mktuple(AST_DECLN, alt /*2*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  }
  return T[0];




//\\ P<OWNDEC> = 
//\\    <OPT-arrayname> <OPT-spec> <SINGLE-OWNDEC> <REST-OF-OWNDEC>,
//\\    "array" <OPT-format> <OPT-spec> <BPAIR> <NAME> <Opt-Init-assign-array>,
//\\    "array" <OPT-format> <OPT-spec> <NAME> <BPAIR> <Opt-Init-assign-array>;

case P_OWNDEC:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <OPT-arrayname>
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-spec>
    T[3] = build_ast(A[ap+2], depth+1); // <SINGLE-OWNDEC>
    T[4] = build_ast(A[ap+3], depth+1); // <REST-OF-OWNDEC>
    T[0] = mktuple(AST_OWNDEC, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_array, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-format>
    T[3] = build_ast(A[ap+2], depth+1); // <OPT-spec>
    T[4] = build_ast(A[ap+3], depth+1); // <BPAIR>
    T[5] = build_ast(A[ap+4], depth+1); // <NAME>
    T[6] = build_ast(A[ap+5], depth+1); // <Opt-Init-assign-array>
    T[0] = mktuple(AST_OWNDEC, alt /*1*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_array, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-format>
    T[3] = build_ast(A[ap+2], depth+1); // <OPT-spec>
    T[4] = build_ast(A[ap+3], depth+1); // <NAME>
    T[5] = build_ast(A[ap+4], depth+1); // <BPAIR>
    T[6] = build_ast(A[ap+5], depth+1); // <Opt-Init-assign-array>
    T[0] = mktuple(AST_OWNDEC, alt /*2*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  }
  return T[0];




//\\ P<REST-OF-ARLIST> = 
//\\    ',' <NAME> <Opt-NAME-LIST> <BPAIR> <REST-OF-ARLIST>,
//\\   ;

case P_REST_OF_ARLIST:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-NAME-LIST>
    T[4] = build_ast(A[ap+3], depth+1); // <BPAIR>
    T[5] = build_ast(A[ap+4], depth+1); // <REST-OF-ARLIST>
    T[0] = mktuple(AST_REST_OF_ARLIST, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_ARLIST, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<REST-OF-ARLIST-68K> = 
//\\    ',' <NAME> <Opt-NAME-LIST> <REST-OF-ARLIST-68K>,
//\\   ;

case P_REST_OF_ARLIST_68K:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-NAME-LIST>
    T[4] = build_ast(A[ap+3], depth+1); // <REST-OF-ARLIST-68K>
    T[0] = mktuple(AST_REST_OF_ARLIST_68K, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_ARLIST_68K, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<OPT-68K-Bounds> = 
//\\    <BPAIR68K>,
//\\   ;

case P_OPT_68K_Bounds:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <BPAIR68K>
    T[0] = mktuple(AST_OPT_68K_Bounds, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_OPT_68K_Bounds, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<OPT-format> = 
//\\    "format",
//\\   ;

case P_OPT_format:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_format, A[ap+0]);
    T[0] = mktuple(AST_OPT_format, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_OPT_format, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ #
//\\ # This is the same ugly hack as <Opt-Assign-NAME-LIST> below
//\\ # The AST handling has to check for and reject the '*' in all contexts except for
//\\ # 68000-style declarations such as "@@16_4000c0 %byte *,acia s,*,acia d"
//\\ #
//\\ # Below is a note from inside the 68K compiler that may be relevant:
//\\ #
//\\ #! %record(*) or %string(*) needs %name (or @@)
//\\ #! %string alone allowed only for %const%string
//\\ #

//\\ P<NAME-or-STAR-68K> = 
//\\    '*',
//\\    <NAME>;

case P_NAME_or_STAR_68K:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '*', A[ap+0]);
    T[0] = mktuple(AST_NAME_or_STAR_68K, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>
    T[0] = mktuple(AST_NAME_or_STAR_68K, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # <Opt-Init-assign> added by gt
//\\ # This hideous hack with '*' for an anonymous entry is yet another of Hamish's idiosyncrasies:
//\\ #
//\\ # @@16_7fffc %byte status,data,*,control
//\\ #                            ^
//\\ #  "/home/gtoal/gtoal.com/athome/edinburgh/APM-gdmr/ETHER/SPY.imp"
//\\ #
//\\ # @@16_4000c0 %byte *,acia s,*,acia d
//\\ #
//\\ # and would appear to just be a lazy way to skip over an address when assigning multiple
//\\ # individual scalars to addresses...
//\\ #
//\\ # Obviously it should not be allowed in any other context - some semantic checking needed here...
//\\ #

//\\ P<Opt-Assign-NAME-LIST> = 
//\\    ',' '*' <Opt-Assign-NAME-LIST>,
//\\    ',' <NAME> <Opt-Init-assign> <Opt-Assign-NAME-LIST>,
//\\   ;

case P_Opt_Assign_NAME_LIST:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);  
    T[2] = lit(AST__LIT, '*', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-Assign-NAME-LIST>
    T[0] = mktuple(AST_Opt_Assign_NAME_LIST, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-Init-assign>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-Assign-NAME-LIST>
    T[0] = mktuple(AST_Opt_Assign_NAME_LIST, alt /*1*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[0] = mktuple(AST_Opt_Assign_NAME_LIST, alt /*2*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # Need <EXPR> instead of <CEXPR> to catch = tostring(i) because cexpr only got tostring
//\\ # Need '== <EXPR>' instead of '== <LVALUE>' to catch '== length(s)', i.e. a %map although it looks like a fn call.
//\\ # - the latter being more of a failing of LVALUE that here.
//\\ # Removed:
//\\ #   '==' <LVALUE>,
//\\ #   '=' <CEXPR>,
//\\ # These will be improved once we have semantic checks...
//\\ #

//\\ P<Opt-Init-assign> = 
//\\    <ASSOP> <EXPR>,
//\\   ;

case P_Opt_Init_assign:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <ASSOP>
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>
    T[0] = mktuple(AST_Opt_Init_assign, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_Opt_Init_assign, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # removed string resolution from assop - too much type checking

//\\ P<ASSOP> = 
//\\    '=' '=',
//\\    <SCALAR-ASSIGN>;

case P_ASSOP:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_ASSOP, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <SCALAR-ASSIGN>
    T[0] = mktuple(AST_ASSOP, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # An initialised array declaration does not need a %C following the '=' before the list of initial values.
//\\ # this is a stupid hack to get around comments in the middle of array declarations :-(
//\\ # note that it gobbles the newline
//\\ # This has to handle: "== nil(*)" from %ownrecord(i tc f)%namearray tc refs(1:maxtc) == nil(*)
//\\ # Turns out <SCALAR-ASSIGN> didn't include '==' so switched to <ASSOP> instead

//\\ P<Opt-Init-assign-array> = 
//\\    <ASSOP> <stupid> <Opt-UNARY-OP> <COPERAND> <REST-OF-CEXPR> <REPFACT> <ROCL>,
//\\   ;

case P_Opt_Init_assign_array:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <ASSOP>
    T[2] = build_ast(A[ap+1], depth+1); // <stupid>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-UNARY-OP>
    T[4] = build_ast(A[ap+3], depth+1); // <COPERAND>
    T[5] = build_ast(A[ap+4], depth+1); // <REST-OF-CEXPR>
    T[6] = build_ast(A[ap+5], depth+1); // <REPFACT>
    T[7] = build_ast(A[ap+6], depth+1); // <ROCL>
    T[0] = mktuple(AST_Opt_Init_assign_array, alt /*0*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else               {
    T[0] = mktuple(AST_Opt_Init_assign_array, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # the version without "for" is to support an old-style statement, %WHILE <cond> %THEN <ui>

//\\ P<Percent-WU> = 
//\\    "while" <CONDITION>,
//\\    "until" <CONDITION>;

case P_Percent_WU:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_while, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <CONDITION>
    T[0] = mktuple(AST_Percent_WU, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_until, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <CONDITION>
    T[0] = mktuple(AST_Percent_WU, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<Percent-WUF> = 
//\\    "while" <CONDITION>,
//\\    "until" <CONDITION>,
//\\    "for" <NAME> <SCALAR-ASSIGN> <EXPR> ',' <EXPR> ',' <EXPR>;

case P_Percent_WUF:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_while, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <CONDITION>
    T[0] = mktuple(AST_Percent_WUF, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_until, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <CONDITION>
    T[0] = mktuple(AST_Percent_WUF, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_for, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <SCALAR-ASSIGN>
    T[4] = build_ast(A[ap+3], depth+1); // <EXPR>  
    T[5] = lit(AST__LIT, ',', A[ap+4]);
    T[6] = build_ast(A[ap+5], depth+1); // <EXPR>  
    T[7] = lit(AST__LIT, ',', A[ap+6]);
    T[8] = build_ast(A[ap+7], depth+1); // <EXPR>
    T[0] = mktuple(AST_Percent_WUF, alt /*2*/, /*phrases*/ 8, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8]*/);
  }
  return T[0];




//\\ P<SCALAR-ASSIGN> = 
//\\    '=',
//\\    '<' '-';

case P_SCALAR_ASSIGN:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);
    T[0] = mktuple(AST_SCALAR_ASSIGN, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = lit(AST__LIT, '<', A[ap+0]);  
    T[2] = lit(AST__LIT, '-', A[ap+1]);
    T[0] = mktuple(AST_SCALAR_ASSIGN, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<Opt-UNTIL> = 
//\\    "until" <CONDITION>,
//\\   ;

case P_Opt_UNTIL:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_until, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <CONDITION>
    T[0] = mktuple(AST_Opt_UNTIL, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_Opt_UNTIL, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<Opt-CYCPARM> = 
//\\    <NAME> <SCALAR-ASSIGN> <EXPR> ',' <EXPR> ',' <EXPR>,
//\\   ;

case P_Opt_CYCPARM:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>
    T[2] = build_ast(A[ap+1], depth+1); // <SCALAR-ASSIGN>
    T[3] = build_ast(A[ap+2], depth+1); // <EXPR>  
    T[4] = lit(AST__LIT, ',', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <EXPR>  
    T[6] = lit(AST__LIT, ',', A[ap+5]);
    T[7] = build_ast(A[ap+6], depth+1); // <EXPR>
    T[0] = mktuple(AST_Opt_CYCPARM, alt /*0*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else               {
    T[0] = mktuple(AST_Opt_CYCPARM, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # gt changed signal to allow 2 exprs.  Mouses Imp77 adds an optional string!
//\\ # 68000: %signal 5,,holeend,"HEAPPUT: heap corrupt" %if holeend>lhb_limit

//\\ P<OPEXPR2> = 
//\\    ',' <OPT-EXPR> <OPEXPR>,
//\\   ;

case P_OPEXPR2:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-EXPR>
    T[3] = build_ast(A[ap+2], depth+1); // <OPEXPR>
    T[0] = mktuple(AST_OPEXPR2, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_OPEXPR2, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<OPT-EXPR> = 
//\\    <EXPR>,
//\\   ;

case P_OPT_EXPR:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <EXPR>
    T[0] = mktuple(AST_OPT_EXPR, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_OPT_EXPR, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # single optional ", expr" for use with %signal event (, subevent)?

//\\ P<OPEXPR> = 
//\\    ',' <OPT-EXPR> <OPSTRING>,
//\\   ;

case P_OPEXPR:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-EXPR>
    T[3] = build_ast(A[ap+2], depth+1); // <OPSTRING>
    T[0] = mktuple(AST_OPEXPR, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_OPEXPR, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # %signal 3,4,position,"Set input fails" %unless position=0

//\\ P<OPSTRING> = 
//\\    ',' <STRING-EXPR>,
//\\   ;

case P_OPSTRING:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <STRING-EXPR>
    T[0] = mktuple(AST_OPSTRING, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_OPSTRING, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # reversed conditions and 1-line cycles

//\\ P<REST-OF-SS1> = 
//\\    <Percent-IU> <CONDITION> <S>,
//\\    <Percent-WUF> <S>,
//\\    <S>,
//\\   ;

case P_REST_OF_SS1:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <Percent-IU>
    T[2] = build_ast(A[ap+1], depth+1); // <CONDITION>
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[0] = mktuple(AST_REST_OF_SS1, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <Percent-WUF>
    T[2] = build_ast(A[ap+1], depth+1); // <S>
    T[0] = mktuple(AST_REST_OF_SS1, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <S>
    T[0] = mktuple(AST_REST_OF_SS1, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_SS1, alt /*3*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<REST-OF-OWNDEC> = 
//\\    ',' <SINGLE-OWNDEC> <REST-OF-OWNDEC>,
//\\   ;

case P_REST_OF_OWNDEC:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <SINGLE-OWNDEC>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-OWNDEC>
    T[0] = mktuple(AST_REST_OF_OWNDEC, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_REST_OF_OWNDEC, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<SINGLE-OWNDEC> = 
//\\    <NAME> <Opt-ALIAS> <Opt-Init-assign>;

case P_SINGLE_OWNDEC:
  T[1] = build_ast(A[ap+0], depth+1); // <NAME>
  T[2] = build_ast(A[ap+1], depth+1); // <Opt-ALIAS>
  T[3] = build_ast(A[ap+2], depth+1); // <Opt-Init-assign>
  return mktuple(AST_SINGLE_OWNDEC, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);



//\\ P<ROCL> = 
//\\    ',' <stupid> <Opt-UNARY-OP> <COPERAND> <REST-OF-CEXPR> <REPFACT> <ROCL>,
//\\   ;

case P_ROCL:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <stupid>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-UNARY-OP>
    T[4] = build_ast(A[ap+3], depth+1); // <COPERAND>
    T[5] = build_ast(A[ap+4], depth+1); // <REST-OF-CEXPR>
    T[6] = build_ast(A[ap+5], depth+1); // <REPFACT>
    T[7] = build_ast(A[ap+6], depth+1); // <ROCL>
    T[0] = mktuple(AST_ROCL, alt /*0*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else               {
    T[0] = mktuple(AST_ROCL, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<stupid> = 
//\\    <COMMENT>,
//\\   ;

case P_stupid:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <COMMENT>
    T[0] = mktuple(AST_stupid, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_stupid, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # extrinsic is an old form meaning roughly "external spec"

//\\ P<XOWN> = 
//\\    "own",
//\\    "external",
//\\    "extrinsic",
//\\    "constant",
//\\    "const";

case P_XOWN:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_own, A[ap+0]);
    T[0] = mktuple(AST_XOWN, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_external, A[ap+0]);
    T[0] = mktuple(AST_XOWN, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = kw(AST__KW, KW_extrinsic, A[ap+0]);
    T[0] = mktuple(AST_XOWN, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 3) {  
    T[1] = kw(AST__KW, KW_constant, A[ap+0]);
    T[0] = mktuple(AST_XOWN, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_const, A[ap+0]);
    T[0] = mktuple(AST_XOWN, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];


//\\ E
@


1.11
log
@small grammar tidying
@
text
@d32 19
d52 1
d57 1
a57 1
//\\ int at_startofline_____ = TRUE;
d97 2
d765 1
a765 1
//\\ # we use some parse-time code in phrase <COLON> to modify how line reconstruction
d3989 2
d3996 1
a3996 1
//\\    "array" <OPT-spec> <NAME> <Opt-NAME-LIST> <BPAIR> <REST-OF-ARLIST>,
d4011 6
a4016 5
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-NAME-LIST>
    T[5] = build_ast(A[ap+4], depth+1); // <BPAIR>
    T[6] = build_ast(A[ap+5], depth+1); // <REST-OF-ARLIST>
    T[0] = mktuple(AST_DECLN, alt /*1*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
@


1.10
log
@Actually seems to be working now, all the awkward cases handled.
@
text
@d1 13
d16 1
d19 1
d22 1
d24 1
d27 2
a31 8
//\\ #ifdef UNUSED_FOR_NOW
//\\ // some semantic routine assistance:
//\\ int typedef_table[123];// for now
//\\ int push(int val, int *table);
//\\ 
//\\ int check(int Aval, int *table);
//\\ 
//\\ #endif
d37 2
a38 1
//\\ int at_startofline_____ = TRUE; // not using this yet so giving it a name I won't use by accident by confusing it with at_startofstatement
d46 2
d77 16
a298 21
//\\ # This is an extended grammar which now accepts constructs from multiple versions of Imp
//\\ # - it was primarily based on a correct Imp80 grammar, then modified to add Imp77 constructs
//\\ # followed by features from Pdp15 Imp, old Emas "Imp9", and Hamish's 68000 extensions, etc
//\\ # The original base grammar was:
//\\ #   https://history.dcs.ed.ac.uk/archive/os/emas/emas2/compilers/imp80/imp80ps04.txt
//\\ #
//\\ # Since this accepts multiple dialects, I'm tempted to call it "PImp", short for "Polyglot Imp"...
//\\ #
//\\ # There is good info re the phrase structure grammar to be found at
//\\ # http://www.ancientgeek.org.uk/EMAS/EMAS_Manuals/IMP/A_Syntactic_and_Semantic_Definition_of_the_IMP_Language.pdf
//\\ #

//\\ P<SS> = 
//\\    <EXTERNALS> <LAST-ITEMS-IN-FILE>;

case P_SS:
  T[1] = build_ast(A[ap+0], depth+1); // <EXTERNALS>
  T[2] = build_ast(A[ap+1], depth+1); // <LAST-ITEMS-IN-FILE>
  return mktuple(AST_SS, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);


d317 2
a318 15
//\\ # The last items in a file. Main program has to be last, whether %begin/%endofprogram,
//\\ # or %begin/%end/%endoffile
//\\ # prim and perm files are effectively all externals followed by %endofprim or %endofperm
//\\ # a file of just externals has to end in %endoffile
//\\ #
//\\ # And to throw a spanner in the works, some old Pdp15 programs *appear* to omit the %begin
//\\ # from the begin/endofprogram, because they allow '!' comments to terminate with a ';'
//\\ # which later Imp versions doesn't allow.  For example in edit15.i15 we find:
//\\ #
//\\ # !!CS,N/CS,==1;%BEGIN; !EDIT15: COMPATIBLE CONTEXT EDITOR FOR PDP9/15
//\\ # This isn't really a problem with block structure, it's a problem with
//\\ # incompatible comment conventions which will likely require a command-line
//\\ # option to fix.
//\\ #
//\\ # the final EOF below is only for begin/endofprogram
d376 1
d418 1
a418 2
//\\ # It's not common but I've also seen %routine xxx/%endofprogram
//\\ # in FMACS/BOOT.imp needs to be handled.
d447 1
d604 1
a640 1
//\\    <68K-register-offset>
a644 1

d646 9
a654 2
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <68K-register-offset>  
d658 2
a659 2
    T[0] = mktuple(AST_68K_stuff, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 1) {
d663 2
a664 2
    T[0] = mktuple(AST_68K_stuff, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 2) {
d666 1
a666 1
    T[0] = mktuple(AST_68K_stuff, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
d670 1
a670 13
    T[0] = mktuple(AST_68K_stuff, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];


case P_68K_register_offset:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '-', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <INT-CONST>
    T[0] = mktuple(AST_68K_register_offset, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <INT-CONST>
    T[0] = mktuple(AST_68K_register_offset, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
d691 1
a691 1
//\\ P<spec> =
a694 8
//\\ P<Opt-68K-code-address> = 
//\\    '(' <INT-CONST> ')',
//\\   ;

//\\ P<OPT-spec> = 
//\\    <spec>,
//\\   ;

a695 6
  T[1] = build_ast(A[ap+0], depth+1); // <obscure-spec>
  T[2] = build_ast(A[ap+1], depth+1); // <Opt-68K-code-address>
  return mktuple(AST_spec, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);


case P_obscure_spec:
d698 1
a698 1
    T[0] = mktuple(AST_obscure_spec, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d701 2
a702 1
    T[0] = mktuple(AST_obscure_spec, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
a707 10
case P_OPT_spec:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <spec>
    T[0] = mktuple(AST_OPT_spec, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_OPT_spec, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];


d709 3
d725 17
d753 1
a753 1
case P_OPT_LABEL:
d761 1
a761 1
    T[0] = mktuple(AST_OPT_LABEL, alt /*0*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
d769 1
a769 1
    T[0] = mktuple(AST_OPT_LABEL, alt /*1*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
d774 1
a774 1
    T[0] = mktuple(AST_OPT_LABEL, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d779 1
a779 1
    T[0] = mktuple(AST_OPT_LABEL, alt /*3*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d781 1
a781 1
    T[0] = mktuple(AST_OPT_LABEL, alt /*4*/, /*phrases*/ 0, T /**/);
a873 1

d924 3
a926 4
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-ALIAS>
    T[4] = build_ast(A[ap+3], depth+1); // <FPP>
    T[5] = build_ast(A[ap+4], depth+1); // <S>
    T[0] = mktuple(AST_INTERNAL, alt /*7*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
d1091 1
a1091 1
case P_GOTO_DESTINATION:
d1097 1
a1097 1
    T[0] = mktuple(AST_GOTO_DESTINATION, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d1100 1
a1100 1
    T[0] = mktuple(AST_GOTO_DESTINATION, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
d1103 1
a1103 1
    T[0] = mktuple(AST_GOTO_DESTINATION, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
d1445 1
d1561 1
a1782 6
//\\ # expensive hacky test to temporarily handle X'...'
//\\ # ... and it's broken :-(  <!...> currently not working properly.
//\\ # both being reported wrongly, and not generating correct code below:
//\\ # a negated phrase should not create an AST entry. Or rather, it should create a null one.
//\\ # - I think the problem is only phrases can be negated, not BIPs ... so ...
//\\ #
d1861 1
a1861 1
case P_OPT_PM:
d1864 1
a1864 1
    T[0] = mktuple(AST_OPT_PM, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d1867 1
a1867 1
    T[0] = mktuple(AST_OPT_PM, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
d1869 1
a1869 1
    T[0] = mktuple(AST_OPT_PM, alt /*2*/, /*phrases*/ 0, T /**/);
d2270 1
d2313 1
d2317 1
d2366 1
a2366 1
case P_Opt_PARAMETERS:
d2372 1
a2372 1
    T[0] = mktuple(AST_Opt_PARAMETERS, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d2374 1
a2374 1
    T[0] = mktuple(AST_Opt_PARAMETERS, alt /*1*/, /*phrases*/ 0, T /**/);
d2385 1
a2385 1
case P_REST_OF_PARAMETERS:
d2390 1
a2390 1
    T[0] = mktuple(AST_REST_OF_PARAMETERS, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d2392 1
a2392 1
    T[0] = mktuple(AST_REST_OF_PARAMETERS, alt /*1*/, /*phrases*/ 0, T /**/);
d2536 1
a2536 1
//\\ #
d2620 1
d2671 1
a2671 1
//\\ # 
d2674 1
a2674 1
//\\ # 
d2685 1
d2731 13
d2893 1
a2893 1
//\\ # priority than '>>' and \3 >> 1 does what you would expect.
d2895 1
d2901 1
a2901 1
zxcv
a3051 8
//\\ # compare re <OPERAND> =
//\\ #   <NAME> <Opt-PARAMETERS-OR-POINTERINDEX> <Opt-RECORDFIELD-OR-POINTERINDEX>,
//\\ #   <CONST>,
//\\ #   '(' <EXPR> ')',
//\\ #   '|' <EXPR> '|',
//\\ #   '!' <EXPR> '!';
//\\ # - so I'll add || to COPERAND as well...
//\\ # needs a semantic test that <NAME> is a defined const...
a3139 2
//\\ # This remains to be done (from 68000 Imp, file APM-gdmr/I/IMNHANG.imp ):
//\\ #                                         ^
a3140 3
//\\ #                                         ^
//\\ #   "/home/gtoal/gtoal.com/athome/edinburgh/APM-gdmr/I/IMNHANG.imp"
//\\ #
a3141 2
//\\ #                                   ^ <OPT-68K-Bounds> is only appropriate if <OPT-arrayname> was present...
//\\ #
d3361 10
a3370 4
    T[1] = kw(AST__KW, KW_writeonly, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <68K-memptr>
    T[0] = mktuple(AST_68K_memptr, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {  
d3373 1
a3373 1
    T[0] = mktuple(AST_68K_memptr, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3375 1
a3375 1
    T[0] = mktuple(AST_68K_memptr, alt /*2*/, /*phrases*/ 0, T /**/);
d3464 4
a3728 3
//\\ #                                       ^
//\\ #   "/home/gtoal/gtoal.com/athome/edinburgh/APM-gdmr/I/IMNHANG.imp"
//\\ #
d3945 2
d3948 1
a3948 1
//\\ # 
d4003 1
@


1.9
log
@Big update to add a lot of 68000 Imp constructs.
Looks like Hamish went wild with extensions to Imp...
@
text
@a0 44
//\\ # Here's what's still not parsing (from the Fred Machine sources on gtoal.com)
//\\ #
//\\ # I thought the majority of these had been handled but apparently not.
//\\ #
//\\ # %else
//\\ # "APM-gdmr/I/IMP22G.imp", Line 3977, Col 3: Syntax error while looking for <INTERNALS> <INTERNALS>
//\\ #
//\\ # ... this one turns out to be the old favourite of a single ' in a comment that follows a switch label...
//\\ # - hopefully the update to the lexical analyzer will let me fix that now, by forcing 'at_start_of_statement'
//\\ # after a label... (this is probably what PDS's <COLON> did...)
//\\ #
//\\ # 3962c3962
//\\ # < do(forass):  !FORASS:loopvar:start'
//\\ # ---
//\\ # > do(forass):  !FORASS:loopvar:start
//\\ #
//\\ # @@-78(a5) %integerfn REM(%integer a,b)
//\\ # "APM-gdmr/I/PERM20C.imp", Line 16, Col 17: Syntax error while looking for <XTYPE> <OPT-name>
//\\ #
//\\ # @@16_3F00-6 %routine {|}   SIGNAL
//\\ # "APM-gdmr/I/PRIM22.imp", Line 37, Col 12: Syntax error while looking for <DIGIT-SEQ> <rest-of-number>
//\\ #
//\\ # @@16_3F00-192 %routine         closeinput
//\\ #               ^
//\\ # "APM-gdmr/I/PRIMGEN.imp", Line 4, Col 14: Syntax error while looking for <DIGIT-SEQ> <rest-of-number>
//\\ #
//\\ # @@16_7fffc %writeonly %volatile %Byteinteger Eths, Ethd, Ethz, Ethc
//\\ #            ^
//\\ # "APM-gdmr/SYS/ETHER.imp", Line 69, Col 11: Syntax error while looking for <Opt-alphanumeric-SEQ> <Opt-alphanumeric-SEQ>
//\\ #
//\\ # @@16_4000c0 %byte *,acia s,*,acia d
//\\ #                  ^
//\\ # "APM-gdmr/SYS/IO_NTY.imp", Line 5, Col 17: Syntax error while looking for <BASE-XTYPE> <Opt-INTEGER>
//\\ #
//\\ # %conststring(1) %array(1:max params) parameters="B","W","L"
//\\ #                         ^
//\\ # "APM-gdmr/USEFUL/PAMTEST.imp", Line 7, Col 24: Syntax error while looking for <DIGIT-SEQ> <rest-of-number>
//\\ #
//\\ # %string(255) %array(0:maxfiles) list
//\\ #                                     ^
//\\ # "APM-gdmr/USEFUL/PRINT.imp", Line 27, Col 36: Syntax error while looking for <opt-letter-or-digit-seq> <opt-letter-or-digit-seq>
//\\ # {at least that one I understand - it's still looking for the regular array bounds pair that should come in that position}
//\\ #
//\\ #
d9 1
d12 52
d276 4
d378 2
a379 1

d397 1
a397 1
//\\ # - this isn't the 70's any more.
d400 2
a401 2
//\\    <OPT-LABEL> <INTERNAL> <INTERNALS>,
//\\    <OPT-LABEL>;
d405 1
a405 1
    T[1] = build_ast(A[ap+0], depth+1); // <OPT-LABEL>
d410 1
a410 1
    T[1] = build_ast(A[ap+0], depth+1); // <OPT-LABEL>
d417 8
d445 2
d448 2
a449 3
//\\ # '@@' <68K-code-address> before a routine name is an external spec in 68000 Imp, and
//\\ # <Opt-68K-code-address> after an external %spec is a perm routine spec in 68000 Imp.
//\\ # as in: %integerfnspec(16_1124) REM(%integer a,b)  { found in APM-gdmr/I/GGPERM.imp }
a450 1

d453 1
a453 2
//\\    <Percent-SEX> <RT> "spec" <Opt-68K-code-address> <NAME> <Opt-ALIAS> <FPP> <S>,
//\\    '@@' <68K-code-address> <Percent-SEX> <RT> <NAME> <Opt-ALIAS> <FPP> <S>,
d455 1
d457 2
d485 8
a492 19
    T[2] = build_ast(A[ap+1], depth+1); // <RT>  
    T[3] = kw(AST__KW, KW_spec, A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-68K-code-address>
    T[5] = build_ast(A[ap+4], depth+1); // <NAME>
    T[6] = build_ast(A[ap+5], depth+1); // <Opt-ALIAS>
    T[7] = build_ast(A[ap+6], depth+1); // <FPP>
    T[8] = build_ast(A[ap+7], depth+1); // <S>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*1*/, /*phrases*/ 8, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '@@', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <68K-code-address>
    T[3] = build_ast(A[ap+2], depth+1); // <Percent-SEX>
    T[4] = build_ast(A[ap+3], depth+1); // <RT>
    T[5] = build_ast(A[ap+4], depth+1); // <NAME>
    T[6] = build_ast(A[ap+5], depth+1); // <Opt-ALIAS>
    T[7] = build_ast(A[ap+6], depth+1); // <FPP>
    T[8] = build_ast(A[ap+7], depth+1); // <S>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*2*/, /*phrases*/ 8, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8]*/);
  } else if (alt == 3) {
d502 10
a511 1
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*3*/, /*phrases*/ 9, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9]*/);
d516 18
d536 2
a537 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*5*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 6) {  
d540 2
a541 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*6*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 7) {  
d547 2
a548 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*7*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 8) {  
d553 2
a554 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*8*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 9) {  
d557 2
a558 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*9*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 10) {  
d563 2
a564 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*10*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 11) {  
d567 2
a568 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*11*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 12) {  
d572 2
a573 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*12*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 13) {  
d578 2
a579 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*13*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 14) {  
d583 2
a584 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*14*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 15) {  
d588 2
a589 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*15*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 16) {  
d592 2
a593 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*16*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 17) {  
d596 2
a597 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*17*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 18) {
d599 1
a599 1
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*18*/, /*phrases*/ 1, T /*T[1]*/);
d602 1
a602 1
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*19*/, /*phrases*/ 1, T /*T[1]*/);
d607 1
a607 3

//\\ # 68000.  Note there is a %routine blah/%endofprogram in FMACS/BOOT.imp needs to be handled.
//\\ #         And a %begin/%end without an %endoffile in FMACS/FIRST4.imp
a608 1
//\\ # I have no idea what "@@#ldte " means below.
d612 2
a613 1
//\\ # %record(f)%array portinfo(1:31)
d615 2
d618 3
a620 1
//\\ # @@16_3F00-192 %routine         closeinput
d623 2
a624 5
//\\ P<Opt-68K-address> = 
//\\    '@@' <68K-register-offset> '(' <68K-register> ')',
//\\    '@@' <68K-code-address> '-' <INT-CONST>,
//\\    '@@' <68K-code-address>,
//\\    '@@' '#' <NAME>,
d627 1
a627 1
case P_Opt_68K_address:
d630 2
a631 20
    T[2] = build_ast(A[ap+1], depth+1); // <68K-register-offset>  
    T[3] = lit(AST__LIT, '(', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <68K-register>  
    T[5] = lit(AST__LIT, ')', A[ap+4]);
    T[0] = mktuple(AST_Opt_68K_address, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '@@', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <68K-code-address>  
    T[3] = lit(AST__LIT, '-', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <INT-CONST>
    T[0] = mktuple(AST_Opt_68K_address, alt /*1*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '@@', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <68K-code-address>
    T[0] = mktuple(AST_Opt_68K_address, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 3) {  
    T[1] = lit(AST__LIT, '@@', A[ap+0]);  
    T[2] = lit(AST__LIT, '#', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>
    T[0] = mktuple(AST_Opt_68K_address, alt /*3*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d633 1
a633 1
    T[0] = mktuple(AST_Opt_68K_address, alt /*4*/, /*phrases*/ 0, T /**/);
d640 7
a646 6
//\\ P<68K-register> = 
//\\    <NAME>;

case P_68K_register:
  T[1] = build_ast(A[ap+0], depth+1); // <NAME>
  return mktuple(AST_68K_register, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d649 21
a670 3
//\\ P<68K-register-offset> = 
//\\    '-' <INT-CONST>,
//\\    <INT-CONST>;
d685 18
a702 1
//\\ # this is for 68000 Imp: %integerfnspec(16_1124) REM(%integer a,b)
d705 1
a705 1
//\\    '(' <68K-code-address> ')',
d708 34
d745 1
a745 1
    T[2] = build_ast(A[ap+1], depth+1); // <68K-code-address>  
d754 9
a762 8

//\\ # numeric labels are a historical form...

//\\ P<OPT-LABEL> = 
//\\    <NAME> '(' <CEXPR> ')' ':' <OPT-LABEL>,
//\\    <NAME> '(' '*' ')' ':' <OPT-LABEL>,
//\\    <NAME> ':' <OPT-LABEL>,
//\\    <DIGIT-SEQ> ':' <OPT-LABEL>,
d770 3
a772 3
    T[4] = lit(AST__LIT, ')', A[ap+3]);  
    T[5] = lit(AST__LIT, ':', A[ap+4]);
    T[6] = build_ast(A[ap+5], depth+1); // <OPT-LABEL>
d778 3
a780 3
    T[4] = lit(AST__LIT, ')', A[ap+3]);  
    T[5] = lit(AST__LIT, ':', A[ap+4]);
    T[6] = build_ast(A[ap+5], depth+1); // <OPT-LABEL>
d783 3
a785 3
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>  
    T[2] = lit(AST__LIT, ':', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <OPT-LABEL>
d788 3
a790 3
    T[1] = build_ast(A[ap+0], depth+1); // <DIGIT-SEQ>  
    T[2] = lit(AST__LIT, ':', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <OPT-LABEL>
d800 2
a801 1
//\\ # they cannot appear in external routines.
d844 1
a844 1
//\\    <FAULT-LIST> '-' '>' <GOTO-DESTINATION>;
d850 1
a850 1
  T[4] = build_ast(A[ap+3], depth+1); // <GOTO-DESTINATION>
d873 1
d876 3
a878 2
//\\ #   %realfn %spec f(%real x)
//\\ # the fully-qualified form is also valid but comes in via the <EXTERNAL> route.
d882 1
a882 2
//\\ # They are only allowed in the body of a procedure, and in the older compilers,
//\\ # all declarations in a block had to precede any code.
d884 1
a884 2
//\\ # There is good info re the phrase structure grammar to be found at
//\\ # http://www.ancientgeek.org.uk/EMAS/EMAS_Manuals/IMP/A_Syntactic_and_Semantic_Definition_of_the_IMP_Language.pdf
d886 1
d899 1
a899 1
//\\    "spec" <NAME> <Opt-ALIAS> <FPP> <S>,
d1021 1
a1021 1
//\\    '-' '>' <GOTO-DESTINATION>,
d1051 1
a1051 1
    T[3] = build_ast(A[ap+2], depth+1); // <GOTO-DESTINATION>
d1100 1
a1100 1
//\\ P<GOTO-DESTINATION> = 
d1145 1
a1145 2
//\\ #
//\\ # added an old record declaration syntax for examples out of ai2logo.i
d1154 3
a1156 5
//\\ #    <XOWN> <XTYPE>         ("array name" | "name")?  ("spec")?  <SINGLE-OWNDEC>            <REST-OF-OWNDEC>,
//\\ #    <XOWN> <XTYPE> "array" ("format")?               ("spec")?  <NAME> <BPAIR> <CONSTLIST>;
//\\ #           <XTYPE>         ("array name" | "name")?  <NAME-or-STAR-68K> <Opt-Init-assign> <Opt-Assign-NAME-LIST>,
//\\ #           <XTYPE> "array" ("format")?               <NAME>                    <Opt-NAME-LIST> <BPAIR> <REST-OF-ARLIST>;
//\\ #   <XOWN> "record" "array" <NAME> <BPAIR> '(' <RECFMT-REF> ')' <S> <XTYPE> <DECLN> <S>,
d1161 2
a1162 10
//\\ # To do: handle %OWNSTRING(1) STERMIN=TOSTRING(10); which is currently rejected.
//\\ # - initialisation with the result of a procedure call (or any non-const expression) should
//\\ # be OK inside a block but not at the external level.
//\\ # Though if the initialisation method is by copying from the GLAP to the GLA, maybe there
//\\ # was a reason why any %owns could not be initialised this way.  It may be that tostring
//\\ # was an exception because it was a prim function and could be treated like a constant
//\\ # by the compiler...
//\\ #
//\\ # 68000: what does this mean?  @@724(a5) %integername heapfront
//\\ # also on 68000: %bytename b == length(s)
d1164 2
a1165 1
//\\ # Yet another special case from Hamish's compiler...
a1167 7
//\\ # So... "%ownrecord(i tc f)%name" must match <Opt-68K-address> <XOWN> <XTYPE>
//\\ # because "%array tc refs(1:maxtc) == nil(*)" matches "array" <OPT-format> <OPT-spec> <NAME> <BPAIR> <CONSTLIST>;
//\\ #
//\\ # We'll be OK as long as "%record(i tc f)%name" matches <XTYPE>
//\\ # and "== nil(*)" matches <CONSTLIST>
//\\ # The first four "record" items below are old format (EMAS Imp, pre-Imp80)
//\\ #
d1177 3
a1179 1
//\\ # once again I need to put in a special case to cover one of Hamish's weird notions...
d1183 5
a1187 8
//\\    <Opt-68K-address> <XOWN> <XTYPE> <OWNDEC> <S>,
//\\    <Opt-68K-address> <XOWN> "record" "array" <RADEC> <REST-OF-RADEC> <S>,
//\\    <Opt-68K-address> <XOWN> "record" <RDEC> <REST-OF-RDEC> <S>,
//\\    <Opt-68K-address> <XTYPE> <DECLN> <S>,
//\\    <Opt-68K-address> "record" "array" <RADEC> <REST-OF-RADEC> <S>,
//\\    <Opt-68K-address> "record" <RDEC> <REST-OF-RDEC> <S>,
//\\    "record" "format" <RECFMT-spec-OR-BODY> <S>,
//\\    "switch" <NAME> <Opt-NAME-LIST> '(' <EXPR> ':' <EXPR> ')' <REST-OF-SWLIST> <S>;
d1191 1
a1191 1
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-68K-address>
d1198 8
a1205 2
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-68K-address>
    T[2] = build_ast(A[ap+1], depth+1); // <XOWN>  
d1211 4
a1214 4
    T[0] = mktuple(AST_DECLARATION_S, alt /*1*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-68K-address>
    T[2] = build_ast(A[ap+1], depth+1); // <XOWN>  
d1219 1
a1219 28
    T[0] = mktuple(AST_DECLARATION_S, alt /*2*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } else if (alt == 3) {
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-68K-address>
    T[2] = build_ast(A[ap+1], depth+1); // <XTYPE>
    T[3] = build_ast(A[ap+2], depth+1); // <DECLN>
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[0] = mktuple(AST_DECLARATION_S, alt /*3*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 4) {
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-68K-address>  
    T[2] = kw(AST__KW, KW_record, A[ap+1]);  
    T[3] = kw(AST__KW, KW_array, A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <RADEC>
    T[5] = build_ast(A[ap+4], depth+1); // <REST-OF-RADEC>
    T[6] = build_ast(A[ap+5], depth+1); // <S>
    T[0] = mktuple(AST_DECLARATION_S, alt /*4*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } else if (alt == 5) {
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-68K-address>  
    T[2] = kw(AST__KW, KW_record, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <RDEC>
    T[4] = build_ast(A[ap+3], depth+1); // <REST-OF-RDEC>
    T[5] = build_ast(A[ap+4], depth+1); // <S>
    T[0] = mktuple(AST_DECLARATION_S, alt /*5*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 6) {  
    T[1] = kw(AST__KW, KW_record, A[ap+0]);  
    T[2] = kw(AST__KW, KW_format, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <RECFMT-spec-OR-BODY>
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[0] = mktuple(AST_DECLARATION_S, alt /*6*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d1221 29
a1249 11
    T[1] = kw(AST__KW, KW_switch, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-NAME-LIST>  
    T[4] = lit(AST__LIT, '(', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <EXPR>  
    T[6] = lit(AST__LIT, ':', A[ap+5]);
    T[7] = build_ast(A[ap+6], depth+1); // <EXPR>  
    T[8] = lit(AST__LIT, ')', A[ap+7]);
    T[9] = build_ast(A[ap+8], depth+1); // <REST-OF-SWLIST>
    T[10] = build_ast(A[ap+9], depth+1); // <S>
    T[0] = mktuple(AST_DECLARATION_S, alt /*7*/, /*phrases*/ 10, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9], T[10]*/);
d1459 1
a1459 1

d1565 9
a1573 1

d1575 2
a1576 2
//\\    "comment" <Rest-of-line>,
//\\    '!' <Rest-of-line>;
d1581 1
a1581 1
    T[2] = build_ast(A[ap+1], depth+1); // <Rest-of-line>
d1585 1
a1585 1
    T[2] = build_ast(A[ap+1], depth+1); // <Rest-of-line>
a1591 2
//\\ # This is a hack that needs to be better integrated with comments and whitespace and machine code instructions...
//\\ # must end in <NL>, not <S> ...
d1593 7
a1599 7
//\\ P<Rest-of-line> = 
//\\    <char> <Rest-of-line>,
//\\    <dqstring> <Rest-of-line>,
//\\    <sqstring> <Rest-of-line>,
//\\    <letter> <Rest-of-line>,
//\\    <digit> <Rest-of-line>,
//\\    <stropped> <Rest-of-line>,
d1602 1
a1602 1
case P_Rest_of_line:
d1605 2
a1606 2
    T[2] = build_ast(A[ap+1], depth+1); // <Rest-of-line>
    T[0] = mktuple(AST_Rest_of_line, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1609 2
a1610 2
    T[2] = build_ast(A[ap+1], depth+1); // <Rest-of-line>
    T[0] = mktuple(AST_Rest_of_line, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1613 2
a1614 2
    T[2] = build_ast(A[ap+1], depth+1); // <Rest-of-line>
    T[0] = mktuple(AST_Rest_of_line, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1617 2
a1618 2
    T[2] = build_ast(A[ap+1], depth+1); // <Rest-of-line>
    T[0] = mktuple(AST_Rest_of_line, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1621 2
a1622 2
    T[2] = build_ast(A[ap+1], depth+1); // <Rest-of-line>
    T[0] = mktuple(AST_Rest_of_line, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1625 2
a1626 2
    T[2] = build_ast(A[ap+1], depth+1); // <Rest-of-line>
    T[0] = mktuple(AST_Rest_of_line, alt /*5*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1629 1
a1629 48
    T[0] = mktuple(AST_Rest_of_line, alt /*6*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # A tweaked version for unparsed machine-code statements.
//\\ # With luck the assembly code format doesn't allow unbalanced quotes such as:  LDA #'x
//\\ #

//\\ P<Rest-of-statement> = 
//\\    <!semi> <char> <Rest-of-statement>,
//\\    <dqstring> <Rest-of-statement>,
//\\    <sqstring> <Rest-of-statement>,
//\\    <letter> <Rest-of-statement>,
//\\    <digit> <Rest-of-statement>,
//\\    <stropped> <Rest-of-statement>,
//\\    <NL-or-SEMI>;

case P_Rest_of_statement:
  if (alt == 0)        {
    T[1] = -1; // <!semi>
    T[2] = bip(AST_char, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <Rest-of-statement>
    T[0] = mktuple(AST_Rest_of_statement, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 1) {
    T[1] = bip(AST_dqstring, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Rest-of-statement>
    T[0] = mktuple(AST_Rest_of_statement, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 2) {
    T[1] = bip(AST_sqstring, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Rest-of-statement>
    T[0] = mktuple(AST_Rest_of_statement, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 3) {
    T[1] = build_ast(A[ap+0], depth+1); // <letter>
    T[2] = build_ast(A[ap+1], depth+1); // <Rest-of-statement>
    T[0] = mktuple(AST_Rest_of_statement, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 4) {
    T[1] = build_ast(A[ap+0], depth+1); // <digit>
    T[2] = build_ast(A[ap+1], depth+1); // <Rest-of-statement>
    T[0] = mktuple(AST_Rest_of_statement, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 5) {
    T[1] = bip(AST_stropped, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Rest-of-statement>
    T[0] = mktuple(AST_Rest_of_statement, alt /*5*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <NL-or-SEMI>
    T[0] = mktuple(AST_Rest_of_statement, alt /*6*/, /*phrases*/ 1, T /*T[1]*/);
d1874 1
a1874 1
//\\ P<OPT-PM> = 
d1895 1
a1895 1
//\\    '@@' <OPT-PM> <DIGIT-SEQ>,
d1901 1
a1901 1
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-PM>
d1962 3
d1966 1
a1966 1
//\\ # Hamish's PDP15 imp machine code syntax definitely not supported.
d1969 5
a1973 1
//\\    <Rest-of-statement>;
d1976 22
a1997 2
  T[1] = build_ast(A[ap+0], depth+1); // <Rest-of-statement>
  return mktuple(AST_UCI, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d2071 1
a2071 1
//\\ # <NAME> <Opt-PARAMETERS> added by gt for predicates
d2077 1
a2077 1
//\\    <NAME> <Opt-PARAMETERS>,
d2093 1
a2093 1
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-PARAMETERS>
d2138 2
a2139 2
//\\ # Current Imp77 restricted to -> a.("test").b  with a and b being optional.
//\\ # Older Emas implementation allowed multiple parts I'm fairly sure, eg -> a.("match1").b.("match2").c
d2145 2
d2194 4
a2197 1
//\\ # No bracketed expressions, only '.' operator allowed.
d2283 5
a2287 2
//\\ # Ordering is important, eg ## must come before #

d2330 3
a2332 2


d2375 1
a2375 1
//\\ # 'Application' i.e. parameters to routine or function call
d2377 2
a2378 2
//\\ P<Opt-PARAMETERS> = 
//\\    '(' <EXPR> <REST-OF-PARAMETERS> ')',
d2385 1
a2385 1
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-PARAMETERS>  
d2396 2
a2397 2
//\\ P<REST-OF-PARAMETERS> = 
//\\    ',' <EXPR> <REST-OF-PARAMETERS>,
d2404 1
a2404 1
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-PARAMETERS>
d2546 1
a2546 3
//\\ #P<EXPR> =
//\\ #   <Opt-UNARY-OP> <OPERAND> <REST-OF-EXPR>;
//\\ # for Hamish's PDP9/15 Imp (old): INDP == INDEX0++P
d2548 1
d2550 1
a2550 1
//\\ # Need lvalue fix for:  b[3] = nl
a2551 1

d2556 1
a2556 1
//\\    <Opt-PARAMETERS>;
d2575 1
a2575 1
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-PARAMETERS>
d2621 14
a2634 2
//\\ # Unfortunately there may be obscure cases where an ambiguous parse might result.

d2671 28
a2698 3
//\\ # operators all together for now until we use the grammar to handle precedence.
//\\ # regular exprs converted, cexprs not done yet.

d2867 28
a2894 2
//\\ # unary operators.  Highest precedence.

d2900 1
a2900 1

d3351 4
d3357 1
a3357 1
//\\    <OPT-68K-register> <BASE-XTYPE> <OPT-name>;
d3360 1
a3360 1
  T[1] = build_ast(A[ap+0], depth+1); // <OPT-68K-register>
a3365 4
//\\ # C-like register qualifiers (Hamish, again)
//\\ # %register(a2)%integer r1,r2
//\\ # %register(a2)%byte%name bn
//\\ # %register(a3)%short%name sn
d3367 4
a3370 2
//\\ P<OPT-68K-register> = 
//\\    "register" '(' <68K-register> ')',
d3373 1
a3373 1
case P_OPT_68K_register:
d3375 27
a3401 5
    T[1] = kw(AST__KW, KW_register, A[ap+0]);  
    T[2] = lit(AST__LIT, '(', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <68K-register>  
    T[4] = lit(AST__LIT, ')', A[ap+3]);
    T[0] = mktuple(AST_OPT_68K_register, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d3403 1
a3403 1
    T[0] = mktuple(AST_OPT_68K_register, alt /*1*/, /*phrases*/ 0, T /**/);
d3409 16
d3537 1
a3537 1
//\\    "array" <ADECLN>;
d3547 1
a3547 1
    T[2] = build_ast(A[ap+1], depth+1); // <ADECLN>
d3556 2
a3557 2
//\\ P<ADECLN> = 
//\\    <NAME> <Opt-NAME-LIST> <BPAIR> <REST-OF-ARLIST>;
d3559 1
a3559 1
case P_ADECLN:
d3563 2
a3564 2
  T[4] = build_ast(A[ap+3], depth+1); // <REST-OF-ARLIST>
  return mktuple(AST_ADECLN, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d3568 2
a3569 2
//\\ P<REST-OF-ARLIST> = 
//\\    ',' <ADECLN>,
d3572 1
a3572 1
case P_REST_OF_ARLIST:
d3575 2
a3576 2
    T[2] = build_ast(A[ap+1], depth+1); // <ADECLN>
    T[0] = mktuple(AST_REST_OF_ARLIST, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3578 1
a3578 1
    T[0] = mktuple(AST_REST_OF_ARLIST, alt /*1*/, /*phrases*/ 0, T /**/);
d3698 3
a3700 2
//\\ # WAS P<OPT-arrayname-OR-name> = "array" "name", "name", ;
//\\ # but "name" removed because it fits better with <XTYPE>
d3702 4
a3705 1
//\\ # <Opt-DIMENSIONS> added to handle (see below) %routine y (%integer %name %array (1) %name b)
d3710 1
d3719 5
d3725 1
a3725 1
    T[0] = mktuple(AST_OPT_arrayname, alt /*1*/, /*phrases*/ 0, T /**/);
d3952 2
a3953 16


//\\ # Scalar declaration
//\\ # <Opt-Init-assign> added by gt
//\\ # "name" has been removed from <OPT-array-OR-name> and moved to <XTYPE> which precedes <DECLN>
//\\ #
//\\ # 68K: %bytespec(16_7fffc)status
//\\ # More 68K: %integerarrayspec(16_C00000) frame(0:32767)
//\\ #
//\\ # Jesus wept :-(  MORE...:
//\\ #    %integer%array%name an10(1:10)
//\\ # is likely the same as
//\\ #    %integer%array(1)%name an10
//\\ #  in Imp77.  We just haven't been told the lower bound...
//\\ #
//\\ # These are 68000 syntax which is rejected by Imp77:
d3962 5
a3966 1
//\\ # once again I need to put in a special case to cover one of Hamish's weird notions...
d3968 6
d3976 3
a3978 2
//\\    <OPT-arrayname> <OPT-68K-spec> <NAME> <OPT-68K-Bounds> <Opt-Init-assign> <Opt-Assign-NAME-LIST>,
//\\    "array" <OPT-68K-Bounds> <OPT-68K-spec> <OPT-format> <ADECLN>;
d3983 2
a3984 2
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-68K-spec>
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>
d3989 8
d3999 2
a4000 2
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-68K-Bounds>
    T[3] = build_ast(A[ap+2], depth+1); // <OPT-68K-spec>
d4002 4
a4005 2
    T[5] = build_ast(A[ap+4], depth+1); // <ADECLN>
    T[0] = mktuple(AST_DECLN, alt /*1*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
d4011 4
d4016 31
a4046 2
//\\ P<OPT-68K-Bounds> = 
//\\    <BPAIR68K>,
d4049 8
a4056 4
case P_OPT_68K_Bounds:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <BPAIR68K>
    T[0] = mktuple(AST_OPT_68K_Bounds, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d4058 1
a4058 1
    T[0] = mktuple(AST_OPT_68K_Bounds, alt /*1*/, /*phrases*/ 0, T /**/);
a4063 11
//\\ # Unbelievable how many ad-hoc hacks Hamish has put in his 68000 Imp compiler :-(
//\\ #
//\\ # This one is for:
//\\ #   %integerarrayspec(16_C00000) frame(0:32767)
//\\ # and
//\\ #   %bytespec(16_7fffc)status
//\\ #
//\\ # which I'm pretty sure he has already covered with a *different* extension in the same compiler :-(
//\\ # i.e.
//\\ #   @@16_7fffc %byte status  ???
//\\ #
d4065 2
a4066 2
//\\ P<OPT-68K-spec> = 
//\\    "spec" '(' <68K-code-address> ')',
d4069 1
a4069 1
case P_OPT_68K_spec:
d4071 5
a4075 5
    T[1] = kw(AST__KW, KW_spec, A[ap+0]);  
    T[2] = lit(AST__LIT, '(', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <68K-code-address>  
    T[4] = lit(AST__LIT, ')', A[ap+3]);
    T[0] = mktuple(AST_OPT_68K_spec, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d4077 1
a4077 1
    T[0] = mktuple(AST_OPT_68K_spec, alt /*1*/, /*phrases*/ 0, T /**/);
a4082 1
//\\ # Might have to change this to <CEXPR> once <CEXPR> works a bit better...
d4084 12
a4095 2
//\\ P<68K-code-address> = 
//\\    <INT-CONST>;
a4096 3
case P_68K_code_address:
  T[1] = build_ast(A[ap+0], depth+1); // <INT-CONST>
  return mktuple(AST_68K_code_address, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d4191 1
a4191 2
//\\    '=' '=' <EXPR>,
//\\    <SCALAR-ASSIGN> <EXPR>,
d4195 18
d4216 2
a4217 3
    T[3] = build_ast(A[ap+2], depth+1); // <EXPR>
    T[0] = mktuple(AST_Opt_Init_assign, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 1) {
d4219 26
a4244 2
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>
    T[0] = mktuple(AST_Opt_Init_assign, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d4246 1
a4246 1
    T[0] = mktuple(AST_Opt_Init_assign, alt /*2*/, /*phrases*/ 0, T /**/);
a4431 19
//\\ # removed string resolution from assop - too much type checking

//\\ P<ASSOP> = 
//\\    '=' '=',
//\\    <SCALAR-ASSIGN>;

case P_ASSOP:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_ASSOP, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <SCALAR-ASSIGN>
    T[0] = mktuple(AST_ASSOP, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



a4459 28
//\\ # Again "name" has been moved from <OPT-arrayname-OR-name> to <XTYPE> which precedes <OWNDEC>
//\\ #

//\\ P<OWNDEC> = 
//\\    <OPT-arrayname> <OPT-spec> <SINGLE-OWNDEC> <REST-OF-OWNDEC>,
//\\    "array" <OPT-format> <OPT-spec> <Opt-68K-code-address> <NAME> <BPAIR> <CONSTLIST>;

case P_OWNDEC:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <OPT-arrayname>
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-spec>
    T[3] = build_ast(A[ap+2], depth+1); // <SINGLE-OWNDEC>
    T[4] = build_ast(A[ap+3], depth+1); // <REST-OF-OWNDEC>
    T[0] = mktuple(AST_OWNDEC, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_array, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-format>
    T[3] = build_ast(A[ap+2], depth+1); // <OPT-spec>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-68K-code-address>
    T[5] = build_ast(A[ap+4], depth+1); // <NAME>
    T[6] = build_ast(A[ap+5], depth+1); // <BPAIR>
    T[7] = build_ast(A[ap+6], depth+1); // <CONSTLIST>
    T[0] = mktuple(AST_OWNDEC, alt /*1*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  }
  return T[0];



a4488 27
//\\ # An initialised array declaration does not need a %C following the '=' before the list of initial values.
//\\ # this is a stupid hack to get around comments in the middle of array declarations :-(
//\\ # note that it gobbles the newline
//\\ # This has to handle: "== nil(*)" from %ownrecord(i tc f)%namearray tc refs(1:maxtc) == nil(*)
//\\ # Turns out <SCALAR-ASSIGN> didn't include '==' so switched to <ASSOP> instead

//\\ P<CONSTLIST> = 
//\\    <ASSOP> <stupid> <Opt-UNARY-OP> <COPERAND> <REST-OF-CEXPR> <REPFACT> <ROCL>,
//\\   ;

case P_CONSTLIST:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <ASSOP>
    T[2] = build_ast(A[ap+1], depth+1); // <stupid>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-UNARY-OP>
    T[4] = build_ast(A[ap+3], depth+1); // <COPERAND>
    T[5] = build_ast(A[ap+4], depth+1); // <REST-OF-CEXPR>
    T[6] = build_ast(A[ap+5], depth+1); // <REPFACT>
    T[7] = build_ast(A[ap+6], depth+1); // <ROCL>
    T[0] = mktuple(AST_CONSTLIST, alt /*0*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else               {
    T[0] = mktuple(AST_CONSTLIST, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



a4521 16
  }
  return T[0];




//\\ P<OPT-spec> = 
//\\    "spec",
//\\   ;

case P_OPT_spec:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_spec, A[ap+0]);
    T[0] = mktuple(AST_OPT_spec, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_OPT_spec, alt /*1*/, /*phrases*/ 0, T /**/);
@


1.8
log
@grammar tweaks for initialisations in 68000 Imp
may need some semantic checks for some rules which previpusly caught problems at the grammar level
@
text
@d1 44
d423 5
d431 3
a433 3
//\\    <Percent-SEX> <RT> "spec" <NAME> <Opt-ALIAS> <FPP> <S>,
//\\    '@@' <INT-CONST> <Percent-SEX> <RT> <NAME> <Opt-ALIAS> <FPP> <S>,
//\\    <Percent-SEX> <RT> <NAME> <Opt-ALIAS> <FPP> <S> <INTERNALS> <end68K> <S>,
d440 2
d463 6
a468 5
    T[4] = build_ast(A[ap+3], depth+1); // <NAME>
    T[5] = build_ast(A[ap+4], depth+1); // <Opt-ALIAS>
    T[6] = build_ast(A[ap+5], depth+1); // <FPP>
    T[7] = build_ast(A[ap+6], depth+1); // <S>
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*1*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
d471 1
a471 1
    T[2] = build_ast(A[ap+1], depth+1); // <INT-CONST>
d487 1
a487 1
    T[8] = build_ast(A[ap+7], depth+1); // <end68K>
d519 10
d532 2
a533 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*10*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 11) {  
d538 2
a539 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*11*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 12) {  
d543 2
a544 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*12*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 13) {  
d548 2
a549 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*13*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 14) {  
d552 2
a553 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*14*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 15) {  
d556 2
a557 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*15*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 16) {
d559 1
a559 1
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*16*/, /*phrases*/ 1, T /*T[1]*/);
d562 1
a562 19
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*17*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # nasty special case for some 68000 sources which are routine BLAH/endofprogram

//\\ P<end68K> = 
//\\    "endofprogram",
//\\    "end";

case P_end68K:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_endofprogram, A[ap+0]);
    T[0] = mktuple(AST_end68K, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_end, A[ap+0]);
    T[0] = mktuple(AST_end68K, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
d576 3
d581 4
a584 2
//\\ P<Opt-address> = 
//\\    '@@' <INT-CONST> <Opt-register>,
d588 1
a588 1
case P_Opt_address:
d591 5
a595 3
    T[2] = build_ast(A[ap+1], depth+1); // <INT-CONST>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-register>
    T[0] = mktuple(AST_Opt_address, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d597 10
d610 27
a636 1
    T[0] = mktuple(AST_Opt_address, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d638 2
a639 1
    T[0] = mktuple(AST_Opt_address, alt /*2*/, /*phrases*/ 0, T /**/);
d645 1
a645 1
//\\ # @@400(a5) %record(*)%namearray in(0:7)
d647 2
a648 2
//\\ P<Opt-register> = 
//\\    '(' <NAME> ')',
d651 1
a651 1
case P_Opt_register:
d654 1
a654 1
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>  
d656 1
a656 1
    T[0] = mktuple(AST_Opt_register, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d658 1
a658 1
    T[0] = mktuple(AST_Opt_register, alt /*1*/, /*phrases*/ 0, T /**/);
d1051 1
d1063 1
a1063 1
//\\ #           <XTYPE>         ("array name" | "name")?  <NAME> <Opt-Init-assign> <Opt-Assign-NAME-LIST>,
d1081 5
d1087 2
d1091 11
d1104 6
a1109 6
//\\    <Opt-address> <XOWN> <XTYPE> <OWNDEC> <S>,
//\\    <Opt-address> <XOWN> "record" "array" <RADEC> <REST-OF-RADEC> <S>,
//\\    <Opt-address> <XOWN> "record" <RDEC> <REST-OF-RDEC> <S>,
//\\    <Opt-address> <XTYPE> <DECLN> <S>,
//\\    <Opt-address> "record" "array" <RADEC> <REST-OF-RADEC> <S>,
//\\    <Opt-address> "record" <RDEC> <REST-OF-RDEC> <S>,
d1115 1
a1115 1
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-address>
d1122 1
a1122 1
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-address>
d1131 1
a1131 1
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-address>
d1139 1
a1139 1
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-address>
d1145 1
a1145 1
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-address>  
d1153 1
a1153 1
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-address>  
d1323 15
a1337 4
//\\ # "else if ..." or "else" or "finish {else ...}"
//\\ # there's an ugly form of "else if ... start" that I haven't found an
//\\ # example of yet, which I'm not going to add unless I do.  If I remember
//\\ # right, it did not balance starts and finished correctly.
d1340 2
a1341 2
//\\    "else" <Percent-IU> <CONDITION> <S> <INTERNALS> <FINISH-S>,
//\\    "else" <S> <INTERNALS> "finish" <S>,
d1349 5
a1353 4
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[5] = build_ast(A[ap+4], depth+1); // <INTERNALS>
    T[6] = build_ast(A[ap+5], depth+1); // <FINISH-S>
    T[0] = mktuple(AST_FINISH_S, alt /*0*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
d1356 6
a1361 5
    T[2] = build_ast(A[ap+1], depth+1); // <S>
    T[3] = build_ast(A[ap+2], depth+1); // <INTERNALS>  
    T[4] = kw(AST__KW, KW_finish, A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <S>
    T[0] = mktuple(AST_FINISH_S, alt /*1*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
d1372 16
d1641 1
a1641 3
//\\    <DIGIT-SEQ> '_' <DIGIT-SEQ> <NAME>,
//\\    <DIGIT-SEQ> '_' <DIGIT-SEQ>,
//\\    <DIGIT-SEQ> '_' <NAME>,
d1643 1
a1643 1
//\\    <OLDHEX>;
d1649 2
a1650 3
    T[3] = build_ast(A[ap+2], depth+1); // <DIGIT-SEQ>
    T[4] = build_ast(A[ap+3], depth+1); // <NAME>
    T[0] = mktuple(AST_INT_CONST, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
a1651 10
    T[1] = build_ast(A[ap+0], depth+1); // <DIGIT-SEQ>  
    T[2] = lit(AST__LIT, '_', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <DIGIT-SEQ>
    T[0] = mktuple(AST_INT_CONST, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <DIGIT-SEQ>  
    T[2] = lit(AST__LIT, '_', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>
    T[0] = mktuple(AST_INT_CONST, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 3) {
d1653 1
a1653 1
    T[0] = mktuple(AST_INT_CONST, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
d1655 29
a1683 2
    T[1] = build_ast(A[ap+0], depth+1); // <OLDHEX>
    T[0] = mktuple(AST_INT_CONST, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
a1770 10

//\\ P<OLDHEX> = 
//\\    <OPT-SQ-LETTER> <sqstring>;

case P_OLDHEX:
  T[1] = build_ast(A[ap+0], depth+1); // <OPT-SQ-LETTER>
  T[2] = bip(AST_sqstring, A[ap+1]);
  return mktuple(AST_OLDHEX, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);


d1778 2
a1779 20
//\\ P<OPT-SQ-LETTER> = 
//\\    'M',
//\\    'X',
//\\    'B',
//\\   ;

case P_OPT_SQ_LETTER:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, 'M', A[ap+0]);
    T[0] = mktuple(AST_OPT_SQ_LETTER, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, 'X', A[ap+0]);
    T[0] = mktuple(AST_OPT_SQ_LETTER, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, 'B', A[ap+0]);
    T[0] = mktuple(AST_OPT_SQ_LETTER, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_OPT_SQ_LETTER, alt /*3*/, /*phrases*/ 0, T /**/);
  }
  return T[0];
d1781 4
a1786 3
//\\ #P<OPT-SQ-LETTER> =
//\\ #   <alphanumeric>,
//\\ #  ;
d2164 1
a2164 1
//\\    '(' <STRING-RVALUE> ')';
d2168 1
a2168 1
  T[2] = build_ast(A[ap+1], depth+1); // <STRING-RVALUE>
d3018 9
d3029 1
a3029 1
//\\    <XTYPE> <OPT-arrayname> <NAME> <Opt-NAME-LIST>,
d3031 1
a3031 1
//\\    "name" <NAME> <Opt-NAME-LIST>;
d3038 3
a3040 2
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-NAME-LIST>
    T[0] = mktuple(AST_FORMAL_PARAMETER_DECLARATION, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d3050 28
a3077 3
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-NAME-LIST>
    T[0] = mktuple(AST_FORMAL_PARAMETER_DECLARATION, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d3171 2
a3173 1
//\\    "short" <Opt-INTEGER>,
d3196 1
a3196 1
    T[1] = kw(AST__KW, KW_half, A[ap+0]);
d3204 4
d3210 1
a3210 1
    T[0] = mktuple(AST_BASE_XTYPE, alt /*7*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3214 1
a3214 1
    T[0] = mktuple(AST_BASE_XTYPE, alt /*8*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3220 2
d3224 1
a3224 1
//\\    <BASE-XTYPE> <OPT-name>;
d3227 27
a3253 3
  T[1] = build_ast(A[ap+0], depth+1); // <BASE-XTYPE>
  T[2] = build_ast(A[ap+1], depth+1); // <OPT-name>
  return mktuple(AST_XTYPE, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3415 44
d3462 1
a3462 1
//\\    '(' <EXPR> ':' <EXPR> <REST-OF-BPLIST> ')';
d3466 1
a3466 1
  T[2] = build_ast(A[ap+1], depth+1); // <EXPR>
d3468 1
a3468 1
  T[4] = build_ast(A[ap+3], depth+1); // <EXPR>
d3474 14
d3509 20
d3531 3
d3536 1
a3536 1
//\\    "array" "name",
d3541 4
a3544 3
    T[1] = kw(AST__KW, KW_array, A[ap+0]);  
    T[2] = kw(AST__KW, KW_name, A[ap+1]);
    T[0] = mktuple(AST_OPT_arrayname, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3552 23
d3779 20
d3801 2
a3802 2
//\\    <OPT-arrayname> <NAME> <Opt-Init-assign> <Opt-Assign-NAME-LIST>,
//\\    "array" <OPT-format> <ADECLN>;
d3807 6
a3812 4
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-Init-assign>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-Assign-NAME-LIST>
    T[0] = mktuple(AST_DECLN, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d3815 51
a3865 3
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-format>
    T[3] = build_ast(A[ap+2], depth+1); // <ADECLN>
    T[0] = mktuple(AST_DECLN, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d3871 10
d3897 27
d3925 13
d3940 1
d3946 5
d3955 1
a3955 1
    T[0] = mktuple(AST_Opt_Assign_NAME_LIST, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d3957 1
a3957 1
    T[0] = mktuple(AST_Opt_Assign_NAME_LIST, alt /*1*/, /*phrases*/ 0, T /**/);
d3974 1
a3974 1
//\\    '=' <EXPR>,
d3983 2
a3984 2
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);
d4018 1
a4018 1
//\\    "for" <NAME> '=' <EXPR> ',' <EXPR> ',' <EXPR>;
d4031 2
a4032 2
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>  
    T[3] = lit(AST__LIT, '=', A[ap+2]);
d4045 18
d4081 1
a4081 1
//\\    <NAME> '=' <EXPR> ',' <EXPR> ',' <EXPR>,
d4086 2
a4087 2
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
d4178 1
a4178 2
//\\    '=',
//\\    '<' '-';
d4185 2
a4186 2
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);
a4187 4
  } else               {  
    T[1] = lit(AST__LIT, '<', A[ap+0]);  
    T[2] = lit(AST__LIT, '-', A[ap+1]);
    T[0] = mktuple(AST_ASSOP, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d4226 1
a4226 1
//\\    "array" <OPT-format> <OPT-spec> <NAME> <BPAIR> <CONSTLIST>;
d4239 5
a4243 4
    T[4] = build_ast(A[ap+3], depth+1); // <NAME>
    T[5] = build_ast(A[ap+4], depth+1); // <BPAIR>
    T[6] = build_ast(A[ap+5], depth+1); // <CONSTLIST>
    T[0] = mktuple(AST_OWNDEC, alt /*1*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
d4281 2
d4285 1
a4285 1
//\\    '=' <stupid> <Opt-UNARY-OP> <COPERAND> <REST-OF-CEXPR> <REPFACT> <ROCL>,
d4289 2
a4290 2
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);
@


1.7
log
@*** empty log message ***
@
text
@a0 6
//\\ # I am considering removing <alphanumeric> and <digit> from the BIPs
//\\ # and just handling them via graamar rules (or regexps, once support is added)
//\\ # because a quick pass over the AST can consolidate a string of alphanumerics
//\\ # into a <NAME> relatively easily.  We really just need stropped letters,
//\\ # both types of string, NL, and EOF.  Everything else can be done with individual
//\\ # characters...
a2 4
//\\ # upper or lower case letter or a digit, but only if the digit is following a letter
//\\ B<alphanumeric> = 1;
//\\ # digit
//\\ B<digit> = 2;
d4 1
a4 1
//\\ B<sqstring> = 3;
d6 209
a214 4
//\\ B<dqstring> = 4;
//\\ B<NL> = 5;
//\\ B<char> = 6;
//\\ B<EOF> = 7;
d264 2
d268 4
a271 4
//\\    "begin" <S> <INTERNALS> <ENDPROGRAM> <BLANKS> <EOF>,
//\\    "endoffile" <BLANKS> <EOF>,
//\\    "endofperm" <BLANKS> <EOF>,
//\\    "endofprim" <BLANKS> <EOF>;
d275 6
a280 7
    T[1] = kw(AST__KW, KW_begin, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <S>
    T[3] = build_ast(A[ap+2], depth+1); // <INTERNALS>
    T[4] = build_ast(A[ap+3], depth+1); // <ENDPROGRAM>
    T[5] = build_ast(A[ap+4], depth+1); // <BLANKS>
    T[6] = bip(AST_EOF, A[ap+5]);
    T[0] = mktuple(AST_LAST_ITEMS_IN_FILE, alt /*0*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
d282 6
a287 4
    T[1] = kw(AST__KW, KW_endoffile, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <BLANKS>
    T[3] = bip(AST_EOF, A[ap+2]);
    T[0] = mktuple(AST_LAST_ITEMS_IN_FILE, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d289 10
a298 9
    T[1] = kw(AST__KW, KW_endofperm, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <BLANKS>
    T[3] = bip(AST_EOF, A[ap+2]);
    T[0] = mktuple(AST_LAST_ITEMS_IN_FILE, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_endofprim, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <BLANKS>
    T[3] = bip(AST_EOF, A[ap+2]);
    T[0] = mktuple(AST_LAST_ITEMS_IN_FILE, alt /*3*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d305 3
a307 3
//\\ P<ENDPROGRAM> = 
//\\    "endofprogram",
//\\    "end" <BLANKS> "endoffile";
d309 1
a309 1
case P_ENDPROGRAM:
d311 2
a312 2
    T[1] = kw(AST__KW, KW_endofprogram, A[ap+0]);
    T[0] = mktuple(AST_ENDPROGRAM, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d314 2
a315 4
    T[1] = kw(AST__KW, KW_end, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <BLANKS>  
    T[3] = kw(AST__KW, KW_endoffile, A[ap+2]);
    T[0] = mktuple(AST_ENDPROGRAM, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d359 19
d381 1
d383 2
a384 1
//\\    <Percent-SEX> <RT> <NAME> <Opt-ALIAS> <FPP> <S> <INTERNALS> "end" <S>,
d387 1
d394 3
d401 8
a408 1
  if (alt == 0)        {
d416 12
a427 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*0*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else if (alt == 1) {
d434 2
a435 2
    T[7] = build_ast(A[ap+6], depth+1); // <INTERNALS>  
    T[8] = kw(AST__KW, KW_end, A[ap+7]);
d437 2
a438 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*1*/, /*phrases*/ 9, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9]*/);
  } else if (alt == 2) {
d440 2
a441 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 3) {  
d444 6
a449 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 4) {  
d455 2
a456 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*4*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 5) {  
d461 2
a462 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*5*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 6) {  
d465 2
a466 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*6*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 7) {  
d470 2
a471 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*7*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 8) {  
d476 2
a477 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*8*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 9) {  
d481 15
a495 2
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*9*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 10) {
d497 1
a497 1
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*10*/, /*phrases*/ 1, T /*T[1]*/);
d500 71
a570 1
    T[0] = mktuple(AST_EXTERNAL_OR_INTERNAL, alt /*11*/, /*phrases*/ 1, T /*T[1]*/);
d768 9
a789 21
//\\ # from "begin" "end" blocks

//\\ P<Opt-OFPROGRAM> = 
//\\    "of" "program" <BLANKS> <EOF>,
//\\    <S>;

case P_Opt_OFPROGRAM:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_of, A[ap+0]);  
    T[2] = kw(AST__KW, KW_program, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <BLANKS>
    T[4] = bip(AST_EOF, A[ap+3]);
    T[0] = mktuple(AST_Opt_OFPROGRAM, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <S>
    T[0] = mktuple(AST_Opt_OFPROGRAM, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



d837 1
a837 1
//\\    <NAME> <Opt-PARAMETERS> <Opt-RECORDFIELD> <OPT-ASSIGN> <AUI>,
d855 1
a855 1
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-PARAMETERS>
d974 1
a974 1
//\\ #           <XTYPE>         ("array name" | "name")?  <NAME> <Opt-Const-assign> <Opt-Assign-NAME-LIST>,
d988 7
d997 6
a1002 6
//\\    <XOWN> <XTYPE> <OWNDEC> <S>,
//\\    <XOWN> "record" "array" <RADEC> <REST-OF-RADEC> <S>,
//\\    <XOWN> "record" <RDEC> <REST-OF-RDEC> <S>,
//\\    <XTYPE> <DECLN> <S>,
//\\    "record" "array" <RADEC> <REST-OF-RADEC> <S>,
//\\    "record" <RDEC> <REST-OF-RDEC> <S>,
d1008 25
a1032 1
    T[1] = build_ast(A[ap+0], depth+1); // <XOWN>
d1034 1
a1034 1
    T[3] = build_ast(A[ap+2], depth+1); // <OWNDEC>
d1036 3
a1038 3
    T[0] = mktuple(AST_DECLARATION_S, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <XOWN>  
d1044 3
a1046 3
    T[0] = mktuple(AST_DECLARATION_S, alt /*1*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <XOWN>  
d1051 1
a1051 19
    T[0] = mktuple(AST_DECLARATION_S, alt /*2*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 3) {
    T[1] = build_ast(A[ap+0], depth+1); // <XTYPE>
    T[2] = build_ast(A[ap+1], depth+1); // <DECLN>
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[0] = mktuple(AST_DECLARATION_S, alt /*3*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 4) {  
    T[1] = kw(AST__KW, KW_record, A[ap+0]);  
    T[2] = kw(AST__KW, KW_array, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <RADEC>
    T[4] = build_ast(A[ap+3], depth+1); // <REST-OF-RADEC>
    T[5] = build_ast(A[ap+4], depth+1); // <S>
    T[0] = mktuple(AST_DECLARATION_S, alt /*4*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 5) {  
    T[1] = kw(AST__KW, KW_record, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <RDEC>
    T[3] = build_ast(A[ap+2], depth+1); // <REST-OF-RDEC>
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[0] = mktuple(AST_DECLARATION_S, alt /*5*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d1382 1
a1382 1
//\\    <alphanumeric> <Rest-of-line>,
d1401 1
a1401 1
    T[1] = bip(AST_alphanumeric, A[ap+0]);
d1405 1
a1405 1
    T[1] = bip(AST_digit, A[ap+0]);
d1420 73
d1500 3
d1631 6
a1636 6
//\\ # current line reconstruction doesn't support this. Letters come through as part of <alphanumeric>s.
//\\ #P<OPT-SQ-LETTER> =
//\\ #   'M',
//\\ #   'X',
//\\ #   'B',
//\\ #  ;
d1639 3
a1641 1
//\\    <alphanumeric>,
d1645 2
a1646 2
  if (alt == 0)        {
    T[1] = bip(AST_alphanumeric, A[ap+0]);
d1648 6
d1655 1
a1655 1
    T[0] = mktuple(AST_OPT_SQ_LETTER, alt /*1*/, /*phrases*/ 0, T /**/);
d1661 3
d1668 4
d1761 1
a1761 1
  T[1] = bip(AST_digit, A[ap+0]);
d1784 1
a1784 1
//\\    <alphanumeric> <!SQUO-STRING> <rest-of-name>;
d1787 1
a1787 1
  T[1] = bip(AST_alphanumeric, A[ap+0]);
d1789 1
a1789 1
  T[3] = build_ast(A[ap+2], depth+1); // <rest-of-name>
d1793 5
a1797 16

//\\ P<rest-of-name> = 
//\\    <NAME>,
//\\   ;

case P_rest_of_name:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>
    T[0] = mktuple(AST_rest_of_name, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_name, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



d1811 1
a1811 1
//\\    <Rest-of-line>;
d1814 1
a1814 1
  T[1] = build_ast(A[ap+0], depth+1); // <Rest-of-line>
a1878 2
//\\ # <NAME> <Opt-PARAMETERS> added by gt for predicates
//\\ # RESTOFSC handles double-sided conditions such as '0' <= ch <= '9'
d1889 2
d2096 1
d2099 1
d2101 1
a2102 2
//\\    '=' '=',
//\\    <NOT-EQUALS-ADDRESS>,
d2110 4
a2114 3
    T[0] = mktuple(AST_COMP, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <NOT-EQUALS>
d2116 3
a2118 4
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_COMP, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d2120 1
a2120 1
    T[1] = build_ast(A[ap+0], depth+1); // <NOT-EQUALS-ADDRESS>
d2359 3
d2395 1
a2395 1
//\\    '_' <NAME> <Opt-PARAMETERS> <Opt-RECORDFIELD>,
d2402 1
a2402 1
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-PARAMETERS>
d2897 1
a2897 1
//\\    <XTYPE> <OPT-arrayname-OR-name> <NAME> <Opt-NAME-LIST>,
d2904 1
a2904 1
    T[2] = build_ast(A[ap+1], depth+1); // <OPT-arrayname-OR-name>
d2999 3
a3001 1
//\\ # label and short added by gt as a quick hack
d3003 3
a3005 1
//\\ # Why is it record (<rfref?>) rather than record (<rfref>) - is record () ever an option?
d3007 1
a3007 1
//\\ P<XTYPE> = 
d3011 4
a3014 2
//\\    "long" <BTYPE>,
//\\    "byte" <FULLTYPE>,
a3015 2
//\\    "half" <FULLTYPE>,
//\\    "short" <FULLTYPE>,
d3018 1
a3018 1
case P_XTYPE:
d3021 1
a3021 1
    T[0] = mktuple(AST_XTYPE, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d3024 1
a3024 1
    T[0] = mktuple(AST_XTYPE, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
d3027 1
a3027 1
    T[0] = mktuple(AST_XTYPE, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
d3030 2
a3031 2
    T[2] = build_ast(A[ap+1], depth+1); // <BTYPE>
    T[0] = mktuple(AST_XTYPE, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3034 2
a3035 2
    T[2] = build_ast(A[ap+1], depth+1); // <FULLTYPE>
    T[0] = mktuple(AST_XTYPE, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3037 8
d3047 1
a3047 9
    T[0] = mktuple(AST_XTYPE, alt /*5*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 6) {  
    T[1] = kw(AST__KW, KW_half, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <FULLTYPE>
    T[0] = mktuple(AST_XTYPE, alt /*6*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 7) {  
    T[1] = kw(AST__KW, KW_short, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <FULLTYPE>
    T[0] = mktuple(AST_XTYPE, alt /*7*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3051 1
a3051 1
    T[0] = mktuple(AST_XTYPE, alt /*8*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3057 10
d3173 3
d3178 1
a3178 1
//\\    <OPT-arrayname-OR-name> <NAME> <Opt-NAME-LIST>,
d3183 1
a3183 1
    T[1] = build_ast(A[ap+0], depth+1); // <OPT-arrayname-OR-name>
d3262 2
d3265 1
a3265 1
//\\ P<OPT-arrayname-OR-name> = 
a3266 1
//\\    "name",
d3269 1
a3269 1
case P_OPT_arrayname_OR_name:
d3273 1
a3273 4
    T[0] = mktuple(AST_OPT_arrayname_OR_name, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_name, A[ap+0]);
    T[0] = mktuple(AST_OPT_arrayname_OR_name, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
d3275 1
a3275 1
    T[0] = mktuple(AST_OPT_arrayname_OR_name, alt /*2*/, /*phrases*/ 0, T /**/);
d3282 1
a3282 1
//\\ P<FULLTYPE> = 
d3286 1
a3286 1
case P_FULLTYPE:
d3289 1
a3289 1
    T[0] = mktuple(AST_FULLTYPE, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d3291 1
a3291 1
    T[0] = mktuple(AST_FULLTYPE, alt /*1*/, /*phrases*/ 0, T /**/);
d3354 1
d3356 1
a3356 1
//\\ P<BTYPE> = 
d3359 2
a3360 1
//\\    "long" "real";
d3362 1
a3362 1
case P_BTYPE:
d3365 1
a3365 1
    T[0] = mktuple(AST_BTYPE, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d3368 2
a3369 2
    T[0] = mktuple(AST_BTYPE, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
d3372 3
a3374 1
    T[0] = mktuple(AST_BTYPE, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3423 7
d3482 3
a3484 1
//\\ # <Opt-Const-assign> added by gt
d3487 1
a3487 1
//\\    <OPT-arrayname-OR-name> <NAME> <Opt-Const-assign> <Opt-Assign-NAME-LIST>,
d3492 1
a3492 1
    T[1] = build_ast(A[ap+0], depth+1); // <OPT-arrayname-OR-name>
d3494 1
a3494 1
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-Const-assign>
d3523 1
a3523 1
//\\ # <Opt-Const-assign> added by gt
d3526 1
a3526 1
//\\    ',' <NAME> <Opt-Const-assign> <Opt-Assign-NAME-LIST>,
d3533 1
a3533 1
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-Const-assign>
d3543 8
a3550 1
//\\ # The <CEXPR> one may be redundant.  Had to put expr first to catch = tostring(i) because cexpr only got tostring
d3552 2
a3553 1
//\\ P<Opt-Const-assign> = 
a3554 1
//\\    '=' <CEXPR>,
d3557 1
a3557 1
case P_Opt_Const_assign:
d3559 5
d3566 1
a3566 5
    T[0] = mktuple(AST_Opt_Const_assign, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <CEXPR>
    T[0] = mktuple(AST_Opt_Const_assign, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3568 1
a3568 1
    T[0] = mktuple(AST_Opt_Const_assign, alt /*2*/, /*phrases*/ 0, T /**/);
d3664 1
d3667 1
a3667 1
//\\    ',' <EXPR> <OPEXPR>,
d3673 1
a3673 1
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>
d3683 16
d3702 1
a3702 1
//\\    ',' <EXPR>,
d3708 3
a3710 2
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>
    T[0] = mktuple(AST_OPEXPR, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3718 18
d3788 2
d3792 1
a3792 1
//\\    <OPT-arrayname-OR-name> <OPT-spec> <SINGLE-OWNDEC> <REST-OF-OWNDEC>,
d3797 1
a3797 1
    T[1] = build_ast(A[ap+0], depth+1); // <OPT-arrayname-OR-name>
d3835 1
a3835 1
//\\    <NAME> <Opt-ALIAS> <Opt-Assign-CONST>;
d3840 1
a3840 1
  T[3] = build_ast(A[ap+2], depth+1); // <Opt-Assign-CONST>
a3917 26
  }
  return T[0];



//\\ # '== 0' needed for %const %record(*) %name nil == 0 - gt  Only 0 allowed.

//\\ P<Opt-Assign-CONST> = 
//\\    '=' <Opt-UNARY-OP> <COPERAND> <REST-OF-CEXPR>,
//\\    '=' '=' <DIGIT-SEQ>,
//\\   ;

case P_Opt_Assign_CONST:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-UNARY-OP>
    T[3] = build_ast(A[ap+2], depth+1); // <COPERAND>
    T[4] = build_ast(A[ap+3], depth+1); // <REST-OF-CEXPR>
    T[0] = mktuple(AST_Opt_Assign_CONST, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <DIGIT-SEQ>
    T[0] = mktuple(AST_Opt_Assign_CONST, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_Opt_Assign_CONST, alt /*2*/, /*phrases*/ 0, T /**/);
@


1.6
log
@major grammar improvements - eg string resolution
@
text
@d1 6
d21 2
a22 2
//\\ # Extended grammar which now accepts constructs from multiple versions of Imp
//\\ # - primarily based on a correct Imp80 grammar, modified to add Imp77 constructs,
d1229 5
d1236 1
a1236 3
//\\    'M',
//\\    'X',
//\\    'B',
d1240 2
a1241 2
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, 'M', A[ap+0]);
a1242 6
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, 'X', A[ap+0]);
    T[0] = mktuple(AST_OPT_SQ_LETTER, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, 'B', A[ap+0]);
    T[0] = mktuple(AST_OPT_SQ_LETTER, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
d1244 1
a1244 1
    T[0] = mktuple(AST_OPT_SQ_LETTER, alt /*3*/, /*phrases*/ 0, T /**/);
@


1.5
log
@if/then/else cleaned up!
@
text
@d1 1
d3 1
d5 1
d7 1
d9 1
d15 7
a21 2
//\\ # Extended grammar for Imp80 on Emas-2900 series, also accepts several Imp77 constructs...
//\\ # based on https://history.dcs.ed.ac.uk/archive/os/emas/emas2/compilers/imp80/imp80ps04.txt
d24 1
a24 1
//\\    <STATEMENT-LIST> <EOF>;
d27 2
a28 2
  T[1] = build_ast(A[ap+0], depth+1); // <STATEMENT-LIST>
  T[2] = bip(AST_EOF, A[ap+1]);
d32 1
d34 2
a35 2
//\\ P<STATEMENT-LIST> = 
//\\    <STATEMENT> <STATEMENT-LIST>,
d38 1
a38 1
case P_STATEMENT_LIST:
d40 3
a42 3
    T[1] = build_ast(A[ap+0], depth+1); // <STATEMENT>
    T[2] = build_ast(A[ap+1], depth+1); // <STATEMENT-LIST>
    T[0] = mktuple(AST_STATEMENT_LIST, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d44 50
a93 1
    T[0] = mktuple(AST_STATEMENT_LIST, alt /*1*/, /*phrases*/ 0, T /**/);
a98 2
//\\ # gt removed <TEXT>, added <COMMENT>.  Moved sw(*): up to take precedence.
//\\ # added %on %event * %start
d100 65
a164 18
//\\ P<STATEMENT> = 
//\\    <NAME> '(' '*' ')' ':',
//\\    <XOWN> <XTYPE> <OWNDEC> <S>,
//\\    <UI> <RESTOFSS1>,
//\\    <IF-S>,
//\\    "cycle" <CYCPARM> <S>,
//\\    "repeat" <RESTOFREPEAT> <S>,
//\\    <Percent-WU> "cycle" <S>,
//\\    <XTYPE> <DECLN> <S>,
//\\    "end" <ENDLIST> <S>,
//\\    "record" "format" <RFSTMNT> <S>,
//\\    <Percent-SEX> <RT> <Opt-PercentSPEC> <NAME> <Opt-ALIAS> <FPP> <S>,
//\\    "include" <CONST>,
//\\    "from" <NAME> "include" <NAME> <Opt-NLIST>,
//\\    "begin" <S>,
//\\    "on" <Opt-PercentEVENT> '*' <RESTOFNLIST> "start" <S>,
//\\    "on" <Opt-PercentEVENT> <CEXPR> <RESTOFNLIST> "start" <S>,
//\\    "switch" <NAME> <Opt-NLIST> '(' <EXPR> ':' <EXPR> ')' <RESTOFSWLIST> <S>,
a165 1
//\\    '*' <UCI>,
d168 1
a168 1
//\\    "control" <CONST> <S>,
d172 82
a253 1
case P_STATEMENT:
d256 8
d268 342
a609 1
    T[0] = mktuple(AST_STATEMENT, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
d611 70
d685 9
a693 1
    T[0] = mktuple(AST_STATEMENT, alt /*1*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d695 6
a700 3
    T[1] = build_ast(A[ap+0], depth+1); // <UI>
    T[2] = build_ast(A[ap+1], depth+1); // <RESTOFSS1>
    T[0] = mktuple(AST_STATEMENT, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
a701 18
    T[1] = build_ast(A[ap+0], depth+1); // <IF-S>
    T[0] = mktuple(AST_STATEMENT, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 4) {  
    T[1] = kw(AST__KW, KW_cycle, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <CYCPARM>
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*4*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 5) {  
    T[1] = kw(AST__KW, KW_repeat, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <RESTOFREPEAT>
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*5*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 6) {
    T[1] = build_ast(A[ap+0], depth+1); // <Percent-WU>  
    T[2] = kw(AST__KW, KW_cycle, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*6*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 7) {
d705 15
a719 7
    T[0] = mktuple(AST_STATEMENT, alt /*7*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 8) {  
    T[1] = kw(AST__KW, KW_end, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <ENDLIST>
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*8*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 9) {  
d722 1
a722 1
    T[3] = build_ast(A[ap+2], depth+1); // <RFSTMNT>
d724 2
a725 42
    T[0] = mktuple(AST_STATEMENT, alt /*9*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 10) {
    T[1] = build_ast(A[ap+0], depth+1); // <Percent-SEX>
    T[2] = build_ast(A[ap+1], depth+1); // <RT>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-PercentSPEC>
    T[4] = build_ast(A[ap+3], depth+1); // <NAME>
    T[5] = build_ast(A[ap+4], depth+1); // <Opt-ALIAS>
    T[6] = build_ast(A[ap+5], depth+1); // <FPP>
    T[7] = build_ast(A[ap+6], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*10*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else if (alt == 11) {  
    T[1] = kw(AST__KW, KW_include, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <CONST>
    T[0] = mktuple(AST_STATEMENT, alt /*11*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 12) {  
    T[1] = kw(AST__KW, KW_from, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>  
    T[3] = kw(AST__KW, KW_include, A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <NAME>
    T[5] = build_ast(A[ap+4], depth+1); // <Opt-NLIST>
    T[0] = mktuple(AST_STATEMENT, alt /*12*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 13) {  
    T[1] = kw(AST__KW, KW_begin, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*13*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 14) {  
    T[1] = kw(AST__KW, KW_on, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-PercentEVENT>  
    T[3] = lit(AST__LIT, '*', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <RESTOFNLIST>  
    T[5] = kw(AST__KW, KW_start, A[ap+4]);
    T[6] = build_ast(A[ap+5], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*14*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } else if (alt == 15) {  
    T[1] = kw(AST__KW, KW_on, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-PercentEVENT>
    T[3] = build_ast(A[ap+2], depth+1); // <CEXPR>
    T[4] = build_ast(A[ap+3], depth+1); // <RESTOFNLIST>  
    T[5] = kw(AST__KW, KW_start, A[ap+4]);
    T[6] = build_ast(A[ap+5], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*15*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } else if (alt == 16) {  
d728 1
a728 1
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-NLIST>  
d734 1
a734 1
    T[9] = build_ast(A[ap+8], depth+1); // <RESTOFSWLIST>
d736 78
a813 6
    T[0] = mktuple(AST_STATEMENT, alt /*16*/, /*phrases*/ 10, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9], T[10]*/);
  } else if (alt == 17) {  
    T[1] = kw(AST__KW, KW_list, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*17*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 18) {  
d815 31
a845 5
    T[2] = build_ast(A[ap+1], depth+1); // <UCI>
    T[0] = mktuple(AST_STATEMENT, alt /*18*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 19) {  
    T[1] = kw(AST__KW, KW_trusted, A[ap+0]);  
    T[2] = kw(AST__KW, KW_program, A[ap+1]);
d847 9
a855 5
    T[0] = mktuple(AST_STATEMENT, alt /*19*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 20) {  
    T[1] = kw(AST__KW, KW_main, A[ap+0]);  
    T[2] = kw(AST__KW, KW_ep, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>
d857 5
a861 9
    T[0] = mktuple(AST_STATEMENT, alt /*20*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 21) {  
    T[1] = kw(AST__KW, KW_control, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <CONST>
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*21*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 22) {
    T[1] = build_ast(A[ap+0], depth+1); // <COMMENT>
    T[0] = mktuple(AST_STATEMENT, alt /*22*/, /*phrases*/ 1, T /*T[1]*/);
d863 4
a866 2
    T[1] = build_ast(A[ap+0], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*23*/, /*phrases*/ 1, T /*T[1]*/);
d884 3
d889 2
a890 2
//\\    "else" <Percent-IU> <CONDITION> <S> <STARTLESS-FINISH-S>,
//\\    "else" <S> <FINISH-NO-ELSE-S>,
d899 3
a901 2
    T[5] = build_ast(A[ap+4], depth+1); // <STARTLESS-FINISH-S>
    T[0] = mktuple(AST_FINISH_S, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
d905 4
a908 2
    T[3] = build_ast(A[ap+2], depth+1); // <FINISH-NO-ELSE-S>
    T[0] = mktuple(AST_FINISH_S, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d920 1
a920 1
//\\    "else" "start" <S> <FINISH-NO-ELSE-S>,
d930 4
a933 2
    T[4] = build_ast(A[ap+3], depth+1); // <FINISH-NO-ELSE-S>
    T[0] = mktuple(AST_Opt_ELSE_S, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
a951 32
//\\ P<STARTLESS-FINISH-S> = 
//\\    <STATEMENT-LIST> <FINISH-S>;

case P_STARTLESS_FINISH_S:
  T[1] = build_ast(A[ap+0], depth+1); // <STATEMENT-LIST>
  T[2] = build_ast(A[ap+1], depth+1); // <FINISH-S>
  return mktuple(AST_STARTLESS_FINISH_S, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<FINISH-NO-ELSE-S> = 
//\\    <STATEMENT-LIST> "finish" <S>;

case P_FINISH_NO_ELSE_S:
  T[1] = build_ast(A[ap+0], depth+1); // <STATEMENT-LIST>
  T[2] = kw(AST__KW, KW_finish, A[ap+1]);
  T[3] = build_ast(A[ap+2], depth+1); // <S>
  return mktuple(AST_FINISH_NO_ELSE_S, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);



//\\ P<START-FINISH-S> = 
//\\    "start" <S> <STARTLESS-FINISH-S>;

case P_START_FINISH_S:
  T[1] = kw(AST__KW, KW_start, A[ap+0]);
  T[2] = build_ast(A[ap+1], depth+1); // <S>
  T[3] = build_ast(A[ap+2], depth+1); // <STARTLESS-FINISH-S>
  return mktuple(AST_START_FINISH_S, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);



d953 1
a953 1
//\\    <Opt-then> <START-FINISH-S>,
d958 6
a963 3
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-then>
    T[2] = build_ast(A[ap+1], depth+1); // <START-FINISH-S>
    T[0] = mktuple(AST_THEN_S, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d975 1
a975 1
//\\ P<Opt-then> = 
d979 1
a979 1
case P_Opt_then:
d982 1
a982 1
    T[0] = mktuple(AST_Opt_then, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d984 1
a984 1
    T[0] = mktuple(AST_Opt_then, alt /*1*/, /*phrases*/ 0, T /**/);
d991 1
a991 1
//\\ P<Opt-start> = 
d995 1
a995 1
case P_Opt_start:
d998 1
a998 1
    T[0] = mktuple(AST_Opt_start, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d1000 1
a1000 1
    T[0] = mktuple(AST_Opt_start, alt /*1*/, /*phrases*/ 0, T /**/);
d1087 1
a1087 1
//\\ # <NUMBER> '_' <NUMBER>, and  <NUMBER> '_' <NAME>, added by gt
d1093 1
a1093 1
//\\ # E"ebcdic" etc also not handled.
d1095 6
a1100 8
//\\ P<CONST> = 
//\\    <NUMBER> '_' <NUMBER> <NAME>,
//\\    <NUMBER> '_' <NUMBER>,
//\\    <NUMBER> '_' <NAME>,
//\\    <NUMBER>,
//\\    <OLDHEX>,
//\\    <sqstring>,
//\\    <dqstring>;
d1102 1
a1102 1
case P_CONST:
d1104 1
a1104 1
    T[1] = build_ast(A[ap+0], depth+1); // <NUMBER>  
d1106 1
a1106 1
    T[3] = build_ast(A[ap+2], depth+1); // <NUMBER>
d1108 1
a1108 1
    T[0] = mktuple(AST_CONST, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d1110 1
a1110 1
    T[1] = build_ast(A[ap+0], depth+1); // <NUMBER>  
d1112 2
a1113 2
    T[3] = build_ast(A[ap+2], depth+1); // <NUMBER>
    T[0] = mktuple(AST_CONST, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1115 1
a1115 1
    T[1] = build_ast(A[ap+0], depth+1); // <NUMBER>  
d1118 1
a1118 1
    T[0] = mktuple(AST_CONST, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1120 3
a1122 3
    T[1] = build_ast(A[ap+0], depth+1); // <NUMBER>
    T[0] = mktuple(AST_CONST, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 4) {
d1124 17
a1140 2
    T[0] = mktuple(AST_CONST, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 5) {
d1142 54
a1195 1
    T[0] = mktuple(AST_CONST, alt /*5*/, /*phrases*/ 1, T /*T[1]*/);
d1197 2
a1198 2
    T[1] = bip(AST_dqstring, A[ap+0]);
    T[0] = mktuple(AST_CONST, alt /*6*/, /*phrases*/ 1, T /*T[1]*/);
d1209 3
d1214 1
a1214 1
//\\    <alphanumeric> <sqstring>;
d1217 1
a1217 1
  T[1] = bip(AST_alphanumeric, A[ap+0]);
d1222 112
d1335 2
a1336 1
//\\ P<NUMBER> = 
d1339 1
a1339 1
case P_NUMBER:
d1342 1
a1342 1
  return mktuple(AST_NUMBER, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1347 1
a1347 1
//\\    <NUMBER>,
d1352 1
a1352 1
    T[1] = build_ast(A[ap+0], depth+1); // <NUMBER>
d1397 2
a1398 1
//\\ # Machine-specific machine-code removed.
d1410 3
a1412 3
//\\ P<RESTOFCOND> = 
//\\    "and" <SC> <RESTOFANDC>,
//\\    "or" <SC> <RESTOFORC>,
d1415 1
a1415 1
case P_RESTOFCOND:
d1419 2
a1420 2
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFANDC>
    T[0] = mktuple(AST_RESTOFCOND, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1424 2
a1425 2
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFORC>
    T[0] = mktuple(AST_RESTOFCOND, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1427 1
a1427 1
    T[0] = mktuple(AST_RESTOFCOND, alt /*2*/, /*phrases*/ 0, T /**/);
d1434 2
a1435 2
//\\ P<RESTOFANDC> = 
//\\    "and" <SC> <RESTOFANDC>,
d1438 1
a1438 1
case P_RESTOFANDC:
d1442 2
a1443 2
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFANDC>
    T[0] = mktuple(AST_RESTOFANDC, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1445 1
a1445 1
    T[0] = mktuple(AST_RESTOFANDC, alt /*1*/, /*phrases*/ 0, T /**/);
d1452 2
a1453 2
//\\ P<RESTOFORC> = 
//\\    "or" <SC> <RESTOFORC>,
d1456 1
a1456 1
case P_RESTOFORC:
d1460 2
a1461 2
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFORC>
    T[0] = mktuple(AST_RESTOFORC, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1463 1
a1463 1
    T[0] = mktuple(AST_RESTOFORC, alt /*1*/, /*phrases*/ 0, T /**/);
d1469 1
a1469 1
//\\ # <NAME> <Opt-APP> added by gt for predicates
d1473 1
a1473 1
//\\    <SC> <RESTOFCOND>;
d1477 1
a1477 1
  T[2] = build_ast(A[ap+1], depth+1); // <RESTOFCOND>
d1483 3
a1485 2
//\\    <EXPR> <COMP1> <EXPR> <RESTOFSC>,
//\\    <NAME> <Opt-APP>,
d1491 3
d1495 1
a1495 1
    T[2] = build_ast(A[ap+1], depth+1); // <COMP1>
d1497 3
a1499 3
    T[4] = build_ast(A[ap+3], depth+1); // <RESTOFSC>
    T[0] = mktuple(AST_SC, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 1) {
d1501 3
a1503 3
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-APP>
    T[0] = mktuple(AST_SC, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 2) {  
d1507 1
a1507 1
    T[0] = mktuple(AST_SC, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1511 1
a1511 1
    T[0] = mktuple(AST_SC, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1518 2
a1519 2
//\\ P<RESTOFSC> = 
//\\    <COMP2> <EXPR>,
d1522 1
a1522 1
case P_RESTOFSC:
d1524 1
a1524 1
    T[1] = build_ast(A[ap+0], depth+1); // <COMP2>
d1526 1
a1526 1
    T[0] = mktuple(AST_RESTOFSC, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1528 1
a1528 1
    T[0] = mktuple(AST_RESTOFSC, alt /*1*/, /*phrases*/ 0, T /**/);
d1535 153
a1687 1
//\\ P<COMP1> = 
d1695 1
a1695 2
//\\    '>',
//\\    '-' '>';
d1697 1
a1697 1
case P_COMP1:
d1700 1
a1700 1
    T[0] = mktuple(AST_COMP1, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d1703 1
a1703 1
    T[0] = mktuple(AST_COMP1, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
d1707 1
a1707 1
    T[0] = mktuple(AST_COMP1, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1710 1
a1710 1
    T[0] = mktuple(AST_COMP1, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
d1714 1
a1714 1
    T[0] = mktuple(AST_COMP1, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1717 1
a1717 1
    T[0] = mktuple(AST_COMP1, alt /*5*/, /*phrases*/ 1, T /*T[1]*/);
d1721 2
a1722 2
    T[0] = mktuple(AST_COMP1, alt /*6*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 7) {  
d1724 1
a1724 5
    T[0] = mktuple(AST_COMP1, alt /*7*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = lit(AST__LIT, '-', A[ap+0]);  
    T[2] = lit(AST__LIT, '>', A[ap+1]);
    T[0] = mktuple(AST_COMP1, alt /*8*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1773 1
a1773 1
//\\ # can't have a double-sided string resolution...
d1775 3
a1777 9
//\\ P<COMP2> = 
//\\    '=',
//\\    <NOT-EQUALS>,
//\\    '=' '=',
//\\    <NOT-EQUALS-ADDRESS>,
//\\    '<' '=',
//\\    '<',
//\\    '>' '=',
//\\    '>';
d1779 1
a1779 1
case P_COMP2:
d1781 7
a1787 26
    T[1] = lit(AST__LIT, '=', A[ap+0]);
    T[0] = mktuple(AST_COMP2, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <NOT-EQUALS>
    T[0] = mktuple(AST_COMP2, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_COMP2, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 3) {
    T[1] = build_ast(A[ap+0], depth+1); // <NOT-EQUALS-ADDRESS>
    T[0] = mktuple(AST_COMP2, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 4) {  
    T[1] = lit(AST__LIT, '<', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_COMP2, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 5) {  
    T[1] = lit(AST__LIT, '<', A[ap+0]);
    T[0] = mktuple(AST_COMP2, alt /*5*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 6) {  
    T[1] = lit(AST__LIT, '>', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_COMP2, alt /*6*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {  
    T[1] = lit(AST__LIT, '>', A[ap+0]);
    T[0] = mktuple(AST_COMP2, alt /*7*/, /*phrases*/ 1, T /*T[1]*/);
a1792 1
//\\ # 'Application' i.e. parameters to routine or function call
d1794 2
a1795 2
//\\ P<Opt-APP> = 
//\\    '(' <EXPR> <RESTOFAPP> ')',
d1798 1
a1798 1
case P_Opt_APP:
d1800 1
a1800 1
    T[1] = lit(AST__LIT, '(', A[ap+0]);
d1802 88
a1889 3
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFAPP>  
    T[4] = lit(AST__LIT, ')', A[ap+3]);
    T[0] = mktuple(AST_Opt_APP, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d1891 1
a1891 1
    T[0] = mktuple(AST_Opt_APP, alt /*1*/, /*phrases*/ 0, T /**/);
d1898 12
a1909 2
//\\ P<RESTOFAPP> = 
//\\    ',' <EXPR> <RESTOFAPP>,
d1912 5
a1916 6
case P_RESTOFAPP:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFAPP>
    T[0] = mktuple(AST_RESTOFAPP, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1918 1
a1918 1
    T[0] = mktuple(AST_RESTOFAPP, alt /*1*/, /*phrases*/ 0, T /**/);
d1925 12
a1936 2
//\\ P<EXPR> = 
//\\    <Opt-UNARY-OP> <OPERAND> <RESTOFEXPR>;
d1938 1
a1938 1
case P_EXPR:
d1941 7
a1947 2
  T[3] = build_ast(A[ap+2], depth+1); // <RESTOFEXPR>
  return mktuple(AST_EXPR, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1949 27
d1978 4
a1981 2
//\\ P<RESTOFEXPR> = 
//\\    <OP> <OPERAND> <RESTOFEXPR>,
d1984 26
a2009 6
case P_RESTOFEXPR:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <OP>
    T[2] = build_ast(A[ap+1], depth+1); // <OPERAND>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFEXPR>
    T[0] = mktuple(AST_RESTOFEXPR, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d2011 1
a2011 1
    T[0] = mktuple(AST_RESTOFEXPR, alt /*1*/, /*phrases*/ 0, T /**/);
d2017 2
a2018 1
//\\ # no idea why (<EXPR>) below was originally an <Opt-EXPR>
d2021 1
a2021 1
//\\    <NAME> <Opt-APP> <Opt-ENAME>,
d2024 2
a2025 1
//\\    '|' <EXPR> '|';
d2030 2
a2031 2
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-APP>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-ENAME>
d2041 1
a2041 1
  } else               {  
d2046 5
a2050 20
  }
  return T[0];



//\\ # fortunately this is all *much* simpler in Imp than in C !

//\\ P<Opt-ENAME> = 
//\\    '_' <NAME> <Opt-APP> <Opt-ENAME>,
//\\   ;

case P_Opt_ENAME:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '_', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-APP>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-ENAME>
    T[0] = mktuple(AST_Opt_ENAME, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[0] = mktuple(AST_Opt_ENAME, alt /*1*/, /*phrases*/ 0, T /**/);
d2057 1
d2083 1
d2103 1
d2169 1
d2196 1
d2227 1
a2227 1
//\\ # unary operators
d2252 1
d2288 2
d2291 2
a2292 2
//\\ P<RESTOFSWLIST> = 
//\\    ',' <NAME> <Opt-NLIST> '(' <EXPR> ':' <EXPR> ')' <RESTOFSWLIST>,
d2295 1
a2295 1
case P_RESTOFSWLIST:
d2299 1
a2299 1
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-NLIST>  
d2305 2
a2306 2
    T[9] = build_ast(A[ap+8], depth+1); // <RESTOFSWLIST>
    T[0] = mktuple(AST_RESTOFSWLIST, alt /*0*/, /*phrases*/ 9, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9]*/);
d2308 1
a2308 1
    T[0] = mktuple(AST_RESTOFSWLIST, alt /*1*/, /*phrases*/ 0, T /**/);
d2315 2
a2316 2
//\\ P<Opt-NLIST> = 
//\\    ',' <NAME> <Opt-NLIST>,
d2319 1
a2319 1
case P_Opt_NLIST:
d2323 2
a2324 2
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-NLIST>
    T[0] = mktuple(AST_Opt_NLIST, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d2326 1
a2326 1
    T[0] = mktuple(AST_Opt_NLIST, alt /*1*/, /*phrases*/ 0, T /**/);
d2333 2
a2334 2
//\\ P<RESTOFNLIST> = 
//\\    ',' <CEXPR> <RESTOFNLIST>,
d2337 1
a2337 1
case P_RESTOFNLIST:
d2341 2
a2342 2
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFNLIST>
    T[0] = mktuple(AST_RESTOFNLIST, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d2344 1
a2344 1
    T[0] = mktuple(AST_RESTOFNLIST, alt /*1*/, /*phrases*/ 0, T /**/);
d2350 6
d2358 1
a2358 1
//\\    <Opt-UNARY-OP> <COPERAND> <RESTOFCEXPR>;
d2363 1
a2363 1
  T[3] = build_ast(A[ap+2], depth+1); // <RESTOFCEXPR>
d2368 2
a2369 2
//\\ P<RESTOFCEXPR> = 
//\\    <OP> <COPERAND> <RESTOFCEXPR>,
d2372 1
a2372 1
case P_RESTOFCEXPR:
d2376 2
a2377 2
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFCEXPR>
    T[0] = mktuple(AST_RESTOFCEXPR, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d2379 1
a2379 1
    T[0] = mktuple(AST_RESTOFCEXPR, alt /*1*/, /*phrases*/ 0, T /**/);
d2385 8
d2397 3
a2399 1
//\\    '(' <Opt-CEXPR> ')';
d2408 1
a2408 1
  } else               {  
d2410 1
a2410 1
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-CEXPR>  
d2413 10
d2429 1
a2429 17
//\\ P<Opt-CEXPR> = 
//\\    <CEXPR>,
//\\   ;

case P_Opt_CEXPR:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <CEXPR>
    T[0] = mktuple(AST_Opt_CEXPR, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_Opt_CEXPR, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<Opt-PercentEVENT> = 
d2433 1
a2433 1
case P_Opt_PercentEVENT:
d2436 1
a2436 1
    T[0] = mktuple(AST_Opt_PercentEVENT, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d2438 1
a2438 1
    T[0] = mktuple(AST_Opt_PercentEVENT, alt /*1*/, /*phrases*/ 0, T /**/);
d2446 1
a2446 1
//\\    '(' <FPDEL> <RESTOFFPLIST> ')',
d2452 2
a2453 2
    T[2] = build_ast(A[ap+1], depth+1); // <FPDEL>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFFPLIST>  
d2464 2
a2465 2
//\\ P<RESTOFFPLIST> = 
//\\    <Opt-Comma> <FPDEL> <RESTOFFPLIST>,
d2468 1
a2468 1
case P_RESTOFFPLIST:
d2471 3
a2473 3
    T[2] = build_ast(A[ap+1], depth+1); // <FPDEL>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFFPLIST>
    T[0] = mktuple(AST_RESTOFFPLIST, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d2475 1
a2475 1
    T[0] = mktuple(AST_RESTOFFPLIST, alt /*1*/, /*phrases*/ 0, T /**/);
d2482 4
a2485 4
//\\ P<FPDEL> = 
//\\    <XTYPE> <Opt-PercentQNAME> <NAME> <Opt-NLIST>,
//\\    <RT> <Opt-PercentNAME> <NAME> <Opt-NLIST> <FPP>,
//\\    "name" <NAME> <Opt-NLIST>;
d2487 1
a2487 1
case P_FPDEL:
d2490 1
a2490 1
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-PercentQNAME>
d2492 2
a2493 2
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-NLIST>
    T[0] = mktuple(AST_FPDEL, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d2496 1
a2496 1
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-PercentNAME>
d2498 1
a2498 1
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-NLIST>
d2500 1
a2500 1
    T[0] = mktuple(AST_FPDEL, alt /*1*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
d2504 2
a2505 2
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-NLIST>
    T[0] = mktuple(AST_FPDEL, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d2512 1
a2512 1
//\\ P<Opt-PercentNAME> = 
d2516 1
a2516 1
case P_Opt_PercentNAME:
d2519 1
a2519 1
    T[0] = mktuple(AST_Opt_PercentNAME, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d2521 1
a2521 1
    T[0] = mktuple(AST_Opt_PercentNAME, alt /*1*/, /*phrases*/ 0, T /**/);
d2532 1
a2532 1
//\\    <XTYPE> <FM>;
d2543 1
a2543 1
    T[2] = build_ast(A[ap+1], depth+1); // <FM>
d2550 15
d2566 4
a2569 1
//\\ P<FM> = 
a2570 1
//\\    "map",
d2573 1
a2573 1
case P_FM:
d2576 1
a2576 4
    T[0] = mktuple(AST_FM, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_map, A[ap+0]);
    T[0] = mktuple(AST_FM, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
d2579 1
a2579 1
    T[0] = mktuple(AST_FM, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
d2586 2
d2598 1
a2598 1
//\\    "record" '(' <Opt-RFREF> ')';
d2631 3
a2633 5
    T[1] = kw(AST__KW, KW_record, A[ap+0]);  
    T[2] = lit(AST__LIT, '(', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-RFREF>  
    T[4] = lit(AST__LIT, ')', A[ap+3]);
    T[0] = mktuple(AST_XTYPE, alt /*8*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d2640 1
d2643 2
a2644 2
//\\    <RFREF>,
//\\    '*',
d2648 5
a2652 3
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <RFREF>
    T[0] = mktuple(AST_Opt_RFREF, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d2654 4
a2657 2
    T[1] = lit(AST__LIT, '*', A[ap+0]);
    T[0] = mktuple(AST_Opt_RFREF, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
d2667 1
a2667 1
//\\ P<RFREF> = 
d2669 1
a2669 1
//\\    <RFDEC> <RESTOFRFDEC> <ALTRFDEC>;
d2671 1
a2671 1
case P_RFREF:
d2674 1
a2674 1
    T[0] = mktuple(AST_RFREF, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d2676 4
a2679 4
    T[1] = build_ast(A[ap+0], depth+1); // <RFDEC>
    T[2] = build_ast(A[ap+1], depth+1); // <RESTOFRFDEC>
    T[3] = build_ast(A[ap+2], depth+1); // <ALTRFDEC>
    T[0] = mktuple(AST_RFREF, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d2685 1
d2687 2
a2688 2
//\\ P<ALTRFDEC> = 
//\\    "or" <RFDEC> <RESTOFRFDEC> <ALTRFDEC>,
d2691 1
a2691 1
case P_ALTRFDEC:
d2694 4
a2697 4
    T[2] = build_ast(A[ap+1], depth+1); // <RFDEC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFRFDEC>
    T[4] = build_ast(A[ap+3], depth+1); // <ALTRFDEC>
    T[0] = mktuple(AST_ALTRFDEC, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d2699 1
a2699 1
    T[0] = mktuple(AST_ALTRFDEC, alt /*1*/, /*phrases*/ 0, T /**/);
d2706 2
a2707 2
//\\ P<RESTOFRFDEC> = 
//\\    ',' <RFDEC> <RESTOFRFDEC>,
d2710 1
a2710 1
case P_RESTOFRFDEC:
d2713 3
a2715 3
    T[2] = build_ast(A[ap+1], depth+1); // <RFDEC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFRFDEC>
    T[0] = mktuple(AST_RESTOFRFDEC, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d2717 1
a2717 1
    T[0] = mktuple(AST_RESTOFRFDEC, alt /*1*/, /*phrases*/ 0, T /**/);
d2724 3
a2726 3
//\\ P<RFDEC> = 
//\\    <XTYPE> <RFELMNT>,
//\\    '(' <RFDEC> <RESTOFRFDEC> <ALTRFDEC> ')';
d2728 1
a2728 1
case P_RFDEC:
d2731 2
a2732 2
    T[2] = build_ast(A[ap+1], depth+1); // <RFELMNT>
    T[0] = mktuple(AST_RFDEC, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d2735 3
a2737 3
    T[2] = build_ast(A[ap+1], depth+1); // <RFDEC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFRFDEC>
    T[4] = build_ast(A[ap+3], depth+1); // <ALTRFDEC>  
d2739 1
a2739 1
    T[0] = mktuple(AST_RFDEC, alt /*1*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
d2746 2
a2747 2
//\\ P<RFELMNT> = 
//\\    <Opt-PercentQNAME> <NAME> <Opt-NLIST>,
d2750 1
a2750 1
case P_RFELMNT:
d2752 1
a2752 1
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-PercentQNAME>
d2754 2
a2755 2
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-NLIST>
    T[0] = mktuple(AST_RFELMNT, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d2759 1
a2759 1
    T[0] = mktuple(AST_RFELMNT, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d2768 1
a2768 1
//\\    <NAME> <Opt-NLIST> <BPAIR> <RESTOFARLIST>;
d2772 1
a2772 1
  T[2] = build_ast(A[ap+1], depth+1); // <Opt-NLIST>
d2774 1
a2774 1
  T[4] = build_ast(A[ap+3], depth+1); // <RESTOFARLIST>
d2779 1
a2779 1
//\\ P<RESTOFARLIST> = 
d2783 1
a2783 1
case P_RESTOFARLIST:
d2787 1
a2787 1
    T[0] = mktuple(AST_RESTOFARLIST, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d2789 1
a2789 1
    T[0] = mktuple(AST_RESTOFARLIST, alt /*1*/, /*phrases*/ 0, T /**/);
d2798 1
a2798 1
//\\    '(' <EXPR> ':' <EXPR> <RESTOFBPLIST> ')';
d2805 1
a2805 1
  T[5] = build_ast(A[ap+4], depth+1); // <RESTOFBPLIST>
d2812 2
a2813 2
//\\ P<RESTOFBPLIST> = 
//\\    ',' <EXPR> ':' <EXPR> <RESTOFBPLIST>,
d2816 1
a2816 1
case P_RESTOFBPLIST:
d2822 2
a2823 2
    T[5] = build_ast(A[ap+4], depth+1); // <RESTOFBPLIST>
    T[0] = mktuple(AST_RESTOFBPLIST, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
d2825 1
a2825 1
    T[0] = mktuple(AST_RESTOFBPLIST, alt /*1*/, /*phrases*/ 0, T /**/);
d2832 1
a2832 1
//\\ P<Opt-PercentQNAME> = 
d2837 1
a2837 1
case P_Opt_PercentQNAME:
d2841 1
a2841 1
    T[0] = mktuple(AST_Opt_PercentQNAME, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d2844 1
a2844 1
    T[0] = mktuple(AST_Opt_PercentQNAME, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
d2846 1
a2846 1
    T[0] = mktuple(AST_Opt_PercentQNAME, alt /*2*/, /*phrases*/ 0, T /**/);
d2869 1
d2905 1
a2905 1
//\\ # Or at least SHOULD be used in switch label.  Looks like it isn't... gt
d2908 1
a2908 1
//\\    <Opt-UNARY-OP> <COPERAND> <RESTOFCEXPR>,
d2915 1
a2915 1
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFCEXPR>
d2989 1
a2989 16

//\\ P<Opt-PercentSPEC> = 
//\\    "spec",
//\\   ;

case P_Opt_PercentSPEC:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_spec, A[ap+0]);
    T[0] = mktuple(AST_Opt_PercentSPEC, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_Opt_PercentSPEC, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



d3019 1
a3019 1
//\\ P<RFSTMNT> = 
d3021 1
a3021 1
//\\    <NAME> '(' <RFDEC> <RESTOFRFDEC> <ALTRFDEC> ')';
d3023 1
a3023 1
case P_RFSTMNT:
d3027 1
a3027 1
    T[0] = mktuple(AST_RFSTMNT, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3031 3
a3033 3
    T[3] = build_ast(A[ap+2], depth+1); // <RFDEC>
    T[4] = build_ast(A[ap+3], depth+1); // <RESTOFRFDEC>
    T[5] = build_ast(A[ap+4], depth+1); // <ALTRFDEC>  
d3035 1
a3035 39
    T[0] = mktuple(AST_RFSTMNT, alt /*1*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  }
  return T[0];



//\\ # prim and perm added by gt

//\\ P<ENDLIST> = 
//\\    "of" "program",
//\\    "of" "file",
//\\    "of" "prim",
//\\    "of" "perm",
//\\    "of" "list",
//\\   ;

case P_ENDLIST:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_of, A[ap+0]);  
    T[2] = kw(AST__KW, KW_program, A[ap+1]);
    T[0] = mktuple(AST_ENDLIST, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_of, A[ap+0]);  
    T[2] = kw(AST__KW, KW_file, A[ap+1]);
    T[0] = mktuple(AST_ENDLIST, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 2) {  
    T[1] = kw(AST__KW, KW_of, A[ap+0]);  
    T[2] = kw(AST__KW, KW_prim, A[ap+1]);
    T[0] = mktuple(AST_ENDLIST, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 3) {  
    T[1] = kw(AST__KW, KW_of, A[ap+0]);  
    T[2] = kw(AST__KW, KW_perm, A[ap+1]);
    T[0] = mktuple(AST_ENDLIST, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 4) {  
    T[1] = kw(AST__KW, KW_of, A[ap+0]);  
    T[2] = kw(AST__KW, KW_list, A[ap+1]);
    T[0] = mktuple(AST_ENDLIST, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_ENDLIST, alt /*5*/, /*phrases*/ 0, T /**/);
d3045 2
a3046 2
//\\    <Opt-PercentQNAME> <NAME> <Opt-Const-assign> <Opt-Assign-NLIST>,
//\\    "array" <Opt-PercentFORMAT> <ADECLN>;
d3050 1
a3050 1
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-PercentQNAME>
d3053 1
a3053 1
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-Assign-NLIST>
d3057 1
a3057 1
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-PercentFORMAT>
d3066 1
a3066 1
//\\ P<Opt-PercentFORMAT> = 
d3070 1
a3070 1
case P_Opt_PercentFORMAT:
d3073 1
a3073 1
    T[0] = mktuple(AST_Opt_PercentFORMAT, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d3075 1
a3075 1
    T[0] = mktuple(AST_Opt_PercentFORMAT, alt /*1*/, /*phrases*/ 0, T /**/);
d3083 2
a3084 2
//\\ P<Opt-Assign-NLIST> = 
//\\    ',' <NAME> <Opt-Const-assign> <Opt-Assign-NLIST>,
d3087 1
a3087 1
case P_Opt_Assign_NLIST:
d3092 2
a3093 2
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-Assign-NLIST>
    T[0] = mktuple(AST_Opt_Assign_NLIST, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d3095 1
a3095 1
    T[0] = mktuple(AST_Opt_Assign_NLIST, alt /*1*/, /*phrases*/ 0, T /**/);
d3124 1
d3128 19
d3150 1
a3150 1
case P_Percent_WU:
d3154 1
a3154 1
    T[0] = mktuple(AST_Percent_WU, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3158 1
a3158 1
    T[0] = mktuple(AST_Percent_WU, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3168 1
a3168 1
    T[0] = mktuple(AST_Percent_WU, alt /*2*/, /*phrases*/ 8, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8]*/);
d3175 1
a3175 1
//\\ P<RESTOFREPEAT> = 
d3179 1
a3179 1
case P_RESTOFREPEAT:
d3183 1
a3183 1
    T[0] = mktuple(AST_RESTOFREPEAT, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3185 1
a3185 1
    T[0] = mktuple(AST_RESTOFREPEAT, alt /*1*/, /*phrases*/ 0, T /**/);
d3192 1
a3192 1
//\\ P<CYCPARM> = 
d3196 1
a3196 1
case P_CYCPARM:
d3205 1
a3205 1
    T[0] = mktuple(AST_CYCPARM, alt /*0*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
d3207 1
a3207 1
    T[0] = mktuple(AST_CYCPARM, alt /*1*/, /*phrases*/ 0, T /**/);
d3213 1
a3213 71
//\\ # gt added true, false.  moved <AUI> to RESTOFUI so it doesn't follow a label
//\\ # should do something similar with <Opt-ENAME> because labels can't be record fields
//\\ # These are all UIs that cannot be followed by other UIs because they jump elsewhere.
//\\ # (although in some versions of Imp that isn't true of %monitor which can return)

//\\ P<UI> = 
//\\    <NAME> <Opt-APP> <Opt-ENAME> <RESTOFUI> <AUI>,
//\\    '-' '>' <NAME> <Opt-APP>,
//\\    "return",
//\\    "true",
//\\    "false",
//\\    "result" <ASSOP> <EXPR>,
//\\    "monitor" <AUI>,
//\\    "stop",
//\\    "signal" <Opt-PercentEVENT> <CEXPR> <OPEXPR2>,
//\\    "exit",
//\\    "continue";

case P_UI:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-APP>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-ENAME>
    T[4] = build_ast(A[ap+3], depth+1); // <RESTOFUI>
    T[5] = build_ast(A[ap+4], depth+1); // <AUI>
    T[0] = mktuple(AST_UI, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '-', A[ap+0]);  
    T[2] = lit(AST__LIT, '>', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-APP>
    T[0] = mktuple(AST_UI, alt /*1*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 2) {  
    T[1] = kw(AST__KW, KW_return, A[ap+0]);
    T[0] = mktuple(AST_UI, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 3) {  
    T[1] = kw(AST__KW, KW_true, A[ap+0]);
    T[0] = mktuple(AST_UI, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 4) {  
    T[1] = kw(AST__KW, KW_false, A[ap+0]);
    T[0] = mktuple(AST_UI, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 5) {  
    T[1] = kw(AST__KW, KW_result, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <ASSOP>
    T[3] = build_ast(A[ap+2], depth+1); // <EXPR>
    T[0] = mktuple(AST_UI, alt /*5*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 6) {  
    T[1] = kw(AST__KW, KW_monitor, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <AUI>
    T[0] = mktuple(AST_UI, alt /*6*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 7) {  
    T[1] = kw(AST__KW, KW_stop, A[ap+0]);
    T[0] = mktuple(AST_UI, alt /*7*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 8) {  
    T[1] = kw(AST__KW, KW_signal, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-PercentEVENT>
    T[3] = build_ast(A[ap+2], depth+1); // <CEXPR>
    T[4] = build_ast(A[ap+3], depth+1); // <OPEXPR2>
    T[0] = mktuple(AST_UI, alt /*8*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 9) {  
    T[1] = kw(AST__KW, KW_exit, A[ap+0]);
    T[0] = mktuple(AST_UI, alt /*9*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_continue, A[ap+0]);
    T[0] = mktuple(AST_UI, alt /*10*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # gt changed signal to allow 2 exprs
d3250 1
a3250 18
//\\ # can avoid a start/finish block by call1 %and call2 %if condition

//\\ P<AUI> = 
//\\    "and" <UI>,
//\\   ;

case P_AUI:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_and, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <UI>
    T[0] = mktuple(AST_AUI, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_AUI, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



a3254 1
//\\    '-' '>',
a3264 4
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '-', A[ap+0]);  
    T[2] = lit(AST__LIT, '>', A[ap+1]);
    T[0] = mktuple(AST_ASSOP, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3268 1
a3268 1
    T[0] = mktuple(AST_ASSOP, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3274 1
a3274 2
//\\ # gt moved COLON to end instead of front. <COLON> appears to be an action, not a character
//\\ # as the grammar has ':' <COLON> at the location of a label.  So it's a NULL term.
d3276 3
a3278 22
//\\ P<RESTOFUI> = 
//\\    <ASSOP> <EXPR>,
//\\    ':',
//\\   ;

case P_RESTOFUI:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <ASSOP>
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>
    T[0] = mktuple(AST_RESTOFUI, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, ':', A[ap+0]);
    T[0] = mktuple(AST_RESTOFUI, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_RESTOFUI, alt /*2*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<RESTOFSS1> = 
a3279 2
//\\    <Percent-IU> <CONDITION> <S>,
//\\    <Percent-WU> <S>,
d3282 1
a3282 1
case P_RESTOFSS1:
a3283 3
    T[1] = build_ast(A[ap+0], depth+1); // <S>
    T[0] = mktuple(AST_RESTOFSS1, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {
d3287 5
a3291 1
    T[0] = mktuple(AST_RESTOFSS1, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d3293 2
a3294 3
    T[1] = build_ast(A[ap+0], depth+1); // <Percent-WU>
    T[2] = build_ast(A[ap+1], depth+1); // <S>
    T[0] = mktuple(AST_RESTOFSS1, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d3296 1
a3296 1
    T[0] = mktuple(AST_RESTOFSS1, alt /*3*/, /*phrases*/ 0, T /**/);
d3304 2
a3305 2
//\\    <Opt-PercentQNAME> <Opt-VSPEC> <SINGLE-OWNDEC> <RESTOFOWNDEC>,
//\\    "array" <Opt-PercentFORMAT> <Opt-VSPEC> <NAME> <BPAIR> <CONSTLIST>;
d3309 2
a3310 2
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-PercentQNAME>
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-VSPEC>
d3312 1
a3312 1
    T[4] = build_ast(A[ap+3], depth+1); // <RESTOFOWNDEC>
d3316 2
a3317 2
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-PercentFORMAT>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-VSPEC>
d3328 2
a3329 2
//\\ P<RESTOFOWNDEC> = 
//\\    ',' <SINGLE-OWNDEC> <RESTOFOWNDEC>,
d3332 1
a3332 1
case P_RESTOFOWNDEC:
d3336 2
a3337 2
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFOWNDEC>
    T[0] = mktuple(AST_RESTOFOWNDEC, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d3339 1
a3339 1
    T[0] = mktuple(AST_RESTOFOWNDEC, alt /*1*/, /*phrases*/ 0, T /**/);
d3361 1
a3361 1
//\\    '=' <stupid> <Opt-UNARY-OP> <COPERAND> <RESTOFCEXPR> <REPFACT> <ROCL>,
d3370 1
a3370 1
    T[5] = build_ast(A[ap+4], depth+1); // <RESTOFCEXPR>
d3383 1
a3383 1
//\\    ',' <stupid> <Opt-UNARY-OP> <COPERAND> <RESTOFCEXPR> <REPFACT> <ROCL>,
d3392 1
a3392 1
    T[5] = build_ast(A[ap+4], depth+1); // <RESTOFCEXPR>
d3420 1
a3420 1
//\\ P<Opt-VSPEC> = 
d3424 1
a3424 1
case P_Opt_VSPEC:
d3427 1
a3427 1
    T[0] = mktuple(AST_Opt_VSPEC, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d3429 1
a3429 1
    T[0] = mktuple(AST_Opt_VSPEC, alt /*1*/, /*phrases*/ 0, T /**/);
d3438 2
a3439 2
//\\    '=' <Opt-UNARY-OP> <COPERAND> <RESTOFCEXPR>,
//\\    '=' '=' <NUMBER>,
d3447 1
a3447 1
    T[4] = build_ast(A[ap+3], depth+1); // <RESTOFCEXPR>
d3452 1
a3452 1
    T[3] = build_ast(A[ap+2], depth+1); // <NUMBER>
d3461 1
@


1.4
log
@incremental improvements to grammar
@
text
@d46 1
a46 2
//\\    <Percent-IU> <SC> <RESTOFCOND> <RESTOFIU> <S>,
//\\    "finish" <Opt-ELSE> <S>,
a60 2
//\\    "else" <S>,
//\\    "else" <Percent-IU> <SC> <RESTOFCOND>,
d87 2
a88 6
    T[1] = build_ast(A[ap+0], depth+1); // <Percent-IU>
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFCOND>
    T[4] = build_ast(A[ap+3], depth+1); // <RESTOFIU>
    T[5] = build_ast(A[ap+4], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*3*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
d90 2
a91 2
    T[1] = kw(AST__KW, KW_finish, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-ELSE>
a94 5
    T[1] = kw(AST__KW, KW_cycle, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <CYCPARM>
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*5*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 6) {  
d98 2
a99 2
    T[0] = mktuple(AST_STATEMENT, alt /*6*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 7) {
d103 2
a104 2
    T[0] = mktuple(AST_STATEMENT, alt /*7*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 8) {
d108 2
a109 2
    T[0] = mktuple(AST_STATEMENT, alt /*8*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 9) {  
d113 2
a114 2
    T[0] = mktuple(AST_STATEMENT, alt /*9*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 10) {  
d119 2
a120 2
    T[0] = mktuple(AST_STATEMENT, alt /*10*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 11) {
d128 2
a129 2
    T[0] = mktuple(AST_STATEMENT, alt /*11*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else if (alt == 12) {  
d132 2
a133 2
    T[0] = mktuple(AST_STATEMENT, alt /*12*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 13) {  
d139 2
a140 2
    T[0] = mktuple(AST_STATEMENT, alt /*13*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 14) {  
d143 2
a144 2
    T[0] = mktuple(AST_STATEMENT, alt /*14*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 15) {  
d151 2
a152 2
    T[0] = mktuple(AST_STATEMENT, alt /*15*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } else if (alt == 16) {  
d159 2
a160 2
    T[0] = mktuple(AST_STATEMENT, alt /*16*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } else if (alt == 17) {  
d171 2
a172 2
    T[0] = mktuple(AST_STATEMENT, alt /*17*/, /*phrases*/ 10, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9], T[10]*/);
  } else if (alt == 18) {  
d175 4
a180 14
    T[1] = kw(AST__KW, KW_else, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*19*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 20) {  
    T[1] = kw(AST__KW, KW_else, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Percent-IU>
    T[3] = build_ast(A[ap+2], depth+1); // <SC>
    T[4] = build_ast(A[ap+3], depth+1); // <RESTOFCOND>
    T[0] = mktuple(AST_STATEMENT, alt /*20*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 21) {  
    T[1] = lit(AST__LIT, '*', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <UCI>
    T[0] = mktuple(AST_STATEMENT, alt /*21*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 22) {  
d184 2
a185 2
    T[0] = mktuple(AST_STATEMENT, alt /*22*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 23) {  
d190 2
a191 2
    T[0] = mktuple(AST_STATEMENT, alt /*23*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 24) {  
d195 2
a196 2
    T[0] = mktuple(AST_STATEMENT, alt /*24*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 25) {
d198 72
a269 1
    T[0] = mktuple(AST_STATEMENT, alt /*25*/, /*phrases*/ 1, T /*T[1]*/);
d272 85
a356 1
    T[0] = mktuple(AST_STATEMENT, alt /*26*/, /*phrases*/ 1, T /*T[1]*/);
d645 10
d658 1
a658 1
//\\    '(' <SC> <RESTOFCOND> ')',
d674 3
a676 4
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFCOND>  
    T[4] = lit(AST__LIT, ')', A[ap+3]);
    T[0] = mktuple(AST_SC, alt /*2*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d2043 2
a2044 2
//\\    "while" <SC> <RESTOFCOND>,
//\\    "until" <SC> <RESTOFCOND>,
d2050 2
a2051 3
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFCOND>
    T[0] = mktuple(AST_Percent_WU, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d2054 2
a2055 3
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFCOND>
    T[0] = mktuple(AST_Percent_WU, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d2073 1
a2073 1
//\\    "until" <SC> <RESTOFCOND>,
d2079 2
a2080 3
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFCOND>
    T[0] = mktuple(AST_RESTOFREPEAT, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
a2109 41

//\\ P<Opt-ELSE> = 
//\\    "else" <AFTERELSE>,
//\\   ;

case P_Opt_ELSE:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_else, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <AFTERELSE>
    T[0] = mktuple(AST_Opt_ELSE, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_Opt_ELSE, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<AFTERELSE> = 
//\\    "start",
//\\    <Percent-IU> <SC> <RESTOFCOND> <RESTOFIU>,
//\\    <UI>;

case P_AFTERELSE:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_start, A[ap+0]);
    T[0] = mktuple(AST_AFTERELSE, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <Percent-IU>
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFCOND>
    T[4] = build_ast(A[ap+3], depth+1); // <RESTOFIU>
    T[0] = mktuple(AST_AFTERELSE, alt /*1*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <UI>
    T[0] = mktuple(AST_AFTERELSE, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



a2286 24
//\\ P<RESTOFIU> = 
//\\    "start",
//\\    "then" "start",
//\\    "then" <UI> <Opt-ELSE>;

case P_RESTOFIU:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_start, A[ap+0]);
    T[0] = mktuple(AST_RESTOFIU, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_then, A[ap+0]);  
    T[2] = kw(AST__KW, KW_start, A[ap+1]);
    T[0] = mktuple(AST_RESTOFIU, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_then, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <UI>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-ELSE>
    T[0] = mktuple(AST_RESTOFIU, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  }
  return T[0];




d2289 1
a2289 1
//\\    <Percent-IU> <SC> <RESTOFCOND> <S>,
d2299 3
a2301 4
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFCOND>
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[0] = mktuple(AST_RESTOFSS1, alt /*1*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
@


1.3
log
@reordered, and dummy phrases removed
@
text
@d265 2
d312 5
a316 1
//\\ # VERY hacky stopgap just to get stuff to parse. Needs proper syntax.
d474 18
d509 1
a509 1
//\\ # <NAME> <APP> added by gt for predicates
d514 1
a514 1
//\\    <NAME> <APP>,
d527 1
a527 1
    T[2] = build_ast(A[ap+1], depth+1); // <APP>
d544 154
d700 1
a700 1
//\\ P<APP> = 
d704 1
a704 1
case P_APP:
d710 1
a710 1
    T[0] = mktuple(AST_APP, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d712 1
a712 1
    T[0] = mktuple(AST_APP, alt /*1*/, /*phrases*/ 0, T /**/);
a735 1
//\\ # |...| added by gt
d738 1
a738 2
//\\    <Opt-PLUS> <OPERAND> <RESTOFEXPR>,
//\\    '|' <EXPR> '|';
d741 4
a744 13
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-PLUS>
    T[2] = build_ast(A[ap+1], depth+1); // <OPERAND>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFEXPR>
    T[0] = mktuple(AST_EXPR, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {  
    T[1] = lit(AST__LIT, '|', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>  
    T[3] = lit(AST__LIT, '|', A[ap+2]);
    T[0] = mktuple(AST_EXPR, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  }
  return T[0];

d765 1
d768 1
a768 1
//\\    <NAME> <APP> <Opt-ENAME>,
d770 2
a771 1
//\\    '(' <Opt-EXPR> ')';
d776 1
a776 1
    T[2] = build_ast(A[ap+1], depth+1); // <APP>
d782 1
a782 1
  } else               {  
d784 1
a784 1
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-EXPR>  
d787 5
d797 1
a797 16

//\\ P<Opt-EXPR> = 
//\\    <EXPR>,
//\\   ;

case P_Opt_EXPR:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <EXPR>
    T[0] = mktuple(AST_Opt_EXPR, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_Opt_EXPR, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



d800 1
a800 1
//\\    '_' <NAME> <APP> <Opt-ENAME>,
d807 1
a807 1
    T[3] = build_ast(A[ap+2], depth+1); // <APP>
d817 1
d820 4
a823 13
//\\    '+',
//\\    '-',
//\\    '*' '*' '*' '*',
//\\    '*' '*',
//\\    '*',
//\\    '/' '/',
//\\    '/',
//\\    '<' '<',
//\\    '>' '>',
//\\    '!' '!',
//\\    '!',
//\\    '&',
//\\    '.';
d826 2
a827 2
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '+', A[ap+0]);
d829 2
a830 2
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '-', A[ap+0]);
d832 18
a849 21
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '*', A[ap+0]);  
    T[2] = lit(AST__LIT, '*', A[ap+1]);  
    T[3] = lit(AST__LIT, '*', A[ap+2]);  
    T[4] = lit(AST__LIT, '*', A[ap+3]);
    T[0] = mktuple(AST_OP, alt /*2*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 3) {  
    T[1] = lit(AST__LIT, '*', A[ap+0]);  
    T[2] = lit(AST__LIT, '*', A[ap+1]);
    T[0] = mktuple(AST_OP, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 4) {  
    T[1] = lit(AST__LIT, '*', A[ap+0]);
    T[0] = mktuple(AST_OP, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 5) {  
    T[1] = lit(AST__LIT, '/', A[ap+0]);  
    T[2] = lit(AST__LIT, '/', A[ap+1]);
    T[0] = mktuple(AST_OP, alt /*5*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 6) {  
    T[1] = lit(AST__LIT, '/', A[ap+0]);
    T[0] = mktuple(AST_OP, alt /*6*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 7) {  
d852 2
a853 2
    T[0] = mktuple(AST_OP, alt /*7*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 8) {  
d856 18
a873 14
    T[0] = mktuple(AST_OP, alt /*8*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 9) {  
    T[1] = lit(AST__LIT, '!', A[ap+0]);  
    T[2] = lit(AST__LIT, '!', A[ap+1]);
    T[0] = mktuple(AST_OP, alt /*9*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 10) {  
    T[1] = lit(AST__LIT, '!', A[ap+0]);
    T[0] = mktuple(AST_OP, alt /*10*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 11) {  
    T[1] = lit(AST__LIT, '&', A[ap+0]);
    T[0] = mktuple(AST_OP, alt /*11*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = lit(AST__LIT, '.', A[ap+0]);
    T[0] = mktuple(AST_OP, alt /*12*/, /*phrases*/ 1, T /*T[1]*/);
a878 1
//\\ # unary operators
d880 4
a883 5
//\\ P<Opt-PLUS> = 
//\\    '+',
//\\    '-',
//\\    '\\',
//\\   ;
d885 1
a885 1
case P_Opt_PLUS:
d887 5
a891 2
    T[1] = lit(AST__LIT, '+', A[ap+0]);
    T[0] = mktuple(AST_Opt_PLUS, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d893 7
a899 7
    T[1] = lit(AST__LIT, '-', A[ap+0]);
    T[0] = mktuple(AST_Opt_PLUS, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '\\', A[ap+0]);
    T[0] = mktuple(AST_Opt_PLUS, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_Opt_PLUS, alt /*3*/, /*phrases*/ 0, T /**/);
d906 4
a909 3
//\\ P<RESTOFSC> = 
//\\    <COMP2> <EXPR>,
//\\   ;
d911 11
a921 7
case P_RESTOFSC:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <COMP2>
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>
    T[0] = mktuple(AST_RESTOFSC, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_RESTOFSC, alt /*1*/, /*phrases*/ 0, T /**/);
d928 22
a949 2
//\\ P<COMP2> = 
//\\    <COMP1>;
a950 3
case P_COMP2:
  T[1] = build_ast(A[ap+0], depth+1); // <COMP1>
  return mktuple(AST_COMP2, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d954 6
a959 10
//\\ P<COMP1> = 
//\\    '=',
//\\    '#',
//\\    '=' '=',
//\\    '#' '#',
//\\    '<' '=',
//\\    '<',
//\\    '>' '=',
//\\    '>',
//\\    '-' '>';
d961 1
a961 1
case P_COMP1:
d963 2
a964 2
    T[1] = lit(AST__LIT, '=', A[ap+0]);
    T[0] = mktuple(AST_COMP1, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d966 2
a967 2
    T[1] = lit(AST__LIT, '#', A[ap+0]);
    T[0] = mktuple(AST_COMP1, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
d969 3
a971 3
    T[1] = lit(AST__LIT, '=', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_COMP1, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d973 2
a974 17
    T[1] = lit(AST__LIT, '#', A[ap+0]);  
    T[2] = lit(AST__LIT, '#', A[ap+1]);
    T[0] = mktuple(AST_COMP1, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 4) {  
    T[1] = lit(AST__LIT, '<', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_COMP1, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 5) {  
    T[1] = lit(AST__LIT, '<', A[ap+0]);
    T[0] = mktuple(AST_COMP1, alt /*5*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 6) {  
    T[1] = lit(AST__LIT, '>', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_COMP1, alt /*6*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 7) {  
    T[1] = lit(AST__LIT, '>', A[ap+0]);
    T[0] = mktuple(AST_COMP1, alt /*7*/, /*phrases*/ 1, T /*T[1]*/);
d976 2
a977 3
    T[1] = lit(AST__LIT, '-', A[ap+0]);  
    T[2] = lit(AST__LIT, '>', A[ap+1]);
    T[0] = mktuple(AST_COMP1, alt /*8*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d983 1
d985 4
a988 2
//\\ P<RESTOFANDC> = 
//\\    "and" <SC> <RESTOFANDC>,
d991 1
a991 1
case P_RESTOFANDC:
d993 8
a1000 4
    T[1] = kw(AST__KW, KW_and, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFANDC>
    T[0] = mktuple(AST_RESTOFANDC, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1002 18
a1019 1
    T[0] = mktuple(AST_RESTOFANDC, alt /*1*/, /*phrases*/ 0, T /**/);
d1105 1
a1105 1
//\\    <Opt-PLUS> <COPERAND> <RESTOFCEXPR>;
d1108 1
a1108 1
  T[1] = build_ast(A[ap+0], depth+1); // <Opt-PLUS>
d1630 1
a1630 1
//\\    <Opt-PLUS> <COPERAND> <RESTOFCEXPR>,
d1635 1
a1635 1
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-PLUS>
d2018 2
a2019 2
//\\    <NAME> <APP> <Opt-ENAME> <RESTOFUI> <AUI>,
//\\    '-' '>' <NAME> <APP>,
d2033 1
a2033 1
    T[2] = build_ast(A[ap+1], depth+1); // <APP>
d2042 1
a2042 1
    T[4] = build_ast(A[ap+3], depth+1); // <APP>
a2239 1
//\\ # An initialised array declaration does not need a %C following the '=' before the list of initial values.
d2242 1
a2242 1
//\\    <Opt-PercentQNAME> <Opt-VSPEC> <NAME> <Opt-ALIAS> <Opt-CONST> <RESTOFOWNDEC>,
d2249 3
a2251 5
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-ALIAS>
    T[5] = build_ast(A[ap+4], depth+1); // <Opt-CONST>
    T[6] = build_ast(A[ap+5], depth+1); // <RESTOFOWNDEC>
    T[0] = mktuple(AST_OWNDEC, alt /*0*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
d2265 30
d2299 1
a2299 1
//\\    '=' <stupid> <Opt-PLUS> <COPERAND> <RESTOFCEXPR> <REPFACT> <ROCL>,
d2306 1
a2306 1
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-PLUS>
d2321 1
a2321 1
//\\    ',' <stupid> <Opt-PLUS> <COPERAND> <RESTOFCEXPR> <REPFACT> <ROCL>,
d2328 1
a2328 1
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-PLUS>
a2372 20

//\\ P<RESTOFOWNDEC> = 
//\\    ',' <NAME> <Opt-ALIAS> <Opt-CONST> <RESTOFOWNDEC>,
//\\   ;

case P_RESTOFOWNDEC:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-ALIAS>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-CONST>
    T[5] = build_ast(A[ap+4], depth+1); // <RESTOFOWNDEC>
    T[0] = mktuple(AST_RESTOFOWNDEC, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else               {
    T[0] = mktuple(AST_RESTOFOWNDEC, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



d2375 2
a2376 2
//\\ P<Opt-CONST> = 
//\\    '=' <Opt-PLUS> <COPERAND> <RESTOFCEXPR>,
d2380 1
a2380 1
case P_Opt_CONST:
d2383 1
a2383 1
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-PLUS>
d2386 1
a2386 1
    T[0] = mktuple(AST_Opt_CONST, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d2391 1
a2391 1
    T[0] = mktuple(AST_Opt_CONST, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d2393 1
a2393 1
    T[0] = mktuple(AST_Opt_CONST, alt /*2*/, /*phrases*/ 0, T /**/);
@


1.2
log
@before removing dummys
@
text
@d10 1
a10 1
//\\ # Grammar for Imp80.  Originally on Emas-2900 series.
a11 1
//\\ # but updated with several Imp77 constructs.
d13 2
a14 2
//\\ P<TEXTTEXT> = 
//\\    <dqstring>;
d16 4
a19 3
case P_TEXTTEXT:
  T[1] = bip(AST_dqstring, A[ap+0]);
  return mktuple(AST_TEXTTEXT, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d23 2
a24 1
//\\ P<DUMMYAPP> = 
d27 43
a69 2
case P_DUMMYAPP:
  return mktuple(AST_DUMMYAPP, alt /*0*/, /*phrases*/ 0, T /**/);
d71 155
a227 2
//\\ P<DUMMYSTART> = 
//\\   ;
a228 2
case P_DUMMYSTART:
  return mktuple(AST_DUMMYSTART, alt /*0*/, /*phrases*/ 0, T /**/);
d230 3
d234 9
a243 2
//\\ P<TRACE> = 
//\\   ;
a244 2
case P_TRACE:
  return mktuple(AST_TRACE, alt /*0*/, /*phrases*/ 0, T /**/);
d247 3
d251 11
a261 2
//\\ P<READLINEq> = 
//\\   ;
a262 2
case P_READLINEq:
  return mktuple(AST_READLINEq, alt /*0*/, /*phrases*/ 0, T /**/);
a307 191

//\\ P<COLON> = 
//\\   ;

case P_COLON:
  return mktuple(AST_COLON, alt /*0*/, /*phrases*/ 0, T /**/);



//\\ P<NUMBER> = 
//\\    <digit> <rest-of-number>;

case P_NUMBER:
  T[1] = bip(AST_digit, A[ap+0]);
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-number>
  return mktuple(AST_NUMBER, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<ASSOP> = 
//\\    '=' '=',
//\\    '=',
//\\    '-' '>',
//\\    '<' '-';

case P_ASSOP:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_ASSOP, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);
    T[0] = mktuple(AST_ASSOP, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '-', A[ap+0]);  
    T[2] = lit(AST__LIT, '>', A[ap+1]);
    T[0] = mktuple(AST_ASSOP, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {  
    T[1] = lit(AST__LIT, '<', A[ap+0]);  
    T[2] = lit(AST__LIT, '-', A[ap+1]);
    T[0] = mktuple(AST_ASSOP, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<COMP1> = 
//\\    '=',
//\\    '#',
//\\    '=' '=',
//\\    '#' '#',
//\\    '<' '=',
//\\    '<',
//\\    '>' '=',
//\\    '>',
//\\    '-' '>';

case P_COMP1:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);
    T[0] = mktuple(AST_COMP1, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '#', A[ap+0]);
    T[0] = mktuple(AST_COMP1, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_COMP1, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 3) {  
    T[1] = lit(AST__LIT, '#', A[ap+0]);  
    T[2] = lit(AST__LIT, '#', A[ap+1]);
    T[0] = mktuple(AST_COMP1, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 4) {  
    T[1] = lit(AST__LIT, '<', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_COMP1, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 5) {  
    T[1] = lit(AST__LIT, '<', A[ap+0]);
    T[0] = mktuple(AST_COMP1, alt /*5*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 6) {  
    T[1] = lit(AST__LIT, '>', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_COMP1, alt /*6*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 7) {  
    T[1] = lit(AST__LIT, '>', A[ap+0]);
    T[0] = mktuple(AST_COMP1, alt /*7*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = lit(AST__LIT, '-', A[ap+0]);  
    T[2] = lit(AST__LIT, '>', A[ap+1]);
    T[0] = mktuple(AST_COMP1, alt /*8*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<COMP2> = 
//\\    <COMP1>;

case P_COMP2:
  T[1] = build_ast(A[ap+0], depth+1); // <COMP1>
  return mktuple(AST_COMP2, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);


//\\ # binary operators

//\\ P<OP> = 
//\\    '+',
//\\    '-',
//\\    '*' '*' '*' '*',
//\\    '*' '*',
//\\    '*',
//\\    '/' '/',
//\\    '/',
//\\    '<' '<',
//\\    '>' '>',
//\\    '!' '!',
//\\    '!',
//\\    '&',
//\\    '.';

case P_OP:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '+', A[ap+0]);
    T[0] = mktuple(AST_OP, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '-', A[ap+0]);
    T[0] = mktuple(AST_OP, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '*', A[ap+0]);  
    T[2] = lit(AST__LIT, '*', A[ap+1]);  
    T[3] = lit(AST__LIT, '*', A[ap+2]);  
    T[4] = lit(AST__LIT, '*', A[ap+3]);
    T[0] = mktuple(AST_OP, alt /*2*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 3) {  
    T[1] = lit(AST__LIT, '*', A[ap+0]);  
    T[2] = lit(AST__LIT, '*', A[ap+1]);
    T[0] = mktuple(AST_OP, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 4) {  
    T[1] = lit(AST__LIT, '*', A[ap+0]);
    T[0] = mktuple(AST_OP, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 5) {  
    T[1] = lit(AST__LIT, '/', A[ap+0]);  
    T[2] = lit(AST__LIT, '/', A[ap+1]);
    T[0] = mktuple(AST_OP, alt /*5*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 6) {  
    T[1] = lit(AST__LIT, '/', A[ap+0]);
    T[0] = mktuple(AST_OP, alt /*6*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 7) {  
    T[1] = lit(AST__LIT, '<', A[ap+0]);  
    T[2] = lit(AST__LIT, '<', A[ap+1]);
    T[0] = mktuple(AST_OP, alt /*7*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 8) {  
    T[1] = lit(AST__LIT, '>', A[ap+0]);  
    T[2] = lit(AST__LIT, '>', A[ap+1]);
    T[0] = mktuple(AST_OP, alt /*8*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 9) {  
    T[1] = lit(AST__LIT, '!', A[ap+0]);  
    T[2] = lit(AST__LIT, '!', A[ap+1]);
    T[0] = mktuple(AST_OP, alt /*9*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 10) {  
    T[1] = lit(AST__LIT, '!', A[ap+0]);
    T[0] = mktuple(AST_OP, alt /*10*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 11) {  
    T[1] = lit(AST__LIT, '&', A[ap+0]);
    T[0] = mktuple(AST_OP, alt /*11*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = lit(AST__LIT, '.', A[ap+0]);
    T[0] = mktuple(AST_OP, alt /*12*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<rest-of-number> = 
//\\    <NUMBER>,
//\\   ;

case P_rest_of_number:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <NUMBER>
    T[0] = mktuple(AST_rest_of_number, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_number, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



a311 10
//\\ P<OLDHEX> = 
//\\    <alphanumeric> <sqstring>;

case P_OLDHEX:
  T[1] = bip(AST_alphanumeric, A[ap+0]);
  T[2] = bip(AST_sqstring, A[ap+1]);
  return mktuple(AST_OLDHEX, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



d355 18
d374 10
a383 3
//\\ P<S> = 
//\\    <NL>,
//\\    ';';
d385 1
a385 1
case P_S:
d387 4
a390 5
    T[1] = bip(AST_NL, A[ap+0]);
    T[0] = mktuple(AST_S, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = lit(AST__LIT, ';', A[ap+0]);
    T[0] = mktuple(AST_S, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
a406 14
//\\ # expensive hacky test to temporarily handle X'...'
//\\ # ... and it's broken :-(  <!...> currently not working properly.
//\\ # both being reported wrongly, and not generating correct code below:
//\\ # a negated phrase should not create an AST entry. Or rather, it should create a null one.
//\\ # - I think the problem is only phrases can be negated, not BIPs ... so ...

//\\ P<SQUO-STRING> = 
//\\    <sqstring>;

case P_SQUO_STRING:
  T[1] = bip(AST_sqstring, A[ap+0]);
  return mktuple(AST_SQUO_STRING, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);


d424 12
a435 2
//\\ P<NOTESTART> = 
//\\   ;
d437 3
a439 2
case P_NOTESTART:
  return mktuple(AST_NOTESTART, alt /*0*/, /*phrases*/ 0, T /**/);
d442 1
d444 3
a446 1
//\\ P<NOTEFINISH> = 
d449 16
a464 2
case P_NOTEFINISH:
  return mktuple(AST_NOTEFINISH, alt /*0*/, /*phrases*/ 0, T /**/);
d468 2
a469 1
//\\ P<NOTECYCLE> = 
d472 10
a481 2
case P_NOTECYCLE:
  return mktuple(AST_NOTECYCLE, alt /*0*/, /*phrases*/ 0, T /**/);
d485 32
a516 2
//\\ P<NOTEREPEAT> = 
//\\   ;
a517 2
case P_NOTEREPEAT:
  return mktuple(AST_NOTEREPEAT, alt /*0*/, /*phrases*/ 0, T /**/);
d520 1
d522 2
a523 1
//\\ P<NOTECONST> = 
d526 12
a537 2
case P_NOTECONST:
  return mktuple(AST_NOTECONST, alt /*0*/, /*phrases*/ 0, T /**/);
d541 2
a542 1
//\\ P<CHUI> = 
d545 12
a556 2
case P_CHUI:
  return mktuple(AST_CHUI, alt /*0*/, /*phrases*/ 0, T /**/);
d558 1
d560 3
d564 13
a576 2
//\\ P<BIGHOLE> = 
//\\   ;
a577 2
case P_BIGHOLE:
  return mktuple(AST_BIGHOLE, alt /*0*/, /*phrases*/ 0, T /**/);
d581 2
a582 1
//\\ P<CHXTYPE> = 
d585 10
a594 2
case P_CHXTYPE:
  return mktuple(AST_CHXTYPE, alt /*0*/, /*phrases*/ 0, T /**/);
a597 2
//\\ P<HOLE> = 
//\\   ;
d599 22
a620 2
case P_HOLE:
  return mktuple(AST_HOLE, alt /*0*/, /*phrases*/ 0, T /**/);
d624 2
a625 1
//\\ P<MARK> = 
d628 9
a636 2
case P_MARK:
  return mktuple(AST_MARK, alt /*0*/, /*phrases*/ 0, T /**/);
d640 2
a641 1
//\\ P<UP> = 
d644 12
a655 2
case P_UP:
  return mktuple(AST_UP, alt /*0*/, /*phrases*/ 0, T /**/);
d659 65
a723 2
//\\ P<DOWN> = 
//\\   ;
a724 2
case P_DOWN:
  return mktuple(AST_DOWN, alt /*0*/, /*phrases*/ 0, T /**/);
d753 3
a755 4
//\\ P<OPERAND> = 
//\\    <NAME> <APP> <Opt-ENAME>,
//\\    <CONST> <NOTECONST>,
//\\    '(' <Opt-EXPR> ')';
d757 1
a757 1
case P_OPERAND:
d759 5
a763 13
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>
    T[2] = build_ast(A[ap+1], depth+1); // <APP>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-ENAME>
    T[0] = mktuple(AST_OPERAND, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <CONST>
    T[2] = build_ast(A[ap+1], depth+1); // <NOTECONST>
    T[0] = mktuple(AST_OPERAND, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {  
    T[1] = lit(AST__LIT, '(', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-EXPR>  
    T[3] = lit(AST__LIT, ')', A[ap+2]);
    T[0] = mktuple(AST_OPERAND, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
a768 1
//\\ # Constant operand
d770 2
a771 4
//\\ P<COPERAND> = 
//\\    <NAME> <DUMMYAPP>,
//\\    <CONST>,
//\\    '(' <Opt-CEXPR> ')';
d773 3
a775 15
case P_COPERAND:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>
    T[2] = build_ast(A[ap+1], depth+1); // <DUMMYAPP>
    T[0] = mktuple(AST_COPERAND, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <CONST>
    T[0] = mktuple(AST_COPERAND, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = lit(AST__LIT, '(', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-CEXPR>  
    T[3] = lit(AST__LIT, ')', A[ap+2]);
    T[0] = mktuple(AST_COPERAND, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  }
  return T[0];
d779 10
a788 1
//\\ # Constant expression
d790 35
a824 2
//\\ P<CEXPR> = 
//\\    <HOLE> <Opt-PLUS> <COPERAND> <MARK> <RESTOFCEXPR>;
a825 7
case P_CEXPR:
  T[1] = build_ast(A[ap+0], depth+1); // <HOLE>
  T[2] = build_ast(A[ap+1], depth+1); // <Opt-PLUS>
  T[3] = build_ast(A[ap+2], depth+1); // <COPERAND>
  T[4] = build_ast(A[ap+3], depth+1); // <MARK>
  T[5] = build_ast(A[ap+4], depth+1); // <RESTOFCEXPR>
  return mktuple(AST_CEXPR, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
d829 2
a830 2
//\\ P<Opt-CEXPR> = 
//\\    <CEXPR>,
d833 6
a838 4
case P_Opt_CEXPR:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <CEXPR>
    T[0] = mktuple(AST_Opt_CEXPR, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d840 1
a840 1
    T[0] = mktuple(AST_Opt_CEXPR, alt /*1*/, /*phrases*/ 0, T /**/);
a845 2
//\\ # Used in switch label.  (*) marks a catch-all. (like default: in C)
//\\ # Or at least SHOULD be used in switch label.  Looks like it isn't... gt
d847 3
a849 3
//\\ P<STAROREXPR> = 
//\\    <HOLE> <Opt-PLUS> <COPERAND> <MARK> <RESTOFCEXPR>,
//\\    '*';
d851 4
a854 8
case P_STAROREXPR:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <HOLE>
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-PLUS>
    T[3] = build_ast(A[ap+2], depth+1); // <COPERAND>
    T[4] = build_ast(A[ap+3], depth+1); // <MARK>
    T[5] = build_ast(A[ap+4], depth+1); // <RESTOFCEXPR>
    T[0] = mktuple(AST_STAROREXPR, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
d856 2
a857 2
    T[1] = lit(AST__LIT, '*', A[ap+0]);
    T[0] = mktuple(AST_STAROREXPR, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
d863 1
d865 2
a866 2
//\\ P<Opt-STAROREXPR> = 
//\\    <STAROREXPR>,
d869 12
a880 4
case P_Opt_STAROREXPR:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <STAROREXPR>
    T[0] = mktuple(AST_Opt_STAROREXPR, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d882 1
a882 1
    T[0] = mktuple(AST_Opt_STAROREXPR, alt /*1*/, /*phrases*/ 0, T /**/);
a887 1
//\\ # |...| added by gt
d889 3
a891 3
//\\ P<EXPR> = 
//\\    <HOLE> <Opt-PLUS> <OPERAND> <MARK> <RESTOFEXPR>,
//\\    '|' <EXPR> '|';
d893 8
a900 13
case P_EXPR:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <HOLE>
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-PLUS>
    T[3] = build_ast(A[ap+2], depth+1); // <OPERAND>
    T[4] = build_ast(A[ap+3], depth+1); // <MARK>
    T[5] = build_ast(A[ap+4], depth+1); // <RESTOFEXPR>
    T[0] = mktuple(AST_EXPR, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else               {  
    T[1] = lit(AST__LIT, '|', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>  
    T[3] = lit(AST__LIT, '|', A[ap+2]);
    T[0] = mktuple(AST_EXPR, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d907 2
a908 2
//\\ P<Opt-EXPR> = 
//\\    <EXPR>,
d911 6
a916 4
case P_Opt_EXPR:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <EXPR>
    T[0] = mktuple(AST_Opt_EXPR, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d918 1
a918 1
    T[0] = mktuple(AST_Opt_EXPR, alt /*1*/, /*phrases*/ 0, T /**/);
d925 2
a926 14
//\\ P<RESTOFEXPR> = 
//\\    <OP> <OPERAND> <RESTOFEXPR>,
//\\   ;

case P_RESTOFEXPR:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <OP>
    T[2] = build_ast(A[ap+1], depth+1); // <OPERAND>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFEXPR>
    T[0] = mktuple(AST_RESTOFEXPR, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_RESTOFEXPR, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];
d928 5
a952 1
//\\ # 'Application' i.e. parameters to routine or function call
d954 4
a957 3
//\\ P<APP> = 
//\\    '(' <EXPR> <RESTOFAPP> ')',
//\\   ;
d959 8
a966 2
case P_APP:
  if (alt == 0)        {  
d968 3
a970 6
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFAPP>  
    T[4] = lit(AST__LIT, ')', A[ap+3]);
    T[0] = mktuple(AST_APP, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[0] = mktuple(AST_APP, alt /*1*/, /*phrases*/ 0, T /**/);
d977 2
a978 2
//\\ P<RESTOFAPP> = 
//\\    ',' <EXPR> <RESTOFAPP>,
d981 4
a984 6
case P_RESTOFAPP:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFAPP>
    T[0] = mktuple(AST_RESTOFAPP, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d986 1
a986 1
    T[0] = mktuple(AST_RESTOFAPP, alt /*1*/, /*phrases*/ 0, T /**/);
d993 3
a995 3
//\\ P<Percent-IU> = 
//\\    "if",
//\\    "unless";
d997 1
a997 1
case P_Percent_IU:
d999 4
a1002 5
    T[1] = kw(AST__KW, KW_if, A[ap+0]);
    T[0] = mktuple(AST_Percent_IU, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_unless, A[ap+0]);
    T[0] = mktuple(AST_Percent_IU, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
d1009 3
a1011 4
//\\ P<Percent-WU> = 
//\\    "while" <HOLE> <SC> <RESTOFCOND> <MARK>,
//\\    "until" <HOLE> <SC> <RESTOFCOND> <MARK>,
//\\    "for" <HOLE> <NAME> '=' <EXPR> ',' <EXPR> ',' <EXPR> <MARK>;
d1013 1
a1013 1
case P_Percent_WU:
d1015 7
a1021 25
    T[1] = kw(AST__KW, KW_while, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <HOLE>
    T[3] = build_ast(A[ap+2], depth+1); // <SC>
    T[4] = build_ast(A[ap+3], depth+1); // <RESTOFCOND>
    T[5] = build_ast(A[ap+4], depth+1); // <MARK>
    T[0] = mktuple(AST_Percent_WU, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_until, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <HOLE>
    T[3] = build_ast(A[ap+2], depth+1); // <SC>
    T[4] = build_ast(A[ap+3], depth+1); // <RESTOFCOND>
    T[5] = build_ast(A[ap+4], depth+1); // <MARK>
    T[0] = mktuple(AST_Percent_WU, alt /*1*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_for, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <HOLE>
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>  
    T[4] = lit(AST__LIT, '=', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <EXPR>  
    T[6] = lit(AST__LIT, ',', A[ap+5]);
    T[7] = build_ast(A[ap+6], depth+1); // <EXPR>  
    T[8] = lit(AST__LIT, ',', A[ap+7]);
    T[9] = build_ast(A[ap+8], depth+1); // <EXPR>
    T[10] = build_ast(A[ap+9], depth+1); // <MARK>
    T[0] = mktuple(AST_Percent_WU, alt /*2*/, /*phrases*/ 10, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9], T[10]*/);
d1028 2
a1029 2
//\\ P<Opt-ALIAS> = 
//\\    "alias" <TEXTTEXT>,
d1032 6
a1037 5
case P_Opt_ALIAS:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_alias, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <TEXTTEXT>
    T[0] = mktuple(AST_Opt_ALIAS, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1039 1
a1039 1
    T[0] = mktuple(AST_Opt_ALIAS, alt /*1*/, /*phrases*/ 0, T /**/);
a1044 1
//\\ # <Opt-Const-assign> added by gt
d1046 4
a1049 3
//\\ P<Opt-Assign-NLIST> = 
//\\    ',' <NAME> <Opt-Const-assign> <Opt-Assign-NLIST>,
//\\   ;
d1051 16
a1066 3
case P_Opt_Assign_NLIST:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
d1068 2
a1069 5
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-Const-assign>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-Assign-NLIST>
    T[0] = mktuple(AST_Opt_Assign_NLIST, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[0] = mktuple(AST_Opt_Assign_NLIST, alt /*1*/, /*phrases*/ 0, T /**/);
d1076 2
a1077 2
//\\ P<Opt-NLIST> = 
//\\    ',' <NAME> <Opt-NLIST>,
d1080 1
a1080 1
case P_Opt_NLIST:
d1082 2
a1083 4
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-NLIST>
    T[0] = mktuple(AST_Opt_NLIST, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1085 1
a1085 1
    T[0] = mktuple(AST_Opt_NLIST, alt /*1*/, /*phrases*/ 0, T /**/);
d1091 1
d1093 4
a1096 3
//\\ P<FULLTYPE> = 
//\\    "integer",
//\\   ;
d1098 1
a1098 1
case P_FULLTYPE:
d1100 5
a1104 2
    T[1] = kw(AST__KW, KW_integer, A[ap+0]);
    T[0] = mktuple(AST_FULLTYPE, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d1106 3
a1108 1
    T[0] = mktuple(AST_FULLTYPE, alt /*1*/, /*phrases*/ 0, T /**/);
d1115 4
a1118 4
//\\ P<BTYPE> = 
//\\    "real",
//\\    "integer",
//\\    "long" "real";
d1120 1
a1120 1
case P_BTYPE:
d1122 2
a1123 2
    T[1] = kw(AST__KW, KW_real, A[ap+0]);
    T[0] = mktuple(AST_BTYPE, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d1125 2
a1126 2
    T[1] = kw(AST__KW, KW_integer, A[ap+0]);
    T[0] = mktuple(AST_BTYPE, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
d1128 2
a1129 3
    T[1] = kw(AST__KW, KW_long, A[ap+0]);  
    T[2] = kw(AST__KW, KW_real, A[ap+1]);
    T[0] = mktuple(AST_BTYPE, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1189 1
a1189 1
//\\ # added predicate - gt
d1191 4
a1194 4
//\\ P<RT> = 
//\\    "routine",
//\\    "predicate",
//\\    <CHXTYPE> <XTYPE> <FM>;
d1196 4
a1199 4
case P_RT:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_routine, A[ap+0]);
    T[0] = mktuple(AST_RT, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d1201 2
a1202 2
    T[1] = kw(AST__KW, KW_predicate, A[ap+0]);
    T[0] = mktuple(AST_RT, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
d1204 1
a1204 4
    T[1] = build_ast(A[ap+0], depth+1); // <CHXTYPE>
    T[2] = build_ast(A[ap+1], depth+1); // <XTYPE>
    T[3] = build_ast(A[ap+2], depth+1); // <FM>
    T[0] = mktuple(AST_RT, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1210 1
d1212 3
a1214 4
//\\ P<FM> = 
//\\    "fn",
//\\    "map",
//\\    "function";
d1216 1
a1216 22
case P_FM:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_fn, A[ap+0]);
    T[0] = mktuple(AST_FM, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_map, A[ap+0]);
    T[0] = mktuple(AST_FM, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_function, A[ap+0]);
    T[0] = mktuple(AST_FM, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<FPDEL> = 
//\\    <XTYPE> <Opt-PercentQNAME> <NAME> <Opt-NLIST>,
//\\    <RT> <Opt-PercentNAME> <NAME> <Opt-NLIST> <FPP>,
//\\    "name" <NAME> <Opt-NLIST>;

case P_FPDEL:
d1218 7
a1224 17
    T[1] = build_ast(A[ap+0], depth+1); // <XTYPE>
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-PercentQNAME>
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-NLIST>
    T[0] = mktuple(AST_FPDEL, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <RT>
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-PercentNAME>
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-NLIST>
    T[5] = build_ast(A[ap+4], depth+1); // <FPP>
    T[0] = mktuple(AST_FPDEL, alt /*1*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_name, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-NLIST>
    T[0] = mktuple(AST_FPDEL, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1231 2
a1232 2
//\\ P<Opt-PercentNAME> = 
//\\    "name",
d1235 1
a1235 1
case P_Opt_PercentNAME:
d1237 5
a1241 2
    T[1] = kw(AST__KW, KW_name, A[ap+0]);
    T[0] = mktuple(AST_Opt_PercentNAME, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d1243 1
a1243 1
    T[0] = mktuple(AST_Opt_PercentNAME, alt /*1*/, /*phrases*/ 0, T /**/);
d1250 2
a1251 3
//\\ P<Opt-PercentQNAME> = 
//\\    "array" "name",
//\\    "name",
d1254 1
a1254 1
case P_Opt_PercentQNAME:
d1256 4
a1259 6
    T[1] = kw(AST__KW, KW_array, A[ap+0]);  
    T[2] = kw(AST__KW, KW_name, A[ap+1]);
    T[0] = mktuple(AST_Opt_PercentQNAME, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_name, A[ap+0]);
    T[0] = mktuple(AST_Opt_PercentQNAME, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
d1261 1
a1261 1
    T[0] = mktuple(AST_Opt_PercentQNAME, alt /*2*/, /*phrases*/ 0, T /**/);
d1268 3
a1270 3
//\\ P<FPP> = 
//\\    '(' <HOLE> <FPDEL> <MARK> <RESTOFFPLIST> ')',
//\\   ;
d1272 6
a1277 2
case P_FPP:
  if (alt == 0)        {  
d1279 5
a1283 8
    T[2] = build_ast(A[ap+1], depth+1); // <HOLE>
    T[3] = build_ast(A[ap+2], depth+1); // <FPDEL>
    T[4] = build_ast(A[ap+3], depth+1); // <MARK>
    T[5] = build_ast(A[ap+4], depth+1); // <RESTOFFPLIST>  
    T[6] = lit(AST__LIT, ')', A[ap+5]);
    T[0] = mktuple(AST_FPP, alt /*0*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } else               {
    T[0] = mktuple(AST_FPP, alt /*1*/, /*phrases*/ 0, T /**/);
d1290 3
a1292 3
//\\ P<RESTOFFPLIST> = 
//\\    <Opt-Comma> <HOLE> <FPDEL> <MARK> <RESTOFFPLIST>,
//\\   ;
d1294 1
a1294 1
case P_RESTOFFPLIST:
d1296 8
a1303 8
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-Comma>
    T[2] = build_ast(A[ap+1], depth+1); // <HOLE>
    T[3] = build_ast(A[ap+2], depth+1); // <FPDEL>
    T[4] = build_ast(A[ap+3], depth+1); // <MARK>
    T[5] = build_ast(A[ap+4], depth+1); // <RESTOFFPLIST>
    T[0] = mktuple(AST_RESTOFFPLIST, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else               {
    T[0] = mktuple(AST_RESTOFFPLIST, alt /*1*/, /*phrases*/ 0, T /**/);
d1309 13
d1323 2
a1324 2
//\\ P<Opt-Comma> = 
//\\    ',',
d1327 1
a1327 1
case P_Opt_Comma:
d1330 2
a1331 1
    T[0] = mktuple(AST_Opt_Comma, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d1333 1
a1333 1
    T[0] = mktuple(AST_Opt_Comma, alt /*1*/, /*phrases*/ 0, T /**/);
d1339 1
d1341 2
a1342 2
//\\ P<LISTOFF> = 
//\\   ;
d1344 8
a1351 2
case P_LISTOFF:
  return mktuple(AST_LISTOFF, alt /*0*/, /*phrases*/ 0, T /**/);
d1354 1
d1356 2
a1357 1
//\\ P<LISTON> = 
d1360 13
a1372 2
case P_LISTON:
  return mktuple(AST_LISTON, alt /*0*/, /*phrases*/ 0, T /**/);
a1374 1
//\\ # prim and perm added by gt
d1376 4
a1379 7
//\\ P<ENDLIST> = 
//\\    "of" "program" <UP>,
//\\    "of" "file",
//\\    "of" "prim",
//\\    "of" "perm",
//\\    "of" "list" <LISTOFF>,
//\\    <UP>;
d1381 1
a1381 1
case P_ENDLIST:
d1383 3
a1385 4
    T[1] = kw(AST__KW, KW_of, A[ap+0]);  
    T[2] = kw(AST__KW, KW_program, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <UP>
    T[0] = mktuple(AST_ENDLIST, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1387 2
a1388 16
    T[1] = kw(AST__KW, KW_of, A[ap+0]);  
    T[2] = kw(AST__KW, KW_file, A[ap+1]);
    T[0] = mktuple(AST_ENDLIST, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 2) {  
    T[1] = kw(AST__KW, KW_of, A[ap+0]);  
    T[2] = kw(AST__KW, KW_prim, A[ap+1]);
    T[0] = mktuple(AST_ENDLIST, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 3) {  
    T[1] = kw(AST__KW, KW_of, A[ap+0]);  
    T[2] = kw(AST__KW, KW_perm, A[ap+1]);
    T[0] = mktuple(AST_ENDLIST, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 4) {  
    T[1] = kw(AST__KW, KW_of, A[ap+0]);  
    T[2] = kw(AST__KW, KW_list, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <LISTOFF>
    T[0] = mktuple(AST_ENDLIST, alt /*4*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1390 1
a1390 2
    T[1] = build_ast(A[ap+0], depth+1); // <UP>
    T[0] = mktuple(AST_ENDLIST, alt /*5*/, /*phrases*/ 1, T /*T[1]*/);
d1397 2
a1398 2
//\\ P<Opt-PercentFORMAT> = 
//\\    "format",
d1401 1
a1401 1
case P_Opt_PercentFORMAT:
d1403 2
a1404 2
    T[1] = kw(AST__KW, KW_format, A[ap+0]);
    T[0] = mktuple(AST_Opt_PercentFORMAT, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d1406 1
a1406 1
    T[0] = mktuple(AST_Opt_PercentFORMAT, alt /*1*/, /*phrases*/ 0, T /**/);
d1412 1
a1412 2
//\\ # <NAME> <APP> added by gt for predicates
//\\ # RestOfSc handles double-sided conditions such as '0' <= ch <= '9'
d1414 3
a1416 5
//\\ P<SC> = 
//\\    <EXPR> <COMP1> <EXPR> <RESTOFSC>,
//\\    <NAME> <APP>,
//\\    '(' <SC> <RESTOFCOND> ')',
//\\    "not" <SC>;
d1418 2
a1419 12
case P_SC:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <EXPR>
    T[2] = build_ast(A[ap+1], depth+1); // <COMP1>
    T[3] = build_ast(A[ap+2], depth+1); // <EXPR>
    T[4] = build_ast(A[ap+3], depth+1); // <RESTOFSC>
    T[0] = mktuple(AST_SC, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>
    T[2] = build_ast(A[ap+1], depth+1); // <APP>
    T[0] = mktuple(AST_SC, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 2) {  
d1421 5
a1425 8
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFCOND>  
    T[4] = lit(AST__LIT, ')', A[ap+3]);
    T[0] = mktuple(AST_SC, alt /*2*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_not, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[0] = mktuple(AST_SC, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1432 2
a1433 2
//\\ P<RESTOFSC> = 
//\\    <COMP2> <EXPR>,
d1436 1
a1436 1
case P_RESTOFSC:
d1438 2
a1439 3
    T[1] = build_ast(A[ap+0], depth+1); // <COMP2>
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>
    T[0] = mktuple(AST_RESTOFSC, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1441 1
a1441 1
    T[0] = mktuple(AST_RESTOFSC, alt /*1*/, /*phrases*/ 0, T /**/);
d1447 2
a1448 1
//\\ # Imp does not let you mix and/or without explicit brackets. They do not have a precedence relationship
d1450 3
a1452 4
//\\ P<RESTOFCOND> = 
//\\    "and" <SC> <RESTOFANDC>,
//\\    "or" <SC> <RESTOFORC>,
//\\   ;
d1454 9
a1462 13
case P_RESTOFCOND:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_and, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFANDC>
    T[0] = mktuple(AST_RESTOFCOND, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_or, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFORC>
    T[0] = mktuple(AST_RESTOFCOND, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_RESTOFCOND, alt /*2*/, /*phrases*/ 0, T /**/);
d1469 4
a1472 3
//\\ P<RESTOFANDC> = 
//\\    "and" <SC> <RESTOFANDC>,
//\\   ;
d1474 1
a1474 1
case P_RESTOFANDC:
d1476 9
a1484 6
    T[1] = kw(AST__KW, KW_and, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFANDC>
    T[0] = mktuple(AST_RESTOFANDC, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_RESTOFANDC, alt /*1*/, /*phrases*/ 0, T /**/);
d1491 2
a1492 2
//\\ P<RESTOFORC> = 
//\\    "or" <SC> <RESTOFORC>,
d1495 1
a1495 1
case P_RESTOFORC:
d1497 2
a1498 4
    T[1] = kw(AST__KW, KW_or, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFORC>
    T[0] = mktuple(AST_RESTOFORC, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1500 1
a1500 1
    T[0] = mktuple(AST_RESTOFORC, alt /*1*/, /*phrases*/ 0, T /**/);
d1507 2
a1508 3
//\\ P<RESTOFUI> = 
//\\    <ASSOP> <EXPR>,
//\\    ':',
d1511 5
a1515 8
case P_RESTOFUI:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <ASSOP>
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>
    T[0] = mktuple(AST_RESTOFUI, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, ':', A[ap+0]);
    T[0] = mktuple(AST_RESTOFUI, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
d1517 1
a1517 1
    T[0] = mktuple(AST_RESTOFUI, alt /*2*/, /*phrases*/ 0, T /**/);
d1524 9
d1534 2
a1535 2
//\\    "spec" <BIGHOLE>,
//\\    <DOWN>;
d1540 1
a1540 2
    T[2] = build_ast(A[ap+1], depth+1); // <BIGHOLE>
    T[0] = mktuple(AST_Opt_PercentSPEC, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1542 1
a1542 2
    T[1] = build_ast(A[ap+0], depth+1); // <DOWN>
    T[0] = mktuple(AST_Opt_PercentSPEC, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
d1549 5
a1553 2
//\\ P<Opt-VSPEC> = 
//\\    "spec",
d1556 1
a1556 1
case P_Opt_VSPEC:
d1558 11
a1568 2
    T[1] = kw(AST__KW, KW_spec, A[ap+0]);
    T[0] = mktuple(AST_Opt_VSPEC, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d1570 1
a1570 1
    T[0] = mktuple(AST_Opt_VSPEC, alt /*1*/, /*phrases*/ 0, T /**/);
a1575 1
//\\ # List of lower/upper bound pairs, for array declarations.
d1577 3
a1579 3
//\\ P<RESTOFBPLIST> = 
//\\    ',' <EXPR> ':' <EXPR> <RESTOFBPLIST>,
//\\   ;
d1581 1
a1581 1
case P_RESTOFBPLIST:
d1583 3
a1585 6
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>  
    T[3] = lit(AST__LIT, ':', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <EXPR>
    T[5] = build_ast(A[ap+4], depth+1); // <RESTOFBPLIST>
    T[0] = mktuple(AST_RESTOFBPLIST, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
d1587 7
a1593 1
    T[0] = mktuple(AST_RESTOFBPLIST, alt /*1*/, /*phrases*/ 0, T /**/);
d1599 1
d1601 6
a1606 3
//\\ P<Opt-Const-assign> = 
//\\    '=' <EXPR>,
//\\    '=' <CEXPR>,
d1609 1
a1609 1
case P_Opt_Const_assign:
d1611 3
a1613 3
    T[1] = lit(AST__LIT, '=', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>
    T[0] = mktuple(AST_Opt_Const_assign, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1615 15
a1629 3
    T[1] = lit(AST__LIT, '=', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <CEXPR>
    T[0] = mktuple(AST_Opt_Const_assign, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1631 1
a1631 1
    T[0] = mktuple(AST_Opt_Const_assign, alt /*2*/, /*phrases*/ 0, T /**/);
a1660 1
//\\ # Array declaration
d1662 2
a1663 15
//\\ P<ADECLN> = 
//\\    <NAME> <Opt-NLIST> <BPAIR> <RESTOFARLIST>;

case P_ADECLN:
  T[1] = build_ast(A[ap+0], depth+1); // <NAME>
  T[2] = build_ast(A[ap+1], depth+1); // <Opt-NLIST>
  T[3] = build_ast(A[ap+2], depth+1); // <BPAIR>
  T[4] = build_ast(A[ap+3], depth+1); // <RESTOFARLIST>
  return mktuple(AST_ADECLN, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);


//\\ # Multi-dimensional arrays

//\\ P<RESTOFARLIST> = 
//\\    ',' <ADECLN>,
d1666 1
a1666 1
case P_RESTOFARLIST:
d1668 2
a1669 3
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <ADECLN>
    T[0] = mktuple(AST_RESTOFARLIST, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d1671 1
a1671 1
    T[0] = mktuple(AST_RESTOFARLIST, alt /*1*/, /*phrases*/ 0, T /**/);
d1677 1
d1679 3
a1681 3
//\\ P<OWNDEC> = 
//\\    <Opt-PercentQNAME> <Opt-VSPEC> <HOLE> <NAME> <Opt-ALIAS> <Opt-CONST> <MARK> <RESTOFOWNDEC>,
//\\    "array" <Opt-PercentFORMAT> <Opt-VSPEC> <NAME> <BPAIR> <CONSTLIST>;
d1683 9
a1691 19
case P_OWNDEC:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-PercentQNAME>
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-VSPEC>
    T[3] = build_ast(A[ap+2], depth+1); // <HOLE>
    T[4] = build_ast(A[ap+3], depth+1); // <NAME>
    T[5] = build_ast(A[ap+4], depth+1); // <Opt-ALIAS>
    T[6] = build_ast(A[ap+5], depth+1); // <Opt-CONST>
    T[7] = build_ast(A[ap+6], depth+1); // <MARK>
    T[8] = build_ast(A[ap+7], depth+1); // <RESTOFOWNDEC>
    T[0] = mktuple(AST_OWNDEC, alt /*0*/, /*phrases*/ 8, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_array, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-PercentFORMAT>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-VSPEC>
    T[4] = build_ast(A[ap+3], depth+1); // <NAME>
    T[5] = build_ast(A[ap+4], depth+1); // <BPAIR>
    T[6] = build_ast(A[ap+5], depth+1); // <CONSTLIST>
    T[0] = mktuple(AST_OWNDEC, alt /*1*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
d1697 1
d1699 3
a1701 2
//\\ P<RESTOFOWNDEC> = 
//\\    ',' <HOLE> <NAME> <Opt-ALIAS> <Opt-CONST> <MARK> <RESTOFOWNDEC>,
d1704 1
a1704 1
case P_RESTOFOWNDEC:
d1706 7
a1712 8
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <HOLE>
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-ALIAS>
    T[5] = build_ast(A[ap+4], depth+1); // <Opt-CONST>
    T[6] = build_ast(A[ap+5], depth+1); // <MARK>
    T[7] = build_ast(A[ap+6], depth+1); // <RESTOFOWNDEC>
    T[0] = mktuple(AST_RESTOFOWNDEC, alt /*0*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
d1714 1
a1714 1
    T[0] = mktuple(AST_RESTOFOWNDEC, alt /*1*/, /*phrases*/ 0, T /**/);
d1721 4
a1724 6
//\\ P<XOWN> = 
//\\    "own",
//\\    "external",
//\\    "extrinsic",
//\\    "constant",
//\\    "const";
d1726 1
a1726 1
case P_XOWN:
d1728 4
a1731 2
    T[1] = kw(AST__KW, KW_own, A[ap+0]);
    T[0] = mktuple(AST_XOWN, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d1733 4
a1736 8
    T[1] = kw(AST__KW, KW_external, A[ap+0]);
    T[0] = mktuple(AST_XOWN, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = kw(AST__KW, KW_extrinsic, A[ap+0]);
    T[0] = mktuple(AST_XOWN, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 3) {  
    T[1] = kw(AST__KW, KW_constant, A[ap+0]);
    T[0] = mktuple(AST_XOWN, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
d1738 9
a1746 2
    T[1] = kw(AST__KW, KW_const, A[ap+0]);
    T[0] = mktuple(AST_XOWN, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
a1751 2
//\\ # this is a stupid hack to get around comments in the middle of array declarations :-(
//\\ # note that it gobbles the newline
d1753 2
a1754 2
//\\ P<stupid> = 
//\\    <COMMENT>,
d1757 6
a1762 4
case P_stupid:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <COMMENT>
    T[0] = mktuple(AST_stupid, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d1764 1
a1764 1
    T[0] = mktuple(AST_stupid, alt /*1*/, /*phrases*/ 0, T /**/);
a1769 1
//\\ # An initialised array declaration does not need a %C following the '=' before the list of initial values.
d1771 2
a1772 2
//\\ P<CONSTLIST> = 
//\\    '=' <READLINEq> <stupid> <Opt-PLUS> <COPERAND> <RESTOFCEXPR> <REPFACT> <ROCL>,
d1775 10
a1784 11
case P_CONSTLIST:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <READLINEq>
    T[3] = build_ast(A[ap+2], depth+1); // <stupid>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-PLUS>
    T[5] = build_ast(A[ap+4], depth+1); // <COPERAND>
    T[6] = build_ast(A[ap+5], depth+1); // <RESTOFCEXPR>
    T[7] = build_ast(A[ap+6], depth+1); // <REPFACT>
    T[8] = build_ast(A[ap+7], depth+1); // <ROCL>
    T[0] = mktuple(AST_CONSTLIST, alt /*0*/, /*phrases*/ 8, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8]*/);
d1786 1
a1786 1
    T[0] = mktuple(AST_CONSTLIST, alt /*1*/, /*phrases*/ 0, T /**/);
d1793 2
a1794 2
//\\ P<ROCL> = 
//\\    ',' <stupid> <Opt-PLUS> <COPERAND> <RESTOFCEXPR> <REPFACT> <ROCL>,
d1797 1
a1797 1
case P_ROCL:
d1799 3
a1801 8
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <stupid>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-PLUS>
    T[4] = build_ast(A[ap+3], depth+1); // <COPERAND>
    T[5] = build_ast(A[ap+4], depth+1); // <RESTOFCEXPR>
    T[6] = build_ast(A[ap+5], depth+1); // <REPFACT>
    T[7] = build_ast(A[ap+6], depth+1); // <ROCL>
    T[0] = mktuple(AST_ROCL, alt /*0*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
d1803 1
a1803 1
    T[0] = mktuple(AST_ROCL, alt /*1*/, /*phrases*/ 0, T /**/);
a1808 1
//\\ # "42(2)" is equivalent to "42, 42".  (*) means 'as many more are needed to fill the array' so must come last.
d1810 4
a1813 3
//\\ P<REPFACT> = 
//\\    '(' <Opt-STAROREXPR> ')',
//\\   ;
d1815 1
a1815 1
case P_REPFACT:
d1817 8
a1824 4
    T[1] = lit(AST__LIT, '(', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-STAROREXPR>  
    T[3] = lit(AST__LIT, ')', A[ap+2]);
    T[0] = mktuple(AST_REPFACT, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1826 2
a1827 1
    T[0] = mktuple(AST_REPFACT, alt /*1*/, /*phrases*/ 0, T /**/);
d1833 4
d1838 12
a1849 3
//\\ P<RESTOFNLIST> = 
//\\    ',' <CEXPR> <RESTOFNLIST>,
//\\   ;
d1851 47
a1897 8
case P_RESTOFNLIST:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <CEXPR>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFNLIST>
    T[0] = mktuple(AST_RESTOFNLIST, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_RESTOFNLIST, alt /*1*/, /*phrases*/ 0, T /**/);
d1903 1
d1905 2
a1906 2
//\\ P<Opt-PercentEVENT> = 
//\\    "event",
d1909 1
a1909 1
case P_Opt_PercentEVENT:
d1911 4
a1914 2
    T[1] = kw(AST__KW, KW_event, A[ap+0]);
    T[0] = mktuple(AST_Opt_PercentEVENT, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d1916 1
a1916 1
    T[0] = mktuple(AST_Opt_PercentEVENT, alt /*1*/, /*phrases*/ 0, T /**/);
a1921 1
//\\ # gt changed to allow 2 exprs
d1940 1
d1942 2
a1943 2
//\\ P<OPEXPR2> = 
//\\    ',' <EXPR> <OPEXPR>,
d1946 1
a1946 1
case P_OPEXPR2:
d1948 3
a1950 4
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <EXPR>
    T[3] = build_ast(A[ap+2], depth+1); // <OPEXPR>
    T[0] = mktuple(AST_OPEXPR2, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1952 29
a1980 1
    T[0] = mktuple(AST_OPEXPR2, alt /*1*/, /*phrases*/ 0, T /**/);
d1986 2
a1987 2
//\\ # rest of %switch list
//\\ # WOW! Original had '<' ... : ... '>' instead of '(' ... ')' ????
d1989 3
a1991 2
//\\ P<RESTOFSWLIST> = 
//\\    ',' <NAME> <Opt-NLIST> '(' <EXPR> ':' <EXPR> ')' <RESTOFSWLIST>,
d1994 8
a2001 12
case P_RESTOFSWLIST:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-NLIST>  
    T[4] = lit(AST__LIT, '(', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <EXPR>  
    T[6] = lit(AST__LIT, ':', A[ap+5]);
    T[7] = build_ast(A[ap+6], depth+1); // <EXPR>  
    T[8] = lit(AST__LIT, ')', A[ap+7]);
    T[9] = build_ast(A[ap+8], depth+1); // <RESTOFSWLIST>
    T[0] = mktuple(AST_RESTOFSWLIST, alt /*0*/, /*phrases*/ 9, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9]*/);
d2003 1
a2003 1
    T[0] = mktuple(AST_RESTOFSWLIST, alt /*1*/, /*phrases*/ 0, T /**/);
d2010 4
a2013 3
//\\ P<RESTOFREPEAT> = 
//\\    "until" <SC> <RESTOFCOND>,
//\\   ;
d2015 1
a2015 1
case P_RESTOFREPEAT:
d2017 11
a2027 6
    T[1] = kw(AST__KW, KW_until, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <SC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFCOND>
    T[0] = mktuple(AST_RESTOFREPEAT, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_RESTOFREPEAT, alt /*1*/, /*phrases*/ 0, T /**/);
a2032 2
//\\ # gt moved COLON to end instead of front. <COLON> appears to be an action, not a character
//\\ # as the grammar has ':' <COLON> at the location of a label.  So it's a NULL term.
d2038 1
a2038 1
//\\    <COLON>;
d2055 1
a2055 2
    T[1] = build_ast(A[ap+0], depth+1); // <COLON>
    T[0] = mktuple(AST_RESTOFSS1, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
d2061 1
d2063 3
a2065 4
//\\ P<RESTOFIU> = 
//\\    "start" <NOTESTART>,
//\\    "then" "start" <NOTESTART>,
//\\    "then" <HOLE> <UI> <MARK> <Opt-ELSE>;
d2067 9
a2075 10
case P_RESTOFIU:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_start, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NOTESTART>
    T[0] = mktuple(AST_RESTOFIU, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_then, A[ap+0]);  
    T[2] = kw(AST__KW, KW_start, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <NOTESTART>
    T[0] = mktuple(AST_RESTOFIU, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d2077 7
a2083 6
    T[1] = kw(AST__KW, KW_then, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <HOLE>
    T[3] = build_ast(A[ap+2], depth+1); // <UI>
    T[4] = build_ast(A[ap+3], depth+1); // <MARK>
    T[5] = build_ast(A[ap+4], depth+1); // <Opt-ELSE>
    T[0] = mktuple(AST_RESTOFIU, alt /*2*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
d2089 2
a2090 1
//\\ # can avoid a start/finish block by call1 %and call2 %if condition
d2092 2
a2093 2
//\\ P<AUI> = 
//\\    "and" <UI>,
d2096 1
a2096 1
case P_AUI:
d2098 8
a2105 3
    T[1] = kw(AST__KW, KW_and, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <UI>
    T[0] = mktuple(AST_AUI, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d2107 1
a2107 1
    T[0] = mktuple(AST_AUI, alt /*1*/, /*phrases*/ 0, T /**/);
d2114 2
a2115 2
//\\ P<Opt-ELSE> = 
//\\    "else" <AFTERELSE>,
d2118 1
a2118 1
case P_Opt_ELSE:
d2120 8
a2127 3
    T[1] = kw(AST__KW, KW_else, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <AFTERELSE>
    T[0] = mktuple(AST_Opt_ELSE, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d2129 1
a2129 1
    T[0] = mktuple(AST_Opt_ELSE, alt /*1*/, /*phrases*/ 0, T /**/);
d2136 3
a2138 4
//\\ P<AFTERELSE> = 
//\\    "start" <NOTESTART>,
//\\    <Percent-IU> <HOLE> <SC> <RESTOFCOND> <MARK> <RESTOFIU>,
//\\    <UI>;
d2140 4
a2143 13
case P_AFTERELSE:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_start, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NOTESTART>
    T[0] = mktuple(AST_AFTERELSE, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <Percent-IU>
    T[2] = build_ast(A[ap+1], depth+1); // <HOLE>
    T[3] = build_ast(A[ap+2], depth+1); // <SC>
    T[4] = build_ast(A[ap+3], depth+1); // <RESTOFCOND>
    T[5] = build_ast(A[ap+4], depth+1); // <MARK>
    T[6] = build_ast(A[ap+5], depth+1); // <RESTOFIU>
    T[0] = mktuple(AST_AFTERELSE, alt /*1*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
d2145 1
a2145 2
    T[1] = build_ast(A[ap+0], depth+1); // <UI>
    T[0] = mktuple(AST_AFTERELSE, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
d2152 2
a2153 2
//\\ P<Opt-ENAME> = 
//\\    '_' <NAME> <APP> <Opt-ENAME>,
d2156 1
a2156 1
case P_Opt_ENAME:
d2158 2
a2159 5
    T[1] = lit(AST__LIT, '_', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <APP>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-ENAME>
    T[0] = mktuple(AST_Opt_ENAME, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d2161 1
a2161 1
    T[0] = mktuple(AST_Opt_ENAME, alt /*1*/, /*phrases*/ 0, T /**/);
d2168 16
a2183 2
//\\ P<BPAIR> = 
//\\    '(' <EXPR> ':' <EXPR> <RESTOFBPLIST> ')';
a2184 8
case P_BPAIR:
  T[1] = lit(AST__LIT, '(', A[ap+0]);
  T[2] = build_ast(A[ap+1], depth+1); // <EXPR>
  T[3] = lit(AST__LIT, ':', A[ap+2]);
  T[4] = build_ast(A[ap+3], depth+1); // <EXPR>
  T[5] = build_ast(A[ap+4], depth+1); // <RESTOFBPLIST>
  T[6] = lit(AST__LIT, ')', A[ap+5]);
  return mktuple(AST_BPAIR, alt /*0*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
d2187 1
a2187 1
//\\ # '== 0' needed for %const %record(*) %name nil == 0 - gt
d2214 2
a2215 2
//\\ P<Percent-SEX> = 
//\\    "system",
d2217 3
a2219 3
//\\    "dynamic",
//\\    "prim",
//\\   ;
d2221 1
a2221 1
case P_Percent_SEX:
d2223 2
a2224 2
    T[1] = kw(AST__KW, KW_system, A[ap+0]);
    T[0] = mktuple(AST_Percent_SEX, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
d2227 1
a2227 1
    T[0] = mktuple(AST_Percent_SEX, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
d2229 2
a2230 2
    T[1] = kw(AST__KW, KW_dynamic, A[ap+0]);
    T[0] = mktuple(AST_Percent_SEX, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
d2232 2
a2233 123
    T[1] = kw(AST__KW, KW_prim, A[ap+0]);
    T[0] = mktuple(AST_Percent_SEX, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_Percent_SEX, alt /*4*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<CYCPARM> = 
//\\    <NAME> '=' <EXPR> ',' <EXPR> ',' <EXPR>,
//\\   ;

case P_CYCPARM:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <EXPR>  
    T[4] = lit(AST__LIT, ',', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <EXPR>  
    T[6] = lit(AST__LIT, ',', A[ap+5]);
    T[7] = build_ast(A[ap+6], depth+1); // <EXPR>
    T[0] = mktuple(AST_CYCPARM, alt /*0*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else               {
    T[0] = mktuple(AST_CYCPARM, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # RF in the rules below is short for Record Format

//\\ P<RESTOFRFDEC> = 
//\\    ',' <RFDEC> <RESTOFRFDEC>,
//\\   ;

case P_RESTOFRFDEC:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <RFDEC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFRFDEC>
    T[0] = mktuple(AST_RESTOFRFDEC, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_RESTOFRFDEC, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<RFSTMNT> = 
//\\    "spec" <NAME>,
//\\    <NAME> '(' <RFDEC> <RESTOFRFDEC> <ALTRFDEC> ')';

case P_RFSTMNT:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_spec, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[0] = mktuple(AST_RFSTMNT, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>  
    T[2] = lit(AST__LIT, '(', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <RFDEC>
    T[4] = build_ast(A[ap+3], depth+1); // <RESTOFRFDEC>
    T[5] = build_ast(A[ap+4], depth+1); // <ALTRFDEC>  
    T[6] = lit(AST__LIT, ')', A[ap+5]);
    T[0] = mktuple(AST_RFSTMNT, alt /*1*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  }
  return T[0];




//\\ P<RFREF> = 
//\\    <NAME>,
//\\    <RFDEC> <RESTOFRFDEC> <ALTRFDEC>;

case P_RFREF:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>
    T[0] = mktuple(AST_RFREF, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <RFDEC>
    T[2] = build_ast(A[ap+1], depth+1); // <RESTOFRFDEC>
    T[3] = build_ast(A[ap+2], depth+1); // <ALTRFDEC>
    T[0] = mktuple(AST_RFREF, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  }
  return T[0];



//\\ # '*' added by gt

//\\ P<Opt-RFREF> = 
//\\    <RFREF>,
//\\    '*',
//\\   ;

case P_Opt_RFREF:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <RFREF>
    T[0] = mktuple(AST_Opt_RFREF, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '*', A[ap+0]);
    T[0] = mktuple(AST_Opt_RFREF, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_Opt_RFREF, alt /*2*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<RFDEC> = 
//\\    <XTYPE> <RFELMNT>,
//\\    '(' <RFDEC> <RESTOFRFDEC> <ALTRFDEC> ')';

case P_RFDEC:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <XTYPE>
    T[2] = build_ast(A[ap+1], depth+1); // <RFELMNT>
    T[0] = mktuple(AST_RFDEC, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d2235 2
a2236 386
    T[1] = lit(AST__LIT, '(', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <RFDEC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFRFDEC>
    T[4] = build_ast(A[ap+3], depth+1); // <ALTRFDEC>  
    T[5] = lit(AST__LIT, ')', A[ap+4]);
    T[0] = mktuple(AST_RFDEC, alt /*1*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  }
  return T[0];




//\\ P<RFELMNT> = 
//\\    <Opt-PercentQNAME> <NAME> <Opt-NLIST>,
//\\    "array" <ADECLN>;

case P_RFELMNT:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-PercentQNAME>
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-NLIST>
    T[0] = mktuple(AST_RFELMNT, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_array, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <ADECLN>
    T[0] = mktuple(AST_RFELMNT, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<ALTRFDEC> = 
//\\    "or" <RFDEC> <RESTOFRFDEC> <ALTRFDEC>,
//\\   ;

case P_ALTRFDEC:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_or, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <RFDEC>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFRFDEC>
    T[4] = build_ast(A[ap+3], depth+1); // <ALTRFDEC>
    T[0] = mktuple(AST_ALTRFDEC, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[0] = mktuple(AST_ALTRFDEC, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # Machine-specific machine-code removed.

//\\ P<UCI> = 
//\\    <Rest-of-line>;

case P_UCI:
  T[1] = build_ast(A[ap+0], depth+1); // <Rest-of-line>
  return mktuple(AST_UCI, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);


//\\ # gt added true, false.  moved <AUI> to RESTOFUI so it doesn't follow a label
//\\ # should do something similar with <Opt-ENAME> because labels can't be record fields

//\\ P<UI> = 
//\\    <HOLE> <NAME> <APP> <Opt-ENAME> <MARK> <RESTOFUI> <AUI>,
//\\    '-' '>' <NAME> <APP>,
//\\    "return",
//\\    "true",
//\\    "false",
//\\    "result" <ASSOP> <EXPR>,
//\\    "monitor" <AUI>,
//\\    "stop",
//\\    "signal" <Opt-PercentEVENT> <CEXPR> <OPEXPR2>,
//\\    "exit",
//\\    "continue";

case P_UI:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <HOLE>
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <APP>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-ENAME>
    T[5] = build_ast(A[ap+4], depth+1); // <MARK>
    T[6] = build_ast(A[ap+5], depth+1); // <RESTOFUI>
    T[7] = build_ast(A[ap+6], depth+1); // <AUI>
    T[0] = mktuple(AST_UI, alt /*0*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '-', A[ap+0]);  
    T[2] = lit(AST__LIT, '>', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>
    T[4] = build_ast(A[ap+3], depth+1); // <APP>
    T[0] = mktuple(AST_UI, alt /*1*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 2) {  
    T[1] = kw(AST__KW, KW_return, A[ap+0]);
    T[0] = mktuple(AST_UI, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 3) {  
    T[1] = kw(AST__KW, KW_true, A[ap+0]);
    T[0] = mktuple(AST_UI, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 4) {  
    T[1] = kw(AST__KW, KW_false, A[ap+0]);
    T[0] = mktuple(AST_UI, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 5) {  
    T[1] = kw(AST__KW, KW_result, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <ASSOP>
    T[3] = build_ast(A[ap+2], depth+1); // <EXPR>
    T[0] = mktuple(AST_UI, alt /*5*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 6) {  
    T[1] = kw(AST__KW, KW_monitor, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <AUI>
    T[0] = mktuple(AST_UI, alt /*6*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 7) {  
    T[1] = kw(AST__KW, KW_stop, A[ap+0]);
    T[0] = mktuple(AST_UI, alt /*7*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 8) {  
    T[1] = kw(AST__KW, KW_signal, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-PercentEVENT>
    T[3] = build_ast(A[ap+2], depth+1); // <CEXPR>
    T[4] = build_ast(A[ap+3], depth+1); // <OPEXPR2>
    T[0] = mktuple(AST_UI, alt /*8*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 9) {  
    T[1] = kw(AST__KW, KW_exit, A[ap+0]);
    T[0] = mktuple(AST_UI, alt /*9*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_continue, A[ap+0]);
    T[0] = mktuple(AST_UI, alt /*10*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<SS> = 
//\\    <STATEMENT-LIST> <EOF>;

case P_SS:
  T[1] = build_ast(A[ap+0], depth+1); // <STATEMENT-LIST>
  T[2] = bip(AST_EOF, A[ap+1]);
  return mktuple(AST_SS, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<STATEMENT-LIST> = 
//\\    <STATEMENT> <STATEMENT-LIST>,
//\\   ;

case P_STATEMENT_LIST:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <STATEMENT>
    T[2] = build_ast(A[ap+1], depth+1); // <STATEMENT-LIST>
    T[0] = mktuple(AST_STATEMENT_LIST, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_STATEMENT_LIST, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<COMMENT> = 
//\\    "comment" <Rest-of-line>,
//\\    '!' <Rest-of-line>;

case P_COMMENT:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_comment, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Rest-of-line>
    T[0] = mktuple(AST_COMMENT, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {  
    T[1] = lit(AST__LIT, '!', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Rest-of-line>
    T[0] = mktuple(AST_COMMENT, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];



//\\ # gt removed <TEXT>, added <COMMENT>.  Moved sw(*): up to take precedence.
//\\ # added %on %event * %start

//\\ P<STATEMENT> = 
//\\    <NAME> '(' '*' ')' ':' <COLON>,
//\\    <XOWN> <XTYPE> <OWNDEC> <S>,
//\\    <CHUI> <HOLE> <UI> <MARK> <RESTOFSS1>,
//\\    <Percent-IU> <HOLE> <SC> <RESTOFCOND> <MARK> <RESTOFIU> <S>,
//\\    "finish" <NOTEFINISH> <Opt-ELSE> <S>,
//\\    "cycle" <NOTECYCLE> <CYCPARM> <S>,
//\\    "repeat" <NOTEREPEAT> <RESTOFREPEAT> <S>,
//\\    <Percent-WU> "cycle" <NOTECYCLE> <S>,
//\\    <CHXTYPE> <BIGHOLE> <HOLE> <XTYPE> <MARK> <DECLN> <S>,
//\\    "end" <ENDLIST> <S>,
//\\    "record" "format" <RFSTMNT> <S>,
//\\    <HOLE> <Percent-SEX> <RT> <MARK> <Opt-PercentSPEC> <NAME> <Opt-ALIAS> <FPP> <S>,
//\\    "include" <CONST>,
//\\    "from" <NAME> "include" <NAME> <Opt-NLIST>,
//\\    "begin" <DOWN> <S>,
//\\    "on" <TRACE> <Opt-PercentEVENT> '*' <RESTOFNLIST> "start" <NOTESTART> <S>,
//\\    "on" <TRACE> <Opt-PercentEVENT> <CEXPR> <RESTOFNLIST> "start" <NOTESTART> <S>,
//\\    "switch" <NAME> <Opt-NLIST> '(' <EXPR> ':' <EXPR> ')' <RESTOFSWLIST> <S>,
//\\    "list" <S> <LISTON>,
//\\    "else" <NOTEFINISH> <DUMMYSTART> <NOTESTART> <S>,
//\\    "else" <Percent-IU> <SC> <RESTOFCOND>,
//\\    '*' <UCI>,
//\\    "trusted" "program" <S>,
//\\    "main" "ep" <NAME> <S>,
//\\    "control" <CONST> <S>,
//\\    <COMMENT>,
//\\    <S>;

case P_STATEMENT:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>  
    T[2] = lit(AST__LIT, '(', A[ap+1]);  
    T[3] = lit(AST__LIT, '*', A[ap+2]);  
    T[4] = lit(AST__LIT, ')', A[ap+3]);  
    T[5] = lit(AST__LIT, ':', A[ap+4]);
    T[6] = build_ast(A[ap+5], depth+1); // <COLON>
    T[0] = mktuple(AST_STATEMENT, alt /*0*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <XOWN>
    T[2] = build_ast(A[ap+1], depth+1); // <XTYPE>
    T[3] = build_ast(A[ap+2], depth+1); // <OWNDEC>
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*1*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <CHUI>
    T[2] = build_ast(A[ap+1], depth+1); // <HOLE>
    T[3] = build_ast(A[ap+2], depth+1); // <UI>
    T[4] = build_ast(A[ap+3], depth+1); // <MARK>
    T[5] = build_ast(A[ap+4], depth+1); // <RESTOFSS1>
    T[0] = mktuple(AST_STATEMENT, alt /*2*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 3) {
    T[1] = build_ast(A[ap+0], depth+1); // <Percent-IU>
    T[2] = build_ast(A[ap+1], depth+1); // <HOLE>
    T[3] = build_ast(A[ap+2], depth+1); // <SC>
    T[4] = build_ast(A[ap+3], depth+1); // <RESTOFCOND>
    T[5] = build_ast(A[ap+4], depth+1); // <MARK>
    T[6] = build_ast(A[ap+5], depth+1); // <RESTOFIU>
    T[7] = build_ast(A[ap+6], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*3*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else if (alt == 4) {  
    T[1] = kw(AST__KW, KW_finish, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NOTEFINISH>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-ELSE>
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*4*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 5) {  
    T[1] = kw(AST__KW, KW_cycle, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NOTECYCLE>
    T[3] = build_ast(A[ap+2], depth+1); // <CYCPARM>
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*5*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 6) {  
    T[1] = kw(AST__KW, KW_repeat, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NOTEREPEAT>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFREPEAT>
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*6*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 7) {
    T[1] = build_ast(A[ap+0], depth+1); // <Percent-WU>  
    T[2] = kw(AST__KW, KW_cycle, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <NOTECYCLE>
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*7*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 8) {
    T[1] = build_ast(A[ap+0], depth+1); // <CHXTYPE>
    T[2] = build_ast(A[ap+1], depth+1); // <BIGHOLE>
    T[3] = build_ast(A[ap+2], depth+1); // <HOLE>
    T[4] = build_ast(A[ap+3], depth+1); // <XTYPE>
    T[5] = build_ast(A[ap+4], depth+1); // <MARK>
    T[6] = build_ast(A[ap+5], depth+1); // <DECLN>
    T[7] = build_ast(A[ap+6], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*8*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else if (alt == 9) {  
    T[1] = kw(AST__KW, KW_end, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <ENDLIST>
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*9*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 10) {  
    T[1] = kw(AST__KW, KW_record, A[ap+0]);  
    T[2] = kw(AST__KW, KW_format, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <RFSTMNT>
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*10*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 11) {
    T[1] = build_ast(A[ap+0], depth+1); // <HOLE>
    T[2] = build_ast(A[ap+1], depth+1); // <Percent-SEX>
    T[3] = build_ast(A[ap+2], depth+1); // <RT>
    T[4] = build_ast(A[ap+3], depth+1); // <MARK>
    T[5] = build_ast(A[ap+4], depth+1); // <Opt-PercentSPEC>
    T[6] = build_ast(A[ap+5], depth+1); // <NAME>
    T[7] = build_ast(A[ap+6], depth+1); // <Opt-ALIAS>
    T[8] = build_ast(A[ap+7], depth+1); // <FPP>
    T[9] = build_ast(A[ap+8], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*11*/, /*phrases*/ 9, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9]*/);
  } else if (alt == 12) {  
    T[1] = kw(AST__KW, KW_include, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <CONST>
    T[0] = mktuple(AST_STATEMENT, alt /*12*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 13) {  
    T[1] = kw(AST__KW, KW_from, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>  
    T[3] = kw(AST__KW, KW_include, A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <NAME>
    T[5] = build_ast(A[ap+4], depth+1); // <Opt-NLIST>
    T[0] = mktuple(AST_STATEMENT, alt /*13*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 14) {  
    T[1] = kw(AST__KW, KW_begin, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <DOWN>
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*14*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 15) {  
    T[1] = kw(AST__KW, KW_on, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <TRACE>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-PercentEVENT>  
    T[4] = lit(AST__LIT, '*', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <RESTOFNLIST>  
    T[6] = kw(AST__KW, KW_start, A[ap+5]);
    T[7] = build_ast(A[ap+6], depth+1); // <NOTESTART>
    T[8] = build_ast(A[ap+7], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*15*/, /*phrases*/ 8, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8]*/);
  } else if (alt == 16) {  
    T[1] = kw(AST__KW, KW_on, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <TRACE>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-PercentEVENT>
    T[4] = build_ast(A[ap+3], depth+1); // <CEXPR>
    T[5] = build_ast(A[ap+4], depth+1); // <RESTOFNLIST>  
    T[6] = kw(AST__KW, KW_start, A[ap+5]);
    T[7] = build_ast(A[ap+6], depth+1); // <NOTESTART>
    T[8] = build_ast(A[ap+7], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*16*/, /*phrases*/ 8, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8]*/);
  } else if (alt == 17) {  
    T[1] = kw(AST__KW, KW_switch, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-NLIST>  
    T[4] = lit(AST__LIT, '(', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <EXPR>  
    T[6] = lit(AST__LIT, ':', A[ap+5]);
    T[7] = build_ast(A[ap+6], depth+1); // <EXPR>  
    T[8] = lit(AST__LIT, ')', A[ap+7]);
    T[9] = build_ast(A[ap+8], depth+1); // <RESTOFSWLIST>
    T[10] = build_ast(A[ap+9], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*17*/, /*phrases*/ 10, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9], T[10]*/);
  } else if (alt == 18) {  
    T[1] = kw(AST__KW, KW_list, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <S>
    T[3] = build_ast(A[ap+2], depth+1); // <LISTON>
    T[0] = mktuple(AST_STATEMENT, alt /*18*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 19) {  
    T[1] = kw(AST__KW, KW_else, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NOTEFINISH>
    T[3] = build_ast(A[ap+2], depth+1); // <DUMMYSTART>
    T[4] = build_ast(A[ap+3], depth+1); // <NOTESTART>
    T[5] = build_ast(A[ap+4], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*19*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 20) {  
    T[1] = kw(AST__KW, KW_else, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Percent-IU>
    T[3] = build_ast(A[ap+2], depth+1); // <SC>
    T[4] = build_ast(A[ap+3], depth+1); // <RESTOFCOND>
    T[0] = mktuple(AST_STATEMENT, alt /*20*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 21) {  
    T[1] = lit(AST__LIT, '*', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <UCI>
    T[0] = mktuple(AST_STATEMENT, alt /*21*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 22) {  
    T[1] = kw(AST__KW, KW_trusted, A[ap+0]);  
    T[2] = kw(AST__KW, KW_program, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*22*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 23) {  
    T[1] = kw(AST__KW, KW_main, A[ap+0]);  
    T[2] = kw(AST__KW, KW_ep, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*23*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 24) {  
    T[1] = kw(AST__KW, KW_control, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <CONST>
    T[3] = build_ast(A[ap+2], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*24*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 25) {
    T[1] = build_ast(A[ap+0], depth+1); // <COMMENT>
    T[0] = mktuple(AST_STATEMENT, alt /*25*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*26*/, /*phrases*/ 1, T /*T[1]*/);
@


1.1
log
@Initial revision
@
text
@d1 8
a8 37
//\\ B<xNAME> = 0;
//\\ B<xCONST> = 1;
//\\ B<xNOTECONST> = 2;
//\\ B<DUMMYAPP> = 3;
//\\ B<xHOLE> = 4;
//\\ B<xMARK> = 5;
//\\ B<xOP> = 6;
//\\ B<xTEXTTEXT> = 7;
//\\ B<xCHXTYPE> = 8;
//\\ B<xUP> = 9;
//\\ B<xDOWN> = 10;
//\\ B<LISTOFF> = 11;
//\\ B<LISTON> = 12;
//\\ B<xCOMP1> = 13;
//\\ B<xCOMP2> = 14;
//\\ B<xASSOP> = 15;
//\\ B<xBIGHOLE> = 16;
//\\ B<xREADLINEq> = 17;
//\\ B<xCOLON> = 18;
//\\ B<xS> = 19;
//\\ B<xNOTESTART> = 20;
//\\ B<xCHUI> = 21;
//\\ B<TEXT> = 22;
//\\ B<xNOTEFINISH> = 23;
//\\ B<xNOTECYCLE> = 24;
//\\ B<xNOTEREPEAT> = 25;
//\\ B<INCLUDE> = 26;
//\\ B<TRACE> = 27;
//\\ B<DUMMYSTART> = 28;
//\\ B<stropped> = 29;
//\\ B<alphanumeric> = 30;
//\\ B<digit> = 31;
//\\ B<sqstring> = 32;
//\\ B<dqstring> = 33;
//\\ B<NL> = 34;
//\\ B<char> = 35;
//\\ B<EOF> = 36;
d10 1
a10 1
//\\ # Grammar for Imp80 on Emas-2900 series.
d12 1
d23 24
d119 1
d130 4
d137 1
a137 1
    T[0] = mktuple(AST_ASSOP, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d152 2
a153 1
//\\    '>';
d181 1
a181 1
  } else               {  
d184 4
d195 1
a195 8
//\\    '=',
//\\    '#',
//\\    '=' '=',
//\\    '#' '#',
//\\    '<' '=',
//\\    '<',
//\\    '>' '=',
//\\    '>';
d198 2
a199 31
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);
    T[0] = mktuple(AST_COMP2, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = lit(AST__LIT, '#', A[ap+0]);
    T[0] = mktuple(AST_COMP2, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_COMP2, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 3) {  
    T[1] = lit(AST__LIT, '#', A[ap+0]);  
    T[2] = lit(AST__LIT, '#', A[ap+1]);
    T[0] = mktuple(AST_COMP2, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 4) {  
    T[1] = lit(AST__LIT, '<', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_COMP2, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 5) {  
    T[1] = lit(AST__LIT, '<', A[ap+0]);
    T[0] = mktuple(AST_COMP2, alt /*5*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 6) {  
    T[1] = lit(AST__LIT, '>', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_COMP2, alt /*6*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {  
    T[1] = lit(AST__LIT, '>', A[ap+0]);
    T[0] = mktuple(AST_COMP2, alt /*7*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];

d207 1
d216 2
a217 1
//\\    '&';
d228 6
d235 2
a236 2
    T[0] = mktuple(AST_OP, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 3) {  
d238 2
a239 2
    T[0] = mktuple(AST_OP, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 4) {  
d242 2
a243 2
    T[0] = mktuple(AST_OP, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 5) {  
d245 2
a246 2
    T[0] = mktuple(AST_OP, alt /*5*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 6) {  
d249 2
a250 2
    T[0] = mktuple(AST_OP, alt /*6*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 7) {  
d253 2
a254 2
    T[0] = mktuple(AST_OP, alt /*7*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 8) {  
d257 2
a258 2
    T[0] = mktuple(AST_OP, alt /*8*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 9) {  
d260 4
a263 1
    T[0] = mktuple(AST_OP, alt /*9*/, /*phrases*/ 1, T /*T[1]*/);
d265 2
a266 2
    T[1] = lit(AST__LIT, '&', A[ap+0]);
    T[0] = mktuple(AST_OP, alt /*10*/, /*phrases*/ 1, T /*T[1]*/);
d289 12
d303 1
d307 1
d316 2
a317 1
    T[0] = mktuple(AST_CONST, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d321 1
a321 1
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>
d324 5
d330 5
a334 2
    T[0] = mktuple(AST_CONST, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 3) {
d336 1
a336 1
    T[0] = mktuple(AST_CONST, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
d339 1
a339 1
    T[0] = mktuple(AST_CONST, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
d364 1
a364 1
//\\    <alphanumeric> <rest-of-name>;
d368 17
a384 2
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-name>
  return mktuple(AST_NAME, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
d560 1
a560 1
    T[2] = bip(AST_DUMMYAPP, A[ap+1]);
d606 1
d644 1
d647 2
a648 1
//\\    <HOLE> <Opt-PLUS> <OPERAND> <MARK> <RESTOFEXPR>;
d651 15
a665 6
  T[1] = build_ast(A[ap+0], depth+1); // <HOLE>
  T[2] = build_ast(A[ap+1], depth+1); // <Opt-PLUS>
  T[3] = build_ast(A[ap+2], depth+1); // <OPERAND>
  T[4] = build_ast(A[ap+3], depth+1); // <MARK>
  T[5] = build_ast(A[ap+4], depth+1); // <RESTOFEXPR>
  return mktuple(AST_EXPR, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
d765 1
a765 1
    T[1] = kw(AST__KW, 0 /* if */, A[ap+0]);
d768 1
a768 1
    T[1] = kw(AST__KW, 1 /* unless */, A[ap+0]);
d783 1
a783 1
    T[1] = kw(AST__KW, 2 /* while */, A[ap+0]);
d790 1
a790 1
    T[1] = kw(AST__KW, 3 /* until */, A[ap+0]);
d797 1
a797 1
    T[1] = kw(AST__KW, 4 /* for */, A[ap+0]);
d820 1
a820 1
    T[1] = kw(AST__KW, 5 /* alias */, A[ap+0]);
d830 20
d875 1
a875 1
    T[1] = kw(AST__KW, 6 /* integer */, A[ap+0]);
d892 1
a892 1
    T[1] = kw(AST__KW, 7 /* real */, A[ap+0]);
d895 1
a895 1
    T[1] = kw(AST__KW, 6 /* integer */, A[ap+0]);
d898 2
a899 2
    T[1] = kw(AST__KW, 8 /* long */, A[ap+0]);  
    T[2] = kw(AST__KW, 7 /* real */, A[ap+1]);
d921 1
a921 1
    T[1] = kw(AST__KW, 6 /* integer */, A[ap+0]);
d924 1
a924 1
    T[1] = kw(AST__KW, 7 /* real */, A[ap+0]);
d927 1
a927 1
    T[1] = kw(AST__KW, 9 /* label */, A[ap+0]);
d930 1
a930 1
    T[1] = kw(AST__KW, 8 /* long */, A[ap+0]);
d934 1
a934 1
    T[1] = kw(AST__KW, 10 /* byte */, A[ap+0]);
d938 1
a938 1
    T[1] = kw(AST__KW, 11 /* string */, A[ap+0]);
d942 1
a942 1
    T[1] = kw(AST__KW, 12 /* half */, A[ap+0]);
d946 1
a946 1
    T[1] = kw(AST__KW, 13 /* short */, A[ap+0]);
d950 1
a950 1
    T[1] = kw(AST__KW, 14 /* record */, A[ap+0]);  
d969 1
a969 1
    T[1] = kw(AST__KW, 15 /* routine */, A[ap+0]);
d972 1
a972 1
    T[1] = kw(AST__KW, 16 /* predicate */, A[ap+0]);
d992 1
a992 1
    T[1] = kw(AST__KW, 17 /* fn */, A[ap+0]);
d995 1
a995 1
    T[1] = kw(AST__KW, 18 /* map */, A[ap+0]);
d998 1
a998 1
    T[1] = kw(AST__KW, 19 /* function */, A[ap+0]);
d1026 1
a1026 1
    T[1] = kw(AST__KW, 20 /* name */, A[ap+0]);
d1042 1
a1042 1
    T[1] = kw(AST__KW, 20 /* name */, A[ap+0]);
d1059 2
a1060 2
    T[1] = kw(AST__KW, 21 /* array */, A[ap+0]);  
    T[2] = kw(AST__KW, 20 /* name */, A[ap+1]);
d1063 1
a1063 1
    T[1] = kw(AST__KW, 20 /* name */, A[ap+0]);
d1130 17
d1150 2
d1157 2
a1158 2
    T[1] = kw(AST__KW, 22 /* of */, A[ap+0]);  
    T[2] = kw(AST__KW, 23 /* program */, A[ap+1]);
d1162 2
a1163 2
    T[1] = kw(AST__KW, 22 /* of */, A[ap+0]);  
    T[2] = kw(AST__KW, 24 /* file */, A[ap+1]);
d1166 12
a1177 4
    T[1] = kw(AST__KW, 22 /* of */, A[ap+0]);  
    T[2] = kw(AST__KW, 25 /* list */, A[ap+1]);
    T[3] = bip(AST_LISTOFF, A[ap+2]);
    T[0] = mktuple(AST_ENDLIST, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1180 1
a1180 1
    T[0] = mktuple(AST_ENDLIST, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
d1193 1
a1193 1
    T[1] = kw(AST__KW, 26 /* format */, A[ap+0]);
d1229 1
a1229 1
    T[1] = kw(AST__KW, 27 /* not */, A[ap+0]);
d1263 1
a1263 1
    T[1] = kw(AST__KW, 28 /* and */, A[ap+0]);
d1268 1
a1268 1
    T[1] = kw(AST__KW, 29 /* or */, A[ap+0]);
d1286 1
a1286 1
    T[1] = kw(AST__KW, 28 /* and */, A[ap+0]);
d1304 1
a1304 1
    T[1] = kw(AST__KW, 29 /* or */, A[ap+0]);
d1343 1
a1343 1
    T[1] = kw(AST__KW, 30 /* spec */, A[ap+0]);
d1361 1
a1361 1
    T[1] = kw(AST__KW, 30 /* spec */, A[ap+0]);
d1391 22
d1414 1
d1417 1
a1417 1
//\\    <Opt-PercentQNAME> <NAME> <Opt-NLIST>,
d1424 3
a1426 2
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-NLIST>
    T[0] = mktuple(AST_DECLN, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d1428 1
a1428 1
    T[1] = kw(AST__KW, 21 /* array */, A[ap+0]);
d1485 1
a1485 1
    T[1] = kw(AST__KW, 21 /* array */, A[ap+0]);
d1529 1
a1529 1
    T[1] = kw(AST__KW, 31 /* own */, A[ap+0]);
d1532 1
a1532 1
    T[1] = kw(AST__KW, 32 /* external */, A[ap+0]);
d1535 1
a1535 1
    T[1] = kw(AST__KW, 33 /* extrinsic */, A[ap+0]);
d1538 1
a1538 1
    T[1] = kw(AST__KW, 34 /* constant */, A[ap+0]);
d1541 1
a1541 1
    T[1] = kw(AST__KW, 35 /* const */, A[ap+0]);
d1548 18
d1569 1
a1569 1
//\\    '=' <READLINEq> <Opt-PLUS> <COPERAND> <RESTOFCEXPR> <REPFACT> <ROCL>,
d1576 7
a1582 6
    T[3] = build_ast(A[ap+2], depth+1); // <Opt-PLUS>
    T[4] = build_ast(A[ap+3], depth+1); // <COPERAND>
    T[5] = build_ast(A[ap+4], depth+1); // <RESTOFCEXPR>
    T[6] = build_ast(A[ap+5], depth+1); // <REPFACT>
    T[7] = build_ast(A[ap+6], depth+1); // <ROCL>
    T[0] = mktuple(AST_CONSTLIST, alt /*0*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
d1592 1
a1592 1
//\\    ',' <Opt-PLUS> <COPERAND> <RESTOFCEXPR> <REPFACT> <ROCL>,
d1598 7
a1604 6
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-PLUS>
    T[3] = build_ast(A[ap+2], depth+1); // <COPERAND>
    T[4] = build_ast(A[ap+3], depth+1); // <RESTOFCEXPR>
    T[5] = build_ast(A[ap+4], depth+1); // <REPFACT>
    T[6] = build_ast(A[ap+5], depth+1); // <ROCL>
    T[0] = mktuple(AST_ROCL, alt /*0*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
d1656 1
a1656 1
    T[1] = kw(AST__KW, 36 /* event */, A[ap+0]);
d1665 1
d1684 18
d1703 1
d1706 1
a1706 1
//\\    ',' <NAME> <Opt-NLIST> '<' <EXPR> ':' <EXPR> '>' <RESTOFSWLIST>,
d1714 1
a1714 1
    T[4] = lit(AST__LIT, '<', A[ap+3]);
d1718 1
a1718 1
    T[8] = lit(AST__LIT, '>', A[ap+7]);
d1735 1
a1735 1
    T[1] = kw(AST__KW, 3 /* until */, A[ap+0]);
d1785 1
a1785 1
    T[1] = kw(AST__KW, 37 /* start */, A[ap+0]);
d1789 2
a1790 2
    T[1] = kw(AST__KW, 38 /* then */, A[ap+0]);  
    T[2] = kw(AST__KW, 37 /* start */, A[ap+1]);
d1794 1
a1794 1
    T[1] = kw(AST__KW, 38 /* then */, A[ap+0]);
d1813 1
a1813 1
    T[1] = kw(AST__KW, 28 /* and */, A[ap+0]);
d1830 1
a1830 1
    T[1] = kw(AST__KW, 39 /* else */, A[ap+0]);
d1848 1
a1848 1
    T[1] = kw(AST__KW, 37 /* start */, A[ap+0]);
d1900 1
d1904 1
d1914 5
d1920 1
a1920 1
    T[0] = mktuple(AST_Opt_CONST, alt /*1*/, /*phrases*/ 0, T /**/);
d1931 1
d1936 1
a1936 1
    T[1] = kw(AST__KW, 40 /* system */, A[ap+0]);
d1939 1
a1939 1
    T[1] = kw(AST__KW, 32 /* external */, A[ap+0]);
d1942 1
a1942 1
    T[1] = kw(AST__KW, 41 /* dynamic */, A[ap+0]);
d1944 3
d1948 1
a1948 1
    T[0] = mktuple(AST_Percent_SEX, alt /*3*/, /*phrases*/ 0, T /**/);
d2002 1
a2002 1
    T[1] = kw(AST__KW, 30 /* spec */, A[ap+0]);
d2037 1
d2041 1
d2048 3
d2052 1
a2052 1
    T[0] = mktuple(AST_Opt_RFREF, alt /*1*/, /*phrases*/ 0, T /**/);
d2092 1
a2092 1
    T[1] = kw(AST__KW, 21 /* array */, A[ap+0]);
d2107 1
a2107 1
    T[1] = kw(AST__KW, 29 /* or */, A[ap+0]);
d2129 2
a2130 1
//\\ # gt added true, false
d2141 1
a2141 1
//\\    "signal" <Opt-PercentEVENT> <CEXPR> <OPEXPR>,
d2162 1
a2162 1
    T[1] = kw(AST__KW, 42 /* return */, A[ap+0]);
d2165 1
a2165 1
    T[1] = kw(AST__KW, 43 /* true */, A[ap+0]);
d2168 1
a2168 1
    T[1] = kw(AST__KW, 44 /* false */, A[ap+0]);
d2171 1
a2171 1
    T[1] = kw(AST__KW, 45 /* result */, A[ap+0]);
d2176 1
a2176 1
    T[1] = kw(AST__KW, 46 /* monitor */, A[ap+0]);
d2180 1
a2180 1
    T[1] = kw(AST__KW, 47 /* stop */, A[ap+0]);
d2183 1
a2183 1
    T[1] = kw(AST__KW, 48 /* signal */, A[ap+0]);
d2186 1
a2186 1
    T[4] = build_ast(A[ap+3], depth+1); // <OPEXPR>
d2189 1
a2189 1
    T[1] = kw(AST__KW, 49 /* exit */, A[ap+0]);
d2192 1
a2192 1
    T[1] = kw(AST__KW, 50 /* continue */, A[ap+0]);
d2227 21
d2249 2
a2251 1
//\\    <TEXT>,
d2261 2
a2262 2
//\\    <XOWN> <XTYPE> <OWNDEC> <S>,
//\\    "include" <CONST> <INCLUDE>,
d2264 1
d2269 1
d2274 1
a2274 1
//\\    <NAME> '(' '*' ')' ':' <COLON>,
d2279 14
d2298 2
a2299 5
    T[0] = mktuple(AST_STATEMENT, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 1) {
    T[1] = bip(AST_TEXT, A[ap+0]);
    T[0] = mktuple(AST_STATEMENT, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {
d2307 3
a2309 3
    T[0] = mktuple(AST_STATEMENT, alt /*2*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else if (alt == 3) {  
    T[1] = kw(AST__KW, 51 /* finish */, A[ap+0]);
d2313 3
a2315 3
    T[0] = mktuple(AST_STATEMENT, alt /*3*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 4) {  
    T[1] = kw(AST__KW, 52 /* cycle */, A[ap+0]);
d2319 3
a2321 3
    T[0] = mktuple(AST_STATEMENT, alt /*4*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 5) {  
    T[1] = kw(AST__KW, 53 /* repeat */, A[ap+0]);
d2325 2
a2326 2
    T[0] = mktuple(AST_STATEMENT, alt /*5*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 6) {
d2328 1
a2328 1
    T[2] = kw(AST__KW, 52 /* cycle */, A[ap+1]);
d2331 2
a2332 2
    T[0] = mktuple(AST_STATEMENT, alt /*6*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 7) {
d2340 3
a2342 3
    T[0] = mktuple(AST_STATEMENT, alt /*7*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } else if (alt == 8) {  
    T[1] = kw(AST__KW, 54 /* end */, A[ap+0]);
d2345 4
a2348 4
    T[0] = mktuple(AST_STATEMENT, alt /*8*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 9) {  
    T[1] = kw(AST__KW, 14 /* record */, A[ap+0]);  
    T[2] = kw(AST__KW, 26 /* format */, A[ap+1]);
d2351 2
a2352 2
    T[0] = mktuple(AST_STATEMENT, alt /*9*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 10) {
d2362 1
a2362 7
    T[0] = mktuple(AST_STATEMENT, alt /*10*/, /*phrases*/ 9, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9]*/);
  } else if (alt == 11) {
    T[1] = build_ast(A[ap+0], depth+1); // <XOWN>
    T[2] = build_ast(A[ap+1], depth+1); // <XTYPE>
    T[3] = build_ast(A[ap+2], depth+1); // <OWNDEC>
    T[4] = build_ast(A[ap+3], depth+1); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*11*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
d2364 1
a2364 1
    T[1] = kw(AST__KW, 55 /* include */, A[ap+0]);
d2366 1
a2366 2
    T[3] = bip(AST_INCLUDE, A[ap+2]);
    T[0] = mktuple(AST_STATEMENT, alt /*12*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
d2368 8
a2375 1
    T[1] = kw(AST__KW, 56 /* begin */, A[ap+0]);
d2378 14
a2391 4
    T[0] = mktuple(AST_STATEMENT, alt /*13*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 14) {  
    T[1] = kw(AST__KW, 57 /* on */, A[ap+0]);
    T[2] = bip(AST_TRACE, A[ap+1]);
d2395 1
a2395 1
    T[6] = kw(AST__KW, 37 /* start */, A[ap+5]);
d2398 3
a2400 3
    T[0] = mktuple(AST_STATEMENT, alt /*14*/, /*phrases*/ 8, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8]*/);
  } else if (alt == 15) {  
    T[1] = kw(AST__KW, 58 /* switch */, A[ap+0]);
d2410 3
a2412 3
    T[0] = mktuple(AST_STATEMENT, alt /*15*/, /*phrases*/ 10, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9], T[10]*/);
  } else if (alt == 16) {  
    T[1] = kw(AST__KW, 25 /* list */, A[ap+0]);
d2414 4
a2417 4
    T[3] = bip(AST_LISTON, A[ap+2]);
    T[0] = mktuple(AST_STATEMENT, alt /*16*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 17) {  
    T[1] = kw(AST__KW, 39 /* else */, A[ap+0]);
d2419 1
a2419 1
    T[3] = bip(AST_DUMMYSTART, A[ap+2]);
d2422 8
a2429 2
    T[0] = mktuple(AST_STATEMENT, alt /*17*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 18) {  
d2432 4
a2435 4
    T[0] = mktuple(AST_STATEMENT, alt /*18*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 19) {  
    T[1] = kw(AST__KW, 59 /* trusted */, A[ap+0]);  
    T[2] = kw(AST__KW, 23 /* program */, A[ap+1]);
d2437 4
a2440 4
    T[0] = mktuple(AST_STATEMENT, alt /*19*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 20) {  
    T[1] = kw(AST__KW, 60 /* main */, A[ap+0]);  
    T[2] = kw(AST__KW, 61 /* ep */, A[ap+1]);
d2443 3
a2445 3
    T[0] = mktuple(AST_STATEMENT, alt /*20*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 21) {  
    T[1] = kw(AST__KW, 62 /* control */, A[ap+0]);
d2448 4
a2451 9
    T[0] = mktuple(AST_STATEMENT, alt /*21*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 22) {
    T[1] = build_ast(A[ap+0], depth+1); // <NAME>  
    T[2] = lit(AST__LIT, '(', A[ap+1]);  
    T[3] = lit(AST__LIT, '*', A[ap+2]);  
    T[4] = lit(AST__LIT, ')', A[ap+3]);  
    T[5] = lit(AST__LIT, ':', A[ap+4]);
    T[6] = build_ast(A[ap+5], depth+1); // <COLON>
    T[0] = mktuple(AST_STATEMENT, alt /*22*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
d2454 1
a2454 1
    T[0] = mktuple(AST_STATEMENT, alt /*23*/, /*phrases*/ 1, T /*T[1]*/);
@
