char *progname;
static char outname[256];
FILE *outfile;
int debug = (0!=0);
int gram[754] = {
    2, 2, 592, 521, 1, 512, 8, 4, 256, 40, 547, 41, 8, 542, 537, 590,
   40, 534, 41, 527, 526, 6, 537, 590, 40, 534, 41, 527, 3, 590, 527, 526,
    1, 518, 1, 519, 1, 520, 3, 40, 587, 41, 1, 1, 525, 1, 1, 525,
    3, 8, 542, 537, 590, 40, 534, 41, 527, 526, 6, 537, 590, 40, 534, 41,
  527, 3, 591, 528, 526, 3, 1, 514, 1, 515, 0, 1, 1, 532, 1, 1,
  532, 1, 1, 532, 1, 1, 532, 1, 1, 532, 4, 4, 91, 587, 93, 529,
    3, 46, 590, 530, 4, 45, 62, 590, 531, 0, 2, 4, 256, 40, 547, 41,
    6, 543, 537, 590, 40, 534, 41, 2, 2, 583, 535, 0, 2, 3, 44, 583,
  535, 0, 2, 3, 542, 537, 522, 1, 523, 2, 1, 541, 0, 2, 2, 539,
  524, 2, 540, 522, 5, 1, 514, 1, 515, 2, 543, 541, 1, 38, 1, 256,
   11, 1, 514, 1, 515, 1, 43, 1, 45, 1, 33, 1, 126, 2, 543, 541,
    1, 542, 1, 38, 1, 256, 0, 1, 4, 40, 547, 543, 41, 1, 2, 42,
  543, 2, 1, 542, 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, 624, 4, 265,
   40, 536, 41, 4, 548, 266, 266, 267, 3, 548, 266, 266, 3, 548, 266, 267,
    2, 548, 266, 2, 548, 267, 3, 548, 268, 267, 2, 548, 268, 2, 548, 269,
    1, 270, 3, 1, 271, 1, 272, 0, 1, 2, 538, 560, 1, 2, 549, 561,
    1, 2, 550, 562, 1, 2, 551, 563, 1, 2, 552, 564, 1, 2, 553, 565,
    1, 2, 554, 566, 1, 2, 555, 567, 1, 2, 556, 568, 1, 2, 557, 569,
    1, 2, 558, 582, 2, 3, 570, 538, 560, 0, 2, 3, 571, 549, 561, 0,
    2, 3, 572, 550, 562, 0, 2, 3, 573, 551, 563, 0, 2, 3, 574, 552,
  564, 0, 2, 3, 575, 553, 565, 0, 2, 3, 577, 554, 566, 0, 2, 3,
  578, 555, 567, 0, 2, 3, 580, 556, 568, 0, 2, 3, 581, 557, 569, 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, 33344, 38, 1, 2, 38, 38, 1, 1, 94,
    1, 2, 33347, 124, 1, 2, 124, 124, 1, 2, 38, 38, 1, 2, 124, 124,
    2, 4, 63, 558, 58, 559, 0, 1, 2, 585, 559, 1, 2, 61, 61, 2,
    4, 536, 33352, 586, 585, 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, 583, 588, 2, 3, 44,
  583, 588, 0, 1, 1, 587, 1, 1, 513, 1, 1, 513, 7, 1, 593, 1,
  600, 1, 595, 1, 597, 1, 620, 1, 622, 1, 623, 3, 3, 590, 58, 592,
    4, 273, 594, 58, 592, 3, 274, 58, 592, 1, 1, 587, 1, 2, 596, 59,
    2, 1, 587, 0, 1, 4, 123, 598, 619, 125, 2, 1, 599, 0, 1, 2,
  600, 598, 2, 1, 601, 2, 602, 603, 1, 5, 264, 624, 123, 599, 125, 1,
    5, 545, 544, 547, 543, 590, 3, 4, 40, 613, 41, 605, 3, 612, 604, 59,
    3, 606, 608, 59, 2, 5, 44, 543, 590, 612, 604, 0, 2, 1, 59, 1,
  597, 1, 4, 91, 617, 93, 607, 2, 4, 91, 617, 93, 607, 0, 2, 4,
   61, 123, 609, 125, 0, 1, 2, 611, 610, 3, 3, 44, 611, 610, 1, 44,
    0, 2, 1, 594, 3, 123, 609, 125, 2, 2, 61, 587, 0, 2, 2, 263,
16930, 2, 615, 614, 2, 3, 44, 615, 614, 0, 1, 4, 547, 543, 590, 616,
    2, 4, 91, 617, 93, 616, 0, 2, 1, 594, 0, 1, 2, 592, 619, 2,
    2, 592, 619, 0, 2, 6, 275, 40, 587, 41, 592, 621, 5, 276, 40, 587,
   41, 592, 2, 2, 277, 592, 0, 3, 5, 278, 40, 587, 41, 592, 7, 279,
  592, 278, 40, 587, 41, 59, 9, 280, 40, 596, 59, 596, 59, 596, 41, 592,
    4, 3, 281, 590, 59, 2, 282, 59, 2, 283, 59, 3, 284, 596, 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[113] = {
  "EOD", "TAG", "PPP", "MMM",
  "CHAR", "KEYWORD", "integer-constant", "character-constant",
  "string-constant", "SS", "level14", "level14-lv1",
  "level14-lv2", "level14-lv", "opt-post-ppp-or-mmm", "opt-postfix1",
  "opt-postfix2", "opt-postfix3", "opt-postfix4", "opt-postfix5",
  "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[113 -9] = {
    0, 6, 42, 45, 48, 69, 75,
   78, 81, 84, 87, 90, 106, 119, 124, 130, 137, 141, 148, 160, 183, 189, 193,
  197, 203, 213, 216, 258, 264, 268, 272, 276, 280, 284, 288, 292, 296, 300, 304,
  308, 314, 320, 326, 332, 338, 344, 350, 356, 362, 368, 375, 380, 387, 398, 405,
  409, 413, 416, 420, 424, 428, 432, 439, 443, 447, 454, 489, 493, 499, 502, 505,
  508, 523, 537, 540, 544, 548, 554, 558, 562, 568, 575, 582, 596, 604, 609, 615,
  622, 629, 633, 641, 648, 653, 660, 666, 672, 679, 683, 687, 692, 706, 711, 736,
  751,
};
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 () ...", "", 7},
  {1029, 2, "AST_IFTHEN", "if () ... else ...", "", 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, 2, "AST_DefProc", "DefProc", "", 3},
  {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 (;;) ...", "", 8+4+2},
  {1059, 2, "AST_C_While", "while () ...", "", 2},
  {1060, 2, "AST_C_DoWhile", "do ... while ();", "", 1},
  {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_Goto", "goto ...", "", 1},
  {1066, 1, "AST_Sourceline", "src", "", 1},
  {1067, 1, "AST_LINENO", "Line #", "", 1},
  {1068, 1, "AST_REDIRECT", "REDIR", "", 1},
  {1069, 2, "AST_SEQ", ";", "", 3},
  {1070, 2, "AST_CommaSEQ", ",", "", 3},
  {1071, 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", nextfree, nexttrip);
  fflush(stderr);
  exit(2);
}
int character_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] = 1068;
  AST[p+2] = mkconst(val);
}
int build_ast(int ap, int depth)
{
  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++];
  switch (phrase) {
  case 512:
    return -1;
  case 513:
    if (c[A[ap]].l > latest_line) latest_line = c[A[ap]].l;
    return A[ap];
  case 514:
fprintf(stdout, "<<%s>>", c[A[ap]].s);
    if (c[A[ap]].l > latest_line) latest_line = c[A[ap]].l;
    return;
  case 515:
    if (c[A[ap]].l > latest_line) latest_line = c[A[ap]].l;
    return;
  case 516:
    if (c[A[ap]].l > latest_line) latest_line = c[A[ap]].l;
    return;
  case 517:
    if (c[A[ap]].l > latest_line) latest_line = c[A[ap]].l;
    return;
  case 518:
    if (c[A[ap]].l > latest_line) latest_line = c[A[ap]].l;
    return A[ap];
  case 519:
    if (c[A[ap]].l > latest_line) latest_line = c[A[ap]].l;
    return A[ap];
  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(A[ap+0], depth+1);
    T[2] = build_ast(A[ap+1], depth+1);
    return mkbinop(1069, T[1], T[2]);
  } else {
    return -1;
  }
  return T[0];
case 522:
  return -1;
  if (alt == 0) {
    return build_ast(A[ap+0], depth+1);
  } else if (alt == 1) {
    T[1] = build_ast(A[ap+0], depth+1);
    T[2] = build_ast(A[ap+1], depth+1);
    T[3] = build_ast(A[ap+2], depth+1);
    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 == 2) {
    T[0] = mkbinop(1048, build_ast(A[ap+0], depth+1), -1);
    AST[(T[0])+3] = atol(c[AST[(T[0])+2]].s);
    return T[0];
  } else if (alt == 3) {
    T[0] = mkbinop(1048, build_ast(A[ap+0], depth+1), -1);
    AST[(T[0])+3] = c[AST[(T[0])+2]].s[0];
    return T[0];
  } else if (alt == 4) {
    T[0] = mkbinop(1048, build_ast(A[ap+0], depth+1), -1);
    AST[(T[0])+3] = c[AST[(T[0])+2]].s[0];
    return T[0];
  } else {
    return build_ast(A[ap+0], depth+1);
  }
case 523:
case 524:
  return build_ast(A[ap+0], depth+1);
case 525:
  return -1;
  T[1] = build_ast(A[ap+0], depth+1);
  T[2] = build_ast(A[ap+1], depth+1);
  T[3] = build_ast(A[ap+2], depth+1);
  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 526:
  if (alt == 0) return 1010;
  if (alt == 1) return 1012;
  return -1;
case 527:
case 528:
case 529:
case 530:
case 531:
  return build_ast(A[ap+0], depth+1);
case 532:
  if (alt == 3) return -1;
  T[1] = build_ast(A[ap+0], depth+1);
  T[2] = build_ast(A[ap+1], depth+1);
  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 533:
  if (alt == 0) {
    T[1] = build_ast(A[ap+0], depth+1);
    return mkbinop(1057, T[1], 2);
  } else {
    T[1] = build_ast(A[ap+2], depth+1);
    T[2] = build_ast(A[ap+3], depth+1);
    return mkbinop(1017, T[1], T[2]);
  }
case 534:
case 535:
  if (alt == 0) {
    T[1] = build_ast(A[ap+0], depth+1);
    T[2] = build_ast(A[ap+1], depth+1);
    return mkbinop(1054, T[1], T[2]);
  } else {
    return mkbinop(1054, -1, -1);
  }
case 536:
  return -1;
  return build_ast(A[ap+0], depth+1);
case 537:
  return -1;
case 538:
  if (alt == 0) {
    T[1] = build_ast(A[ap+0], depth+1);
    T[2] = build_ast(A[ap+1], depth+1);
    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(A[ap+0], depth+1);
    T[2] = build_ast(A[ap+1], depth+1);
    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 539:
  if (alt == 0) {
    return mkmonop(1011, -1);
  } else if (alt == 1) {
    return mkmonop(1013, -1);
  } else if (alt == 2) {
    T[1] = build_ast(A[ap+0], depth+1);
    T[2] = build_ast(A[ap+1], depth+1);
    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 540:
  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(A[ap+0], depth+1);
  } else if (alt == 7) {
    return build_ast(A[ap+0], depth+1);
  } else if (alt == 8) {
    return mkmonop(1055, -1);
  } else if (alt == 9) {
    return mkbinop(1057, -1, 1);
  }
  return -1;
case 541:
  T[1] = build_ast(A[ap+1], depth+1);
  T[2] = build_ast(A[ap+2], depth+1);
  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 542:
  return mkmonop(1056, build_ast(A[ap+0], depth+1));
case 543:
  if (alt == 0) return build_ast(A[ap+0], depth+1);
  return -1;
case 544:
  return -1;
case 545:
  return -1;
case 546:
  return -1;
case 547:
  if (alt == 0) return 0;
  if (alt == 1) return -1;
  T[0] = build_ast(A[ap+0], depth+1);
  if (alt <= 4) return 8+T[0];
  if (alt <= 7) return 4+T[0];
  if (alt <= 9) return 2+T[0];
  return 1+T[0];
case 548:
  if (alt == 0) return 1<<16;
  if (alt == 0) return 2<<16;
  return 0;
case 549:
case 550:
case 551:
case 552:
case 553:
case 554:
case 555:
case 556:
case 557:
case 558:
case 559:
  T[1] = build_ast(A[ap+0], depth+1);
  T[2] = build_ast(A[ap+1], depth+1);
  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 560:
case 561:
case 562:
case 563:
case 564:
case 565:
case 566:
case 567:
case 568:
case 569:
  if (alt == 0) {
    T[1] = build_ast(A[ap+0], depth+1);
    T[2] = build_ast(A[ap+1], depth+1);
    T[3] = build_ast(A[ap+2], depth+1);
    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 570:
  if (alt == 0) {
    return 1002;
  } else if (alt == 1) {
    return 1003;
  } else {
    return 1004;
  }
case 571:
  if (alt == 0) {
    return 1000;
  } else {
    return 1001;
  }
case 572:
  if (alt == 0) {
    return 1044;
  } else {
    return 1045;
  }
case 573:
  if (alt == 0) {
    return 1022;
  } else if (alt == 1) {
    return 1024;
  } else if (alt == 2) {
    return 1025;
  } else {
    return 1023;
  }
case 574:
  if (alt == 0) {
    return 1026;
  } else {
    return 1027;
  }
case 575:
  return 1038;
case 576:
    return -1;
case 577:
  return 1042;
case 578:
  return 1039;
case 579:
  return -1;
case 580:
  return 1034;
case 581:
  return 1035;
case 582:
  if (alt == 0) {
    T[1] = -1;
    T[2] = build_ast(A[ap+0], depth+1);
    T[3] = build_ast(A[ap+1], depth+1);
    return mk(1018, 3, T);
  } else {
    return -1;
  }
case 583:
  T[1] = build_ast(A[ap+0], depth+1);
  T[2] = build_ast(A[ap+1], depth+1);
  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 584:
  return -1;
case 585:
  if (alt == 0) {
    T[1] = build_ast(A[ap+0], depth+1);
    T[2] = -1;
    T[3] = build_ast(A[ap+2], depth+1);
    T[4] = build_ast(A[ap+3], depth+1);
    return mkbinop(T[3], T[1], T[4]);
  } else {
    return -1;
  }
case 586:
  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 587:
case 588:
  if (alt == 0) {
    T[1] = build_ast(A[ap+0], depth+1);
    T[2] = build_ast(A[ap+1], depth+1);
    if (T[2] == -1) return T[1];
    return mkbinop(1070, T[1], T[2]);
  } else {
    return -1;
  }
case 589:
  return build_ast(A[ap+0], depth+1);
case 590:
  T[1] = build_ast(A[ap+0], depth+1);
  return mkbinop(1049, T[1], 0);
case 591:
  T[1] = build_ast(A[ap+0], depth+1);
  return mkbinop(1049, T[1], 1);
case 592:
  return build_ast(A[ap+0], depth+1);
case 593:
  if (alt == 0) {
    return build_ast(A[ap+1], depth+1);
  } else if (alt == 1) {
    return build_ast(A[ap+1], depth+1);
  }
  return build_ast(A[ap+0], depth+1);
case 594:
  return build_ast(A[ap+0], depth+1);
case 595:
  return build_ast(A[ap+0], depth+1);
case 596:
  if (alt == -1) return -1;
  return build_ast(A[ap+0], depth+1);
case 597:
  T[1] = build_ast(A[ap+0], depth+1);
  T[2] = build_ast(A[ap+1], depth+1);
  return T[2];
case 598:
  return -1;
case 599:
  return -1;
case 600:
  return -1;

case 601:
  return -1;


case 602:
  return -1;




case 603:
  return -1;


case 604:
  return -1;


case 605:
  return -1;



case 606:
case 607:
  return -1;







case 608:
  return -1;





case 609:
case 610:
  return -1;



case 611:
  return -1;





case 613:
case 614:
  return -1;


case 615:
  return -1;


case 616:
  return -1;


case 617:
  return -1;



case 618:
case 619:
  if (alt == 1) return -1;
  T[1] = build_ast(A[ap+0], depth+1);
  T[2] = build_ast(A[ap+1], depth+1);
  if (T[2] == -1) return -1;
  return mkbinop(1069, T[0], T[1]);



case 620:
  T[1] = build_ast(A[ap+0], depth+1);
  T[2] = build_ast(A[ap+1], depth+1);
  if (alt == 0) T[3] = build_ast(A[ap+2], depth+1);
  return T[2];


case 621:
  if (alt == 1) return -1;
  return build_ast(A[ap+0], depth+1);




case 622:
  return -1;





  case 623:
  return -1;




case 624:


  T[1] = build_ast(A[ap+0], depth+1);
  return mkmonop(1019, T[1]);



default:
  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;
    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 1065: ;
  case 1066: ;
  case 1067: ;
  case 1068: ;
  case 1071: ;
  case 1069: ;
  case 1070: ;
  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 > 1071) {
    fprintf(stderr, "* Lookup oper %d and add it to the switch in genstack.c\n", oper);
  }
  switch (oper) {
  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 1070:
    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 1065: ;
  case 1066: ;
  case 1067: ;
  case 1068: ;
  case 1071: ;
  case 1069: ;
  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)]]) == 1068)
        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)]]) == 1068)
        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)]]) == 1068)
        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(0, 0);
    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]) == 1068) program = AST[(program)+2];
    codegen_stack(program);
    fprintf(stdout, "\n");
    fflush(stdout);
  }
  exit(0); return(1);
}
