/*%%*/
#ifndef lint
char yysccsid[] = "@(#)lrpar	0.1 (Chris) 10/03/90";
#endif
#define YYDEBUG 1
/*%%*/
/*%%*/
#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;
/*%%*/
/*%%*/
#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. */
/*%%*/
/*%%*/
     }
     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);
  }
}
/*%%*/
