//\\ B<char> = 0;
//\\ B<internal-identifier> = 1;
//\\ B<integer-constant> = 2;
//\\ # <character-constant> temporarily replaced by <sqstring>
//\\ # and <string> temporarily replaced by <dqstring>
//\\ # because parser.c TEMPORARILY assumes these exist in all parsers :-(
//\\ B<sqstring> = 3;
//\\ B<floating-constant> = 4;
//\\ B<dqstring> = 5;
//\\ B<keyword> = 6;
//\\ B<pp> = 7;
//\\ B<mm> = 8;
//\\ B<andand> = 9;
//\\ B<oror> = 10;
//\\ B<eqeq> = 11;
//\\ # char, NL, and EOF are required by all parsers
//\\ B<NL> = 12;
//\\ B<EOF> = 13;

//\\ C<immediate> = {
//\\ // WARNING: currently parse-time phrases are not being handled properly
//\\ //          by compile(). Are they set to -1 or skipped completely?
//\\ extern int *A; // remove as much of this as possible as soon as things start working again...
//\\ extern int cp;                     // code pointer.  Has to be global state.
//\\ extern int ap;                     // Analysis record pointer.
//\\ int kw(int AST_op, int kw_idx, int ap)  // kw(AST__KW, KW_void, A[ap+0]);
//\\ 
//\\ {
//\\   int data[3];
//\\ 
//\\   data[1] =  kw_idx;
//\\ 
//\\   data[2] =  ap;
//\\ 
//\\   return mktuple(B_keyword, 1, 2, data);
//\\ 
//\\ }
//\\ int check(int Aval, int *table);
//\\ 
//\\ // variables used in line_reconstruction() moved here so they are available to semantic code in grammar.
//\\ int saved = TRUE;
//\\ 
//\\ int at_startofline = TRUE;
//\\ 
//\\ };

//\\ # top-level statement

//\\ P<identifier> = 
//\\    <!keyword-not-allowed-in-context-of-an-identifier> <internal-identifier>;

case P_identifier:
  T[1] = -1; // <!keyword-not-allowed-in-context-of-an-identifier>
  T[2] = bip(AST_internal_identifier, A[ap+1]);
  return mktuple(AST_identifier, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);


//\\ # want to use keyword[] array from parser.h, but this will have to do for now
//\\ # until I can work out a clean mechanism using <immediate:...>

//\\ P<keyword-not-allowed-in-context-of-an-identifier> = 
//\\    "if",
//\\    "const",
//\\    "struct",
//\\    "union",
//\\    "sizeof",
//\\    "typeof",
//\\    "double",
//\\    "long",
//\\    "char",
//\\    "float",
//\\    "void",
//\\    "enum",
//\\    "short",
//\\    "int",
//\\    "signed",
//\\    "unsigned",
//\\    "volatile",
//\\    "auto",
//\\    "register",
//\\    "static",
//\\    "extern",
//\\    "goto",
//\\    "continue",
//\\    "break",
//\\    "return",
//\\    "while",
//\\    "do",
//\\    "for",
//\\    "switch",
//\\    "else",
//\\    "case",
//\\    "default",
//\\    "typedef";

case P_keyword_not_allowed_in_context_of_an_identifier:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_if, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_const, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = kw(AST__KW, KW_struct, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 3) {  
    T[1] = kw(AST__KW, KW_union, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 4) {  
    T[1] = kw(AST__KW, KW_sizeof, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 5) {  
    T[1] = kw(AST__KW, KW_typeof, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*5*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 6) {  
    T[1] = kw(AST__KW, KW_double, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*6*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 7) {  
    T[1] = kw(AST__KW, KW_long, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*7*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 8) {  
    T[1] = kw(AST__KW, KW_char, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*8*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 9) {  
    T[1] = kw(AST__KW, KW_float, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*9*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 10) {  
    T[1] = kw(AST__KW, KW_void, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*10*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 11) {  
    T[1] = kw(AST__KW, KW_enum, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*11*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 12) {  
    T[1] = kw(AST__KW, KW_short, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*12*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 13) {  
    T[1] = kw(AST__KW, KW_int, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*13*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 14) {  
    T[1] = kw(AST__KW, KW_signed, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*14*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 15) {  
    T[1] = kw(AST__KW, KW_unsigned, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*15*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 16) {  
    T[1] = kw(AST__KW, KW_volatile, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*16*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 17) {  
    T[1] = kw(AST__KW, KW_auto, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*17*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 18) {  
    T[1] = kw(AST__KW, KW_register, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*18*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 19) {  
    T[1] = kw(AST__KW, KW_static, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*19*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 20) {  
    T[1] = kw(AST__KW, KW_extern, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*20*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 21) {  
    T[1] = kw(AST__KW, KW_goto, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*21*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 22) {  
    T[1] = kw(AST__KW, KW_continue, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*22*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 23) {  
    T[1] = kw(AST__KW, KW_break, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*23*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 24) {  
    T[1] = kw(AST__KW, KW_return, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*24*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 25) {  
    T[1] = kw(AST__KW, KW_while, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*25*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 26) {  
    T[1] = kw(AST__KW, KW_do, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*26*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 27) {  
    T[1] = kw(AST__KW, KW_for, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*27*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 28) {  
    T[1] = kw(AST__KW, KW_switch, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*28*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 29) {  
    T[1] = kw(AST__KW, KW_else, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*29*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 30) {  
    T[1] = kw(AST__KW, KW_case, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*30*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 31) {  
    T[1] = kw(AST__KW, KW_default, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*31*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_typedef, A[ap+0]);
    T[0] = mktuple(AST_keyword_not_allowed_in_context_of_an_identifier, alt /*32*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<ignored> = 
//\\    <immediate:return FALSE;> ';';

case P_ignored:
  T[1] = -1; // successful semantic call
  T[2] = lit(AST__LIT, ';', A[ap+1]);
  return mktuple(AST_ignored, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<SS> = 
//\\    <opt-external-declaration-list>;

case P_SS:
  T[1] = build_ast(A[ap+0], depth+1); // <opt-external-declaration-list>
  return mktuple(AST_SS, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);



//\\ P<opt-external-declaration-list> = 
//\\    <external-declaration> <opt-external-declaration-list>,
//\\    <EOF>;

case P_opt_external_declaration_list:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <external-declaration>
    T[2] = build_ast(A[ap+1], depth+1); // <opt-external-declaration-list>
    T[0] = mktuple(AST_opt_external_declaration_list, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[1] = bip(AST_EOF, A[ap+0]);
    T[0] = mktuple(AST_opt_external_declaration_list, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<external-declaration> = 
//\\    <typedef-declaration> ';',
//\\    <proc-fn-decl>,
//\\    <possibly-initialised-scalar-or-array-decl>,
//\\    <enum-specifier>,
//\\    <struct-or-union-specifier>,
//\\    ';';

case P_external_declaration:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <typedef-declaration>  
    T[2] = lit(AST__LIT, ';', A[ap+1]);
    T[0] = mktuple(AST_external_declaration, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <proc-fn-decl>
    T[0] = mktuple(AST_external_declaration, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <possibly-initialised-scalar-or-array-decl>
    T[0] = mktuple(AST_external_declaration, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 3) {
    T[1] = build_ast(A[ap+0], depth+1); // <enum-specifier>
    T[0] = mktuple(AST_external_declaration, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 4) {
    T[1] = build_ast(A[ap+0], depth+1); // <struct-or-union-specifier>
    T[0] = mktuple(AST_external_declaration, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = lit(AST__LIT, ';', A[ap+0]);
    T[0] = mktuple(AST_external_declaration, alt /*5*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];



//\\ # Oops - these can be initialised.  Not yet done so.
//\\ #

//\\ P<struct-or-union-specifier> = 
//\\    <struct-or-union> <identifier> '{' <struct-field-declarations> '}',
//\\    <struct-or-union> '{' <struct-field-declarations> '}',
//\\    <struct-or-union> <identifier>;

case P_struct_or_union_specifier:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <struct-or-union>
    T[2] = build_ast(A[ap+1], depth+1); // <identifier>  
    T[3] = lit(AST__LIT, '{', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <struct-field-declarations>  
    T[5] = lit(AST__LIT, '}', A[ap+4]);
    T[0] = mktuple(AST_struct_or_union_specifier, 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); // <struct-or-union>  
    T[2] = lit(AST__LIT, '{', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <struct-field-declarations>  
    T[4] = lit(AST__LIT, '}', A[ap+3]);
    T[0] = mktuple(AST_struct_or_union_specifier, alt /*1*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <struct-or-union>
    T[2] = build_ast(A[ap+1], depth+1); // <identifier>
    T[0] = mktuple(AST_struct_or_union_specifier, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<struct-or-union> = 
//\\    "struct",
//\\    "union";

case P_struct_or_union:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_struct, A[ap+0]);
    T[0] = mktuple(AST_struct_or_union, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_union, A[ap+0]);
    T[0] = mktuple(AST_struct_or_union, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<struct-field-declarations> = 
//\\    <struct-field-declaration> <rest-of-struct-field-declarations>;

case P_struct_field_declarations:
  T[1] = build_ast(A[ap+0], depth+1); // <struct-field-declaration>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-struct-field-declarations>
  return mktuple(AST_struct_field_declarations, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-struct-field-declarations> = 
//\\    <struct-field-declaration> <rest-of-struct-field-declarations>,
//\\   ;

case P_rest_of_struct_field_declarations:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <struct-field-declaration>
    T[2] = build_ast(A[ap+1], depth+1); // <rest-of-struct-field-declarations>
    T[0] = mktuple(AST_rest_of_struct_field_declarations, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_struct_field_declarations, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<struct-field-declaration> = 
//\\    <possibly-initialised-scalar-or-array-decl>;

case P_struct_field_declaration:
  T[1] = build_ast(A[ap+0], depth+1); // <possibly-initialised-scalar-or-array-decl>
  return mktuple(AST_struct_field_declaration, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);


//\\ # I originally thought you could only initialise an array after a declaration
//\\ # that had '[]' in it.  But not the case - a typedef'd declaration may have
//\\ # the array part in the typedef rather than the instance.  Ugly language.
//\\ #
//\\ # Also we can have initialised structs :-/
//\\ #

//\\ P<possibly-initialised-scalar-or-array-decl> = 
//\\    <opt-auto-reg-static-ext> <opt-const-or-volatile-type-qualifier> <type> <rest-of-scalar-or-array-decl> ';';

case P_possibly_initialised_scalar_or_array_decl:
  T[1] = build_ast(A[ap+0], depth+1); // <opt-auto-reg-static-ext>
  T[2] = build_ast(A[ap+1], depth+1); // <opt-const-or-volatile-type-qualifier>
  T[3] = build_ast(A[ap+2], depth+1); // <type>
  T[4] = build_ast(A[ap+3], depth+1); // <rest-of-scalar-or-array-decl>
  T[5] = lit(AST__LIT, ';', A[ap+4]);
  return mktuple(AST_possibly_initialised_scalar_or_array_decl, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);


//\\ # The <opt-scalar-init> part of function pointers is usually going to be "= &procname"... any other type of scalar is dubious...

//\\ P<rest-of-scalar-or-array-decl> = 
//\\    <opt-indirection-decl> <identifier> <array-bounds> <opt-array-init> <opt-rest-of-scalar-or-array-decl>,
//\\    <opt-indirection-decl> '(' <opt-indirection-decl> <identifier> ')' '(' <opt-param-list> ')' <opt-scalar-init> <opt-rest-of-scalar-or-array-decl>,
//\\    <opt-indirection-decl> <identifier> <opt-scalar-init> <opt-rest-of-scalar-or-array-decl>;

case P_rest_of_scalar_or_array_decl:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <opt-indirection-decl>
    T[2] = build_ast(A[ap+1], depth+1); // <identifier>
    T[3] = build_ast(A[ap+2], depth+1); // <array-bounds>
    T[4] = build_ast(A[ap+3], depth+1); // <opt-array-init>
    T[5] = build_ast(A[ap+4], depth+1); // <opt-rest-of-scalar-or-array-decl>
    T[0] = mktuple(AST_rest_of_scalar_or_array_decl, 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-indirection-decl>  
    T[2] = lit(AST__LIT, '(', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <opt-indirection-decl>
    T[4] = build_ast(A[ap+3], depth+1); // <identifier>  
    T[5] = lit(AST__LIT, ')', A[ap+4]);  
    T[6] = lit(AST__LIT, '(', A[ap+5]);
    T[7] = build_ast(A[ap+6], depth+1); // <opt-param-list>  
    T[8] = lit(AST__LIT, ')', A[ap+7]);
    T[9] = build_ast(A[ap+8], depth+1); // <opt-scalar-init>
    T[10] = build_ast(A[ap+9], depth+1); // <opt-rest-of-scalar-or-array-decl>
    T[0] = mktuple(AST_rest_of_scalar_or_array_decl, alt /*1*/, /*phrases*/ 10, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9], T[10]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <opt-indirection-decl>
    T[2] = build_ast(A[ap+1], depth+1); // <identifier>
    T[3] = build_ast(A[ap+2], depth+1); // <opt-scalar-init>
    T[4] = build_ast(A[ap+3], depth+1); // <opt-rest-of-scalar-or-array-decl>
    T[0] = mktuple(AST_rest_of_scalar_or_array_decl, alt /*2*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  }
  return T[0];




//\\ P<opt-rest-of-scalar-or-array-decl> = 
//\\    ',' <rest-of-scalar-or-array-decl>,
//\\   ;

case P_opt_rest_of_scalar_or_array_decl:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <rest-of-scalar-or-array-decl>
    T[0] = mktuple(AST_opt_rest_of_scalar_or_array_decl, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_opt_rest_of_scalar_or_array_decl, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<opt-scalar-init> = 
//\\    '=' <assignment-expression>,
//\\   ;

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




//\\ P<assignment-expression> = 
//\\    <opt-lvalue-assign> <conditional-expression> <opt-rest-of-assignment-expression>;

case P_assignment_expression:
  T[1] = build_ast(A[ap+0], depth+1); // <opt-lvalue-assign>
  T[2] = build_ast(A[ap+1], depth+1); // <conditional-expression>
  T[3] = build_ast(A[ap+2], depth+1); // <opt-rest-of-assignment-expression>
  return mktuple(AST_assignment_expression, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);



//\\ P<opt-rest-of-assignment-expression> = 
//\\    <assignment-operator> <conditional-expression> <opt-rest-of-assignment-expression>,
//\\   ;

case P_opt_rest_of_assignment_expression:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <assignment-operator>
    T[2] = build_ast(A[ap+1], depth+1); // <conditional-expression>
    T[3] = build_ast(A[ap+2], depth+1); // <opt-rest-of-assignment-expression>
    T[0] = mktuple(AST_opt_rest_of_assignment_expression, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_opt_rest_of_assignment_expression, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<conditional-expression> = 
//\\    <logical-or-expression> <rest-of-conditional-expression>;

case P_conditional_expression:
  T[1] = build_ast(A[ap+0], depth+1); // <logical-or-expression>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-conditional-expression>
  return mktuple(AST_conditional_expression, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-conditional-expression> = 
//\\    '?' <expression> ':' <conditional-expression>,
//\\   ;

case P_rest_of_conditional_expression:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '?', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <expression>  
    T[3] = lit(AST__LIT, ':', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <conditional-expression>
    T[0] = mktuple(AST_rest_of_conditional_expression, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_conditional_expression, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<expression> = 
//\\    <comma-statement>;

case P_expression:
  T[1] = build_ast(A[ap+0], depth+1); // <comma-statement>
  return mktuple(AST_expression, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);



//\\ P<comma-statement> = 
//\\    <assignment-expression> <rest-of-comma-statement>;

case P_comma_statement:
  T[1] = build_ast(A[ap+0], depth+1); // <assignment-expression>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-comma-statement>
  return mktuple(AST_comma_statement, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-comma-statement> = 
//\\    ',' <assignment-expression> <rest-of-comma-statement>,
//\\   ;

case P_rest_of_comma_statement:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <assignment-expression>
    T[3] = build_ast(A[ap+2], depth+1); // <rest-of-comma-statement>
    T[0] = mktuple(AST_rest_of_comma_statement, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_comma_statement, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<logical-or-expression> = 
//\\    <logical-and-expression> <rest-of-logical-or-expression>;

case P_logical_or_expression:
  T[1] = build_ast(A[ap+0], depth+1); // <logical-and-expression>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-logical-or-expression>
  return mktuple(AST_logical_or_expression, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-logical-or-expression> = 
//\\    <oror> <logical-and-expression> <rest-of-logical-or-expression>,
//\\   ;

case P_rest_of_logical_or_expression:
  if (alt == 0)        {
    T[1] = bip(AST_oror, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <logical-and-expression>
    T[3] = build_ast(A[ap+2], depth+1); // <rest-of-logical-or-expression>
    T[0] = mktuple(AST_rest_of_logical_or_expression, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_logical_or_expression, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<logical-and-expression> = 
//\\    <inclusive-or-expression> <rest-of-logical-and-expression>;

case P_logical_and_expression:
  T[1] = build_ast(A[ap+0], depth+1); // <inclusive-or-expression>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-logical-and-expression>
  return mktuple(AST_logical_and_expression, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-logical-and-expression> = 
//\\    <andand> <inclusive-or-expression> <rest-of-logical-and-expression>,
//\\   ;

case P_rest_of_logical_and_expression:
  if (alt == 0)        {
    T[1] = bip(AST_andand, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <inclusive-or-expression>
    T[3] = build_ast(A[ap+2], depth+1); // <rest-of-logical-and-expression>
    T[0] = mktuple(AST_rest_of_logical_and_expression, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_logical_and_expression, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<inclusive-or-expression> = 
//\\    <exclusive-or-expression> <rest-of-inclusive-or-expression>;

case P_inclusive_or_expression:
  T[1] = build_ast(A[ap+0], depth+1); // <exclusive-or-expression>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-inclusive-or-expression>
  return mktuple(AST_inclusive_or_expression, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-inclusive-or-expression> = 
//\\    '|' <exclusive-or-expression> <rest-of-inclusive-or-expression>,
//\\   ;

case P_rest_of_inclusive_or_expression:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '|', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <exclusive-or-expression>
    T[3] = build_ast(A[ap+2], depth+1); // <rest-of-inclusive-or-expression>
    T[0] = mktuple(AST_rest_of_inclusive_or_expression, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_inclusive_or_expression, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<exclusive-or-expression> = 
//\\    <bitwise-and-expression> <rest-of-exclusive-or-expression>;

case P_exclusive_or_expression:
  T[1] = build_ast(A[ap+0], depth+1); // <bitwise-and-expression>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-exclusive-or-expression>
  return mktuple(AST_exclusive_or_expression, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-exclusive-or-expression> = 
//\\    '^' <bitwise-and-expression> <rest-of-exclusive-or-expression>,
//\\   ;

case P_rest_of_exclusive_or_expression:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '^', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <bitwise-and-expression>
    T[3] = build_ast(A[ap+2], depth+1); // <rest-of-exclusive-or-expression>
    T[0] = mktuple(AST_rest_of_exclusive_or_expression, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_exclusive_or_expression, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<bitwise-and-expression> = 
//\\    <equality-expression> <rest-of-bitwise-and-expression>;

case P_bitwise_and_expression:
  T[1] = build_ast(A[ap+0], depth+1); // <equality-expression>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-bitwise-and-expression>
  return mktuple(AST_bitwise_and_expression, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-bitwise-and-expression> = 
//\\    '&' <equality-expression> <rest-of-bitwise-and-expression>,
//\\   ;

case P_rest_of_bitwise_and_expression:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '&', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <equality-expression>
    T[3] = build_ast(A[ap+2], depth+1); // <rest-of-bitwise-and-expression>
    T[0] = mktuple(AST_rest_of_bitwise_and_expression, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_bitwise_and_expression, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<equality-expression> = 
//\\    <relational-expression> <rest-of-equality-expression>;

case P_equality_expression:
  T[1] = build_ast(A[ap+0], depth+1); // <relational-expression>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-equality-expression>
  return mktuple(AST_equality_expression, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-equality-expression> = 
//\\    <eqop> <relational-expression> <rest-of-equality-expression>,
//\\   ;

case P_rest_of_equality_expression:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <eqop>
    T[2] = build_ast(A[ap+1], depth+1); // <relational-expression>
    T[3] = build_ast(A[ap+2], depth+1); // <rest-of-equality-expression>
    T[0] = mktuple(AST_rest_of_equality_expression, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_equality_expression, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<relational-expression> = 
//\\    <shift-expression> <rest-of-relational-expression>;

case P_relational_expression:
  T[1] = build_ast(A[ap+0], depth+1); // <shift-expression>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-relational-expression>
  return mktuple(AST_relational_expression, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-relational-expression> = 
//\\    <relop> <shift-expression> <rest-of-relational-expression>,
//\\   ;

case P_rest_of_relational_expression:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <relop>
    T[2] = build_ast(A[ap+1], depth+1); // <shift-expression>
    T[3] = build_ast(A[ap+2], depth+1); // <rest-of-relational-expression>
    T[0] = mktuple(AST_rest_of_relational_expression, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_relational_expression, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<shift-expression> = 
//\\    <additive-expression> <rest-of-shift-expression>;

case P_shift_expression:
  T[1] = build_ast(A[ap+0], depth+1); // <additive-expression>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-shift-expression>
  return mktuple(AST_shift_expression, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-shift-expression> = 
//\\    <shiftop> <additive-expression> <rest-of-shift-expression>,
//\\   ;

case P_rest_of_shift_expression:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <shiftop>
    T[2] = build_ast(A[ap+1], depth+1); // <additive-expression>
    T[3] = build_ast(A[ap+2], depth+1); // <rest-of-shift-expression>
    T[0] = mktuple(AST_rest_of_shift_expression, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_shift_expression, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<additive-expression> = 
//\\    <multiplicative-expression> <rest-of-additive-expression>;

case P_additive_expression:
  T[1] = build_ast(A[ap+0], depth+1); // <multiplicative-expression>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-additive-expression>
  return mktuple(AST_additive_expression, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-additive-expression> = 
//\\    <plusminus> <multiplicative-expression> <rest-of-additive-expression>,
//\\   ;

case P_rest_of_additive_expression:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <plusminus>
    T[2] = build_ast(A[ap+1], depth+1); // <multiplicative-expression>
    T[3] = build_ast(A[ap+2], depth+1); // <rest-of-additive-expression>
    T[0] = mktuple(AST_rest_of_additive_expression, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_additive_expression, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<multiplicative-expression> = 
//\\    <unary-rvalue-expression> <rest-of-multiplicative-expression>;

case P_multiplicative_expression:
  T[1] = build_ast(A[ap+0], depth+1); // <unary-rvalue-expression>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-multiplicative-expression>
  return mktuple(AST_multiplicative_expression, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-multiplicative-expression> = 
//\\    <mulop> <unary-rvalue-expression> <rest-of-multiplicative-expression>,
//\\   ;

case P_rest_of_multiplicative_expression:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <mulop>
    T[2] = build_ast(A[ap+1], depth+1); // <unary-rvalue-expression>
    T[3] = build_ast(A[ap+2], depth+1); // <rest-of-multiplicative-expression>
    T[0] = mktuple(AST_rest_of_multiplicative_expression, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_multiplicative_expression, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # my reading of the spec is that "sizeof" <type-specifier> is valid but "sizeof" '(' <type-specifier> ')' is not,
//\\ # however the latter appears to be accepted by gcc.
//\\ # Should we merge <type-specifier> with <opt-indirection-unary-ops>? Is <type-specifier> ever used without an optional '*' following?

//\\ P<unary-rvalue-expression> = 
//\\    <arithmetic-unary-op> <optionally-cast-unary-rvalue-expression>,
//\\    <boolean-unary-ops> <optionally-cast-unary-rvalue-expression>,
//\\    <bitwise-unary-ops> <optionally-cast-unary-rvalue-expression>,
//\\    <indirection-unary-ops> <unary-address-expression>,
//\\    "sizeof" <unary-rvalue-expression>,
//\\    "sizeof" <unary-lvalue-expression>,
//\\    "sizeof" <type-specifier> <opt-indirection-unary-ops>,
//\\    "sizeof" '(' <type-specifier> <opt-indirection-unary-ops> ')',
//\\    <optionally-cast-postfix-rvalue-expression>;

case P_unary_rvalue_expression:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <arithmetic-unary-op>
    T[2] = build_ast(A[ap+1], depth+1); // <optionally-cast-unary-rvalue-expression>
    T[0] = mktuple(AST_unary_rvalue_expression, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <boolean-unary-ops>
    T[2] = build_ast(A[ap+1], depth+1); // <optionally-cast-unary-rvalue-expression>
    T[0] = mktuple(AST_unary_rvalue_expression, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <bitwise-unary-ops>
    T[2] = build_ast(A[ap+1], depth+1); // <optionally-cast-unary-rvalue-expression>
    T[0] = mktuple(AST_unary_rvalue_expression, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 3) {
    T[1] = build_ast(A[ap+0], depth+1); // <indirection-unary-ops>
    T[2] = build_ast(A[ap+1], depth+1); // <unary-address-expression>
    T[0] = mktuple(AST_unary_rvalue_expression, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 4) {  
    T[1] = kw(AST__KW, KW_sizeof, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <unary-rvalue-expression>
    T[0] = mktuple(AST_unary_rvalue_expression, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 5) {  
    T[1] = kw(AST__KW, KW_sizeof, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <unary-lvalue-expression>
    T[0] = mktuple(AST_unary_rvalue_expression, alt /*5*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 6) {  
    T[1] = kw(AST__KW, KW_sizeof, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <type-specifier>
    T[3] = build_ast(A[ap+2], depth+1); // <opt-indirection-unary-ops>
    T[0] = mktuple(AST_unary_rvalue_expression, alt /*6*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 7) {  
    T[1] = kw(AST__KW, KW_sizeof, A[ap+0]);  
    T[2] = lit(AST__LIT, '(', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <type-specifier>
    T[4] = build_ast(A[ap+3], depth+1); // <opt-indirection-unary-ops>  
    T[5] = lit(AST__LIT, ')', A[ap+4]);
    T[0] = mktuple(AST_unary_rvalue_expression, alt /*7*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <optionally-cast-postfix-rvalue-expression>
    T[0] = mktuple(AST_unary_rvalue_expression, alt /*8*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<optionally-cast-postfix-rvalue-expression> = 
//\\    <cast> <optionally-cast-postfix-rvalue-expression>,
//\\    <postfix-rvalue-expression>;

case P_optionally_cast_postfix_rvalue_expression:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <cast>
    T[2] = build_ast(A[ap+1], depth+1); // <optionally-cast-postfix-rvalue-expression>
    T[0] = mktuple(AST_optionally_cast_postfix_rvalue_expression, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <postfix-rvalue-expression>
    T[0] = mktuple(AST_optionally_cast_postfix_rvalue_expression, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<postfix-rvalue-expression> = 
//\\    <primary-expression> <rest-of-postfix-rvalue-expression>,
//\\    <unary-lvalue-expression> <rest-of-postfix-rvalue-expression>;

case P_postfix_rvalue_expression:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <primary-expression>
    T[2] = build_ast(A[ap+1], depth+1); // <rest-of-postfix-rvalue-expression>
    T[0] = mktuple(AST_postfix_rvalue_expression, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <unary-lvalue-expression>
    T[2] = build_ast(A[ap+1], depth+1); // <rest-of-postfix-rvalue-expression>
    T[0] = mktuple(AST_postfix_rvalue_expression, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<rest-of-postfix-rvalue-expression> = 
//\\    '[' <expression> ']' <rest-of-postfix-rvalue-expression>,
//\\    '(' <actual-param-list> ')' <rest-of-postfix-rvalue-expression>,
//\\    '.' <identifier> <rest-of-postfix-rvalue-expression>,
//\\    '-' '>' <identifier> <rest-of-postfix-rvalue-expression>,
//\\    <post-increment-op> <rest-of-postfix-rvalue-expression>,
//\\   ;

case P_rest_of_postfix_rvalue_expression:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '[', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <expression>  
    T[3] = lit(AST__LIT, ']', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <rest-of-postfix-rvalue-expression>
    T[0] = mktuple(AST_rest_of_postfix_rvalue_expression, 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] = build_ast(A[ap+1], depth+1); // <actual-param-list>  
    T[3] = lit(AST__LIT, ')', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <rest-of-postfix-rvalue-expression>
    T[0] = mktuple(AST_rest_of_postfix_rvalue_expression, 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); // <identifier>
    T[3] = build_ast(A[ap+2], depth+1); // <rest-of-postfix-rvalue-expression>
    T[0] = mktuple(AST_rest_of_postfix_rvalue_expression, 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] = lit(AST__LIT, '>', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <identifier>
    T[4] = build_ast(A[ap+3], depth+1); // <rest-of-postfix-rvalue-expression>
    T[0] = mktuple(AST_rest_of_postfix_rvalue_expression, 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); // <post-increment-op>
    T[2] = build_ast(A[ap+1], depth+1); // <rest-of-postfix-rvalue-expression>
    T[0] = mktuple(AST_rest_of_postfix_rvalue_expression, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_postfix_rvalue_expression, alt /*5*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<post-increment-op> = 
//\\    <pp>,
//\\    <mm>;

case P_post_increment_op:
  if (alt == 0)        {
    T[1] = bip(AST_pp, A[ap+0]);
    T[0] = mktuple(AST_post_increment_op, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = bip(AST_mm, A[ap+0]);
    T[0] = mktuple(AST_post_increment_op, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<actual-param-list> = 
//\\    <assignment-expression> <rest-of-param-list>,
//\\   ;

case P_actual_param_list:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <assignment-expression>
    T[2] = build_ast(A[ap+1], depth+1); // <rest-of-param-list>
    T[0] = mktuple(AST_actual_param_list, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_actual_param_list, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<rest-of-param-list> = 
//\\    ',' <assignment-expression> <rest-of-param-list>,
//\\   ;

case P_rest_of_param_list:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <assignment-expression>
    T[3] = build_ast(A[ap+2], depth+1); // <rest-of-param-list>
    T[0] = mktuple(AST_rest_of_param_list, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_param_list, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<unary-lvalue-expression> = 
//\\    <pre-increment-op> <unary-lvalue-expression>,
//\\    <indirection-unary-ops> <optionally-cast-unary-lvalue-expression>,
//\\    <unary-address-expression>,
//\\    <postfix-lvalue-expression>;

case P_unary_lvalue_expression:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <pre-increment-op>
    T[2] = build_ast(A[ap+1], depth+1); // <unary-lvalue-expression>
    T[0] = mktuple(AST_unary_lvalue_expression, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <indirection-unary-ops>
    T[2] = build_ast(A[ap+1], depth+1); // <optionally-cast-unary-lvalue-expression>
    T[0] = mktuple(AST_unary_lvalue_expression, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <unary-address-expression>
    T[0] = mktuple(AST_unary_lvalue_expression, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <postfix-lvalue-expression>
    T[0] = mktuple(AST_unary_lvalue_expression, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<postfix-lvalue-expression> = 
//\\    <primary-expression> <rest-of-postfix-expression>;

case P_postfix_lvalue_expression:
  T[1] = build_ast(A[ap+0], depth+1); // <primary-expression>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-postfix-expression>
  return mktuple(AST_postfix_lvalue_expression, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-postfix-expression> = 
//\\    '[' <expression> ']' <rest-of-postfix-expression>,
//\\    '(' <actual-param-list> ')' <non-empty-rest-of-postfix-expression>,
//\\    '.' <identifier> <rest-of-postfix-expression>,
//\\    '-' '>' <identifier> <rest-of-postfix-expression>,
//\\    <post-increment-op> <rest-of-postfix-expression>,
//\\   ;

case P_rest_of_postfix_expression:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '[', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <expression>  
    T[3] = lit(AST__LIT, ']', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <rest-of-postfix-expression>
    T[0] = mktuple(AST_rest_of_postfix_expression, 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] = build_ast(A[ap+1], depth+1); // <actual-param-list>  
    T[3] = lit(AST__LIT, ')', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <non-empty-rest-of-postfix-expression>
    T[0] = mktuple(AST_rest_of_postfix_expression, 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); // <identifier>
    T[3] = build_ast(A[ap+2], depth+1); // <rest-of-postfix-expression>
    T[0] = mktuple(AST_rest_of_postfix_expression, 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] = lit(AST__LIT, '>', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <identifier>
    T[4] = build_ast(A[ap+3], depth+1); // <rest-of-postfix-expression>
    T[0] = mktuple(AST_rest_of_postfix_expression, 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); // <post-increment-op>
    T[2] = build_ast(A[ap+1], depth+1); // <rest-of-postfix-expression>
    T[0] = mktuple(AST_rest_of_postfix_expression, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_postfix_expression, alt /*5*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<non-empty-rest-of-postfix-expression> = 
//\\    '[' <expression> ']' <rest-of-postfix-expression>,
//\\    '(' <actual-param-list> ')' <non-empty-rest-of-postfix-expression>,
//\\    '.' <identifier> <rest-of-postfix-expression>,
//\\    '-' '>' <identifier> <rest-of-postfix-expression>,
//\\    <post-increment-op> <rest-of-postfix-expression>;

case P_non_empty_rest_of_postfix_expression:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '[', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <expression>  
    T[3] = lit(AST__LIT, ']', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <rest-of-postfix-expression>
    T[0] = mktuple(AST_non_empty_rest_of_postfix_expression, 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] = build_ast(A[ap+1], depth+1); // <actual-param-list>  
    T[3] = lit(AST__LIT, ')', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <non-empty-rest-of-postfix-expression>
    T[0] = mktuple(AST_non_empty_rest_of_postfix_expression, 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); // <identifier>
    T[3] = build_ast(A[ap+2], depth+1); // <rest-of-postfix-expression>
    T[0] = mktuple(AST_non_empty_rest_of_postfix_expression, 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] = lit(AST__LIT, '>', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <identifier>
    T[4] = build_ast(A[ap+3], depth+1); // <rest-of-postfix-expression>
    T[0] = mktuple(AST_non_empty_rest_of_postfix_expression, alt /*3*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <post-increment-op>
    T[2] = build_ast(A[ap+1], depth+1); // <rest-of-postfix-expression>
    T[0] = mktuple(AST_non_empty_rest_of_postfix_expression, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<primary-expression> = 
//\\    <identifier>,
//\\    <constant>,
//\\    <dqstring>,
//\\    '(' <expression> ')';

case P_primary_expression:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <identifier>
    T[0] = mktuple(AST_primary_expression, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <constant>
    T[0] = mktuple(AST_primary_expression, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {
    T[1] = bip(AST_dqstring, A[ap+0]);
    T[0] = mktuple(AST_primary_expression, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = lit(AST__LIT, '(', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <expression>  
    T[3] = lit(AST__LIT, ')', A[ap+2]);
    T[0] = mktuple(AST_primary_expression, alt /*3*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  }
  return T[0];




//\\ P<constant> = 
//\\    <integer-constant>,
//\\    <sqstring>,
//\\    <floating-constant>,
//\\    <enumeration-constant>;

case P_constant:
  if (alt == 0)        {
    T[1] = bip(AST_integer_constant, A[ap+0]);
    T[0] = mktuple(AST_constant, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {
    T[1] = bip(AST_sqstring, A[ap+0]);
    T[0] = mktuple(AST_constant, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {
    T[1] = bip(AST_floating_constant, A[ap+0]);
    T[0] = mktuple(AST_constant, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <enumeration-constant>
    T[0] = mktuple(AST_constant, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<enumeration-constant> = 
//\\    <identifier>;

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



//\\ P<unary-address-expression> = 
//\\    <address-operator> <optionally-cast-unary-lvalue-expression>;

case P_unary_address_expression:
  T[1] = build_ast(A[ap+0], depth+1); // <address-operator>
  T[2] = build_ast(A[ap+1], depth+1); // <optionally-cast-unary-lvalue-expression>
  return mktuple(AST_unary_address_expression, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<optionally-cast-unary-lvalue-expression> = 
//\\    <cast> <optionally-cast-unary-lvalue-expression>,
//\\    <unary-lvalue-expression>;

case P_optionally_cast_unary_lvalue_expression:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <cast>
    T[2] = build_ast(A[ap+1], depth+1); // <optionally-cast-unary-lvalue-expression>
    T[0] = mktuple(AST_optionally_cast_unary_lvalue_expression, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <unary-lvalue-expression>
    T[0] = mktuple(AST_optionally_cast_unary_lvalue_expression, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<cast> = 
//\\    '(' <type-specifier> <opt-indirection-unary-ops> ')',
//\\    '(' "typeof" '(' <unary-lvalue-expression> ')' ')',
//\\    '(' "typeof" '(' <type-specifier> <opt-indirection-unary-ops> ')' ')';

case P_cast:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '(', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <type-specifier>
    T[3] = build_ast(A[ap+2], depth+1); // <opt-indirection-unary-ops>  
    T[4] = lit(AST__LIT, ')', A[ap+3]);
    T[0] = mktuple(AST_cast, 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] = kw(AST__KW, KW_typeof, A[ap+1]);  
    T[3] = lit(AST__LIT, '(', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <unary-lvalue-expression>  
    T[5] = lit(AST__LIT, ')', A[ap+4]);  
    T[6] = lit(AST__LIT, ')', A[ap+5]);
    T[0] = mktuple(AST_cast, alt /*1*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } else               {  
    T[1] = lit(AST__LIT, '(', A[ap+0]);  
    T[2] = kw(AST__KW, KW_typeof, A[ap+1]);  
    T[3] = lit(AST__LIT, '(', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <type-specifier>
    T[5] = build_ast(A[ap+4], depth+1); // <opt-indirection-unary-ops>  
    T[6] = lit(AST__LIT, ')', A[ap+5]);  
    T[7] = lit(AST__LIT, ')', A[ap+6]);
    T[0] = mktuple(AST_cast, alt /*2*/, /*phrases*/ 7, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7]*/);
  }
  return T[0];



//\\ # <opt-indirection-decl> looks just like <opt-indirection-unary-ops> except that it only
//\\ # happens in a declaration, not a data access.  The significant difference is that the '*'
//\\ # can be preceded by a "const" (and maybe "volatile") keyword, eg "int const *fred" which
//\\ # is a constant pointer to an int.
//\\ #

//\\ P<opt-indirection-decl> = 
//\\    <opt-const-or-volatile-type-qualifier> '*' <opt-indirection-decl>,
//\\   ;

case P_opt_indirection_decl:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <opt-const-or-volatile-type-qualifier>  
    T[2] = lit(AST__LIT, '*', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <opt-indirection-decl>
    T[0] = mktuple(AST_opt_indirection_decl, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_opt_indirection_decl, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<indirection-unary-ops> = 
//\\    '*' <opt-indirection-unary-ops>;

case P_indirection_unary_ops:
  T[1] = lit(AST__LIT, '*', A[ap+0]);
  T[2] = build_ast(A[ap+1], depth+1); // <opt-indirection-unary-ops>
  return mktuple(AST_indirection_unary_ops, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<opt-indirection-unary-ops> = 
//\\    '*' <opt-indirection-unary-ops>,
//\\   ;

case P_opt_indirection_unary_ops:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '*', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <opt-indirection-unary-ops>
    T[0] = mktuple(AST_opt_indirection_unary_ops, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_opt_indirection_unary_ops, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<type-specifier> = 
//\\    <basic-type-specifier>,
//\\    <typedef-name>;

case P_type_specifier:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <basic-type-specifier>
    T[0] = mktuple(AST_type_specifier, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <typedef-name>
    T[0] = mktuple(AST_type_specifier, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<typedef-name> = 
//\\    <identifier>;

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


//\\ # I think struct or union or enum specifier below can be an actual declaration using '{}'s
//\\ # rather than just a struct or enum name.
//\\ #

//\\ P<basic-type-specifier> = 
//\\    "double",
//\\    "long" "double",
//\\    <opt-signed> "char",
//\\    <opt-signed-inttype>,
//\\    "float",
//\\    <struct-or-union-specifier>,
//\\    <enum-specifier>,
//\\    "void";

case P_basic_type_specifier:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_double, A[ap+0]);
    T[0] = mktuple(AST_basic_type_specifier, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_long, A[ap+0]);  
    T[2] = kw(AST__KW, KW_double, A[ap+1]);
    T[0] = mktuple(AST_basic_type_specifier, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <opt-signed>  
    T[2] = kw(AST__KW, KW_char, A[ap+1]);
    T[0] = mktuple(AST_basic_type_specifier, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 3) {
    T[1] = build_ast(A[ap+0], depth+1); // <opt-signed-inttype>
    T[0] = mktuple(AST_basic_type_specifier, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 4) {  
    T[1] = kw(AST__KW, KW_float, A[ap+0]);
    T[0] = mktuple(AST_basic_type_specifier, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 5) {
    T[1] = build_ast(A[ap+0], depth+1); // <struct-or-union-specifier>
    T[0] = mktuple(AST_basic_type_specifier, alt /*5*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 6) {
    T[1] = build_ast(A[ap+0], depth+1); // <enum-specifier>
    T[0] = mktuple(AST_basic_type_specifier, alt /*6*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_void, A[ap+0]);
    T[0] = mktuple(AST_basic_type_specifier, alt /*7*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<enum-specifier> = 
//\\    "enum" '{' <enumerator-list> '}',
//\\    "enum" <identifier> '{' <enumerator-list> '}',
//\\    "enum" <identifier>;

case P_enum_specifier:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_enum, A[ap+0]);  
    T[2] = lit(AST__LIT, '{', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <enumerator-list>  
    T[4] = lit(AST__LIT, '}', A[ap+3]);
    T[0] = mktuple(AST_enum_specifier, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_enum, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <identifier>  
    T[3] = lit(AST__LIT, '{', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <enumerator-list>  
    T[5] = lit(AST__LIT, '}', A[ap+4]);
    T[0] = mktuple(AST_enum_specifier, alt /*1*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_enum, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <identifier>
    T[0] = mktuple(AST_enum_specifier, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<enumerator-list> = 
//\\    <enumerator> <rest-of-enumerator-list>;

case P_enumerator_list:
  T[1] = build_ast(A[ap+0], depth+1); // <enumerator>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-enumerator-list>
  return mktuple(AST_enumerator_list, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-enumerator-list> = 
//\\    ',' <enumerator> <rest-of-enumerator-list>,
//\\    ',',
//\\   ;

case P_rest_of_enumerator_list:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <enumerator>
    T[3] = build_ast(A[ap+2], depth+1); // <rest-of-enumerator-list>
    T[0] = mktuple(AST_rest_of_enumerator_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[0] = mktuple(AST_rest_of_enumerator_list, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_enumerator_list, alt /*2*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<enumerator> = 
//\\    <identifier> '=' <constant-expression>,
//\\    <identifier>;

case P_enumerator:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <identifier>  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <constant-expression>
    T[0] = mktuple(AST_enumerator, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <identifier>
    T[0] = mktuple(AST_enumerator, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<constant-expression> = 
//\\    <conditional-expression>;

case P_constant_expression:
  T[1] = build_ast(A[ap+0], depth+1); // <conditional-expression>
  return mktuple(AST_constant_expression, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);


//\\ # does this omit "signed int"? - check, and add <opt-signed> "int" if needed...

//\\ P<opt-signed-inttype> = 
//\\    <opt-signed> "short" <opt-int>,
//\\    <opt-signed> "long" "long" <opt-int>,
//\\    <opt-signed> "long" <opt-int>,
//\\    <opt-signed> "int",
//\\    "signed",
//\\    "unsigned";

case P_opt_signed_inttype:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <opt-signed>  
    T[2] = kw(AST__KW, KW_short, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <opt-int>
    T[0] = mktuple(AST_opt_signed_inttype, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <opt-signed>  
    T[2] = kw(AST__KW, KW_long, A[ap+1]);  
    T[3] = kw(AST__KW, KW_long, A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <opt-int>
    T[0] = mktuple(AST_opt_signed_inttype, 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-signed>  
    T[2] = kw(AST__KW, KW_long, A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <opt-int>
    T[0] = mktuple(AST_opt_signed_inttype, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 3) {
    T[1] = build_ast(A[ap+0], depth+1); // <opt-signed>  
    T[2] = kw(AST__KW, KW_int, A[ap+1]);
    T[0] = mktuple(AST_opt_signed_inttype, alt /*3*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 4) {  
    T[1] = kw(AST__KW, KW_signed, A[ap+0]);
    T[0] = mktuple(AST_opt_signed_inttype, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_unsigned, A[ap+0]);
    T[0] = mktuple(AST_opt_signed_inttype, alt /*5*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<opt-int> = 
//\\    "int",
//\\   ;

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




//\\ P<opt-signed> = 
//\\    "signed",
//\\    "unsigned",
//\\   ;

case P_opt_signed:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_signed, A[ap+0]);
    T[0] = mktuple(AST_opt_signed, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_unsigned, A[ap+0]);
    T[0] = mktuple(AST_opt_signed, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_opt_signed, alt /*2*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<address-operator> = 
//\\    '&';

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



//\\ P<pre-increment-op> = 
//\\    <pp>,
//\\    <mm>;

case P_pre_increment_op:
  if (alt == 0)        {
    T[1] = bip(AST_pp, A[ap+0]);
    T[0] = mktuple(AST_pre_increment_op, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = bip(AST_mm, A[ap+0]);
    T[0] = mktuple(AST_pre_increment_op, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<optionally-cast-unary-rvalue-expression> = 
//\\    <cast> <optionally-cast-unary-rvalue-expression>,
//\\    <unary-rvalue-expression>;

case P_optionally_cast_unary_rvalue_expression:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <cast>
    T[2] = build_ast(A[ap+1], depth+1); // <optionally-cast-unary-rvalue-expression>
    T[0] = mktuple(AST_optionally_cast_unary_rvalue_expression, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <unary-rvalue-expression>
    T[0] = mktuple(AST_optionally_cast_unary_rvalue_expression, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<bitwise-unary-ops> = 
//\\    '~' <rest-of-bitwise-unary-ops>;

case P_bitwise_unary_ops:
  T[1] = lit(AST__LIT, '~', A[ap+0]);
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-bitwise-unary-ops>
  return mktuple(AST_bitwise_unary_ops, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-bitwise-unary-ops> = 
//\\    '~' <rest-of-bitwise-unary-ops>,
//\\   ;

case P_rest_of_bitwise_unary_ops:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '~', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <rest-of-bitwise-unary-ops>
    T[0] = mktuple(AST_rest_of_bitwise_unary_ops, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_bitwise_unary_ops, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<boolean-unary-ops> = 
//\\    '!' <rest-of-boolean-unary-ops>;

case P_boolean_unary_ops:
  T[1] = lit(AST__LIT, '!', A[ap+0]);
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-boolean-unary-ops>
  return mktuple(AST_boolean_unary_ops, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-boolean-unary-ops> = 
//\\    '!' <rest-of-boolean-unary-ops>,
//\\   ;

case P_rest_of_boolean_unary_ops:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '!', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <rest-of-boolean-unary-ops>
    T[0] = mktuple(AST_rest_of_boolean_unary_ops, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_boolean_unary_ops, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<arithmetic-unary-op> = 
//\\    '+',
//\\    '-';

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




//\\ P<mulop> = 
//\\    '*',
//\\    '/',
//\\    '%';

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




//\\ P<plusminus> = 
//\\    '+',
//\\    '-';

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




//\\ P<shiftop> = 
//\\    '<' '<',
//\\    '>' '>';

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




//\\ P<relop> = 
//\\    '<' '=',
//\\    '<',
//\\    '>' '=',
//\\    '>';

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




//\\ P<eqop> = 
//\\    <eqeq>,
//\\    '!' '=';

case P_eqop:
  if (alt == 0)        {
    T[1] = bip(AST_eqeq, A[ap+0]);
    T[0] = mktuple(AST_eqop, 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_eqop, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<assignment-operator> = 
//\\    '=',
//\\    '*' '=',
//\\    '/' '=',
//\\    '%' '=',
//\\    '+' '=',
//\\    '-' '=',
//\\    '<' '<' '=',
//\\    '>' '>' '=',
//\\    '&' '=',
//\\    '^' '=',
//\\    '|' '=';

case P_assignment_operator:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '=', A[ap+0]);
    T[0] = mktuple(AST_assignment_operator, 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_assignment_operator, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 2) {  
    T[1] = lit(AST__LIT, '/', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_assignment_operator, 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_assignment_operator, 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_assignment_operator, alt /*4*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 5) {  
    T[1] = lit(AST__LIT, '-', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_assignment_operator, alt /*5*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 6) {  
    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_assignment_operator, alt /*6*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 7) {  
    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_assignment_operator, alt /*7*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 8) {  
    T[1] = lit(AST__LIT, '&', A[ap+0]);  
    T[2] = lit(AST__LIT, '=', A[ap+1]);
    T[0] = mktuple(AST_assignment_operator, 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_assignment_operator, alt /*9*/, /*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_assignment_operator, alt /*10*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  }
  return T[0];




//\\ P<opt-lvalue-assign> = 
//\\    <unary-lvalue-expression> <assignment-operator>,
//\\   ;

case P_opt_lvalue_assign:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <unary-lvalue-expression>
    T[2] = build_ast(A[ap+1], depth+1); // <assignment-operator>
    T[0] = mktuple(AST_opt_lvalue_assign, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_opt_lvalue_assign, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<opt-array-init> = 
//\\    '=' '{' <constant-initializer-list> '}',
//\\    '=' <dqstring>,
//\\   ;

case P_opt_array_init:
  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); // <constant-initializer-list>  
    T[4] = lit(AST__LIT, '}', A[ap+3]);
    T[0] = mktuple(AST_opt_array_init, 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] = bip(AST_dqstring, A[ap+1]);
    T[0] = mktuple(AST_opt_array_init, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_opt_array_init, alt /*2*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<constant-initializer-list> = 
//\\    <constant-initializer> <rest-of-constant-initializer-list>;

case P_constant_initializer_list:
  T[1] = build_ast(A[ap+0], depth+1); // <constant-initializer>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-constant-initializer-list>
  return mktuple(AST_constant_initializer_list, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-constant-initializer-list> = 
//\\    ',' <constant-initializer> <rest-of-constant-initializer-list>,
//\\    ',',
//\\   ;

case P_rest_of_constant_initializer_list:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <constant-initializer>
    T[3] = build_ast(A[ap+2], depth+1); // <rest-of-constant-initializer-list>
    T[0] = mktuple(AST_rest_of_constant_initializer_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[0] = mktuple(AST_rest_of_constant_initializer_list, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_constant_initializer_list, alt /*2*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<constant-initializer> = 
//\\    <constant-expression>,
//\\    '{' <constant-initializer-list> '}';

case P_constant_initializer:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <constant-expression>
    T[0] = mktuple(AST_constant_initializer, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = lit(AST__LIT, '{', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <constant-initializer-list>  
    T[3] = lit(AST__LIT, '}', A[ap+2]);
    T[0] = mktuple(AST_constant_initializer, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  }
  return T[0];




//\\ P<array-bounds> = 
//\\    '[' <opt-constant-expression> ']' <opt-array-bounds>;

case P_array_bounds:
  T[1] = lit(AST__LIT, '[', A[ap+0]);
  T[2] = build_ast(A[ap+1], depth+1); // <opt-constant-expression>
  T[3] = lit(AST__LIT, ']', A[ap+2]);
  T[4] = build_ast(A[ap+3], depth+1); // <opt-array-bounds>
  return mktuple(AST_array_bounds, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);



//\\ P<opt-array-bounds> = 
//\\    '[' <opt-constant-expression> ']' <opt-array-bounds>,
//\\   ;

case P_opt_array_bounds:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '[', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <opt-constant-expression>  
    T[3] = lit(AST__LIT, ']', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <opt-array-bounds>
    T[0] = mktuple(AST_opt_array_bounds, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[0] = mktuple(AST_opt_array_bounds, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<opt-constant-expression> = 
//\\    <constant-expression>,
//\\   ;

case P_opt_constant_expression:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <constant-expression>
    T[0] = mktuple(AST_opt_constant_expression, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_opt_constant_expression, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<type> = 
//\\    <enum-specifier>,
//\\    <struct-or-union-specifier>,
//\\    "typeof" '(' <unary-lvalue-expression> ')',
//\\    "typeof" '(' <type-specifier> <opt-indirection-unary-ops> ')',
//\\    <basic-type-specifier>,
//\\    <typedef-name>,
//\\    "void";

case P_type:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <enum-specifier>
    T[0] = mktuple(AST_type, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <struct-or-union-specifier>
    T[0] = mktuple(AST_type, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = kw(AST__KW, KW_typeof, A[ap+0]);  
    T[2] = lit(AST__LIT, '(', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <unary-lvalue-expression>  
    T[4] = lit(AST__LIT, ')', A[ap+3]);
    T[0] = mktuple(AST_type, alt /*2*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 3) {  
    T[1] = kw(AST__KW, KW_typeof, A[ap+0]);  
    T[2] = lit(AST__LIT, '(', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <type-specifier>
    T[4] = build_ast(A[ap+3], depth+1); // <opt-indirection-unary-ops>  
    T[5] = lit(AST__LIT, ')', A[ap+4]);
    T[0] = mktuple(AST_type, alt /*3*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else if (alt == 4) {
    T[1] = build_ast(A[ap+0], depth+1); // <basic-type-specifier>
    T[0] = mktuple(AST_type, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 5) {
    T[1] = build_ast(A[ap+0], depth+1); // <typedef-name>
    T[0] = mktuple(AST_type, alt /*5*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_void, A[ap+0]);
    T[0] = mktuple(AST_type, alt /*6*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<opt-const-or-volatile-type-qualifier> = 
//\\    <const-or-volatile-type-qualifier>,
//\\   ;

case P_opt_const_or_volatile_type_qualifier:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <const-or-volatile-type-qualifier>
    T[0] = mktuple(AST_opt_const_or_volatile_type_qualifier, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_opt_const_or_volatile_type_qualifier, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<const-or-volatile-type-qualifier> = 
//\\    "const",
//\\    "volatile";

case P_const_or_volatile_type_qualifier:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_const, A[ap+0]);
    T[0] = mktuple(AST_const_or_volatile_type_qualifier, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_volatile, A[ap+0]);
    T[0] = mktuple(AST_const_or_volatile_type_qualifier, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<opt-auto-reg-static-ext> = 
//\\    "auto",
//\\    "register",
//\\    "static",
//\\    "extern",
//\\   ;

case P_opt_auto_reg_static_ext:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_auto, A[ap+0]);
    T[0] = mktuple(AST_opt_auto_reg_static_ext, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_register, A[ap+0]);
    T[0] = mktuple(AST_opt_auto_reg_static_ext, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {  
    T[1] = kw(AST__KW, KW_static, A[ap+0]);
    T[0] = mktuple(AST_opt_auto_reg_static_ext, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 3) {  
    T[1] = kw(AST__KW, KW_extern, A[ap+0]);
    T[0] = mktuple(AST_opt_auto_reg_static_ext, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_opt_auto_reg_static_ext, alt /*4*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<identifier-list> = 
//\\    <identifier> <rest-of-identifier-list>;

case P_identifier_list:
  T[1] = build_ast(A[ap+0], depth+1); // <identifier>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-identifier-list>
  return mktuple(AST_identifier_list, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-identifier-list> = 
//\\    ',' <identifier-list>,
//\\   ;

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




//\\ P<more-forward-decls-or-actual-body> = 
//\\    <opt-extern-proc-name-and-params-list> ';',
//\\    <compound-statement>;

case P_more_forward_decls_or_actual_body:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <opt-extern-proc-name-and-params-list>  
    T[2] = lit(AST__LIT, ';', A[ap+1]);
    T[0] = mktuple(AST_more_forward_decls_or_actual_body, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <compound-statement>
    T[0] = mktuple(AST_more_forward_decls_or_actual_body, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<extern-proc-spec> = 
//\\    <opt-auto-reg-static-ext> <opt-const-or-volatile-type-qualifier> <opt-basic-type-specifier-or-typedef-name>;

case P_extern_proc_spec:
  T[1] = build_ast(A[ap+0], depth+1); // <opt-auto-reg-static-ext>
  T[2] = build_ast(A[ap+1], depth+1); // <opt-const-or-volatile-type-qualifier>
  T[3] = build_ast(A[ap+2], depth+1); // <opt-basic-type-specifier-or-typedef-name>
  return mktuple(AST_extern_proc_spec, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);



//\\ P<opt-basic-type-specifier-or-typedef-name> = 
//\\    <opt-basic-type-specifier>,
//\\    <typedef-name>;

case P_opt_basic_type_specifier_or_typedef_name:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <opt-basic-type-specifier>
    T[0] = mktuple(AST_opt_basic_type_specifier_or_typedef_name, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <typedef-name>
    T[0] = mktuple(AST_opt_basic_type_specifier_or_typedef_name, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<identifier-or-function-pointer> = 
//\\    '(' '*' <identifier> ')',
//\\    <identifier>;

case P_identifier_or_function_pointer:
  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); // <identifier>  
    T[4] = lit(AST__LIT, ')', A[ap+3]);
    T[0] = mktuple(AST_identifier_or_function_pointer, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <identifier>
    T[0] = mktuple(AST_identifier_or_function_pointer, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<extern-proc-name-and-params> = 
//\\    <opt-indirection-decl> <identifier-or-function-pointer> '(' <opt-param-list> ')';

case P_extern_proc_name_and_params:
  T[1] = build_ast(A[ap+0], depth+1); // <opt-indirection-decl>
  T[2] = build_ast(A[ap+1], depth+1); // <identifier-or-function-pointer>
  T[3] = lit(AST__LIT, '(', A[ap+2]);
  T[4] = build_ast(A[ap+3], depth+1); // <opt-param-list>
  T[5] = lit(AST__LIT, ')', A[ap+4]);
  return mktuple(AST_extern_proc_name_and_params, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);



//\\ P<opt-extern-proc-name-and-params-list> = 
//\\    ',' <extern-proc-name-and-params> <opt-extern-proc-name-and-params-list>,
//\\   ;

case P_opt_extern_proc_name_and_params_list:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <extern-proc-name-and-params>
    T[3] = build_ast(A[ap+2], depth+1); // <opt-extern-proc-name-and-params-list>
    T[0] = mktuple(AST_opt_extern_proc_name_and_params_list, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_opt_extern_proc_name_and_params_list, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<proc-fn-decl> = 
//\\    <extern-proc-spec> <extern-proc-name-and-params> <more-forward-decls-or-actual-body>,
//\\    <extern-proc-spec> <opt-indirection-decl> <identifier> '(' <identifier-list> ')' <opt-oldstyle-param-list> ';' <compound-statement>;

case P_proc_fn_decl:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <extern-proc-spec>
    T[2] = build_ast(A[ap+1], depth+1); // <extern-proc-name-and-params>
    T[3] = build_ast(A[ap+2], depth+1); // <more-forward-decls-or-actual-body>
    T[0] = mktuple(AST_proc_fn_decl, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <extern-proc-spec>
    T[2] = build_ast(A[ap+1], depth+1); // <opt-indirection-decl>
    T[3] = build_ast(A[ap+2], depth+1); // <identifier>  
    T[4] = lit(AST__LIT, '(', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <identifier-list>  
    T[6] = lit(AST__LIT, ')', A[ap+5]);
    T[7] = build_ast(A[ap+6], depth+1); // <opt-oldstyle-param-list>  
    T[8] = lit(AST__LIT, ';', A[ap+7]);
    T[9] = build_ast(A[ap+8], depth+1); // <compound-statement>
    T[0] = mktuple(AST_proc_fn_decl, alt /*1*/, /*phrases*/ 9, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9]*/);
  }
  return T[0];




//\\ P<compound-statement> = 
//\\    '{' '}',
//\\    '{' <statement-list> '}';

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



//\\ # Actually I don't think declarations inside a block are allowed
//\\ # to be preceded by labels.
//\\ # So the three lines below (which are in P<statement>) probably should
//\\ # be separated out and put in <statement-list> below separately from the
//\\ # options which can have <opt-labels> in front of them.
//\\ #
//\\ #   <extern-proc-spec> <extern-proc-name-and-params> <more-forward-decls-or-actual-body>,
//\\ #   <in-proc-data-declaration>,
//\\ #   <opt-external-declaration-list>;
//\\ # Also still to add are label declarations (inside blocks):
//\\ # P<label-declaration> =
//\\ #    "__label__" <identifier-list> ';';
//\\ # (I'm not sure if "label" as a keyword is valid too, or does it have to be #define'd as __label__ ?

//\\ P<statement-list> = 
//\\    <opt-labels> <statement> <rest-of-statement-list>;

case P_statement_list:
  T[1] = build_ast(A[ap+0], depth+1); // <opt-labels>
  T[2] = build_ast(A[ap+1], depth+1); // <statement>
  T[3] = build_ast(A[ap+2], depth+1); // <rest-of-statement-list>
  return mktuple(AST_statement_list, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);



//\\ P<rest-of-statement-list> = 
//\\    <opt-labels> <statement> <rest-of-statement-list>,
//\\   ;

case P_rest_of_statement_list:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <opt-labels>
    T[2] = build_ast(A[ap+1], depth+1); // <statement>
    T[3] = build_ast(A[ap+2], depth+1); // <rest-of-statement-list>
    T[0] = mktuple(AST_rest_of_statement_list, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_statement_list, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # added as a test: <extern-proc-spec> <extern-proc-name-and-params> <more-forward-decls-or-actual-body>,

//\\ P<statement> = 
//\\    ';',
//\\    <compound-statement>,
//\\    <selection-statement>,
//\\    <iteration-statement>,
//\\    <jump-statement>,
//\\    <expression> ';',
//\\    <extern-proc-spec> <extern-proc-name-and-params> <more-forward-decls-or-actual-body>,
//\\    <in-proc-data-declaration>,
//\\    <opt-external-declaration-list>;

case P_statement:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ';', A[ap+0]);
    T[0] = mktuple(AST_statement, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <compound-statement>
    T[0] = mktuple(AST_statement, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1); // <selection-statement>
    T[0] = mktuple(AST_statement, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 3) {
    T[1] = build_ast(A[ap+0], depth+1); // <iteration-statement>
    T[0] = mktuple(AST_statement, alt /*3*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 4) {
    T[1] = build_ast(A[ap+0], depth+1); // <jump-statement>
    T[0] = mktuple(AST_statement, alt /*4*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 5) {
    T[1] = build_ast(A[ap+0], depth+1); // <expression>  
    T[2] = lit(AST__LIT, ';', A[ap+1]);
    T[0] = mktuple(AST_statement, alt /*5*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 6) {
    T[1] = build_ast(A[ap+0], depth+1); // <extern-proc-spec>
    T[2] = build_ast(A[ap+1], depth+1); // <extern-proc-name-and-params>
    T[3] = build_ast(A[ap+2], depth+1); // <more-forward-decls-or-actual-body>
    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); // <in-proc-data-declaration>
    T[0] = mktuple(AST_statement, alt /*7*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <opt-external-declaration-list>
    T[0] = mktuple(AST_statement, alt /*8*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<in-proc-data-declaration> = 
//\\    <opt-auto-reg-static-ext> <opt-const-or-volatile-type-qualifier> <type> <decl-list>,
//\\    <struct-decl>;

case P_in_proc_data_declaration:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <opt-auto-reg-static-ext>
    T[2] = build_ast(A[ap+1], depth+1); // <opt-const-or-volatile-type-qualifier>
    T[3] = build_ast(A[ap+2], depth+1); // <type>
    T[4] = build_ast(A[ap+3], depth+1); // <decl-list>
    T[0] = mktuple(AST_in_proc_data_declaration, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <struct-decl>
    T[0] = mktuple(AST_in_proc_data_declaration, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<struct-decl> = 
//\\    "struct" <new-structname> '{' <struct-member-list> '}';

case P_struct_decl:
  T[1] = kw(AST__KW, KW_struct, A[ap+0]);
  T[2] = build_ast(A[ap+1], depth+1); // <new-structname>
  T[3] = lit(AST__LIT, '{', A[ap+2]);
  T[4] = build_ast(A[ap+3], depth+1); // <struct-member-list>
  T[5] = lit(AST__LIT, '}', A[ap+4]);
  return mktuple(AST_struct_decl, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);



//\\ P<struct-member-list> = 
//\\    <struct-member-declaration> <struct-member-list>,
//\\   ;

case P_struct_member_list:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <struct-member-declaration>
    T[2] = build_ast(A[ap+1], depth+1); // <struct-member-list>
    T[0] = mktuple(AST_struct_member_list, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_struct_member_list, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<struct-member-declaration> = 
//\\    <struct-decl>,
//\\    <possibly-initialised-scalar-decl>,
//\\    <possibly-initialised-array-decl>;

case P_struct_member_declaration:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <struct-decl>
    T[0] = mktuple(AST_struct_member_declaration, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1); // <possibly-initialised-scalar-decl>
    T[0] = mktuple(AST_struct_member_declaration, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <possibly-initialised-array-decl>
    T[0] = mktuple(AST_struct_member_declaration, alt /*2*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<possibly-initialised-array-decl> = 
//\\    <opt-auto-reg-static-ext> <opt-const-or-volatile-type-qualifier> <type> <opt-indirection-decl> <identifier> <array-bounds> <opt-array-init> ';';

case P_possibly_initialised_array_decl:
  T[1] = build_ast(A[ap+0], depth+1); // <opt-auto-reg-static-ext>
  T[2] = build_ast(A[ap+1], depth+1); // <opt-const-or-volatile-type-qualifier>
  T[3] = build_ast(A[ap+2], depth+1); // <type>
  T[4] = build_ast(A[ap+3], depth+1); // <opt-indirection-decl>
  T[5] = build_ast(A[ap+4], depth+1); // <identifier>
  T[6] = build_ast(A[ap+5], depth+1); // <array-bounds>
  T[7] = build_ast(A[ap+6], depth+1); // <opt-array-init>
  T[8] = lit(AST__LIT, ';', A[ap+7]);
  return mktuple(AST_possibly_initialised_array_decl, alt /*0*/, /*phrases*/ 8, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8]*/);



//\\ P<possibly-initialised-scalar-decl> = 
//\\    <opt-auto-reg-static-ext> <opt-const-or-volatile-type-qualifier> <type> <rest-of-scalar-decl>;

case P_possibly_initialised_scalar_decl:
  T[1] = build_ast(A[ap+0], depth+1); // <opt-auto-reg-static-ext>
  T[2] = build_ast(A[ap+1], depth+1); // <opt-const-or-volatile-type-qualifier>
  T[3] = build_ast(A[ap+2], depth+1); // <type>
  T[4] = build_ast(A[ap+3], depth+1); // <rest-of-scalar-decl>
  return mktuple(AST_possibly_initialised_scalar_decl, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);



//\\ P<rest-of-scalar-decl> = 
//\\    <opt-indirection-decl> <identifier> <opt-scalar-init> <opt-rest-of-scalar-decl> ';';

case P_rest_of_scalar_decl:
  T[1] = build_ast(A[ap+0], depth+1); // <opt-indirection-decl>
  T[2] = build_ast(A[ap+1], depth+1); // <identifier>
  T[3] = build_ast(A[ap+2], depth+1); // <opt-scalar-init>
  T[4] = build_ast(A[ap+3], depth+1); // <opt-rest-of-scalar-decl>
  T[5] = lit(AST__LIT, ';', A[ap+4]);
  return mktuple(AST_rest_of_scalar_decl, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);



//\\ P<opt-rest-of-scalar-decl> = 
//\\    ',' <opt-indirection-decl> <identifier> <opt-scalar-init> <opt-rest-of-scalar-decl>,
//\\   ;

case P_opt_rest_of_scalar_decl:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <opt-indirection-decl>
    T[3] = build_ast(A[ap+2], depth+1); // <identifier>
    T[4] = build_ast(A[ap+3], depth+1); // <opt-scalar-init>
    T[5] = build_ast(A[ap+4], depth+1); // <opt-rest-of-scalar-decl>
    T[0] = mktuple(AST_opt_rest_of_scalar_decl, alt /*0*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  } else               {
    T[0] = mktuple(AST_opt_rest_of_scalar_decl, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<new-structname> = 
//\\    <identifier>;

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



//\\ P<decl-list> = 
//\\    <decl> <rest-of-decl-list>;

case P_decl_list:
  T[1] = build_ast(A[ap+0], depth+1); // <decl>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-decl-list>
  return mktuple(AST_decl_list, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-decl-list> = 
//\\    ',' <decl-list>,
//\\   ;

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




//\\ P<decl> = 
//\\    <opt-indirection-decl> <identifier> <possibly-empty-array-bounds-list> <opt-array-init>,
//\\    <opt-indirection-decl> <identifier> <opt-scalar-init>;

case P_decl:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <opt-indirection-decl>
    T[2] = build_ast(A[ap+1], depth+1); // <identifier>
    T[3] = build_ast(A[ap+2], depth+1); // <possibly-empty-array-bounds-list>
    T[4] = build_ast(A[ap+3], depth+1); // <opt-array-init>
    T[0] = mktuple(AST_decl, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <opt-indirection-decl>
    T[2] = build_ast(A[ap+1], depth+1); // <identifier>
    T[3] = build_ast(A[ap+2], depth+1); // <opt-scalar-init>
    T[0] = mktuple(AST_decl, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  }
  return T[0];




//\\ P<possibly-empty-array-bounds-list> = 
//\\    '[' <opt-constant-expression> ']' <optional-possibly-empty-array-bounds-list>;

case P_possibly_empty_array_bounds_list:
  T[1] = lit(AST__LIT, '[', A[ap+0]);
  T[2] = build_ast(A[ap+1], depth+1); // <opt-constant-expression>
  T[3] = lit(AST__LIT, ']', A[ap+2]);
  T[4] = build_ast(A[ap+3], depth+1); // <optional-possibly-empty-array-bounds-list>
  return mktuple(AST_possibly_empty_array_bounds_list, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);



//\\ P<optional-possibly-empty-array-bounds-list> = 
//\\    '[' <opt-constant-expression> ']' <optional-possibly-empty-array-bounds-list>,
//\\   ;

case P_optional_possibly_empty_array_bounds_list:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, '[', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <opt-constant-expression>  
    T[3] = lit(AST__LIT, ']', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <optional-possibly-empty-array-bounds-list>
    T[0] = mktuple(AST_optional_possibly_empty_array_bounds_list, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[0] = mktuple(AST_optional_possibly_empty_array_bounds_list, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<jump-statement> = 
//\\    "goto" <label> ';',
//\\    "continue" ';',
//\\    "break" ';',
//\\    "return" <opt-expression> ';';

case P_jump_statement:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_goto, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <label>  
    T[3] = lit(AST__LIT, ';', A[ap+2]);
    T[0] = mktuple(AST_jump_statement, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_continue, A[ap+0]);  
    T[2] = lit(AST__LIT, ';', A[ap+1]);
    T[0] = mktuple(AST_jump_statement, alt /*1*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 2) {  
    T[1] = kw(AST__KW, KW_break, A[ap+0]);  
    T[2] = lit(AST__LIT, ';', A[ap+1]);
    T[0] = mktuple(AST_jump_statement, alt /*2*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_return, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <opt-expression>  
    T[3] = lit(AST__LIT, ';', A[ap+2]);
    T[0] = mktuple(AST_jump_statement, alt /*3*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  }
  return T[0];




//\\ P<opt-expression> = 
//\\    <expression>,
//\\   ;

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




//\\ P<label> = 
//\\    <identifier>;

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



//\\ P<iteration-statement> = 
//\\    "while" '(' <expression> ')' <statement>,
//\\    "do" <statement> "while" '(' <expression> ')' ';',
//\\    "for" '(' <opt-expression> ';' <opt-expression> ';' <opt-expression> ')' <statement>;

case P_iteration_statement:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_while, A[ap+0]);  
    T[2] = lit(AST__LIT, '(', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <expression>  
    T[4] = lit(AST__LIT, ')', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <statement>
    T[0] = mktuple(AST_iteration_statement, 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_do, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <statement>  
    T[3] = kw(AST__KW, KW_while, A[ap+2]);  
    T[4] = lit(AST__LIT, '(', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <expression>  
    T[6] = lit(AST__LIT, ')', A[ap+5]);  
    T[7] = lit(AST__LIT, ';', A[ap+6]);
    T[0] = mktuple(AST_iteration_statement, 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_for, A[ap+0]);  
    T[2] = lit(AST__LIT, '(', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <opt-expression>  
    T[4] = lit(AST__LIT, ';', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <opt-expression>  
    T[6] = lit(AST__LIT, ';', A[ap+5]);
    T[7] = build_ast(A[ap+6], depth+1); // <opt-expression>  
    T[8] = lit(AST__LIT, ')', A[ap+7]);
    T[9] = build_ast(A[ap+8], depth+1); // <statement>
    T[0] = mktuple(AST_iteration_statement, alt /*2*/, /*phrases*/ 9, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9]*/);
  }
  return T[0];




//\\ P<selection-statement> = 
//\\    "if" '(' <expression> ')' <statement> <opt-else>,
//\\    "switch" '(' <expression> ')' <statement>;

case P_selection_statement:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_if, A[ap+0]);  
    T[2] = lit(AST__LIT, '(', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <expression>  
    T[4] = lit(AST__LIT, ')', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <statement>
    T[6] = build_ast(A[ap+5], depth+1); // <opt-else>
    T[0] = mktuple(AST_selection_statement, alt /*0*/, /*phrases*/ 6, T /*T[1], T[2], T[3], T[4], T[5], T[6]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_switch, A[ap+0]);  
    T[2] = lit(AST__LIT, '(', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <expression>  
    T[4] = lit(AST__LIT, ')', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <statement>
    T[0] = mktuple(AST_selection_statement, alt /*1*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  }
  return T[0];




//\\ P<opt-else> = 
//\\    "else" <statement>,
//\\   ;

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



//\\ # guard to give better error on "label: }" which should be "label: ; }"

//\\ P<missing-semicolon-after-label-at-end-of-block> = 
//\\    '}';

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



//\\ P<opt-labels> = 
//\\    <label> ':' <opt-labels> <!missing-semicolon-after-label-at-end-of-block>,
//\\    "case" <constant-expression> ':' <opt-labels> <!missing-semicolon-after-label-at-end-of-block>,
//\\    "default" ':' <opt-labels> <!missing-semicolon-after-label-at-end-of-block>,
//\\   ;

case P_opt_labels:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <label>  
    T[2] = lit(AST__LIT, ':', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <opt-labels>
    T[4] = -1; // <!missing-semicolon-after-label-at-end-of-block>
    T[0] = mktuple(AST_opt_labels, alt /*0*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_case, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <constant-expression>  
    T[3] = lit(AST__LIT, ':', A[ap+2]);
    T[4] = build_ast(A[ap+3], depth+1); // <opt-labels>
    T[5] = -1; // <!missing-semicolon-after-label-at-end-of-block>
    T[0] = mktuple(AST_opt_labels, 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_default, A[ap+0]);  
    T[2] = lit(AST__LIT, ':', A[ap+1]);
    T[3] = build_ast(A[ap+2], depth+1); // <opt-labels>
    T[4] = -1; // <!missing-semicolon-after-label-at-end-of-block>
    T[0] = mktuple(AST_opt_labels, alt /*2*/, /*phrases*/ 4, T /*T[1], T[2], T[3], T[4]*/);
  } else               {
    T[0] = mktuple(AST_opt_labels, alt /*3*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # formal parameter list can also be just a list of types (but can still end in "...")
//\\ # normal current style however is to have named parameters.
//\\ #

//\\ P<opt-param-list> = 
//\\    <formal-param> <opt-rest-of-param-list>,
//\\    "void",
//\\   ;

case P_opt_param_list:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <formal-param>
    T[2] = build_ast(A[ap+1], depth+1); // <opt-rest-of-param-list>
    T[0] = mktuple(AST_opt_param_list, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else if (alt == 1) {  
    T[1] = kw(AST__KW, KW_void, A[ap+0]);
    T[0] = mktuple(AST_opt_param_list, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_opt_param_list, alt /*2*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<opt-oldstyle-param-list> = 
//\\    <oldstyle-param-list>,
//\\   ;

case P_opt_oldstyle_param_list:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <oldstyle-param-list>
    T[0] = mktuple(AST_opt_oldstyle_param_list, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_opt_oldstyle_param_list, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<oldstyle-param-list> = 
//\\    <oldstyle-formal-param> <opt-rest-of-oldstyle-param-list>,
//\\    "void";

case P_oldstyle_param_list:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <oldstyle-formal-param>
    T[2] = build_ast(A[ap+1], depth+1); // <opt-rest-of-oldstyle-param-list>
    T[0] = mktuple(AST_oldstyle_param_list, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_void, A[ap+0]);
    T[0] = mktuple(AST_oldstyle_param_list, alt /*1*/, /*phrases*/ 1, T /*T[1]*/);
  }
  return T[0];




//\\ P<opt-rest-of-oldstyle-param-list> = 
//\\    ';' <oldstyle-param-list>,
//\\   ;

case P_opt_rest_of_oldstyle_param_list:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ';', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <oldstyle-param-list>
    T[0] = mktuple(AST_opt_rest_of_oldstyle_param_list, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_opt_rest_of_oldstyle_param_list, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<oldstyle-formal-param> = 
//\\    <opt-const-or-volatile-type-qualifier> <type> <oldstyle-parameter-list>;

case P_oldstyle_formal_param:
  T[1] = build_ast(A[ap+0], depth+1); // <opt-const-or-volatile-type-qualifier>
  T[2] = build_ast(A[ap+1], depth+1); // <type>
  T[3] = build_ast(A[ap+2], depth+1); // <oldstyle-parameter-list>
  return mktuple(AST_oldstyle_formal_param, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);



//\\ P<oldstyle-parameter-list> = 
//\\    <whatever> <rest-of-oldstyle-parameter-list>;

case P_oldstyle_parameter_list:
  T[1] = build_ast(A[ap+0], depth+1); // <whatever>
  T[2] = build_ast(A[ap+1], depth+1); // <rest-of-oldstyle-parameter-list>
  return mktuple(AST_oldstyle_parameter_list, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);



//\\ P<rest-of-oldstyle-parameter-list> = 
//\\    ',' <oldstyle-parameter-list>,
//\\   ;

case P_rest_of_oldstyle_parameter_list:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <oldstyle-parameter-list>
    T[0] = mktuple(AST_rest_of_oldstyle_parameter_list, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_oldstyle_parameter_list, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<whatever> = 
//\\    <opt-indirection-decl> <opt-identifier> <optional-possibly-empty-array-bounds-list>;

case P_whatever:
  T[1] = build_ast(A[ap+0], depth+1); // <opt-indirection-decl>
  T[2] = build_ast(A[ap+1], depth+1); // <opt-identifier>
  T[3] = build_ast(A[ap+2], depth+1); // <optional-possibly-empty-array-bounds-list>
  return mktuple(AST_whatever, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);



//\\ P<opt-rest-of-param-list> = 
//\\    ',' '.' '.' '.',
//\\    ',' <formal-param> <opt-rest-of-param-list>,
//\\   ;

case P_opt_rest_of_param_list:
  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_opt_rest_of_param_list, 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] = build_ast(A[ap+1], depth+1); // <formal-param>
    T[3] = build_ast(A[ap+2], depth+1); // <opt-rest-of-param-list>
    T[0] = mktuple(AST_opt_rest_of_param_list, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {
    T[0] = mktuple(AST_opt_rest_of_param_list, alt /*2*/, /*phrases*/ 0, T /**/);
  }
  return T[0];




//\\ P<formal-param> = 
//\\    <procedure-as-parameter>,
//\\    <opt-const-or-volatile-type-qualifier> <type> <opt-indirection-decl> <opt-identifier> <optional-possibly-empty-array-bounds-list>;

case P_formal_param:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <procedure-as-parameter>
    T[0] = mktuple(AST_formal_param, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <opt-const-or-volatile-type-qualifier>
    T[2] = build_ast(A[ap+1], depth+1); // <type>
    T[3] = build_ast(A[ap+2], depth+1); // <opt-indirection-decl>
    T[4] = build_ast(A[ap+3], depth+1); // <opt-identifier>
    T[5] = build_ast(A[ap+4], depth+1); // <optional-possibly-empty-array-bounds-list>
    T[0] = mktuple(AST_formal_param, alt /*1*/, /*phrases*/ 5, T /*T[1], T[2], T[3], T[4], T[5]*/);
  }
  return T[0];




//\\ P<opt-identifier> = 
//\\    <identifier>,
//\\   ;

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




//\\ P<procedure-as-parameter> = 
//\\    <opt-auto-reg-static-ext> <opt-const-or-volatile-type-qualifier> <opt-basic-type-specifier> '(' <opt-indirection-decl> <identifier> ')' '(' <opt-param-list> ')',
//\\    <opt-auto-reg-static-ext> <opt-const-or-volatile-type-qualifier> <typedef-name> '(' <opt-indirection-decl> <identifier> ')' '(' <opt-param-list> ')';

case P_procedure_as_parameter:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <opt-auto-reg-static-ext>
    T[2] = build_ast(A[ap+1], depth+1); // <opt-const-or-volatile-type-qualifier>
    T[3] = build_ast(A[ap+2], depth+1); // <opt-basic-type-specifier>  
    T[4] = lit(AST__LIT, '(', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <opt-indirection-decl>
    T[6] = build_ast(A[ap+5], depth+1); // <identifier>  
    T[7] = lit(AST__LIT, ')', A[ap+6]);  
    T[8] = lit(AST__LIT, '(', A[ap+7]);
    T[9] = build_ast(A[ap+8], depth+1); // <opt-param-list>  
    T[10] = lit(AST__LIT, ')', A[ap+9]);
    T[0] = mktuple(AST_procedure_as_parameter, alt /*0*/, /*phrases*/ 10, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9], T[10]*/);
  } else               {
    T[1] = build_ast(A[ap+0], depth+1); // <opt-auto-reg-static-ext>
    T[2] = build_ast(A[ap+1], depth+1); // <opt-const-or-volatile-type-qualifier>
    T[3] = build_ast(A[ap+2], depth+1); // <typedef-name>  
    T[4] = lit(AST__LIT, '(', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <opt-indirection-decl>
    T[6] = build_ast(A[ap+5], depth+1); // <identifier>  
    T[7] = lit(AST__LIT, ')', A[ap+6]);  
    T[8] = lit(AST__LIT, '(', A[ap+7]);
    T[9] = build_ast(A[ap+8], depth+1); // <opt-param-list>  
    T[10] = lit(AST__LIT, ')', A[ap+9]);
    T[0] = mktuple(AST_procedure_as_parameter, alt /*1*/, /*phrases*/ 10, T /*T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9], T[10]*/);
  }
  return T[0];




//\\ P<opt-basic-type-specifier> = 
//\\    <basic-type-specifier>,
//\\   ;

case P_opt_basic_type_specifier:
  if (alt == 0)        {
    T[1] = build_ast(A[ap+0], depth+1); // <basic-type-specifier>
    T[0] = mktuple(AST_opt_basic_type_specifier, alt /*0*/, /*phrases*/ 1, T /*T[1]*/);
  } else               {
    T[0] = mktuple(AST_opt_basic_type_specifier, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];



//\\ # Wonder if this would do it? <opt-indirection-decl> '(' <opt-indirection-decl> <identifier> ')' '(' <opt-param-list> ')' <opt-scalar-init> <opt-rest-of-scalar-or-array-decl>,

//\\ P<typedef-declaration> = 
//\\    "typedef" <type-specifier> <opt-indirection-decl> '(' <opt-indirection-decl> <identifier> ')' '(' <opt-param-list> ')',
//\\    "typedef" <struct-decl> <maybe-indirect-typedef-name-list>,
//\\    "typedef" <type-specifier> <maybe-indirect-typedef-name-list>;

case P_typedef_declaration:
  if (alt == 0)        {  
    T[1] = kw(AST__KW, KW_typedef, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <type-specifier>
    T[3] = build_ast(A[ap+2], depth+1); // <opt-indirection-decl>  
    T[4] = lit(AST__LIT, '(', A[ap+3]);
    T[5] = build_ast(A[ap+4], depth+1); // <opt-indirection-decl>
    T[6] = build_ast(A[ap+5], depth+1); // <identifier>  
    T[7] = lit(AST__LIT, ')', A[ap+6]);  
    T[8] = lit(AST__LIT, '(', A[ap+7]);
    T[9] = build_ast(A[ap+8], depth+1); // <opt-param-list>  
    T[10] = lit(AST__LIT, ')', A[ap+9]);
    T[0] = mktuple(AST_typedef_declaration, alt /*0*/, /*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 == 1) {  
    T[1] = kw(AST__KW, KW_typedef, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <struct-decl>
    T[3] = build_ast(A[ap+2], depth+1); // <maybe-indirect-typedef-name-list>
    T[0] = mktuple(AST_typedef_declaration, alt /*1*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  } else               {  
    T[1] = kw(AST__KW, KW_typedef, A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <type-specifier>
    T[3] = build_ast(A[ap+2], depth+1); // <maybe-indirect-typedef-name-list>
    T[0] = mktuple(AST_typedef_declaration, alt /*2*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);
  }
  return T[0];




//\\ P<maybe-indirect-typedef-name-list> = 
//\\    <opt-indirection-decl> <typedef-name> <rest-of-maybe-indirect-typedef-name-list>;

case P_maybe_indirect_typedef_name_list:
  T[1] = build_ast(A[ap+0], depth+1); // <opt-indirection-decl>
  T[2] = build_ast(A[ap+1], depth+1); // <typedef-name>
  T[3] = build_ast(A[ap+2], depth+1); // <rest-of-maybe-indirect-typedef-name-list>
  return mktuple(AST_maybe_indirect_typedef_name_list, alt /*0*/, /*phrases*/ 3, T /*T[1], T[2], T[3]*/);



//\\ P<rest-of-maybe-indirect-typedef-name-list> = 
//\\    ',' <maybe-indirect-typedef-name-list>,
//\\   ;

case P_rest_of_maybe_indirect_typedef_name_list:
  if (alt == 0)        {  
    T[1] = lit(AST__LIT, ',', A[ap+0]);
    T[2] = build_ast(A[ap+1], depth+1); // <maybe-indirect-typedef-name-list>
    T[0] = mktuple(AST_rest_of_maybe_indirect_typedef_name_list, alt /*0*/, /*phrases*/ 2, T /*T[1], T[2]*/);
  } else               {
    T[0] = mktuple(AST_rest_of_maybe_indirect_typedef_name_list, alt /*1*/, /*phrases*/ 0, T /**/);
  }
  return T[0];


//\\ E
