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


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


desc
@Imp80 grammar
@


1.1
log
@Initial revision
@
text
@//\\ B<stropped> = 0;
//\\ B<alphanumeric> = 1;
//\\ B<digit> = 2;
//\\ B<sqstring> = 3;
//\\ B<dqstring> = 4;
//\\ B<NL> = 5;
//\\ B<char> = 6;
//\\ B<EOF> = 7;

//\\ # 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

//\\ 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];



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

//\\ P<STATEMENT> = 
//\\    <NAME> '(' '*' ')' ':',
//\\    <XOWN> <XTYPE> <OWNDEC> <S>,
//\\    <UI> <RESTOFSS1>,
//\\    <Percent-IU> <SC> <RESTOFCOND> <RESTOFIU> <S>,
//\\    "finish" <Opt-ELSE> <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>,
//\\    "list" <S>,
//\\    "else" <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[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] = 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); // <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]*/);
  } else if (alt == 3) {
    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]*/);
  } else if (alt == 4) {  
    T[1] = kw(AST__KW, KW_finish, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <Opt-ELSE>
    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_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) {  
    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 /*6*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } 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); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*7*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 8) {
    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_STATEMENT, alt /*8*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } 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); // <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 /*11*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  } 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); // <S>
    T[0] = mktuple(AST_STATEMENT, alt /*14*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } 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] = 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 /*15*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } else if (alt == 16) {  
    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 /*16*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } 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[0] = mktuple(AST_STATEMENT, alt /*18*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 19) {  
    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) {  
    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]*/);
  }
  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];




//\\ 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];




//\\ P<Rest-of-line> = 
//\\    <char> <Rest-of-line>,
//\\    <dqstring> <Rest-of-line>,
//\\    <sqstring> <Rest-of-line>,
//\\    <alphanumeric> <Rest-of-line>,
//\\    <digit> <Rest-of-line>,
//\\    <stropped> <Rest-of-line>,
//\\    <NL>;

case P_Rest_of_line:
  if (alt == 0)        {
    T[1] = bip(AST_char, A[ap+0]);
    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]*/);
  } else if (alt == 1) {
    T[1] = bip(AST_dqstring, A[ap+0]);
    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]*/);
  } else if (alt == 2) {
    T[1] = bip(AST_sqstring, A[ap+0]);
    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]*/);
  } else if (alt == 3) {
    T[1] = bip(AST_alphanumeric, A[ap+0]);
    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]*/);
  } else if (alt == 4) {
    T[1] = bip(AST_digit, A[ap+0]);
    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]*/);
  } else if (alt == 5) {
    T[1] = bip(AST_stropped, A[ap+0]);
    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]*/);
  } else               {
    T[1] = bip(AST_NL, A[ap+0]);
    T[0] = mktuple(AST_Rest_of_line, alt /*6*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # <NUMBER> '_' <NUMBER>, and  <NUMBER> '_' <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.

//\\ P<CONST> = 
//\\    <NUMBER> '_' <NUMBER> <NAME>,
//\\    <NUMBER> '_' <NUMBER>,
//\\    <NUMBER> '_' <NAME>,
//\\    <NUMBER>,
//\\    <OLDHEX>,
//\\    <sqstring>,
//\\    <dqstring>;

case P_CONST:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <NUMBER>  
    T[2] = lit(AST__LIT, '_', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <NUMBER>
    T[4] = build_ast(A[ap+3], depth+1); // <NAME>
    T[0] = mktuple(AST_CONST, 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); // <NUMBER>  
    T[2] = lit(AST__LIT, '_', A[ap+1]);
    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]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <NUMBER>  
    T[2] = lit(AST__LIT, '_', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <NAME>
    T[0] = mktuple(AST_CONST, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 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) {
    T[1] = build_ast(A[ap+0], depth+1); // <OLDHEX>
    T[0] = mktuple(AST_CONST, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 5) {
    T[1] = bip(AST_sqstring, A[ap+0]);
    T[0] = mktuple(AST_CONST, alt /*5*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = bip(AST_dqstring, A[ap+0]);
    T[0] = mktuple(AST_CONST, alt /*6*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # 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<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]*/);



//\\ 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<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];




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

case P_NAME:
  T[1] = bip(AST_alphanumeric, A[ap+0]);
  T[2] = -1; // <!SQUO-STRING>
  T[3] = build_ast(A[ap+2], depth+1); // <rest-of-name>
  return mktuple(AST_NAME, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);



//\\ 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];




//\\ 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]*/);


//\\ # 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]*/);


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

//\\ P<RESTOFCOND> = 
//\\    "and" <SC> <RESTOFANDC>,
//\\    "or" <SC> <RESTOFORC>,
//\\   ;

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 /**/);
  }
  return T[0];




//\\ P<RESTOFORC> = 
//\\    "or" <SC> <RESTOFORC>,
//\\   ;

case P_RESTOFORC:
  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); // <RESTOFORC>
    T[0] = mktuple(AST_RESTOFORC, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_RESTOFORC, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



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

//\\ P<SC> = 
//\\    <EXPR> <COMP1> <EXPR> <RESTOFSC>,
//\\    <NAME> <APP>,
//\\    '(' <SC> <RESTOFCOND> ')',
//\\    "not" <SC>;

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) {  
    T[1] = lit(AST__LIT, '(', A[ap+0]);
    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]*/);
  }
  return T[0];



//\\ # 'Application' i.e. parameters to routine or function call

//\\ P<APP> = 
//\\    '(' <EXPR> <RESTOFAPP> ')',
//\\   ;

case P_APP:
  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[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 /**/);
  }
  return T[0];




//\\ P<RESTOFAPP> = 
//\\    ',' <EXPR> <RESTOFAPP>,
//\\   ;

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]*/);
  } else               {
    T[0] = mktuple(AST_RESTOFAPP, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # |...| added by gt

//\\ P<EXPR> = 
//\\    <Opt-PLUS> <OPERAND> <RESTOFEXPR>,
//\\    '|' <EXPR> '|';

case P_EXPR:
  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];




//\\ 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];




//\\ P<OPERAND> = 
//\\    <NAME> <APP> <Opt-ENAME>,
//\\    <CONST>,
//\\    '(' <Opt-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); // <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[0] = mktuple(AST_OPERAND, 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-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]*/);
  }
  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];




//\\ P<Opt-ENAME> = 
//\\    '_' <NAME> <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); // <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 /**/);
  }
  return T[0];




//\\ 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];



//\\ # unary operators

//\\ P<Opt-PLUS> = 
//\\    '+',
//\\    '-',
//\\    '\\',
//\\   ;

case P_Opt_PLUS:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '+', A[ap+0]);
    T[0] = mktuple(AST_Opt_PLUS, 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, 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 /**/);
  }
  return T[0];




//\\ P<RESTOFSC> = 
//\\    <COMP2> <EXPR>,
//\\   ;

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 /**/);
  }
  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]*/);



//\\ 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<RESTOFANDC> = 
//\\    "and" <SC> <RESTOFANDC>,
//\\   ;

case P_RESTOFANDC:
  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_RESTOFANDC, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_RESTOFANDC, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  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

//\\ P<RESTOFSWLIST> = 
//\\    ',' <NAME> <Opt-NLIST> '(' <EXPR> ':' <EXPR> ')' <RESTOFSWLIST>,
//\\   ;

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]*/);
  } else               {
    T[0] = mktuple(AST_RESTOFSWLIST, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




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

case P_Opt_NLIST:
  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[0] = mktuple(AST_Opt_NLIST, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_Opt_NLIST, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<RESTOFNLIST> = 
//\\    ',' <CEXPR> <RESTOFNLIST>,
//\\   ;

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 /**/);
  }
  return T[0];




//\\ P<CEXPR> = 
//\\    <Opt-PLUS> <COPERAND> <RESTOFCEXPR>;

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



//\\ P<RESTOFCEXPR> = 
//\\    <OP> <COPERAND> <RESTOFCEXPR>,
//\\   ;

case P_RESTOFCEXPR:
  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); // <RESTOFCEXPR>
    T[0] = mktuple(AST_RESTOFCEXPR, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_RESTOFCEXPR, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<COPERAND> = 
//\\    <NAME>,
//\\    <CONST>,
//\\    '(' <Opt-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               {  
    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];




//\\ 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> = 
//\\    "event",
//\\   ;

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




//\\ P<FPP> = 
//\\    '(' <FPDEL> <RESTOFFPLIST> ')',
//\\   ;

case P_FPP:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '(', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <FPDEL>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFFPLIST>  
    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<RESTOFFPLIST> = 
//\\    <Opt-Comma> <FPDEL> <RESTOFFPLIST>,
//\\   ;

case P_RESTOFFPLIST:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-Comma>
    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]*/);
  } else               {
    T[0] = mktuple(AST_RESTOFFPLIST, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  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:
  if (alt == 0)        {
    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]*/);
  }
  return T[0];




//\\ P<Opt-PercentNAME> = 
//\\    "name",
//\\   ;

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



//\\ # added predicate - gt

//\\ P<RT> = 
//\\    "routine",
//\\    "predicate",
//\\    <XTYPE> <FM>;

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); // <FM>
    T[0] = mktuple(AST_RT, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<FM> = 
//\\    "fn",
//\\    "map",
//\\    "function";

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];



//\\ # label and short added by gt as a quick hack

//\\ P<XTYPE> = 
//\\    "integer",
//\\    "real",
//\\    "label",
//\\    "long" <BTYPE>,
//\\    "byte" <FULLTYPE>,
//\\    "string" <REPFACT>,
//\\    "half" <FULLTYPE>,
//\\    "short" <FULLTYPE>,
//\\    "record" '(' <Opt-RFREF> ')';

case P_XTYPE:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_integer, A[ap+0]);
    T[0] = mktuple(AST_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_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_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); // <BTYPE>
    T[0] = mktuple(AST_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); // <FULLTYPE>
    T[0] = mktuple(AST_XTYPE, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 5) {  
    T[1] = kw(AST__KW, KW_string, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <REPFACT>
    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]*/);
  } else               {  
    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]*/);
  }
  return T[0];



//\\ # '*' added by gt for recordformat(*)

//\\ 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];



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

//\\ 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];




//\\ 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];




//\\ 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<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]*/);
  } else               {  
    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];



//\\ # Array declaration

//\\ 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]*/);



//\\ P<RESTOFARLIST> = 
//\\    ',' <ADECLN>,
//\\   ;

case P_RESTOFARLIST:
  if (alt == 0)        {  
    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]*/);
  } else               {
    T[0] = mktuple(AST_RESTOFARLIST, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



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

//\\ P<BPAIR> = 
//\\    '(' <EXPR> ':' <EXPR> <RESTOFBPLIST> ')';

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]*/);


//\\ # Multi-dimensional arrays

//\\ P<RESTOFBPLIST> = 
//\\    ',' <EXPR> ':' <EXPR> <RESTOFBPLIST>,
//\\   ;

case P_RESTOFBPLIST:
  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); // <RESTOFBPLIST>
    T[0] = mktuple(AST_RESTOFBPLIST, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else               {
    T[0] = mktuple(AST_RESTOFBPLIST, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<Opt-PercentQNAME> = 
//\\    "array" "name",
//\\    "name",
//\\   ;

case P_Opt_PercentQNAME:
  if (alt == 0)        {  
    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]*/);
  } else               {
    T[0] = mktuple(AST_Opt_PercentQNAME, alt /*2*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<FULLTYPE> = 
//\\    "integer",
//\\   ;

case P_FULLTYPE:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_integer, A[ap+0]);
    T[0] = mktuple(AST_FULLTYPE, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_FULLTYPE, 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.

//\\ 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... gt

//\\ P<STAROREXPR> = 
//\\    <Opt-PLUS> <COPERAND> <RESTOFCEXPR>,
//\\    '*';

case P_STAROREXPR:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <Opt-PLUS>
    T[2] = build_ast(A[ap+1], depth+1); // <COPERAND>
    T[3] = build_ast(A[ap+2], depth+1); // <RESTOFCEXPR>
    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];




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

case P_BTYPE:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_real, A[ap+0]);
    T[0] = mktuple(AST_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_BTYPE, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    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]*/);
  }
  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]*/);



//\\ 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];




//\\ 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<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];



//\\ # 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 /**/);
  }
  return T[0];



//\\ # Scalar declaration
//\\ # <Opt-Const-assign> added by gt

//\\ P<DECLN> = 
//\\    <Opt-PercentQNAME> <NAME> <Opt-Const-assign> <Opt-Assign-NLIST>,
//\\    "array" <Opt-PercentFORMAT> <ADECLN>;

case P_DECLN:
  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-Const-assign>
    T[4] = build_ast(A[ap+3], depth+1); // <Opt-Assign-NLIST>
    T[0] = mktuple(AST_DECLN, 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-PercentFORMAT>
    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]*/);
  }
  return T[0];




//\\ P<Opt-PercentFORMAT> = 
//\\    "format",
//\\   ;

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



//\\ # <Opt-Const-assign> added by gt

//\\ P<Opt-Assign-NLIST> = 
//\\    ',' <NAME> <Opt-Const-assign> <Opt-Assign-NLIST>,
//\\   ;

case P_Opt_Assign_NLIST:
  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-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 /**/);
  }
  return T[0];



//\\ # The <CEXPR> one may be redundant.  Had to put expr first to catch = tostring(i) because cexpr only got tostring

//\\ P<Opt-Const-assign> = 
//\\    '=' <EXPR>,
//\\    '=' <CEXPR>,
//\\   ;

case P_Opt_Const_assign:
  if (alt == 0)        {  
    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]*/);
  } 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]*/);
  } else               {
    T[0] = mktuple(AST_Opt_Const_assign, alt /*2*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<Percent-WU> = 
//\\    "while" <SC> <RESTOFCOND>,
//\\    "until" <SC> <RESTOFCOND>,
//\\    "for" <NAME> '=' <EXPR> ',' <EXPR> ',' <EXPR>;

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); // <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]*/);
  } else if (alt == 1) {  
    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_Percent_WU, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_for, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <NAME>  
    T[3] = lit(AST__LIT, '=', A[ap+2]);
    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_WU, 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<RESTOFREPEAT> = 
//\\    "until" <SC> <RESTOFCOND>,
//\\   ;

case P_RESTOFREPEAT:
  if (alt == 0)        {  
    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 /**/);
  }
  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];




//\\ 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];



//\\ # 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> <APP> <Opt-ENAME> <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); // <NAME>
    T[2] = build_ast(A[ap+1], depth+1); // <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); // <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

//\\ P<OPEXPR2> = 
//\\    ',' <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); // <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];



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

//\\ P<OPEXPR> = 
//\\    ',' <EXPR>,
//\\   ;

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



//\\ # 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];




//\\ 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];



//\\ # 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.

//\\ 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<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];




//\\ P<RESTOFSS1> = 
//\\    <S>,
//\\    <Percent-IU> <SC> <RESTOFCOND> <S>,
//\\    <Percent-WU> <S>,
//\\   ;

case P_RESTOFSS1:
  if (alt == 0)        {
    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) {
    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); // <S>
    T[0] = mktuple(AST_RESTOFSS1, 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); // <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]*/);
  } else               {
    T[0] = mktuple(AST_RESTOFSS1, alt /*3*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # An initialised array declaration does not need a %C following the '=' before the list of initial values.

//\\ P<OWNDEC> = 
//\\    <Opt-PercentQNAME> <Opt-VSPEC> <NAME> <Opt-ALIAS> <Opt-CONST> <RESTOFOWNDEC>,
//\\    "array" <Opt-PercentFORMAT> <Opt-VSPEC> <NAME> <BPAIR> <CONSTLIST>;

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); // <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]*/);
  } 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]*/);
  }
  return T[0];



//\\ # this is a stupid hack to get around comments in the middle of array declarations :-(
//\\ # note that it gobbles the newline

//\\ P<CONSTLIST> = 
//\\    '=' <stupid> <Opt-PLUS> <COPERAND> <RESTOFCEXPR> <REPFACT> <ROCL>,
//\\   ;

case P_CONSTLIST:
  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-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]*/);
  } else               {
    T[0] = mktuple(AST_CONSTLIST, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<ROCL> = 
//\\    ',' <stupid> <Opt-PLUS> <COPERAND> <RESTOFCEXPR> <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-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]*/);
  } 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];




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

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




//\\ 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];



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

//\\ P<Opt-CONST> = 
//\\    '=' <Opt-PLUS> <COPERAND> <RESTOFCEXPR>,
//\\    '=' '=' <NUMBER>,
//\\   ;

case P_Opt_CONST:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);
    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[0] = mktuple(AST_Opt_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); // <NUMBER>
    T[0] = mktuple(AST_Opt_CONST, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_Opt_CONST, alt /*2*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ 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
@
