char *progname;
static char outname[256];
FILE *outfile;
int debug = (0!=0);
int gram[740] = {
    2, 2, 585, 521, 1, 512, 8, 5, 256, 40, 540, 536, 41, 8, 535, 530,
  583, 40, 527, 41, 525, 524, 6, 530, 583, 40, 527, 41, 525, 3, 583, 525,
  524, 1, 518, 1, 519, 1, 520, 3, 40, 580, 41, 3, 8, 535, 530, 583,
   40, 527, 41, 525, 524, 6, 530, 583, 40, 527, 41, 525, 3, 584, 525, 524,
    3, 1, 514, 1, 515, 0, 4, 4, 91, 580, 93, 525, 3, 46, 583, 525,
    4, 45, 62, 583, 525, 0, 2, 4, 256, 40, 540, 41, 6, 536, 530, 583,
   40, 527, 41, 2, 2, 576, 528, 0, 2, 3, 44, 576, 528, 0, 2, 3,
  535, 530, 522, 1, 523, 2, 1, 534, 0, 2, 2, 532, 523, 2, 533, 522,
    5, 1, 514, 1, 515, 2, 536, 534, 1, 38, 1, 256, 11, 1, 514, 1,
  515, 1, 43, 1, 45, 1, 33, 1, 126, 2, 536, 534, 1, 535, 1, 38,
    1, 256, 0, 1, 4, 40, 540, 536, 41, 1, 2, 42, 536, 2, 1, 535,
    0, 3, 1, 257, 1, 258, 0, 5, 1, 259, 1, 260, 1, 261, 1, 262,
    0, 1, 1, 41, 12, 1, 263, 2, 264, 617, 4, 265, 40, 529, 41, 4,
  541, 266, 266, 267, 3, 541, 266, 266, 3, 541, 266, 267, 2, 541, 266, 2,
  541, 267, 3, 541, 268, 267, 2, 541, 268, 2, 541, 269, 1, 270, 3, 1,
  271, 1, 272, 0, 1, 2, 531, 553, 1, 2, 542, 554, 1, 2, 543, 555,
    1, 2, 544, 556, 1, 2, 545, 557, 1, 2, 546, 558, 1, 2, 547, 559,
    1, 2, 548, 560, 1, 2, 549, 561, 1, 2, 550, 562, 1, 2, 551, 575,
    2, 3, 563, 531, 553, 0, 2, 3, 564, 542, 554, 0, 2, 3, 565, 543,
  555, 0, 2, 3, 566, 544, 556, 0, 2, 3, 567, 545, 557, 0, 2, 3,
  568, 546, 558, 0, 2, 3, 570, 547, 559, 0, 2, 3, 571, 548, 560, 0,
    2, 3, 573, 549, 561, 0, 2, 3, 574, 550, 562, 0, 3, 1, 42, 1,
   47, 1, 37, 2, 1, 43, 1, 45, 2, 2, 60, 60, 2, 62, 62, 4,
    2, 60, 61, 1, 60, 2, 62, 61, 1, 62, 2, 2, 61, 61, 2, 33,
   61, 1, 2, 33337, 38, 1, 2, 38, 38, 1, 1, 94, 1, 2, 33340, 124,
    1, 2, 124, 124, 1, 2, 38, 38, 1, 2, 124, 124, 2, 4, 63, 551,
   58, 552, 0, 1, 2, 578, 552, 1, 2, 61, 61, 2, 4, 529, 33345, 579,
  578, 0, 11, 1, 61, 2, 43, 61, 2, 45, 61, 2, 42, 61, 2, 47,
   61, 2, 37, 61, 2, 38, 61, 2, 94, 61, 2, 124, 61, 3, 60, 60,
   61, 3, 62, 62, 61, 1, 2, 576, 581, 2, 3, 44, 576, 581, 0, 1,
    1, 580, 1, 1, 513, 1, 1, 513, 7, 3, 123, 590, 125, 1, 586, 1,
  593, 1, 588, 1, 613, 1, 615, 1, 616, 3, 3, 583, 58, 585, 4, 273,
  587, 58, 585, 3, 274, 58, 585, 1, 1, 580, 1, 2, 589, 59, 2, 1,
  580, 0, 1, 2, 591, 612, 2, 1, 592, 0, 1, 2, 593, 591, 2, 1,
  594, 2, 595, 596, 1, 5, 264, 617, 123, 592, 125, 1, 4, 538, 537, 540,
  536, 3, 5, 583, 40, 606, 41, 598, 4, 583, 605, 597, 59, 4, 583, 599,
  601, 59, 2, 5, 44, 536, 583, 605, 597, 0, 2, 1, 59, 3, 123, 590,
  125, 1, 4, 91, 610, 93, 600, 2, 4, 91, 610, 93, 600, 0, 2, 4,
   61, 123, 602, 125, 0, 1, 2, 604, 603, 3, 3, 44, 604, 603, 1, 44,
    0, 2, 1, 587, 3, 123, 602, 125, 2, 2, 61, 580, 0, 2, 2, 263,
16923, 2, 608, 607, 2, 3, 44, 608, 607, 0, 1, 4, 540, 536, 583, 609,
    2, 4, 91, 610, 93, 609, 0, 2, 1, 587, 0, 1, 2, 585, 612, 2,
    2, 585, 612, 0, 2, 6, 275, 40, 580, 41, 585, 614, 7, 276, 40, 580,
   41, 123, 590, 125, 2, 2, 277, 585, 0, 3, 5, 278, 40, 580, 41, 585,
    7, 279, 585, 278, 40, 580, 41, 59, 9, 280, 40, 589, 59, 589, 59, 589,
   41, 585, 4, 3, 281, 583, 59, 2, 282, 59, 2, 283, 59, 3, 284, 589,
   59, 1, 1, 513,
};


char *keyword[29] = {
  "sizeof", "const", "volatile", "auto",
  "register", "static", "extern", "void",
  "struct", "typeof", "long", "int",
  "short", "char", "FILE", "unsigned",
  "signed", "case", "default", "if",
  "switch", "else", "while", "do",
  "for", "goto", "continue", "break",
  "return",
};


int BIP[9] = {
 0, 1, 2, 3, 4, 5, 6, 7, 8,
};




char *phrasename[106] = {
  "EOD", "TAG", "PPP", "MMM",
  "CHAR", "KEYWORD", "integer-constant", "character-constant",
  "string-constant", "SS", "level14", "level14-lv",
  "opt-post-ppp-or-mmm", "opt-postfix", "function-call", "opt-argument-list",
  "comma-opt-argument-list", "lvalue", "opt-cast", "level13",
  "prefix-operator-lv", "opt-prefix-operator", "cast", "pointer-seq",
  "opt-pointer-seq", "opt-qualifier", "opt-scope", "closer",
  "type", "signed", "level12", "level11",
  "level10", "level9", "level8", "level7",
  "level6", "level5", "level4", "level3",
  "level2", "opt-level12", "opt-level11", "opt-level10",
  "opt-level9", "opt-level8", "opt-level7", "opt-level6",
  "opt-level5", "opt-level4", "opt-level3", "level12-op",
  "level11-op", "level10-op", "level9-op", "level8-op",
  "level7-op", "ANDAND", "level6-op", "level5-op",
  "OROR", "level4-op", "level3-op", "opt-conditional",
  "level1", "equiv", "opt-assign-list", "assign-op",
  "expression", "opt-comma-level0-list", "rvalue", "identifier",
  "identifier-lv", "statement", "labeled-statement", "constant-expression",
  "expression-statement", "opt-expression", "compound-statement", "opt-declaration-list",
  "declaration-list", "declaration", "struct-decl", "decl",
  "rest-of-decl", "opt-more-scalar-decls", "forward-decl-or-actual-body", "array-bounds",
  "opt-array-bounds", "opt-array-init", "constant-initializer-list", "rest-of-constant-initializer-list",
  "constant-initializer", "opt-scalar-init", "opt-param-list", "opt-rest-of-param-list",
  "param", "opt-empty-array-bounds", "opt-constant-expression", "statement-list",
  "opt-statement-list", "selection-statement", "opt-else-statement", "iteration-statement",
  "jump-statement", "structname",
};


int phrase_start[106 -9] = {
    0, 6, 43, 64, 70, 86, 99,
  104, 110, 117, 121, 128, 140, 163, 169, 173, 177, 183, 193, 196, 238, 244, 248,
  252, 256, 260, 264, 268, 272, 276, 280, 284, 288, 294, 300, 306, 312, 318, 324,
  330, 336, 342, 348, 355, 360, 367, 378, 385, 389, 393, 396, 400, 404, 408, 412,
  419, 423, 427, 434, 469, 473, 479, 482, 485, 488, 505, 519, 522, 526, 530, 534,
  538, 542, 548, 555, 561, 578, 586, 593, 599, 606, 613, 617, 625, 632, 637, 644,
  650, 656, 663, 667, 671, 676, 692, 697, 722, 737,
};
int bestparse = -1;
char *looking_for = "<UNKNOWN>";
  char stringpool[(1024*32)];
  int nextstring = 0;
  int str_to_pool(char *s)
  {
    int tag;
    for (tag = 0; tag <= nextstring; tag++) {
 if (strcmp(stringpool+tag, s) == 0) {
     return tag;
 }
    }
  }
  struct sourceinfo {
    char *s;
    int l;
    int col;
    int t;
    char *f;
  };
  static struct sourceinfo *c = NULL;
  int nextfree = 0, arraysize = 0;
  char *onecharstr;
  static int *A = NULL;
  int next_free_a = 0, a_size = 0;
  FILE *sourcefile;
  char *curfile;
  int startline = (0==0), whitespace = (0==0), lineno = 1, col = 0, ch, peek;
static void *makespace_(void *c, int nextfree, int *arraysize, int objsize) {
  if ((c == NULL) || (*arraysize == 0) || (nextfree == 0)) {
    c = calloc((32*1024), objsize); *arraysize = (32*1024)-1;
  } else if (nextfree >= *arraysize) {
    *arraysize = (*arraysize * 2) + 1;
    c = (void *)realloc(c, (*arraysize+1) * objsize);
  }
  if (c == NULL) {fprintf(stderr, "makespace: %s\n", strerror(errno)); exit(errno);}
  return c;
}
void stores(char *s, int lineno, int col, int type, char *fname) {
  int tag;
  if (nextstring + strlen(s) + 1 >= (1024*32)) exit(1);
  strcpy(stringpool+nextstring, s);
  tag = str_to_pool(s);
  if (tag == nextstring) nextstring += strlen(s)+1;
  c = (typeof(c))makespace_(c, nextfree, &arraysize, sizeof(c[0]));
  c[nextfree].s = stringpool+tag; c[nextfree].l = lineno; c[nextfree].col = col;
  c[nextfree].f = fname; c[nextfree].t = type;
  nextfree++;
}
void storec(int ch, int lineno, int col, int type, char *fname) {
  onecharstr[ch*2] = ch; onecharstr[ch*2+1] = '\0';
  stores(&onecharstr[ch*2], lineno, col, type, fname);
}
int mkliteral(char *s)
{
  int tag;
  if (nextstring + strlen(s) + 1 >= (1024*32)) exit(1);
  strcpy(stringpool+nextstring, s);
  tag = str_to_pool(s);
  if (tag == nextstring) nextstring += strlen(s)+1;
  c = (typeof(c))makespace_(c, nextfree, &arraysize, sizeof(c[0]));
  c[nextfree].s = stringpool+tag; c[nextfree].l = -1; c[nextfree].col = -1;
  c[nextfree].f = ""; c[nextfree].t = 6;
  return nextfree++;
}
int iskeyword(char *s) {
  int i;
  for (i = 0; i < 29; i++) if (strcmp(s, keyword[i]) == 0) return (0==0);
  return (0!=0);
}
static int xfgetc(FILE *f);
static void xungetc(int c, FILE *f);
void line_reconstruction(void)
{
  for (;;) {
    ch = xfgetc(sourcefile); if (ch == EOF) break;
    ch &= 255;
    peek = xfgetc(sourcefile); xungetc(peek, sourcefile);
    if (isalpha(ch) || (ch == '_')) {
        int nextfree = 0, strsize = 0, startcol = col;
        char *token = NULL;
        whitespace = (0!=0);
        for (;;) {
          token = (typeof(token))makespace_(token, nextfree, &strsize, sizeof(token[0]));
          if (isalpha(ch) || isdigit(ch) || (ch == '_')) {
            col++;
            token[nextfree++] = ch;
          } else {
            token[nextfree] = '\0'; xungetc(ch, sourcefile);
            break;
          }
          ch = xfgetc(sourcefile);
        }
        stores(token, lineno, startcol, iskeyword(token) ? 5 : 1, curfile);
        free(token);
    } else if (isdigit(ch)) {
        int nextfree = 0, numsize = 0;
        char *number = NULL;
        whitespace = (0!=0);
        for (;;) {
          number = (typeof(number))makespace_(number, nextfree, &numsize, sizeof(number[0]));
          if (isdigit(ch)) {
            col++;
            number[nextfree++] = ch;
          } else {
            number[nextfree] = '\0'; xungetc(ch, sourcefile);
            break;
          }
          ch = xfgetc(sourcefile);
        }
        stores(number, lineno, col, 6, curfile);
        free(number);
    } else switch (ch) {
    case '"':
    case '\'':
      {
        int nextfree = 0, strsize = 0, quotech = ch;
        char *string = NULL;
        whitespace = (0!=0);
        col++;
        for (;;) {
          ch = xfgetc(sourcefile);
          col++;
          string = (typeof(string))makespace_(string, nextfree, &strsize, sizeof(string[0]));
   if (ch == quotech) {
            string[nextfree] = '\0';
            break;
   } else if (ch == '\\') {
            ch = xfgetc(sourcefile); col++;
            if (ch == '\\') { string[nextfree++] = ch;
            } else if (ch == '\'') { string[nextfree++] = '\'';
            } else if (ch == '"') { string[nextfree++] = '"';
            } else if (ch == 'n') { string[nextfree++] = '\n';
            } else if (ch == 'r') { string[nextfree++] = '\r';
            } else if (ch == 't') { string[nextfree++] = '\t';
            } else {
       string[nextfree++] = '\\'; string[nextfree++] = ch;
            }
          } else {
            string[nextfree++] = ch;
          }
        }
        stores(string, lineno, col, (quotech == '\'' ? 7 : 8), curfile);
        free(string);
      }
      break;
    case '/':
      col++;
      whitespace = (0!=0);
      if (peek == '/') {
        do {ch = xfgetc(sourcefile);} while (ch != '\n');
        lineno++; col = 0; whitespace = (0==0);
      } else if (peek == '*') {
        ch = xfgetc(sourcefile);
        for (;;) {
          col++;
          ch = xfgetc(sourcefile); peek = xfgetc(sourcefile);
          if ((ch == '*') && (peek == '/')) break;
          xungetc(peek, sourcefile);
        }
        col += 2;
        (void)xfgetc(sourcefile);
      } else {
        storec(ch, lineno, col, 4, curfile);
      }
      break;
    case '+':
    case '-':
      whitespace = (0!=0);
      if (peek == ch) {
        ch = xfgetc(sourcefile);
        peek = xfgetc(sourcefile); xungetc(peek, sourcefile);
        if (ch == '+')
          stores("++", lineno, col, 2, curfile);
        else
          stores("--", lineno, col, 3, curfile);
        col++;
      } else storec(ch, lineno, col, 4, curfile);
      col++;
      break;
    case '\n': lineno++;
    case '\r': startline = (0==0); col = 0; whitespace = (0==0);
      break;
    case '\t':
    case ' ': col++;
      break;
    default:
      whitespace = (0!=0);
      storec(ch, lineno, col++, 4, curfile);
    }
  }
  stores("<EOF>", lineno, col, 0, curfile); nextfree--;
}
static char xline[1024];
static int xi = 0, xcur_line = 1;
static void xungetc(int c, FILE *f)
{
    if (xi > 0) {
      xi -= 1;
    } else if (c == '\n') {
      xcur_line -= 1;
      xi = strlen(xline);
    }
    ungetc(c, f);
}
static int xfgetc(FILE *f)
{
  static int last_line = -1;
  int c, ch;
  c = fgetc(f);
  if (c == EOF) return EOF;
  ch = c&255;
  if (ch == '\n') {
    xline[xi] = '\0'; xi = 0;
    if (last_line != xcur_line) {
      strcpy(stringpool+nextstring, xline);
      last_line = xcur_line;
    }
    xcur_line += 1;
  } else xline[xi++] = ch;
  if (xi == 1023) xi = 1022;
  xline[xi] = '\0';
  return c;
}
void showline(int line)
{
  int i, l;
  l = c[0].l;
  for (i = 0; i < nextfree; i++) {
    if (c[i].t == 7) {
      if (c[i].l == line) fprintf(outfile, "'%s' ", c[i].s);
    } else {
      if (c[i].l == line) fprintf(outfile, "%s ", c[i].s);
    }
  }
}
int cp = 0;
int ap = 0;
int parse(int pp, int depth)
{
  int saved_cp, saved_ap, i, gp, alts, match;
  char saved_desc[256];
  gp = phrase_start[pp-512-9];
  alts = gram[gp];
  gp++;
  saved_cp = cp;
  saved_ap = ap;
  for (i = 0; i < alts; i++) {
    int each, phrases = gram[gp++], phrase_count, gap = 0;
    cp = saved_cp;
    ap = saved_ap;
    if (ap+3 > next_free_a) next_free_a = ap+3;
    A = (typeof(A))makespace_(A, next_free_a, &a_size, sizeof(A[0]));
    A[ap++] = pp;
    A[ap++] = i;
    for (each = 0; each < phrases; each++) if (gram[gp+each] >= 512) gap++;
    A[ap++] = gap;
    ap = ap+gap;
    if (saved_ap+3+gap > next_free_a) next_free_a = saved_ap+3+gap;
    A = (typeof(A))makespace_(A, next_free_a, &a_size, sizeof(A[0]));
    match = (0==0);
    phrase_count = 0;
    for (each = 0; each < phrases; each++) {
      int phrase = gram[gp+each] & ((1 << 14) - 1),
          optional_phrase = gram[gp+each] & (1<<14),
          negated_phrase = gram[gp+each] & (1<<15);
      if (cp > bestparse) {
        static char s[128];
        if (phrase < 256) {
          sprintf(s, "'%c'", phrase);
        } else if (phrase < 512) {
          sprintf(s, "\"%s\"", keyword[phrase-256]);
        } else if (phrase < 512+9) {
          sprintf(s, "{%s}", phrasename[phrase-512]);
        } else {
          sprintf(s, "<%s>", phrasename[phrase-512]);
        }
        looking_for = s;
        bestparse = cp;
      }
      if (phrase < 256) {
        if ((c[cp].t != 4) || (c[cp].s[0] != phrase)) match = (0!=0); else cp++;
      } else if (phrase < 512) {
        if ((c[cp].t != 5) || (strcmp(keyword[phrase-256], c[cp].s) != 0)) match = (0!=0); else cp++;
      } else if (phrase < 512+9) {
        int where = ap;
        if (c[cp].t != BIP[phrase-512]) {
          match = (0!=0);
 } else {
          A[ap++] = phrase;
          A[ap++] = 1;
          A[ap++] = 1;
          A[ap++] = cp++;
          A[saved_ap+3+phrase_count++] = where;
        }
      } else {
        int where = ap;
        if (negated_phrase) {
          int here = cp;
          if (!parse(phrase, depth+1)) {
            A[saved_ap+3+phrase_count++] = -1;
          } else {
            match = (0!=0);
   }
          cp = here;
 } else if (optional_phrase) {
          int input_stream_pos = cp;
          if (parse(phrase, depth+1)) {
            A[saved_ap+3+phrase_count++] = where;
            cp = input_stream_pos;
          } else {
            match = (0!=0);
   }
        } else {
          if (parse(phrase, depth+1)) {
            A[saved_ap+3+phrase_count++] = where;
          } else {
            match = (0!=0);
   }
        }
      }
      if (!match) break;
    }
    gp += phrases;
    if (match) break;
  }
  return(match);
}
struct operation {
  int AST_Code;
  int Children;
  char *Diag_Name;
  char *C_Name;
  char *Stack_Name;
  int Display_Children;
};
struct operation op[] = {
  {1000, 2, "AST_Add", "+", "ADD", 3},
  {1001, 2, "AST_Sub", "-", "SUB", 3},
  {1002, 2, "AST_Mul", "*", "MUL", 3},
  {1003, 2, "AST_Div", "/", "DIV", 3},
  {1004, 2, "AST_Mod", "%", "MOD", 3},
  {1005, 2, "AST_AddAss", "+=", "ADDI", 3},
  {1006, 2, "AST_SubAss", "-=", "SUBI", 3},
  {1007, 2, "AST_MulAss", "*=", "MULI", 3},
  {1008, 2, "AST_DivAss", "/=", "DIVI", 3},
  {1009, 2, "AST_ModAss", "%=", "MODI", 3},
  {1010, 1, "AST_Post_Inc", "()++", "", 1},
  {1011, 1, "AST_Pre_Inc", "++()", "", 1},
  {1012, 1, "AST_Post_Dec", "()--", "", 1},
  {1013, 1 ,"AST_Pre_Dec", "--()", "", 1},
  {1014, 2, "AST_Idx", "[]", "POPI   4", 3},
  {1015, 2, "AST_Member", ".", "ADDI", 3},
  {1016, 2, "AST_Ptr", "->", "ADD", 3},
  {1017, 2, "AST_Call", "()", "", 3},
  {1018, 3, "AST_Cond", "( ? : )", "", 7},
  {1019, 1, "AST_Type", "simple type", "", 1},
  {1020, 0, "AST_Return", "return", "RET", 0},
  {1021, 1, "AST_ReturnResult", "return ...", "RET", 1},
  {1022, 2, "AST_LE", "<=", "CMPLE", 3},
  {1023, 2, "AST_GT", ">", "CMPGT", 3},
  {1024, 2, "AST_LT", "<", "CMPLT", 3},
  {1025, 2, "AST_GE", ">=", "CMPGE", 3},
  {1026, 2, "AST_EQ", "==", "CMPEQ", 3},
  {1027, 2, "AST_NE", "!=", "CMPNE", 3},
  {1028, 3, "AST_IFTHENELSE", "if () ... else ...", "", 7},
  {1029, 2, "AST_IFTHEN", "if () ...", "", 3},
  {1030, 1, "AST_UNeg", "-()", "NEG", 1},
  {1031, 1, "AST_UPos", "+()", "NOOP", 1},
  {1032, 1, "AST_UBitNot", "~()", "NOT", 1},
  {1033, 1, "AST_UBoolNot", "!()", "BNOT", 1},
  {1034, 2, "AST_BoolAnd", "&&", "BAND", 3},
  {1035, 2, "AST_BoolOr", "||", "BOR", 3},
  {1036, 2, "AST_ShortcutBoolAnd", "&&", "", 3},
  {1037, 2, "AST_ShortcutBoolOr", "||", "", 3},
  {1038, 2, "AST_BitAnd", "&", "AND", 3},
  {1039, 2, "AST_BitOr", "|", "OR", 3},
  {1040, 2, "AST_BitAndAss", "&=", "ANDI", 3},
  {1041, 2, "AST_BitOrAss", "|=", "ORI", 3},
  {1042, 2, "AST_BitXor", "^", "XOR", 3},
  {1043, 2, "AST_BitXorAss", "^=", "XORI", 3},
  {1044, 2, "AST_BitLsh", "<<", "LSH", 3},
  {1045, 2, "AST_BitRsh", ">>", "RSH", 3},
  {1046, 2, "AST_BitLshAss", "<<=", "LSHI", 3},
  {1047, 2, "AST_BitRshAss", ">>=", "RSHI", 3},
  {1048, 2, "AST_Const", "Const", "", 0},
  {1049, 2, "AST_Var", "Var", "", 0},
  {1050, 2, "AST_AssignTo", "=", "POPI", 3},
  {1051, 2, "AST_Declare", "VarDec", "", 3},
  {1052, 4, "AST_DefProc", "DefProc", "", 7},
  {1053, 1, "AST_DefParam", "DefParam", "", 1},
  {1054, 2, "AST_UseParam", "Param", "", 3},
  {1055, 1, "AST_AddressOf", "&", "", 1},
  {1056, 1, "AST_IndirectThrough", "*", "PUSHI", 1},
  {1057, 2, "AST_SizeOf", "sizeof", "", 2},
  {1058, 4, "AST_C_ForLoop", "for (;;) ...", "", 15},
  {1059, 2, "AST_C_While", "while () ...", "", 3},
  {1060, 2, "AST_C_DoWhile", "do ... while ();", "", 3},
  {1061, 0, "AST_C_Break", "break", "", 0},
  {1062, 0, "AST_C_Continue", "continue", "", 0},
  {1063, 2, "AST_Cast", "()...", "", 1},
  {1064, 1, "AST_Label", "lab:", "", 1},
  {1065, 1, "AST_Case", "case <n>:", "", 1},
  {1066, 0, "AST_DefaultCase", "default:", "", 0},
  {1067, 1, "AST_Goto", "goto ...", "", 1},
  {1068, 2, "AST_Switch", "switch (...)", "", 3},
  {1069, 1, "AST_Sourceline", "src", "", 1},
  {1070, 1, "AST_LINENO", "Line #", "", 1},
  {1071, 1, "AST_REDIRECT", "REDIR", "", 1},
  {1072, 2, "AST_SEQ", ";", "", 3},
  {1073, 2, "AST_CommaSEQ", ",", "", 3},
  {1074, 1, "AST_LINEAR_BLOB", "BLOB", "", 0},
  {-1, 0, (char *)0}
};
static int nexttrip = 0;
int AST[64*1024];
static int latest_line = -1;
void semantic_error(char *s, char *p)
{
  fprintf(stderr, s, p);
  fprintf(stderr, "Text cells used = %d, Code cells used = %d\n\n", nextfree, nexttrip);
  fflush(stderr);
  exit(2);
}
int character_constant(int ap)
{
  return mkbinop(1048, A[ap+4], c[A[ap+4]].s[0]);
}
int integer_constant(int ap)
{
  return mkbinop(1048, A[ap+4], c[A[ap+4]].s[0]);
}
int string_constant(int ap)
{
  return mkbinop(1048, A[ap+4], c[A[ap+4]].s[0]);
}
int mk(int AST_op, int count, int T[]) {
  int trip;
  int parm;
  trip = nexttrip;
  AST[trip] = AST_op;
  AST[trip+1] = count;
  for (parm = 0; parm < count; parm++) {
    AST[trip+parm+2] = T[parm+1];
  }
  nexttrip += 2+count;
  return trip;
}
int mkmonop(int AST_op, int child) {
  int trip;
  trip = nexttrip;
  AST[trip] = AST_op;
  AST[trip+1] = 1;
  AST[trip+2] = child;
  nexttrip += 3;
  return trip;
}
int mkbinop(int AST_op, int leftchild, int rightchild) {
  int trip;
  trip = nexttrip;
  AST[trip] = AST_op;
  AST[trip+1] = 2;
  AST[trip+2] = leftchild;
  AST[trip+3] = rightchild;
  nexttrip += 4;
  return trip;
}
int mkconst(int n)
{
  char s[128];
  int trip = nexttrip;
  sprintf(s, "%d", n);
  AST[nexttrip] = 1048;
  AST[nexttrip+1] = 2;
  AST[nexttrip+2] = mkliteral(s);
  AST[nexttrip+3] = n;
  nexttrip += 4;
  return trip;
}
void replace(int p, int val)
{
  AST[p] = 1071;
  AST[p+2] = mkconst(val);
}
int build_ast_inner(int ap, int caller)
{
  int T[100];
  int saved_ap;
  int phrase;
  int alt;
  int phrases;
  int i;
  saved_ap = ap;
  phrase = A[ap++] & ((1 << 14) - 1);
  alt = A[ap++];
  phrases = A[ap++];
  if ((phrase < 512) || (phrase > 740)) {
    fprintf(stderr, "* Internal error: build_ast(%d) called from line %d - phrase = %d\n",
     ap, caller, phrase); exit(1);
  }
  switch (phrase) {
  case 512:
    return -1;
  case 513:
  case 514:
  case 515:
  case 516:
  case 517:
  case 518:
  case 519:
  case 520:
    if (c[A[ap]].l > latest_line) latest_line = c[A[ap]].l;
    return A[ap];
case 521:
  if (alt == 0) {
    T[1] = build_ast_inner(A[ap+0], 151);
    T[2] = build_ast_inner(A[ap+1], 152);
    return mkbinop(1072, T[1], T[2]);
  } else {
    return -1;
  }
  return T[0];
case 522:
  if (alt == 0) {
    T[1] = build_ast_inner(A[ap+0], 176);
    T[2] = build_ast_inner(A[ap+1], 177);
    if (T[2] != -1) return 4;
    return mkconst(T[0]&65535);
  } else if ((alt == 1) || (alt == 2)) {
    if (alt == 1) {
      T[1] = build_ast_inner(A[ap+0], 182);
      T[2] = build_ast_inner(A[ap+1], 183);
      T[3] = build_ast_inner(A[ap+2], 184);
      T[4] = build_ast_inner(A[ap+3], 185);
      T[5] = build_ast_inner(A[ap+4], 186);
      T[6] = build_ast_inner(A[ap+5], 187);
    } else {
      T[1] = -1;
      T[2] = build_ast_inner(A[ap+0], 190);
      T[3] = build_ast_inner(A[ap+1], 191);
      T[4] = build_ast_inner(A[ap+2], 192);
      T[5] = build_ast_inner(A[ap+3], 193);
      T[6] = -1;
    }
    T[0] = mkbinop(1017, T[3], T[4]);
    if (T[1] != -1) T[0] = mkmonop(T[1], T[0]);
    if (T[5] != -1) {
      T[7] = T[5];
      while (AST[(T[5])+2] != -1) T[5] = AST[(T[5])+2];
      AST[(T[5])+2] = T[0];
      T[0] = T[7];
    }
    if (T[6] != -1) {
      T[7] = T[6];
      while (AST[(T[6])+2] != -1) T[6] = AST[(T[6])+2];
      AST[(T[6])+2] = T[0];
      T[0] = T[7];
    }
    return T[0];
  } else if (alt == 3) {
    T[1] = build_ast_inner(A[ap+0], 219);
    T[2] = build_ast_inner(A[ap+1], 220);
    T[3] = build_ast_inner(A[ap+2], 221);
    if ((T[2] == -1) && (T[3] == -1)) return T[1];
    if (T[2] == -1) return mkmonop(T[3], T[1]);
    T[0] = T[2];
    while (AST[(T[2])+2] != -1) T[2] = AST[(T[2])+2];
    AST[(T[2])+2] = T[1];
    if (T[3] == -1) return T[0];
    return mkmonop(T[3], T[0]);
  } else if (alt == 4) {
    return integer_constant(ap+0);
  } else if (alt == 5) {
    return character_constant(ap+0);
  } else if (alt == 6) {
    return string_constant(ap+0);
  } else {
    return build_ast_inner(A[ap+0], 236);
  }
  case 523:
  if (alt <= 1) {
    if (alt == 0) {
      T[1] = build_ast_inner(A[ap+0], 249);
      T[2] = build_ast_inner(A[ap+1], 250);
      T[3] = build_ast_inner(A[ap+2], 251);
      T[4] = build_ast_inner(A[ap+3], 252);
      T[5] = build_ast_inner(A[ap+4], 253);
      T[6] = build_ast_inner(A[ap+5], 254);
    } else {
      T[1] = -1;
      T[2] = build_ast_inner(A[ap+0], 257);
      T[3] = build_ast_inner(A[ap+1], 258);
      T[4] = build_ast_inner(A[ap+2], 259);
      T[5] = build_ast_inner(A[ap+3], 260);
      T[6] = -1;
    }
    T[0] = mkbinop(1017, T[3], T[4]);
    if (T[1] != -1) T[0] = mkmonop(T[1], T[0]);
    if (T[5] != -1) {
      T[7] = T[5];
      while (AST[(T[5])+2] != -1) T[5] = AST[(T[5])+2];
      AST[(T[5])+2] = T[0];
      T[0] = T[7];
    }
    if (T[6] != -1) {
      T[7] = T[6];
      while (AST[(T[6])+2] != -1) T[6] = AST[(T[6])+2];
      AST[(T[6])+2] = T[0];
      T[0] = T[7];
    }
    return T[0];
  } else {
    T[1] = build_ast_inner(A[ap+0], 286);
    T[2] = build_ast_inner(A[ap+1], 287);
    T[3] = build_ast_inner(A[ap+2], 288);
    if ((T[2] == -1) && (T[3] == -1)) return T[1];
    if (T[2] == -1) return mkmonop(T[3], T[1]);
    T[0] = T[2];
    while (AST[(T[2])+2] != -1) T[2] = AST[(T[2])+2];
    AST[(T[2])+2] = T[1];
    if (T[3] == -1) return T[0];
    return mkmonop(T[3], T[0]);
  }
case 524:
  if (alt == 0) return 1010;
  if (alt == 1) return 1012;
  return -1;
case 525:
  if (alt == 3) return -1;
  T[1] = build_ast_inner(A[ap+0], 323);
  T[2] = build_ast_inner(A[ap+1], 324);
  if (alt == 0) {
    T[3] = mkbinop(1014, -1, T[1]);
  } else if (alt == 1) {
    T[3] = mkbinop(1015, -1, T[1]);
  } else if (alt == 2) {
    T[3] = mkbinop(1016, -1, T[1]);
  }
  if (T[2] == -1) return T[3];
  T[0] = T[2];
  while (AST[(T[2])+2] != -1) T[2] = AST[(T[2])+2];
  AST[(T[2])+2] = T[3];
  return T[0];
case 526:
  if (alt == 0) {
    T[1] = build_ast_inner(A[ap+0], 348);
    return mkbinop(1057, T[1], 2);
  } else {
    T[1] = build_ast_inner(A[ap+2], 353);
    T[2] = build_ast_inner(A[ap+3], 354);
    return mkbinop(1017, T[1], T[2]);
  }
case 527:
case 528:
  if (alt == 0) {
    T[1] = build_ast_inner(A[ap+0], 369);
    T[2] = build_ast_inner(A[ap+1], 370);
    return mkbinop(1054, T[1], T[2]);
  } else {
    return mkbinop(1054, -1, -1);
  }
case 529:
  if (alt == 0) {
    T[1] = build_ast_inner(A[ap+0], 385);
    T[2] = build_ast_inner(A[ap+1], 386);
    T[3] = build_ast_inner(A[ap+2], 387);
    T[0] = T[1];
    while (AST[(T[1])+2] != -1) T[1] = AST[(T[1])+2];
    AST[(T[1])+2] = T[3];
    return T[0];
  }
  return build_ast_inner(A[ap+0], 394);
case 530:
  return -1;
case 531:
  if (alt == 0) {
    T[1] = build_ast_inner(A[ap+0], 407);
    T[2] = build_ast_inner(A[ap+1], 408);
    T[0] = T[1];
    while (AST[(T[0])+2] != -1) T[0] = AST[(T[0])+2];
    AST[(T[0])+2] = T[2];
    return T[1];
  } else {
    T[1] = build_ast_inner(A[ap+0], 414);
    T[2] = build_ast_inner(A[ap+1], 415);
    if (T[1] == -1) return T[2];
    T[0] = T[1];
    while (AST[(T[0])+2] != -1) T[0] = AST[(T[0])+2];
    AST[(T[0])+2] = T[2];
    return T[1];
  }
case 532:
  if (alt == 0) {
    return mkmonop(1011, -1);
  } else if (alt == 1) {
    return mkmonop(1013, -1);
  } else if (alt == 2) {
    T[1] = build_ast_inner(A[ap+0], 437);
    T[2] = build_ast_inner(A[ap+1], 438);
    if (T[1] == -1) return T[2];
    T[0] = T[1];
    while (AST[(T[1])+2] != -1) T[1] = AST[(T[1])+2];
    AST[(T[1])+2] = T[2];
    return T[0];
  } else if (alt == 3) {
    return mkmonop(1055, -1);
  } else {
    return mkbinop(1057, -1, 0);
  }
case 533:
  if (alt == 0) {
    return mkmonop(1011, -1);
  } else if (alt == 1) {
    return mkmonop(1013, -1);
  } else if (alt == 2) {
    return mkmonop(1031, -1);
  } else if (alt == 3) {
    return mkmonop(1030, -1);
  } else if (alt == 4) {
    return mkmonop(1033, -1);
  } else if (alt == 5) {
    return mkmonop(1032, -1);
  } else if (alt == 6) {
    return build_ast_inner(A[ap+0], 480);
  } else if (alt == 7) {
    return build_ast_inner(A[ap+0], 483);
  } else if (alt == 8) {
    return mkmonop(1055, -1);
  } else if (alt == 9) {
    return mkbinop(1057, -1, 1);
  }
  return -1;
case 534:
  T[1] = build_ast_inner(A[ap+0], 504);
  T[2] = build_ast_inner(A[ap+1], 505);
  if (T[2] == -1) return mkbinop(1063, -1, T[1]);
  T[0] = T[2];
  while (AST[(T[2])+2] != -1) T[2] = AST[(T[2])+2];
  AST[(T[2])+2] = T[1];
  return mkbinop(1063, -1, T[0]);
case 535:
  return mkmonop(1056, build_ast_inner(A[ap+0], 517));
case 536:
  if (alt == 0) return build_ast_inner(A[ap+0], 524);
  return -1;
case 537:
  return -1;
case 538:
  return -1;
case 539:
  return -1;
case 540:
  if (alt == 0) return 0;
  if (alt == 1) return (1<<16)-1;
  if (alt == 2) {T[0] = build_ast_inner(A[ap+0], 563); return (1<<16)-1;}
  if (alt <= 4) return 8+T[0];
  if (alt == 7) return 4+T[0];
  if (alt <= 9) return 2+T[0];
  if (alt <= 10) return 1+T[0];
  return (1<<16)-1;
case 541:
  if (alt == 0) return 1<<16;
  if (alt == 0) return 2<<16;
  return 0;
case 542:
case 543:
case 544:
case 545:
case 546:
case 547:
case 548:
case 549:
case 550:
case 551:
case 552:
  T[1] = build_ast_inner(A[ap+0], 620);
  T[2] = build_ast_inner(A[ap+1], 621);
  if (T[2] == -1) return T[1];
  T[0] = T[2];
  while (AST[(T[0])+2] != -1) T[0] = AST[(T[0])+2];
  AST[(T[0])+2] = T[1];
  return T[2];
case 553:
case 554:
case 555:
case 556:
case 557:
case 558:
case 559:
case 560:
case 561:
case 562:
  if (alt == 0) {
    T[1] = build_ast_inner(A[ap+0], 683);
    T[2] = build_ast_inner(A[ap+1], 684);
    T[3] = build_ast_inner(A[ap+2], 685);
    if (T[3] == -1) return mkbinop(T[1], -1, T[2]);
    T[0] = T[3];
    while(AST[(T[3])+2] != -1) T[3] = AST[(T[3])+2];
    AST[(T[3])+2] = mkbinop(T[1], -1, T[2]);
    return T[3];
  }
  return -1;
case 563:
  if (alt == 0) {
    return 1002;
  } else if (alt == 1) {
    return 1003;
  } else {
    return 1004;
  }
case 564:
  if (alt == 0) {
    return 1000;
  } else {
    return 1001;
  }
case 565:
  if (alt == 0) {
    return 1044;
  } else {
    return 1045;
  }
case 566:
  if (alt == 0) {
    return 1022;
  } else if (alt == 1) {
    return 1024;
  } else if (alt == 2) {
    return 1025;
  } else {
    return 1023;
  }
case 567:
  if (alt == 0) {
    return 1026;
  } else {
    return 1027;
  }
case 568:
  return 1038;
case 569:
    return -1;
case 570:
  return 1042;
case 571:
  return 1039;
case 572:
  return -1;
case 573:
  return 1034;
case 574:
  return 1035;
case 575:
  if (alt == 0) {
    T[1] = -1;
    T[2] = build_ast_inner(A[ap+0], 804);
    T[3] = build_ast_inner(A[ap+1], 805);
    return mk(1018, 3, T);
  } else {
    return -1;
  }
case 576:
  T[1] = build_ast_inner(A[ap+0], 819);
  T[2] = build_ast_inner(A[ap+1], 820);
  if (T[1] == -1) return T[2];
  T[0] = T[1];
  while (AST[(T[0])+3] != -1) T[0] = AST[(T[0])+3];
  AST[(T[0])+3] = T[2];
  return T[1];
case 577:
  return -1;
case 578:
  if (alt == 0) {
    T[1] = build_ast_inner(A[ap+0], 840);
    T[2] = -1;
    T[3] = build_ast_inner(A[ap+2], 842);
    T[4] = build_ast_inner(A[ap+3], 843);
    return mkbinop(T[3], T[1], T[4]);
  } else {
    return -1;
  }
case 579:
  if (alt == 0) {
    return 1050;
  } else if (alt == 1) {
    return 1005;
  } else if (alt == 2) {
    return 1006;
  } else if (alt == 3) {
    return 1007;
  } else if (alt == 4) {
    return 1008;
  } else if (alt == 5) {
    return 1009;
  } else if (alt == 6) {
    return 1040;
  } else if (alt == 7) {
    return 1043;
  } else if (alt == 8) {
    return 1041;
  } else if (alt == 9) {
    return 1046;
  } else {
    return 1047;
  }
case 580:
case 581:
  if (alt == 1) return -1;
  T[1] = build_ast_inner(A[ap+0], 901);
  T[2] = build_ast_inner(A[ap+1], 902);
  if (T[2] == -1) return T[1];
  return mkbinop(1073, T[1], T[2]);
case 582:
  return build_ast_inner(A[ap+0], 911);
case 583:
  T[1] = build_ast_inner(A[ap+0], 918);
  return mkbinop(1049, T[1], 0);
case 584:
  T[1] = build_ast_inner(A[ap+0], 925);
  return mkbinop(1049, T[1], 1);
case 585:
  T[1] = build_ast_inner(A[ap+0], 938);
  return T[1];
case 586:
  if (alt == 0) {
    return mkbinop(1072, mkbinop(1064, build_ast_inner(A[ap+0], 947), -1),
                            build_ast_inner(A[ap+1], 948));
  } else if (alt == 1) {
    return mkbinop(1072, mkbinop(1065, build_ast_inner(A[ap+0], 950), -1),
                            build_ast_inner(A[ap+1], 951));
  }
  return mkbinop(1072, mkmonop(1064, -1),
                          build_ast_inner(A[ap+0], 954));
case 587:
  return build_ast_inner(A[ap+0], 959);
case 588:
  return build_ast_inner(A[ap+0], 963);
case 589:
  if (alt == 1) return -1;
  return build_ast_inner(A[ap+0], 968);
case 590:
  T[1] = build_ast_inner(A[ap+0], 973);
  T[2] = build_ast_inner(A[ap+1], 974);
  return mkbinop(1072, T[1], T[2]);
case 591:
  if (alt == 1) return -1;
  return build_ast_inner(A[ap+0], 982);
case 592:
  T[1] = build_ast_inner(A[ap+0], 986);
  T[2] = build_ast_inner(A[ap+1], 987);
  return mkbinop(1072, T[1], T[2]);
case 593:
  if (alt == 0) {
    T[1] = build_ast_inner(A[ap+0], 994);
  } else {
    T[1] = build_ast_inner(A[ap+0], 996);
    T[2] = build_ast_inner(A[ap+1], 997);
  }
  return -1;
case 594:
  return -1;
case 595:
  T[1] = build_ast_inner(A[ap+0], 1007);
  T[2] = build_ast_inner(A[ap+1], 1008);
  T[3] = build_ast_inner(A[ap+1], 1009);
  T[4] = build_ast_inner(A[ap+1], 1010);
  return -1;
case 596:
  T[1] = -1;
  T[2] = build_ast_inner(A[ap+0], 1018);
  T[3] = build_ast_inner(A[ap+1], 1019);
  T[4] = build_ast_inner(A[ap+2], 1020);
  if (alt == 0) {
    if (T[4] == -1) return -1;
    return mk(1052, 4, T);
  } else if (alt == 1) {
  } else {
    if (T[4] == -1) return T[3];
    return mkbinop(1073, T[3], T[4]);
  }
  return -1;
case 597:
  return -1;
case 598:
  if (alt == 0) return -1;
  return build_ast_inner(A[ap+0], 1042);
case 599:
case 600:
  return -1;
case 601:
  return -1;
case 602:
case 603:
  return -1;
case 604:
  return -1;
case 605:
  return -1;
case 606:
case 607:
  return -1;
case 608:
  return -1;
case 609:
  return -1;
case 610:
  return -1;
case 611:
case 612:
  if (alt == 1) return -1;
  T[1] = build_ast_inner(A[ap+0], 1102);
  T[2] = build_ast_inner(A[ap+1], 1103);
  if (T[2] == -1) return T[1];
  return mkbinop(1072, T[1], T[2]);
case 613:
  T[1] = build_ast_inner(A[ap+0], 1110);
  T[2] = build_ast_inner(A[ap+1], 1111);
  if (alt == 0) {
    T[3] = build_ast_inner(A[ap+2], 1113);
    if (T[3] == -1) return mkbinop(1029, T[1], T[2]);
    return mk(1028, 3, T);
  }
  return mkbinop(1068, T[1], T[2]);
case 614:
  if (alt == 1) return -1;
  T[1] = build_ast_inner(A[ap+0], 1122);
  return T[1];
case 615:
  T[1] = build_ast_inner(A[ap+0], 1130);
  T[2] = build_ast_inner(A[ap+1], 1131);
  if (alt == 0) {
    return mkbinop(1059, T[1], T[2]);
  } else if (alt == 1) {
    return mkbinop(1060, T[1], T[2]);
  } else {
    T[3] = build_ast_inner(A[ap+2], 1137);
    T[4] = build_ast_inner(A[ap+3], 1138);
    return mk(1058, 4, T);
  }
case 616:
  if (alt == 0) {
    T[1] = build_ast_inner(A[ap+0], 1148);
    return mkmonop(1067, T[1]);
  } else if (alt == 1) {
    return mkmonop(1062, -1);
  } else if (alt == 2) {
    return mkmonop(1061, -1);
  } else {
    T[1] = build_ast_inner(A[ap+0], 1155);
    if (T[1] == -1) {
      return mkmonop(1020, -1);
    } else{
      return mkbinop(1021, T[1], -1);
    }
  }
  return -1;
case 617:
  T[1] = build_ast_inner(A[ap+0], 1170);
  return mkmonop(1019, T[1]);


default:
  if ((phrase >= 512) && (phrase < 512+106)) {
    semantic_error("* Missing case label P_%s:\n", phrasename[phrase-512]);
  } else {
    semantic_error("* Missing case label P_<<%d>>\n", (char *)phrase);
  }
  }



  return -1;

}
int print_all_trips(void)
{
  int ap = 0;
  for (;;) {
    int oper = AST[ap], count = AST[ap+1];
    int child = ap+2, disp = op[oper-1000].Display_Children;
    int this;
    if ((oper >= 1000) && (oper <= 1074)) {
      fprintf(stdout, "%4d: %s", ap, op[oper-1000].Diag_Name);
    } else {
      fprintf(stdout, "%4d: %d", ap, oper );
    }
    this = 1<<(count-1);
    for (;;) {
      if (child == ap+2+count) break;
      if (disp&this) fprintf(stdout, " %d", AST[child]);
      this = this >> 1;
      child += 1;
    }
    fprintf(stdout, "\n");
    ap = ap + 2 + AST[ap+1];
    if (ap >= nexttrip) break;
  }
  fprintf(stdout, "-----------------\n");
}
int show_ast(int ap, int depth)
{
  int oper = AST[ap], count = AST[ap+1];
  int child = ap+2, disp = op[oper-1000].Display_Children;
  int this;
  if (ap == -1) {
                                            return -1;
  }
  if (count != op[oper-1000].Children) {
    fprintf(stderr, "oper = %d (%s),  count = %d,  Children = %d\n",
      oper, op[oper-1000].Diag_Name, count, op[oper-1000].Children);
    fflush(stderr);
    assert(count == op[oper-1000].Children);
  }
  switch (oper) {
  case 1049:
    fprintf(stdout, "%4d: %s %s %d\n", ap, op[oper-1000].Diag_Name, c[AST[ap+2]].s, AST[ap+3]);
    break;
  case 1048: ;
    fprintf(stdout, "%4d: %s %s\n", ap, op[oper-1000].Diag_Name, c[AST[ap+2]].s);
    break;
  case 1000: ;
  case 1001: ;
  case 1002: ;
  case 1003: ;
  case 1004: ;
  case 1005: ;
  case 1006: ;
  case 1007: ;
  case 1008: ;
  case 1009: ;
  case 1010: ;
  case 1011: ;
  case 1012: ;
  case 1013: ;
  case 1014: ;
  case 1015: ;
  case 1016: ;
  case 1017: ;
  case 1018: ;
  case 1019: ;
  case 1020: ;
  case 1021: ;
  case 1022: ;
  case 1023: ;
  case 1024: ;
  case 1025: ;
  case 1026: ;
  case 1027: ;
  case 1028: ;
  case 1029: ;
  case 1030: ;
  case 1031: ;
  case 1032: ;
  case 1033: ;
  case 1034: ;
  case 1035: ;
  case 1036: ;
  case 1037: ;
  case 1038: ;
  case 1039: ;
  case 1040: ;
  case 1041: ;
  case 1042: ;
  case 1043: ;
  case 1044: ;
  case 1045: ;
  case 1046: ;
  case 1047: ;
  case 1050: ;
  case 1051: ;
  case 1052: ;
  case 1053: ;
  case 1054: ;
  case 1055: ;
  case 1056: ;
  case 1058: ;
  case 1059: ;
  case 1060: ;
  case 1061: ;
  case 1062: ;
  case 1063: ;
  case 1064: ;
  case 1067: ;
  case 1069: ;
  case 1070: ;
  case 1071: ;
  case 1074: ;
  case 1072: ;
  case 1073: ;
  default:
    fprintf(stdout, "%4d: %s", ap, op[oper-1000].Diag_Name);
    this = 1<<(count-1);
    for (;;) {
      if (child == ap+2+count) break;
      if (disp&this) fprintf(stdout, " %d", AST[child]);
      this = this >> 1;
      child += 1;
    }
    fprintf(stdout, "\n");
    {
      child = ap+2;
      for (;;) {
        if (child == ap+2+count) break;
        show_ast(AST[child], depth+1);
        child += 1;
      }
    }
    break;
  }
  fflush(stdout);
  return -1;
}
void emit(char *lab, char *opcode, char *mode, char *opd, char *comment)
{
  fprintf(stdout, "%s  %s %s%s ; %s\n", lab, opcode, mode, opd, comment);
}
int codegen_stack(int ap)
{
  int oper = AST[ap], count = AST[ap+1];
  int child = ap+2, disp = op[oper-1000].Display_Children;
  char *opname = op[oper-1000].Diag_Name;
  char *code = op[oper-1000].Stack_Name;
  int this;
  if (ap == -1) return -1;
  if ((count <= 2) && (*code != '\0')) {
    if (count >= 1) codegen_stack(AST[child]);
    if (count >= 2) codegen_stack(AST[child+1]);
    emit("", code, "", "", ""); return;
  }
  if (count != op[oper-1000].Children) {
    fprintf(stderr, "Oper = %d (%s)\n", oper, opname);
    assert(count == op[oper-1000].Children);
  }
  if (oper < 1000 || oper > 1074) {
    fprintf(stderr, "* Lookup oper %d and add it to the switch in genstack.c\n", oper);
  }
  switch (oper) {
  case 1072: break;
  case 1049:
    if (AST[child+1] == 0) {
      emit("", "PUSH", "", c[AST[child]].s, "");
    } else if (AST[child+1] == 1) {
      emit("", "PUSH", "&", c[AST[child]].s, "");
    } else {
      fprintf(stderr, "AST[%d+1] = %d\n", child, AST[child+1]);
      assert((unsigned int)AST[child+1] <= 1);
    }
    break;
  case 1048:
    if (c[AST[child]].t == 7) {
      emit("", "PUSH", "#'", c[AST[child]].s, "");
    } else {
      emit("", "PUSH", "#", c[AST[child]].s, "");
    }
    break;
  case 1073:
    codegen_stack(AST[child]);
    if (AST[child+1] != -1) {
      emit("", "POP", "", "", "void");
      codegen_stack(AST[child+1]);
    }
    break;
  case 1017: ;
    {
      int UseParam, Var, count;
      char callee[128];
      assert(AST[AST[child+1]] == 1054);
      UseParam = AST[child+1]; count = 0;
      while (AST[UseParam] == 1054) {
        count += 1; UseParam = AST[(UseParam)+3];
      }
      codegen_stack(AST[child+1]);
      Var = AST[child];
      child = Var+2;
      sprintf(callee, "%s,%d", c[AST[child]].s, count-1);
      emit("", "CALL", "", callee, "");
    }
    break;
  case 1000: ;
  case 1001: ;
  case 1002: ;
  case 1003: ;
  case 1004: ;
  case 1005: ;
  case 1006: ;
  case 1007: ;
  case 1008: ;
  case 1009: ;
  case 1010: ;
  case 1011: ;
  case 1012: ;
  case 1013: ;
  case 1014: ;
  case 1015: ;
  case 1016: ;
  case 1018: ;
  case 1019: ;
  case 1020: ;
  case 1021: ;
  case 1022: ;
  case 1023: ;
  case 1024: ;
  case 1025: ;
  case 1026: ;
  case 1027: ;
  case 1028: ;
  case 1029: ;
  case 1030: ;
  case 1031: ;
  case 1032: ;
  case 1033: ;
  case 1034: ;
  case 1035: ;
  case 1036: ;
  case 1037: ;
  case 1038: ;
  case 1039: ;
  case 1040: ;
  case 1041: ;
  case 1042: ;
  case 1043: ;
  case 1044: ;
  case 1045: ;
  case 1046: ;
  case 1047: ;
  case 1050: ;
  case 1051: ;
  case 1052: ;
  case 1053: ;
  case 1054: ;
  case 1055: ;
  case 1056: ;
  case 1057: ;
  case 1058: ;
  case 1059: ;
  case 1060: ;
  case 1061: ;
  case 1062: ;
  case 1063: ;
  case 1064: ;
  case 1067: ;
  case 1069: ;
  case 1070: ;
  case 1071: ;
  case 1074: ;
  default:
    {
      child = ap+2;
      for (;;) {
        if (child == ap+2+count) break;
        codegen_stack(AST[child]);
        child += 1;
      }
      emit("", "", "", "", opname);
    }
    break;
  }
  fflush(stdout);
  return -1;
}
void Fold(int p)
{
  int op, arity;
  op = ((p) == -1 ? -1 : AST[p]);
  if (op == -1) return;
  arity = ((p) == -1 ? -1 : AST[(p)+1]);
  if (arity == 1) {
    if (((AST[(p)+2]) == -1 ? -1 : AST[AST[(p)+2]]) == 1048) {
    switch (op) {
      case 1030: replace(p, -AST[AST[(p)+3]]); return;
      case 1031: replace(p, +AST[AST[(p)+3]]); return;
      case 1032: replace(p, ~AST[AST[(p)+3]]); return;
      case 1033: replace(p, !AST[AST[(p)+3]]); return;
      default:
 break;
    }
    }
  } else if (arity == 2) {
    if ((((AST[(p)+2]) == -1 ? -1 : AST[AST[(p)+2]]) == 1048) && (((AST[(p)+3]) == -1 ? -1 : AST[AST[(p)+3]]) == 1048)) {
    switch (op) {
    case 1000: replace(p, AST[(AST[(p)+2])+3] + AST[(AST[(p)+3])+3]); return;
    case 1001: replace(p, AST[(AST[(p)+2])+3] - AST[(AST[(p)+3])+3]); return;
    case 1002: replace(p, AST[(AST[(p)+2])+3] * AST[(AST[(p)+3])+3]); return;
    case 1003: replace(p, AST[(AST[(p)+2])+3] / AST[(AST[(p)+3])+3]); return;
    case 1004: replace(p, AST[(AST[(p)+2])+3] % AST[(AST[(p)+3])+3]); return;
    case 1022: replace(p, AST[(AST[(p)+2])+3] <= AST[(AST[(p)+3])+3]); return;
    case 1023: replace(p, AST[(AST[(p)+2])+3] > AST[(AST[(p)+3])+3]); return;
    case 1024: replace(p, AST[(AST[(p)+2])+3] < AST[(AST[(p)+3])+3]); return;
    case 1025: replace(p, AST[(AST[(p)+2])+3] >= AST[(AST[(p)+3])+3]); return;
    case 1026: replace(p, AST[(AST[(p)+2])+3] == AST[(AST[(p)+3])+3]); return;
    case 1027: replace(p, AST[(AST[(p)+2])+3] != AST[(AST[(p)+3])+3]); return;
    case 1034: replace(p, AST[(AST[(p)+2])+3] && AST[(AST[(p)+3])+3]); return;
    case 1035: replace(p, AST[(AST[(p)+2])+3] || AST[(AST[(p)+3])+3]); return;
    case 1036: replace(p, AST[(AST[(p)+2])+3] && AST[(AST[(p)+3])+3]); return;
    case 1037: replace(p, AST[(AST[(p)+2])+3] || AST[(AST[(p)+3])+3]); return;
    case 1038: replace(p, AST[(AST[(p)+2])+3] & AST[(AST[(p)+3])+3]); return;
    case 1039: replace(p, AST[(AST[(p)+2])+3] | AST[(AST[(p)+3])+3]); return;
    case 1042: replace(p, AST[(AST[(p)+2])+3] ^ AST[(AST[(p)+3])+3]); return;
    case 1044: replace(p, AST[(AST[(p)+2])+3] << AST[(AST[(p)+3])+3]); return;
    case 1045: replace(p, AST[(AST[(p)+2])+3] >> AST[(AST[(p)+3])+3]); return;
    default:
      break;
    }
    }
  } else if (op == 1018) {
    if ((((AST[(p)+2]) == -1 ? -1 : AST[AST[(p)+2]]) == 1048)
     && (((AST[(p)+3]) == -1 ? -1 : AST[AST[(p)+3]]) == 1048)
     && (((AST[(p)+2+(2)]) == -1 ? -1 : AST[AST[(p)+2+(2)]]) == 1048)
    ) {
      replace(p, ( AST[(AST[(p)+2])+3] ? AST[(AST[(p)+3])+3] : AST[(AST[(p)+2+(2)])+3])); return;
    }
  }
}
void fold_constant_expressions(int p)
{
  int i, disp, this;
  if ((p == -1) || (AST[p] == -1)) return;
  for (i = 0; i < ((p) == -1 ? -1 : AST[(p)+1]); i++) {
    if (AST[(p)+2+(i)] != -1) {
      while (((AST[(p)+2+(i)]) == -1 ? -1 : AST[AST[(p)+2+(i)]]) == 1071)
        AST[(p)+2+(i)] = AST[(AST[(p)+2+(i)])+2];
    }
  }
  disp = op[((p) == -1 ? -1 : AST[p])-1000].Display_Children; this = 1;
  for (i = 0; i < ((p) == -1 ? -1 : AST[(p)+1]); i++) {
    if ((AST[(p)+2+(i)] != -1) && (disp&this)) fold_constant_expressions(AST[(p)+2+(i)]);
    this = this<<1;
  }
  for (i = 0; i < ((p) == -1 ? -1 : AST[(p)+1]); i++) {
    if (AST[(p)+2+(i)] != -1) {
      while (((AST[(p)+2+(i)]) == -1 ? -1 : AST[AST[(p)+2+(i)]]) == 1071)
        AST[(p)+2+(i)] = AST[(AST[(p)+2+(i)])+2];
    }
  }
  Fold(p);
  for (i = 0; i < ((p) == -1 ? -1 : AST[(p)+1]); i++) {
    if (AST[(p)+2+(i)] != -1) {
      while (((AST[(p)+2+(i)]) == -1 ? -1 : AST[AST[(p)+2+(i)]]) == 1071)
        AST[(p)+2+(i)] = AST[(AST[(p)+2+(i)])+2];
    }
  }
}
int main(int argc, char **argv) {
  int opt_3address = (0!=0), opt_debug = (0!=0), opt_stack = (0!=0), opt_c = (0!=0), opt_execute = (0!=0), opt_optimiser = (0!=0);
  char *s;
  progname = strdup(argv[0]);
  if ((s = strrchr(progname, '/')) != NULL) progname = s+1;
  if ((s = strrchr(progname, '\\')) != NULL) progname = s+1;
  if ((s = strrchr(progname, ']')) != NULL) progname = s+1;
  if ((s = strrchr(progname, ';')) != NULL) *s = '\0';
  if (((s = strrchr(progname, '.')) != NULL) && (strcasecmp(s, ".exe") == 0)) *s = '\0';
  if (((s = strrchr(progname, '.')) != NULL) && (strcasecmp(s, ".com") == 0)) *s = '\0';
 moreopt:
  if ((argc >= 2) && strcmp(argv[1], "-O") == 0) {
    argv++; argc--; opt_optimiser = (0==0); goto moreopt;
  }
  if ((argc >= 2) && strcmp(argv[1], "-d") == 0) {
    argv++; argc--; debug = (0==0); goto moreopt;
  }
  if ((argc >= 2) && strcmp(argv[1], "-3") == 0) {
    argv++; argc--; opt_3address = (0==0); goto moreopt;
  }
  if ((argc >= 2) && strcmp(argv[1], "-s") == 0) {
    argv++; argc--; opt_stack = (0==0); goto moreopt;
  }
  if ((argc >= 2) && strcmp(argv[1], "-c") == 0) {
    argv++; argc--; opt_c = (0==0); goto moreopt;
  }
  if ((argc >= 2) && strcmp(argv[1], "-e") == 0) {
    argv++; argc--; opt_execute = (0==0); goto moreopt;
  }
  if ((argc >= 2) && strcmp(argv[1], "-h") == 0) {
      fprintf(stderr, "%s:\n", progname);
      fprintf(stderr, "\t-3\tgenerate low-level 3-address code using c\n");
      fprintf(stderr, "\t-c\tgenerate high-level c translation\n");
      fprintf(stderr, "\t-s\tgenerate stack-based assembly code\n");
      fprintf(stderr, "\t-e\texecute directly\n");
      fprintf(stderr, "\t-d\tdebug\n");
      fprintf(stderr, "\t-h\thelp (this info)\n");
      exit(0);
  }
  if (argc != 2) {
    fprintf(stderr, "syntax: %s [-3cdehs] filename\n", progname);
    exit(1);
  }
  if (!(opt_3address || opt_c || opt_execute || opt_stack)) opt_stack = (0==0);
  sourcefile = fopen(argv[1], "r");
  if (sourcefile == NULL) {
    fprintf(stderr, "%s: %s - %s\n", progname, strerror(errno), argv[1]);
    exit(errno);
  }
  if (opt_execute) {
    outfile = stdout;
  } else {
    char *s;
    sprintf(outname, "%s", argv[1]);
    s = strrchr(outname, '.');
    if (s == NULL) s = outname+strlen(outname);
    if (opt_3address || opt_c) {
      sprintf(s, "%s", ".c");
    } else if (opt_stack) {
      sprintf(s, "%s", ".asm");
    } else {
      fprintf(stderr, "Won't\n"); exit(123);
    }
    outfile = fopen(outname, "w");
    if (outfile == NULL) {
      fprintf(stderr, "%s: cannot output to %s - %s\n", progname, outname, strerror(errno));
    }
  }
  curfile = argv[1]; startline = (0==0); whitespace = (0==0);
  onecharstr = (char *)malloc(512);
  line_reconstruction();
 resume:
  if (!parse(521, 0)) {
    if (bestparse == nextfree) {
      fprintf(stderr, "\"%s\", Line %d, Col %d: Premature end of file while looking for %s\n",
                       argv[1], c[bestparse].l, c[bestparse].col+1, looking_for);
      exit(1);
    } else {
      int i;
      fprintf(stderr, "\"%s\", Line %d, Col %d: Syntax error while looking for %s near ",
                       argv[1], c[bestparse].l, c[bestparse].col+1, looking_for);
      for (i = bestparse; i < bestparse+3; i++) {
        if (i == nextfree) {
          fprintf(stderr, "<End of file>\n");
          exit(1);
          break;
        }
        switch (c[i].t) {
        case 1:
        case 4:
        case 6:
          fprintf(stderr, "%s", c[i].s);
          break;
        case 7:
          fprintf(stderr, "'%s'", c[i].s);
          break;
        case 8:
          fprintf(stderr, "\"%s\"", c[i].s);
          break;
        }
        fprintf(stderr, (i == (bestparse+2) ? " ..." : " "));
      }
      fprintf(stderr, "\n");
      exit(1);
    }
    exit(1);
  } else {
    int program = build_ast_inner(0, 267);
    fprintf(stdout, "Text cells used = %d, Code cells used = %d\n", nextfree, nexttrip);
    fflush(stdout);
    print_all_trips();
    show_ast(program, 0);
    fold_constant_expressions(program);
    while (((program) == -1 ? -1 : AST[program]) == 1071) program = AST[(program)+2];
    codegen_stack(program);
    fprintf(stdout, "\n");
    fflush(stdout);
  }
  exit(0); return(1);
}
