
# line 2 "error_table.y"
/*
 *
 *	Copyright (C) 1988, 1989 by the Massachusetts Institute of Technology
 *    	Developed by the MIT Student Information Processing Board (SIPB).
 *    	For copying information, see the file mit-copyright.h in this release.
 *
 */
#include <stdio.h>
char *str_concat(), *ds(), *quote(); /* *malloc(), *realloc(); NEXXXT */
char *current_token = (char *)NULL;
extern char *table_name;

# line 14 "error_table.y"
typedef union  {
	char *dynstr;
} YYSTYPE;
# define ERROR_TABLE 257
# define ERROR_CODE_ENTRY 258
# define END 259
# define STRING 260
# define QUOTED_STRING 261

# line 22 "error_table.y"
#define yyclearin yychar = -1
#define yyerrok yyerrflag = 0
extern int yychar;
extern short yyerrflag;
#ifndef YYMAXDEPTH
#define YYMAXDEPTH 150
#endif
YYSTYPE yylval, yyval;
# define YYERRCODE 256

# line 64 "error_table.y"

/*
 *
 * Copyright 1986, 1987 by the MIT Student Information Processing Board
 *
 * For copyright info, see mit-sipb-copyright.h.
 */

#include <string.h>
#include <assert.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/time.h>
#include "internal.h"
#include "error_table.h"
#include "mit-sipb-copyright.h"

#ifndef	lint
static char const rcsid_error_table_y[] =
    "$Header: error_table.y,v 1.7 89/01/01 07:23:17 raeburn Locked $";
#endif

/* char *malloc(), *realloc(); NEXXXT */
extern FILE *hfile, *cfile;

static long gensym_n = 0;
char *
gensym(x)
	char const *x;
{
	char *symbol;
	if (!gensym_n) {
		struct timeval tv;
		struct timezone tzp;
		gettimeofday(&tv, &tzp);
		gensym_n = (tv.tv_sec%10000)*100 + tv.tv_usec/10000;
	}
	symbol = malloc(32 * sizeof(char));
	gensym_n++;
	sprintf(symbol, "et%ld", gensym_n);
	return(symbol);
}

char *
ds(string)
	char const *string;
{
	char *rv;
	rv = malloc(strlen(string)+1);
	strcpy(rv, string);
	return(rv);
}

char *
quote(string)
	char const *string;
{
	char *rv;
	rv = malloc(strlen(string)+3);
	strcpy(rv, "\"");
	strcat(rv, string);
	strcat(rv, "\"");
	return(rv);
}

long table_number;
int current = 0;
char **error_codes = (char **)NULL;

add_ec(name, description)
	char const *name, *description;
{
	fprintf(cfile, "\t\"%s\",\n", description);
	if (error_codes == (char **)NULL) {
		error_codes = (char **)malloc(sizeof(char *));
		*error_codes = (char *)NULL;
	}
	error_codes = (char **)realloc((char *)error_codes,
				       (current + 2)*sizeof(char *));
	error_codes[current++] = ds(name);
	error_codes[current] = (char *)NULL;
}

add_ec_val(name, val, description)
	char const *name, *val, *description;
{
	const int ncurrent = atoi(val);
	if (ncurrent < current) {
		printf("Error code %s (%d) out of order", name,
		       current);
		return;
	}
      
	while (ncurrent > current)
	     fputs("\t(char *)NULL,\n", cfile), current++;
	
	fprintf(cfile, "\t\"%s\",\n", description);
	if (error_codes == (char **)NULL) {
		error_codes = (char **)malloc(sizeof(char *));
		*error_codes = (char *)NULL;
	}
	error_codes = (char **)realloc((char *)error_codes,
				       (current + 2)*sizeof(char *));
	error_codes[current++] = ds(name);
	error_codes[current] = (char *)NULL;
} 

put_ecs()
{
	int i;
	for (i = 0; i < current; i++) {
	     if (error_codes[i] != (char *)NULL)
		  fprintf(hfile, "#define %-40s (%ldL)\n",
			  error_codes[i], table_number + i);
	}
}

/*
 * char_to_num -- maps letters and numbers into a small numbering space
 * 	uppercase ->  1-26
 *	lowercase -> 27-52
 *	digits    -> 53-62
 *	underscore-> 63
 */

static const char char_set[] =
	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";

int char_to_num(c)
	char c;
{
	const char *where;
	int diff;

	where = strchr (char_set, c);
	if (where) {
		diff = where - char_set + 1;
		assert (diff < (1 << ERRCODE_RANGE));
		return diff;
	}
	else if (isprint (c))
		fprintf (stderr,
			 "Illegal character `%c' in error table name\n",
			 c);
	else
		fprintf (stderr,
			 "Illegal character %03o in error table name\n",
			 c);
	exit (1);
}

set_table_num(string)
	char *string;
{
	if (char_to_num (string[0]) > char_to_num ('z')) {
		fprintf (stderr, "%s%s%s%s",
			 "First character of error table name must be ",
			 "a letter; name ``",
			 string, "'' rejected\n");
		exit (1);
	}
	if (strlen(string) > 4) {
		fprintf(stderr, "Table name %s too long, truncated ",
			string);
		string[4] = '\0';
		fprintf(stderr, "to %s\n", string);
	}
	while (*string != '\0') {
		table_number = (table_number << BITS_PER_CHAR)
			+ char_to_num(*string);
		string++;
	}
	table_number = table_number << ERRCODE_RANGE;
}

#include "et_lex.lex.c"
short yyexca[] ={
-1, 1,
	0, -1,
	-2, 0,
	};
# define YYNPROD 9
# define YYLAST 29
short yyact[]={

  15,  16,  11,   7,   8,   7,   4,   2,  12,  17,
  14,   6,   5,   1,   3,  10,   0,   9,   0,   0,
   0,   0,   0,   0,   0,  13,   0,   0,  18 };
short yypact[]={

-250,-1000,-254,-253,-1000,-255,-1000,-258,-1000,-1000,
 -36,-1000,-261,-259,-1000,-1000, -35,-261,-1000 };
short yypgo[]={

   0,  15,  10,  14,  13,  12,  11 };
short yyr1[]={

   0,   4,   3,   5,   5,   6,   6,   1,   2 };
short yyr2[]={

   0,   4,   1,   2,   1,   4,   6,   1,   1 };
short yychk[]={

-1000,  -4, 257,  -3, 260,  -5,  -6, 258, 259,  -6,
  -1, 260,  44,  61,  -2, 261, 260,  44,  -2 };
short yydef[]={

   0,  -2,   0,   0,   2,   0,   4,   0,   1,   3,
   0,   7,   0,   0,   5,   8,   0,   0,   6 };
# line 1 "/usr/lib/yaccpar"
#ifndef lint
static char yaccpar_sccsid[] = "@(#)yaccpar	4.1	(Berkeley)	2/11/83";
#endif not lint

# define YYFLAG -1000
# define YYERROR goto yyerrlab
# define YYACCEPT return(0)
# define YYABORT return(1)

/*	parser for yacc output	*/

#ifdef YYDEBUG
int yydebug = 0; /* 1 for debugging */
#endif
YYSTYPE yyv[YYMAXDEPTH]; /* where the values are stored */
int yychar = -1; /* current input token number */
int yynerrs = 0;  /* number of errors */
short yyerrflag = 0;  /* error recovery flag */

yyparse() {

	short yys[YYMAXDEPTH];
	short yyj, yym;
	register YYSTYPE *yypvt;
	register short yystate, *yyps, yyn;
	register YYSTYPE *yypv;
	register short *yyxi;

	yystate = 0;
	yychar = -1;
	yynerrs = 0;
	yyerrflag = 0;
	yyps= &yys[-1];
	yypv= &yyv[-1];

 yystack:    /* put a state and value onto the stack */

#ifdef YYDEBUG
	if( yydebug  ) printf( "state %d, char 0%o\n", yystate, yychar );
#endif
		if( ++yyps>= &yys[YYMAXDEPTH] ) { yyerror( "yacc stack overflow" ); return(1); }
		*yyps = yystate;
		++yypv;
		*yypv = yyval;

 yynewstate:

	yyn = yypact[yystate];

	if( yyn<= YYFLAG ) goto yydefault; /* simple state */

	if( yychar<0 ) if( (yychar=yylex())<0 ) yychar=0;
	if( (yyn += yychar)<0 || yyn >= YYLAST ) goto yydefault;

	if( yychk[ yyn=yyact[ yyn ] ] == yychar ){ /* valid shift */
		yychar = -1;
		yyval = yylval;
		yystate = yyn;
		if( yyerrflag > 0 ) --yyerrflag;
		goto yystack;
		}

 yydefault:
	/* default state action */

	if( (yyn=yydef[yystate]) == -2 ) {
		if( yychar<0 ) if( (yychar=yylex())<0 ) yychar = 0;
		/* look through exception table */

		for( yyxi=yyexca; (*yyxi!= (-1)) || (yyxi[1]!=yystate) ; yyxi += 2 ) ; /* VOID */

		while( *(yyxi+=2) >= 0 ){
			if( *yyxi == yychar ) break;
			}
		if( (yyn = yyxi[1]) < 0 ) return(0);   /* accept */
		}

	if( yyn == 0 ){ /* error */
		/* error ... attempt to resume parsing */

		switch( yyerrflag ){

		case 0:   /* brand new error */

			yyerror( "syntax error" );
		yyerrlab:
			++yynerrs;

		case 1:
		case 2: /* incompletely recovered error ... try again */

			yyerrflag = 3;

			/* find a state where "error" is a legal shift action */

			while ( yyps >= yys ) {
			   yyn = yypact[*yyps] + YYERRCODE;
			   if( yyn>= 0 && yyn < YYLAST && yychk[yyact[yyn]] == YYERRCODE ){
			      yystate = yyact[yyn];  /* simulate a shift of "error" */
			      goto yystack;
			      }
			   yyn = yypact[*yyps];

			   /* the current yyps has no shift onn "error", pop stack */

#ifdef YYDEBUG
			   if( yydebug ) printf( "error recovery pops state %d, uncovers %d\n", *yyps, yyps[-1] );
#endif
			   --yyps;
			   --yypv;
			   }

			/* there is no state on the stack with an error shift ... abort */

	yyabort:
			return(1);


		case 3:  /* no shift yet; clobber input char */

#ifdef YYDEBUG
			if( yydebug ) printf( "error recovery discards char %d\n", yychar );
#endif

			if( yychar == 0 ) goto yyabort; /* don't discard EOF, quit */
			yychar = -1;
			goto yynewstate;   /* try again in the same state */

			}

		}

	/* reduction by production yyn */

#ifdef YYDEBUG
		if( yydebug ) printf("reduce %d\n",yyn);
#endif
		yyps -= yyr2[yyn];
		yypvt = yypv;
		yypv -= yyr2[yyn];
		yyval = yypv[1];
		yym=yyn;
			/* consult goto table to find next state */
		yyn = yyr1[yyn];
		yyj = yypgo[yyn] + *yyps + 1;
		if( yyj>=YYLAST || yychk[ yystate = yyact[yyj] ] != -yyn ) yystate = yyact[yypgo[yyn]];
		switch(yym){
			
case 1:
# line 27 "error_table.y"
{ table_name = ds(yypvt[-2].dynstr);
			  current_token = table_name;
			  put_ecs(); } break;
case 2:
# line 33 "error_table.y"
{ current_token = yypvt[-0].dynstr;
			  set_table_num(yypvt[-0].dynstr);
			  yyval.dynstr = yypvt[-0].dynstr; } break;
case 5:
# line 43 "error_table.y"
{ add_ec(yypvt[-2].dynstr, yypvt[-0].dynstr);
			  free(yypvt[-2].dynstr);
			  free(yypvt[-0].dynstr); } break;
case 6:
# line 47 "error_table.y"
{ add_ec_val(yypvt[-4].dynstr, yypvt[-2].dynstr, yypvt[-0].dynstr);
			  free(yypvt[-4].dynstr);
			  free(yypvt[-2].dynstr);
			  free(yypvt[-0].dynstr);
			} break;
case 7:
# line 55 "error_table.y"
{ yyval.dynstr = ds(yypvt[-0].dynstr);
			  current_token = yyval.dynstr; } break;
case 8:
# line 60 "error_table.y"
{ yyval.dynstr = ds(yypvt[-0].dynstr);
			  current_token = yyval.dynstr; } break;
# line 148 "/usr/lib/yaccpar"

		}
		goto yystack;  /* stack new state and value */

	}
