#include "defs.h"

/*  The three line banner used here should be replaced with a one line
 *  #ident directive if the target C compiler supports #ident
 *  directives.
 *
 *  If the skeleton is changed, the banner should be changed so that
 *  the altered version can easily be distinguished from the original.
 */

char *banner[] = {
  "/*%%*/",
  "#ifndef lint",
  "char yysccsid[] = \"@(#)lrpar	0.1 (Chris) 10/03/90\";",
  "#endif",
  "#define YYDEBUG 1",
  "/*%%*/",
  0
};

char *header[] = {
  "/*%%*/",
  "#define yyclearin (yychar=(-1))",
  "#define yyerrok (yyerrflag=0)",
  "#ifndef YYSTACKSIZE",
  "#ifdef YYMAXDEPTH",
  "#define YYSTACKSIZE YYMAXDEPTH",
  "#else",
  "#define YYSTACKSIZE 300",
  "#endif",
  "#endif",
  "int yydebug;",
  "int yynerrs;",
  "int yyerrflag;",
  "int yychar;",
  "short *yyssp;",
  "YYSTYPE *yyvsp;",
  "YYSTYPE yyval;",
  "YYSTYPE yylval;",
  "#define yystacksize YYSTACKSIZE",
  "/*short yyss[YYSTACKSIZE];*/",
  "/*YYSTYPE yyvs[YYSTACKSIZE];*/",
  "#define mallocate malloc",
  "extern char *malloc();",
  "extern int lineno;",
  "extern char *fname;",
  "/*%%*/",
  0
};

char *body[] = {
  "/*%%*/",
  "#define YYABORT goto yyabort",
  "#define YYACCEPT goto yyaccept",
  "#define YYERROR goto yyerrlab",
  "",
  "#define LRACCEPT 1",
  "#define LROK 0",
  "#define LRSYNERR -1",
  "#define LRABORT -2",
  "",
  "struct lrmachine {",
  "  short yyss[YYSTACKSIZE], *yyssp;",
  "  YYSTYPE yyvs[YYSTACKSIZE], *yyvsp;",
  "  int yystate, yychar;",
  "};",
  "extern struct lrmachine *lr_create();",
  "",
  "int yyparse()",
  "{",
  "  struct lrmachine *lrm;",
  "  int r;",
  "",
  "  yydebug = 0;",
  "  lrm = lr_create();",
  "  do {",
  "    r = lr_move(lrm);",
  "    if (r < 0) {",
  "      lr_error(lrm, \"Syntax error\");",
  "      /* yyerror(\"syntax error.\\n\"); */",
  "      r = lr_panic(lrm);",
  "    }",
  "  } while(r == LROK);",
  "  if (r == LRABORT) return(1);",
  "  return(0); /* Accept. */",
  "}",
  "",
  "struct lrmachine *lr_create()",
  "{",
  "  struct lrmachine *lrm = (struct lrmachine *) mallocate(sizeof(struct lrmachine));",
  "  lrm->yyssp = lrm->yyss;  lrm->yyvsp = lrm->yyvs;",
  "  *(lrm->yyssp) = lrm->yystate = 0;",
  "  lrm->yychar = (-1);",
  "  return(lrm);",
  "}",
  "",
  "int lr_move(lrm)",
  "     struct lrmachine *lrm;",
  "{",
  "  int yyn, yym;",
  "",
  "  /* First, lex a character if we need one. */",
  "  /* Need to show that doing this before the default reduction",
  "     will work (see original skeleton. */",
  "  if ( ! yydefred[lrm->yystate] && lrm->yychar < 0) {",
  "    if ( (lrm->yychar = yylex()) < 0) lrm->yychar = 0;",
  "    if (yydebug) {",
  "      char *yys = 0;",
  "      if (lrm->yychar <= YYMAXTOKEN) yys = yyname[lrm->yychar];",
  "      if (! yys) yys = \"illegal token\";",
  "      fprintf(stderr, \"yydebug: state %d: reading %d (%s)\\n\",",
  "         lrm->yystate, lrm->yychar, yys);",
  "    }",
  "  }",
  "",
  "  if (yydebug)",
  "    fprintf(stderr, \"yydebug: state %d: see %d, \", lrm->yystate, lrm->yychar);",
  "",
  "  /* Now, try a shift (if no default reduction). */",
  "  if ( ! yydefred[lrm->yystate] && (yyn = yysindex[lrm->yystate]) &&",
  "          (yyn += lrm->yychar) >= 0 && yyn <= YYTABLESIZE &&",
  "          yycheck[yyn] == lrm->yychar )",
  "   {",
  "     if (yydebug) fprintf(stderr, \"shifting to %d\\n\", yytable[yyn]);",
  "     if (lrm->yyssp >= lrm->yyss + YYSTACKSIZE - 1) goto yyoverflow;",
  "     *++(lrm->yyssp) = lrm->yystate = yytable[yyn];",
  "     *++(lrm->yyvsp) = yylval;",
  "     lrm->yychar = (-1); /* This effectively shifts the character. */",
  "     return(LROK);",
  "   }",
  "",
  "  /* No shift, so check for a reduction. */",
  "  if ( yydefred[lrm->yystate] ||",
  "       ((yyn = yyrindex[lrm->yystate]) && (yyn += lrm->yychar) >= 0 &&",
  "          yyn <= YYTABLESIZE && yycheck[yyn] == lrm->yychar) )",
  "   {",
  "     YYSTYPE yyval;",
  "     if (yydefred[lrm->yystate])  yyn = yydefred[lrm->yystate];",
  "      else yyn = yytable[yyn];",
  "     if (yydebug) fprintf(stderr, \"reducing by rule %d\\n\", yyn);",
  "     yym = yylen[yyn];",
  "     yyval = lrm->yyvsp[1-yym];",
  "",
  "     switch (yyn) { /* Reduction actions. */",
  "/*%%*/",
  0
};

char *trailer[] = {
  "/*%%*/",
  "     }",
  "     lrm->yyssp -= yym;  lrm->yyvsp -= yym;",
  "     lrm->yystate = *(lrm->yyssp);",
  "     yym = yylhs[yyn];",
  "",
  "     if (lrm->yystate == 0 && yym == 0) {",
  "       /* Check the way the grammar is made: may only have to be done",
  "           once at start of parse... */",
  "       if (yydebug)",
  "         fprintf(stderr, \"yydebug: ...after reduction, go to %d from 0\\n\",",
  "            YYFINAL);",
  "       *++(lrm->yyssp) = lrm->yystate = YYFINAL;",
  "       *++(lrm->yyvsp) = yyval;",
  "       if (lrm->yychar < 0) {",
  "         if ( (lrm->yychar = yylex()) < 0) lrm->yychar = 0;",
  "         if (yydebug) {",
  "           char *yys = 0;",
  "           if (lrm->yychar <= YYMAXTOKEN) yys = yyname[lrm->yychar];",
  "           if (! yys) yys = \"illegal token\";",
  "           fprintf(stderr, \"yydebug: state %d: reading %d (%s)\\n\",",
  "              lrm->yystate, lrm->yychar, yys);",
  "         }",
  "       }",
  "       if (lrm->yychar == 0) return(LRACCEPT); /* ACCEPT! */",
  "       return(LROK);",
  "     }",
  "",
  "     if ((yyn = yygindex[yym]) && (yyn += lrm->yystate) >= 0 &&",
  "          yyn <= YYTABLESIZE && yycheck[yyn] == lrm->yystate)",
  "       lrm->yystate = yytable[yyn]; else lrm->yystate = yydgoto[yym];",
  "",
  "     if (yydebug)",
  "       fprintf(stderr, \"yydebug: ...after reduction, goto %d from %d\\n\",",
  "         lrm->yystate, *(lrm->yyssp));",
  "     if (lrm->yyssp >= lrm->yyss + YYSTACKSIZE - 1) goto yyoverflow;",
  "     *++(lrm->yyssp) = lrm->yystate;",
  "     *++(lrm->yyvsp) = yyval;",
  "     return(LROK);",
  "   }",
  "        ",
  "  /* If we\'ve got to here, then it\'s an error. */",
  "  return(LRSYNERR);",
  "",
  "yyoverflow:",
  "  yyerror(\"yacc stack overflow.\\n\");",
  "  return(LRABORT);",
  "}",
  "",
  "",
  "",
  "lr_error(lrm, m)",
  "     struct lrmachine *lrm;",
  "     char *m;",
  "{",
  "  char *yys;",
  "  if (lrm->yychar <= YYMAXTOKEN) yys = yyname[lrm->yychar];",
  "  if (! yys) yys = \"illegal token\";",
  "  if (lrm->yychar == ID || lrm->yychar == OP)",
  "    fprintf(stderr, \"File \'%s\', line %d -- %s: Found unexpected \'%s\'\\n\", ",
  "	    fname, lineno, m, sm_pname(yylval.symbol));  ",
  "  else",
  "    fprintf(stderr, \"File \'%s\', line %d -- %s: Found unexpected %s\\n\", fname, ",
  "	    lineno, m, yys);",
  "}",
  "",
  "",
  "lr_panic(lrm)",
  "     struct lrmachine *lrm;",
  "{",
  "  char *yys;",
  "  int yyn, r;",
  "",
  "  for(;;) {",
  "    /* First, back up stack until error token can be shifted. */",
  "    while( ! (yyn = yysindex[*(lrm->yyssp)]) || (yyn += YYERRCODE) < 0 ||",
  "           yyn > YYTABLESIZE || yycheck[yyn] != YYERRCODE)",
  "     {",
  "       if (yydebug)",
  "          fprintf(stderr, \"yydebug: err poping state %d\\n\", *(lrm->yyssp));",
  "       if (lrm->yyssp <= lrm->yyss) return(LRABORT);",
  "       --(lrm->yyssp);  --(lrm->yyvsp);",
  "     }",
  "    if (yydebug) fprintf(stderr, \"yydebug: err shift from %d to %d\\n\",",
  "                            *(lrm->yyssp), yytable[yyn]);",
  "    if (lrm->yyssp >= lrm->yyss + YYSTACKSIZE -1) {",
  "       yyerror(\"yacc stack overflow.\\n\");",
  "       return(LRABORT);",
  "    }",
  "    *++(lrm->yyssp) = lrm->yystate = yytable[yyn];",
  "    *++(lrm->yyvsp) = yylval;",
  "",
  "    /* Now, discard tokens until a token can be shifted. */",
  "    for(;;) {",
  "      r = lr_move(lrm);",
  "      if (r == LRACCEPT) return(LRACCEPT);",
  "      if (r == LROK && lrm->yychar == -1) break; /* Good shift! */",
  "      if (r == LROK) continue; /* Don\'t discard until we can\'t move. */",
  "      if (r == LRABORT || lrm->yychar == 0) return(LRABORT);",
  "      if (yydebug) {",
  "        yys = (lrm->yychar <= YYMAXTOKEN ? yyname[lrm->yychar] : 0);",
  "        if (!yys) yys = \"illegal token\";",
  "        fprintf(stderr, \"yydebug: state %d: err discard token %d (%s)\\n\",",
  "          lrm->yystate, lrm->yychar, yys);",
  "      }",
  "      lrm->yychar = -1; /* Discard the character. */",
  "    }",
  "",
  "    /* Finally, try to do two more shifts before ending panic. */",
  "    do { r = lr_move(lrm); } while (r == LROK && lrm->yychar != -1);",
  "    if (r < 0) continue; /* Still bad: try again. */",
  "    if (r == LRACCEPT) return(r);",
  "    do { r = lr_move(lrm); } while (r == LROK && lrm->yychar != -1);",
  "    if (r < 0) continue; /* Still bad: try again. */",
  "    return(r);",
  "  }",
  "}",
  "/*%%*/",
  0
};


write_section(section)
     char *section[];
{
  register int i;

  for (i = 0; section[i]; ++i) {
     ++outline;
     fprintf(output_file, "%s\n", section[i]);
  }
}
