[comp.os.minix] Yacc for Minix

glenn@extro.ucc.su.oz (G. Geers [ext 3241]) (06/28/89)

The next four articles contain a public domain version of yacc.
This has only been tested on PC-MINIX (1.3c with 1.1 compiler) but
should work on ST-MINIX with no modifications (see README.MINIX).

		Share and Enjoy,
				Glenn

Glenn Geers
Dept. Theoretical Physics
University of Sydney
Sydney, N.S.W. 2006 		Phone: +61 2 692-3241

Perfection was a word invented by
someone who couldn't do any better

Usual disclaimer applies


--- cut here --- cut here --- cut here --- cut here --- cut here ---
#!/bin/sh
# This is a shell archive.  Remove anything before the /bin/sh line
# then unpack it by saving it in a file and typing "sh file"
# (Files unpacked will be owned by you and have default permissions).
# Don't worry about trailing garbage - the archive ends with exit
# This archive contains the following files:
#	./yprcft.c
#	./yprlok.c
#	./yptitm.c
#	./ysetup.c
#	./yskpcm.c
#	./ysmnam.c
#	./ystagn.c
#	./ystate.c
#	./ystin.c
#	./ystuni.c
#	./ysumry.c
#	./ywarry.c
#	./ywract.c
#	./ywritm.c
#	./ywstat.c
#	./yypars
#
if `test ! -s ./yprcft.c`
then
echo "writing ./yprcft.c"
cat > ./yprcft.c << '\EOF\'
#include "y3.h"

precftn(r, t, s)
{
	/* decide a shift/reduce conflict by precedence.*/
	/* r is a rule number, t a token number */
	/* the conflict is in state s */
	/* temp1[t] is changed to reflect the action */

	int	lp, lt, action;

	lp = levprd[r];
	lt = toklev[t];
	if ( PLEVEL(lt) == 0 || PLEVEL(lp) == 0 ) {
		/* conflict */
		if ( foutput != NULL ) 
			fprintf( foutput, "\n%d: shift/reduce conflict (shift %d, red'n %d) on %s",
			    s, temp1[t], r, symnam(t) );
		++zzsrconf;
		return;
	}
	if ( PLEVEL(lt) == PLEVEL(lp) ) 
		action = ASSOC(lt);
	else if ( PLEVEL(lt) > PLEVEL(lp) ) 
		action = RASC;  /* shift */
	else 
		action = LASC;  /* reduce */

	switch ( action ) {

	case BASC:  /* error action */
		temp1[t] = ERRCODE;
		return;

	case LASC:  /* reduce */
		temp1[t] = -r;
		return;

	}
}
\EOF\
else
  echo "will not over write ./yprcft.c"
fi
if `test ! -s ./yprlok.c`
then
echo "writing ./yprlok.c"
cat > ./yprlok.c << '\EOF\'
#include "y1.h"

prlook( p ) 
struct looksets *p;

{
	register j, *pp;
	pp = p->lset;
	if ( pp == 0 ) 
		fprintf( foutput, "\tNULL");
	else      {
		fprintf( foutput, " { " );
		TLOOP(j)
		 {
			if ( BIT(pp, j) ) 
				fprintf( foutput,  "%s ", symnam(j) );
		}
		fprintf( foutput,  "}" );
	}
}
\EOF\
else
  echo "will not over write ./yprlok.c"
fi
if `test ! -s ./yptitm.c`
then
echo "writing ./yptitm.c"
cat > ./yptitm.c << '\EOF\'
#include "y1.h"

/*
 * yptitm.1c
 *
 * Modified to make debug code conditionally compile.
 * 28-Aug-81
 * Bob Denny
 */

putitem( ptr, lptr )  
int	*ptr;
struct looksets *lptr;


{
	register struct item *j;

#ifdef debug
	if ( foutput != NULL ) {

		fprintf( foutput, "putitem(%s), state %d\n", writem(ptr), nstate );
	}
#endif
	j = pstate[nstate+1];
	j->pitem = ptr;
	if ( !nolook ) 
		j->look = flset( lptr );
	pstate[nstate+1] = ++j;
	if ( (int *)j > zzmemsz ) {

		zzmemsz = (int *)j;
		if ( zzmemsz >=  &mem0[MEMSIZE] ) 
			error( "out of state space" );
	}
}
\EOF\
else
  echo "will not over write ./yptitm.c"
fi
if `test ! -s ./ysetup.c`
then
echo "writing ./ysetup.c"
cat > ./ysetup.c << '\EOF\'
/*
 * YSETUP.C  -- Modified for use with DECUS LEX
 *              Variable "yylval" resides in yylex(), not in yypars();
 *              Therefore, is defined "extern" here.
 *
 *              Also, the command line processing for the Decus version
 *              has been changed.  A new switch has been added to allow
 *              specification of the "table" file name(s), and unused
 *              switch processing removed.
 *
 *                               NOTE
 *              This probably won't run on UNIX any more.
 *
 * Bob Denny 27-Aug-81
 * Bob Denny 22-Mar-82 (01) Added header line, changes for 'new' DECUS library
 * Bob Denny 12-Apr-83 (02) Make filename[] size per #define'd FNAMESIZE so
 *                          VAX filenames won't blow out.  Conditionalize
 *                          time handling for banner.  Make filespec buffer
 *                          static for safety, since global "infile" is
 *                          pointed to it.
 * Scott Guthery 15-May-83  (03) Fixed up option flag handling for RT-11
 *			 23-Dec-83  Adapted for IBM PC/XT & DeSmet C compiler
 */

#include "y2.h"

static char	filename[FNAMESIZE];

int	i, j, lev, t, ty;
int	c;
int	tempty;
int	*p;
int	defsw, infsw;
char	actname[8];
char	*cp;

setup(argc, argv)
int	argc;
char	*argv[];
{
	char	finsave[FNAMESIZE];

	defsw = infsw = 0;
	foutput = NULL;
	fdefine = NULL;
	i = 1;                                               /*(03)*/
	while ( argc > 1 && argv[i][0] == '-' )               /*(03)*/ {
		while ( *++(argv[i]) ) {
			switch ( *argv[i] ) {
			case 'i':
			case 'I':
				infsw++;
				continue;
			case 'h':
			case 'H':
				defsw++;
				continue;
			default:
				fprintf(stderr, "Illegal option: %c\n", *argv[i]);
				usage();
			}
		}
		i++;                                              /*(03)*/
		argc--;
	}

	if (argc < 2) 
		usage();               /* Catch no filename given */

	/*
 * Now open the input file with a default extension of ".Y",
 * then replace the period in argv[1] with a null, so argv[1]
 * can be used to form the table, defs and info filenames.
 */

	cp = argv[i];
	while (*cp++ != '.' && *cp != '\0')
		; /* Scan past '.' or to null */
	if (*cp == '\0') {
		strcpy(filename, argv[i]); 
		strcat(filename, ".Y");
	} else
	 {
		strcpy(filename, argv[i]);
		*(argv[i] - 1) = '\0';             /* Null the period */
	}

	strcpy(finsave, filename);
	if ((finput = fopen( filename, "r" )) == NULL )
		error( "cannot open input file \"%s\"", filename );

	/*
 * Now open the .H and .I files if requested.
 */

	if (defsw) {
		strcpy(filename, argv[i]); 
		strcat(filename, ".h");
		fdefine = fopen(filename, "w");
		if (fdefine == NULL) 
			error("cannot open defs file\"%s\"", filename);
	}

	if (infsw) {
		strcpy(filename, argv[i]); 
		strcat(filename, ".i");
		foutput = fopen(filename, "w");
		if (foutput == NULL) 
			error("cannot open info file\"%s\"", filename);
	}
	/*
 * Now the "table" output C file.
 */
	strcpy(filename, argv[i]); 
	strcat(filename, ".c");
	ftable = fopen(filename, "w");
	if ( ftable == NULL ) 
		error( "cannot open table file\"%s\"", filename);
	/*
 * Finally, the temp files.
 */
	ftemp = fopen( TEMPNAME, "w" );
	if ( ftemp == NULL ) 
		error( "cannot open temp file" );
	faction = fopen( ACTNAME, "w" );
	if ( faction == NULL ) 
		error( "cannot open action file" );
	/*
 * Now put the full filename of the input file into
 * the "filename" buffer for cpyact(), and point the
 * global cell "infile" at it.
 */
	strcpy(filename, finsave);
	infile = filename;
	/*
 * Put out a header line at the beginning of the 'table' file.
 */
	fprintf(ftable, "/*\n * Created by CSD YACC from \"%s\"\n */\n",
	    infile);
	/*
 * Complete  initialization.
 */
	cnamp = cnames;
	defin(0, "$end");
	extval = 0400;
	defin(0, "error");
	defin(1, "$accept");
	mem = mem0;
	lev = 0;
	ty = 0;
	i = 0;

	yyparse();
}


yyparse()
{
	/* sorry -- no yacc parser here.....
                we must bootstrap somehow... */

	for ( t = gettok(); t != MARK && t != ENDFILE; ) {
		switch ( t ) {

		case ';':
			t = gettok();
			break;

		case START:
			if ( (t = gettok()) != IDENTIFIER ) {
				error( "bad %%start construction" );
			}
			start = chfind(1, tokname);
			t = gettok();
			continue;

		case TYPEDEF:
			if ( (t = gettok()) != TYPENAME ) 
				error( "bad syntax in %%type" );
			ty = numbval;
			for (; ; ) {
				t = gettok();
				switch ( t ) {

				case IDENTIFIER:
					if ( (t = chfind( 1, tokname ) ) < NTBASE ) {
						j = TYPE( toklev[t] );
						if ( j != 0 && j != ty ) {
							error( "type redeclaration of token %s",
							    tokset[t].name );
						} else 
							SETTYPE( toklev[t], ty);
					} else
					 {
						j = nontrst[t-NTBASE].tvalue;
						if ( j != 0 && j != ty ) {
							error( "type redeclaration of nonterminal %s",
							    nontrst[t-NTBASE].name );
						} else 
							nontrst[t-NTBASE].tvalue = ty;
					}
				case ',':
					continue;

				case ';':
					t = gettok();
					break;
				default:
					break;
				}
				break;
			}
			continue;

		case UNION:
			/* copy the union declaration to the output */
			cpyunion();
			t = gettok();
			continue;

		case LEFT:
		case BINARY:
		case RIGHT:
			++i;
		case TERM:
			lev = t - TERM;  /* nonzero means new prec. and assoc. */
			ty = 0;

			/* get identifiers so defined */

			t = gettok();
			if ( t == TYPENAME ) {
				/* there is a type defined */
				ty = numbval;
				t = gettok();
			}
			for (; ; ) {
				switch ( t ) {

				case ',':
					t = gettok();
					continue;

				case ';':
					break;

				case IDENTIFIER:
					j = chfind(0, tokname);
					if ( lev ) {
						if ( ASSOC(toklev[j]) ) 
							error( "redeclaration of precedence of%s", tokname );
						SETASC(toklev[j], lev);
						SETPLEV(toklev[j], i);
					}
					if ( ty ) {
						if ( TYPE(toklev[j]) ) 
							error( "redeclaration of type of %s", tokname );
						SETTYPE(toklev[j], ty);
					}
					if ( (t = gettok()) == NUMBER ) {
						tokset[j].value = numbval;
						if ( j < ndefout && j > 2 ) {
							error( "please define type number of %s earlier",
							    tokset[j].name );
						}
						t = gettok();
					}
					continue;

				}

				break;
			}

			continue;

		case LCURLY:
			defout();
			cpycode();
			t = gettok();
			continue;

		default:
			printf("Unrecognized character: %o\n", t);
			error( "syntax error" );

		}

	}

	if ( t == ENDFILE ) {
		error( "unexpected EOF before %%" );
	}
	/* t is MARK */

	defout();

	fprintf( ftable, "#define yyclearin yychar = -1\n" );
	fprintf( ftable, "#define yyerrok yyerrflag = 0\n" );
	/*
   fprintf( ftable,"extern int yychar;\nextern short yyerrflag;\n" );
*/
	fprintf( ftable, "#ifndef YYMAXDEPTH\n#define YYMAXDEPTH 150\n#endif\n" );
	if (!ntypes)
		fprintf( ftable,  "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n" );
#ifdef unix
	fprintf( ftable,  "YYSTYPE yylval, yyval;\n" );
#else
	fprintf( ftable, "extern YYSTYPE yylval;  /*CSD & DECUS LEX */\n");
	fprintf( ftable, "YYSTYPE yyval;          /*CSD & DECUS LEX */\n");
#endif
	prdptr[0] = mem;
	/* added production */
	*mem++ = NTBASE;
	*mem++ = start;  /* if start is 0, we will overwrite with the lhs of the firstrule */
	*mem++ = 1;
	*mem++ = 0;
	prdptr[1] = mem;
	while ( (t = gettok()) == LCURLY ) 
		cpycode();
	if ( t != C_IDENTIFIER ) 
		error( "bad syntax on first rule" );
	if ( !start ) 
		prdptr[0][1] = chfind(1, tokname);

	/* read rules */

	while ( t != MARK && t != ENDFILE ) {

		/* process a rule */

		if ( t == '|' ) {
			*mem++ = *prdptr[nprod-1];
		} else if ( t == C_IDENTIFIER ) {
			*mem = chfind(1, tokname);
			if ( *mem < NTBASE ) 
				error( "token illegal on LHS of grammar rule" );
			++mem;
		} else 
			error( "illegal rule: missing semicolon or | ?" );

		/* read rule body */
		t = gettok();
more_rule:
		while ( t == IDENTIFIER ) {
			*mem = chfind(1, tokname);
			if ( *mem < NTBASE ) 
				levprd[nprod] = toklev[*mem];
			++mem;
			t = gettok();
		}
		if ( t == PREC ) {
			if ( gettok() != IDENTIFIER) 
				error( "illegal %%prec syntax" );
			j = chfind(2, tokname);
			if ( j >= NTBASE)
				error("nonterminal %s illegal after %%prec", nontrst[j-NTBASE].name);
			levprd[nprod] = toklev[j];
			t = gettok();
		}
		if ( t == '=' ) {
			levprd[nprod] |= ACTFLAG;
			fprintf( faction, "\ncase %d:", nprod );
			cpyact( mem - prdptr[nprod] - 1 );
			fprintf( faction, " break;" );
			if ( (t = gettok()) == IDENTIFIER ) {
				/* action within rule... */
				sprintf( actname, "$$%d", nprod );
				j = chfind(1, actname);  /* make it a nonterminal */
				/* the current rule will become rule number nprod+1 */
				/* move the contents down, and make room for the null */
				for ( p = mem; p >= prdptr[nprod]; --p ) 
					p[2] = *p;
				mem += 2;
				/* enter null production for action */
				p = prdptr[nprod];
				*p++ = j;
				*p++ = -nprod;

				/* update the production information */
				levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
				levprd[nprod] = ACTFLAG;

				if ( ++nprod >= NPROD ) 
					error( "more than %d rules", NPROD );
				prdptr[nprod] = p;

				/* make the action appear in the original rule */
				*mem++ = j;

				/* get some more of the rule */

				goto more_rule;
			}

		}

		while ( t == ';' ) 
			t = gettok();

		*mem++ = -nprod;

		/* check that default action is reasonable */

		if ( ntypes && !(levprd[nprod] & ACTFLAG) && nontrst[*prdptr[nprod]-NTBASE].tvalue ) {
			/* no explicit action, LHS has value */
			/*01*/
			tempty = prdptr[nprod][1];
			if ( tempty < 0 ) 
				error( "must return a value, since LHS has a type" );
			else if ( tempty >= NTBASE ) 
				tempty = nontrst[tempty-NTBASE].tvalue;
			else 
				tempty = TYPE( toklev[tempty] );
			if ( tempty != nontrst[*prdptr[nprod]-NTBASE].tvalue ) {
				error( "default action causes potential type clash" );
			}
		}
		if ( ++nprod >= NPROD ) 
			error( "more than %d rules", NPROD );
		prdptr[nprod] = mem;
		levprd[nprod] = 0;
	}
	/* end of all rules */
	fprintf(faction, "/* End of actions */"); /* Properly terminate the last line */
	finact();
	if ( t == MARK ) {
		fprintf( ftable, "\n#line %d\n", lineno );
		while ( (c = unix_getc(finput)) != EOF ) 
			putc( c, ftable );
	}
	fclose( finput );
}


usage()

{
	fprintf(stderr, "UNIX YACC (CSD Variant):\n");
	fprintf(stderr, "   yacc -hi infile\n\n");
	fprintf(stderr, "Switches:\n");
	fprintf(stderr, "   -h   Create definitions header file\n");
	fprintf(stderr, "   -i   Create parser description file\n\n");
	fprintf(stderr, "Default input file extension is \".y\"\n");
	fprintf(stderr, "Defs file same name, \".h\" extension.\n");
	fprintf(stderr, "Info file same name, \".i\" extension.\n");
	exit(EX_ERR);
}
\EOF\
else
  echo "will not over write ./ysetup.c"
fi
if `test ! -s ./yskpcm.c`
then
echo "writing ./yskpcm.c"
cat > ./yskpcm.c << '\EOF\'
#include "y2.h"

skipcom()
{
	/* skip over comments */
	register c, i;  /* i is the number of lines skipped */
	i = 0;                                                         /*01*/
	/* skipcom is called after reading a / */

	if ( unix_getc(finput) != '*' ) 
		error( "illegal comment" );
	c = unix_getc(finput);
	while ( c != EOF ) {
		while ( c == '*' ) {
			if ( (c = unix_getc(finput)) == '/' ) 
				return( i );
		}
		if ( c == '\n' ) 
			++i;
		c = unix_getc(finput);
	}
	error( "EOF inside comment" );
	/* NOTREACHED */
}
\EOF\
else
  echo "will not over write ./yskpcm.c"
fi
if `test ! -s ./ysmnam.c`
then
echo "writing ./ysmnam.c"
cat > ./ysmnam.c << '\EOF\'
#include "y1.h"

char	*symnam(i)
{
	/* return a pointer to the name of symbol i */
	char	*cp;

	cp = (i >= NTBASE) ? nontrst[i-NTBASE].name : tokset[i].name ;
	if ( *cp == ' ' ) 
		++cp;
	return( cp );
}
\EOF\
else
  echo "will not over write ./ysmnam.c"
fi
if `test ! -s ./ystagn.c`
then
echo "writing ./ystagn.c"
cat > ./ystagn.c << '\EOF\'
#include "y1.h"

/*
 * ystagn.1c
 *
 * Modified to make debug code conditionally compile.
 * 28-Aug-81
 * Bob Denny
 */

stagen()

{
	/* generate the states */

	int	i, j;
	register c;
	register struct wset *p, *q;

	/* initialize */

	nstate = 0;
	/* THIS IS FUNNY from the standpoint of portability */
	/* it represents the magic moment when the mem0 array, which has
        /* been holding the productions, starts to hold item pointers, of a
        /* different type... */
	/* someday, alloc should be used to allocate all this stuff... for now, we
        /* accept that if pointers don't fit in integers, there is a problem... */

	pstate[0] = pstate[1] = (struct item *)mem;
	aryfil( clset.lset, tbitset, 0 );
	putitem( prdptr[0] + 1, &clset );
	tystate[0] = MUSTDO;
	nstate = 1;
	pstate[2] = pstate[1];

	aryfil( amem, ACTSIZE, 0 );

	/* now, the main state generation loop */

more:
	SLOOP(i)

	 {
		if ( tystate[i] != MUSTDO ) 
			continue;
		tystate[i] = DONE;
		aryfil( temp1, nnonter + 1, 0 );
		/* take state i, close it, and do gotos */
		closure(i);
		WSLOOP(wsets, p)

		 {
			/* generate goto's */
			if ( p->flag ) 
				continue;
			p->flag = 1;
			c = *(p->pitem);
			if ( c <= 1 ) {

				if ( pstate[i+1] - pstate[i] <= p - wsets ) 
					tystate[i] = MUSTLOOKAHEAD;
				continue;
			}
			/* do a goto on c */
			WSLOOP(p, q)

			 {
				if ( c == *(q->pitem) ) {

					/* this item contributes to the goto */
					putitem( q->pitem + 1, &q->ws );
					q->flag = 1;
				}
			}
			if ( c < NTBASE ) {

				state(c);  /* register new state */
			} else
			 {
				temp1[c-NTBASE] = state(c);
			}
		}
#ifdef debug
		if ( foutput != NULL ) {

			fprintf( foutput,  "%d: ", i );
			NTLOOP(j)

			 {
				if ( temp1[j] ) 
					fprintf( foutput,  "%s %d, ", nontrst[j].name, temp1[j] );
			}
			fprintf( foutput, "\n");
		}
#endif
		indgo[i] = apack( &temp1[1], nnonter - 1 ) - 1;
		goto more; /* we have done one goto; do some more */
	}
	/* no more to do... stop */
}
\EOF\
else
  echo "will not over write ./ystagn.c"
fi
if `test ! -s ./ystate.c`
then
echo "writing ./ystate.c"
cat > ./ystate.c << '\EOF\'
#include "y1.h"

state(c)
{
	/* sorts last state,and sees if it equals earlier ones. returns state number */
	int	size1, size2;
	register i;
	int	*s;                                                              /*01*/
	struct looksets *ss;                                         /*01*/
	int	s__;                                                     /*01*/
	struct item *p1, *p2, *k, *l, *q1, *q2;
	p1 = pstate[nstate];
	p2 = pstate[nstate+1];
	if (p1 == p2) 
		return(0); /* null state */
	/* sort the items */
	for (k = p2 - 1; k > p1; k--) {
		/* make k the biggest */
		for (l = k - 1; l >= p1; --l)
			if ( l->pitem > k->pitem ) {
				s = k->pitem;
				k->pitem = l->pitem;
				l->pitem = s;
				ss = k->look;
				k->look = l->look;
				l->look = ss;
			}
	}
	size1 = p2 - p1; /* size of state */

	for ( i = (c >= NTBASE) ? ntstates[c-NTBASE] : tstates[c]; i != 0; i = mstates[i] ) {
		/* get ith state */
		q1 = pstate[i];
		q2 = pstate[i+1];
		size2 = q2 - q1;
		if (size1 != size2) 
			continue;
		k = p1;
		for (l = q1; l < q2; l++) {
			if ( l->pitem != k->pitem ) 
				break;
			++k;
		}
		if (l != q2) 
			continue;
		/* found it */
		pstate[nstate+1] = pstate[nstate]; /* delete last state */
		/* fix up lookaheads */
		if ( nolook ) 
			return(i);
		for ( l = q1, k = p1; l < q2; ++l, ++k ) {
			SETLOOP(s__) clset.lset[s__] = l->look->lset[s__];
			if ( setunion( clset.lset, k->look->lset ) ) {
				tystate[i] = MUSTDO;
				/* register the new set */
				l->look = flset( &clset );
			}
		}
		return (i);
	}
	/* state is new */
	if ( nolook ) 
		error( "yacc state/nolook error" );
	pstate[nstate+2] = p2;
	if (nstate + 1 >= NSTATES) 
		error("too many states" );
	if ( c >= NTBASE ) {
		mstates[ nstate ] = ntstates[ c-NTBASE ];
		ntstates[ c-NTBASE ] = nstate;
	} else      {
		mstates[ nstate ] = tstates[ c ];
		tstates[ c ] = nstate;
	}
	tystate[nstate] = MUSTDO;
	return(nstate++);
}
\EOF\
else
  echo "will not over write ./ystate.c"
fi
if `test ! -s ./ystin.c`
then
echo "writing ./ystin.c"
cat > ./ystin.c << '\EOF\'
#include "y4.h"

stin(i)
{
	register *r, *s, n, flag, j, *q1, *q2;

	greed[i] = 0;

	/* enter state i into the a array */

	q2 = mem0 + yypact[i+1];
	q1 = mem0 + yypact[i];
	/* find an acceptable place */

	for ( n = -maxoff; n < ACTSIZE; ++n ) {

		flag = 0;
		for ( r = q1; r < q2; r += 2 ) {
			if ( (s = *r + n + a ) < a ) 
				goto nextn;
			if ( *s == 0 ) 
				++flag;
			else if ( *s != r[1] ) 
				goto nextn;
		}

		/* check that the position equals another only if the states are identical */

		for ( j = 0; j < nstate; ++j ) {
			if ( pa[j] == n ) {
				if ( flag ) 
					goto nextn;  /* we have some disagreement */
				if ( yypact[j+1] + yypact[i] == yypact[j] + yypact[i+1] ) {
					/* states are equal */
					pa[i] = n;
					if ( adb > 1 ) 
						fprintf( ftable, "State %d: entry at %d equals state %d\n",
						    i, n, j );
					return;
				}
				goto nextn;  /* we have some disagreement */
			}
		}

		for ( r = q1; r < q2; r += 2 ) {
			if ( (s = *r + n + a ) >= &a[ACTSIZE] ) 
				error( "out of space in optimizer a array" );
			if ( s > maxa ) 
				maxa = s;
			if ( *s != 0 && *s != r[1] ) 
				error( "clobber of a array, pos'n %d, by %d", s - a, r[1] );
			*s = r[1];
		}
		pa[i] = n;
		if ( adb > 1 ) 
			fprintf( ftable, "State %d: entry at %d\n", i, pa[i] );
		return;

nextn:
		;
	}

	error( "Error; failure to place state %d\n", i );
}
\EOF\
else
  echo "will not over write ./ystin.c"
fi
if `test ! -s ./ystuni.c`
then
echo "writing ./ystuni.c"
cat > ./ystuni.c << '\EOF\'
#include "y1.h"

setunion( a, b ) 
register *a, *b;

{
	/* set a to the union of a and b */
	/* return 1 if b is not a subset of a, 0 otherwise */
	register i, x, sub;

	sub = 0;
	SETLOOP(i)
	 {
		*a = (x = *a) | *b++;
		if ( *a++ != x ) 
			sub = 1;
	}
	return( sub );
}
\EOF\
else
  echo "will not over write ./ystuni.c"
fi
if `test ! -s ./ysumry.c`
then
echo "writing ./ysumry.c"
cat > ./ysumry.c << '\EOF\'
#include "y1.h"

summary()
{
	/* output the summary on the tty */

	if ( foutput != NULL ) {
		fprintf( foutput, "\n%d/%d terminals, %d/%d nonterminals\n", ntokens, NTERMS,
		    nnonter, NNONTERM );
		fprintf( foutput, "%d/%d grammar rules, %d/%d states\n", nprod, NPROD, nstate, NSTATES );
		fprintf( foutput, "%d shift/reduce, %d reduce/reduce conflicts reported\n", zzsrconf, zzrrconf );
		fprintf( foutput, "%d/%d working sets used\n", zzcwp - wsets,  WSETSIZE );
		fprintf( foutput, "memory: states,etc. %d/%d, parser %d/%d\n", zzmemsz - mem0, MEMSIZE,
		    memp - amem, ACTSIZE );
		fprintf( foutput, "%d/%d distinct lookahead sets\n", nlset, LSETSIZE );
		fprintf( foutput, "%d extra closures\n", zzclose - 2 * nstate );
		fprintf( foutput, "%d shift entries, %d exceptions\n", zzacent, zzexcp );
		fprintf( foutput, "%d goto entries\n", zzgoent );
		fprintf( foutput, "%d entries saved by goto default\n", zzgobest );
	}
	if ( zzsrconf != 0 || zzrrconf != 0 ) {
		fprintf( stdout, "\nconflicts: ");
		if ( zzsrconf )
			fprintf( stdout, "%d shift/reduce" , zzsrconf );
		if ( zzsrconf && zzrrconf )
			fprintf( stdout, ", " );
		if ( zzrrconf )
			fprintf( stdout, "%d reduce/reduce" , zzrrconf );
		fprintf( stdout, "\n" );
	}

	fclose( ftemp );
	if ( fdefine != NULL ) 
		fclose( fdefine );
}
\EOF\
else
  echo "will not over write ./ysumry.c"
fi
if `test ! -s ./ywarry.c`
then
echo "writing ./ywarry.c"
cat > ./ywarry.c << '\EOF\'
#include "y3.h"

warray( s, v, n ) 
char	*s;
int	*v, n;

{

	register i;

	fprintf( ftable, "short %s[]={\n", s );
	for ( i = 0; i < n; ) {
		if ( i % 10 == 0 ) 
			fprintf( ftable, "\n" );
		fprintf( ftable, "%4d", v[i] );
		if ( ++i == n ) 
			fprintf( ftable, " };\n" );
		else 
			fprintf( ftable, "," );
	}
}
\EOF\
else
  echo "will not over write ./ywarry.c"
fi
if `test ! -s ./ywract.c`
then
echo "writing ./ywract.c"
cat > ./ywract.c << '\EOF\'
#include "y3.h"

wract(i)
{
	/* output state i */
	/* temp1 has the actions, lastred the default */
	int	p, p0, p1;
	int	ntimes, tred, count, j;
	int	flag;

	/* find the best choice for lastred */

	lastred = 0;
	ntimes = 0;
	TLOOP(j)
	 {
		if ( temp1[j] >= 0 ) 
			continue;
		if ( temp1[j] + lastred == 0 ) 
			continue;
		/* count the number of appearances of temp1[j] */
		count = 0;
		tred = -temp1[j];
		levprd[tred] |= REDFLAG;
		TLOOP(p)
		 {
			if ( temp1[p] + tred == 0 ) 
				++count;
		}
		if ( count > ntimes ) {
			lastred = tred;
			ntimes = count;
		}
	}

	/* for error recovery, arrange that, if there is a shift on the
        /* error recovery token, `error', that the default be the error action */
	if ( temp1[1] > 0 ) 
		lastred = 0;

	/* clear out entries in temp1 which equal lastred */
	TLOOP(p) if ( temp1[p] + lastred == 0 )
		temp1[p] = 0;

	wrstate(i);
	defact[i] = lastred;

	flag = 0;
	TLOOP(p0)
	 {
		if ( (p1 = temp1[p0]) != 0 ) {
			if ( p1 < 0 ) {
				p1 = -p1;
				goto exc;
			} else if ( p1 == ACCEPTCODE ) {
				p1 = -1;
				goto exc;
			} else if ( p1 == ERRCODE ) {
				p1 = 0;
				goto exc;
exc:
				if ( flag++ == 0 ) 
					fprintf( ftable, "-1, %d,\n", i );
				fprintf( ftable, "\t%d, %d,\n", tokset[p0].value, p1 );
				++zzexcp;
			} else            {
				fprintf( ftemp, "%d,%d,", tokset[p0].value, p1 );
				++zzacent;
			}
		}
	}
	if ( flag ) {
		defact[i] = -2;
		fprintf( ftable, "\t-2, %d,\n", lastred );
	}
	fprintf( ftemp, "\n" );
	return;
}
\EOF\
else
  echo "will not over write ./ywract.c"
fi
if `test ! -s ./ywritm.c`
then
echo "writing ./ywritm.c"
cat > ./ywritm.c << '\EOF\'
/*
 * ywritm.c -
 *
 * HISTORY
 */

#include "y1.h"

extern char	sarr[ISIZE];

char	*chcopy();

char	*writem(pp)
int	*pp;
{
	/* creates output string for item pointed to by pp */
	int	i, *p;
	char	*q;

	for (p = pp; *p > 0; ++p)
		;
	p = prdptr[-*p];
	q = chcopy(sarr, nontrst[*p - NTBASE].name);
	q = chcopy(q, " : ");

	for (; ; ) {
		*q++ = ++p == pp ? '_' : ' ';
		*q = '\0';
		if ((i = *p) <= 0)
			break;
		q = chcopy(q, symnam(i));
		if (q > &sarr[ISIZE - 30])
			error("item too big");
	}

	if ((i = *pp) < 0) {
		/* an item calling for a reduction */
		q = chcopy(q, "    (");
		sprintf(q, "%d)", -i);
	}
	return (sarr);
}
\EOF\
else
  echo "will not over write ./ywritm.c"
fi
if `test ! -s ./ywstat.c`
then
echo "writing ./ywstat.c"
cat > ./ywstat.c << '\EOF\'
#include "y3.h"

wrstate(i)
{
	/* writes state i */
	register j0, j1;
	register struct item *pp, *qq;
	register struct wset *u;

	if ( foutput == NULL ) 
		return;
	fprintf( foutput, "\nstate %d\n", i);
	ITMLOOP(i, pp, qq) fprintf( foutput, "\t%s\n", writem(pp->pitem));
	if ( tystate[i] == MUSTLOOKAHEAD ) {
		/* print out empty productions in closure */
		WSLOOP( wsets + (pstate[i+1] - pstate[i]), u )
		 {
			if ( *(u->pitem) < 0 ) 
				fprintf( foutput, "\t%s\n", writem(u->pitem) );
		}
	}

	/* check for state equal to another */

	TLOOP(j0) if ( (j1 = temp1[j0]) != 0 ) {
		fprintf( foutput, "\n\t%s  ", symnam(j0) );
		if ( j1 > 0 ) {
			/* shift, error, or accept */
			if ( j1 == ACCEPTCODE ) 
				fprintf( foutput,  "accept" );
			else if ( j1 == ERRCODE ) 
				fprintf( foutput, "error" );
			else 
				fprintf( foutput,  "shift %d", j1 );
		} else 
			fprintf( foutput, "reduce %d", -j1 );
	}

	/* output the final production */

	if ( lastred ) 
		fprintf( foutput, "\n\t.  reduce %d\n\n", lastred );
	else 
		fprintf( foutput, "\n\t.  error\n\n" );

	/* now, output nonterminal actions */

	j1 = ntokens;
	for ( j0 = 1; j0 <= nnonter; ++j0 ) {
		if ( temp1[++j1] ) 
			fprintf( foutput, "\t%s  goto %d\n", symnam( j0 + NTBASE), temp1[j1] );
	}

}


wdef( s, n ) 
char	*s;

{
	/* output a definition of s to the value n */
	fprintf( ftable, "# define %s %d\n", s, n );
}
\EOF\
else
  echo "will not over write ./ywstat.c"
fi
if `test ! -s ./yypars`
then
echo "writing ./yypars"
cat > ./yypars << '\EOF\'
/*	@(#)yaccpar	1.9	*/

/*
** Skeleton parser driver for yacc output
*/

/*
** yacc user known macros and defines
*/
#define YYERROR		goto yyerrlab
#define YYACCEPT	return(0)
#define YYABORT		return(1)
#define YYBACKUP( newtoken, newvalue )\
{\
	if ( yychar >= 0 || ( yyr2[ yytmp ] >> 1 ) != 1 )\
	{\
		yyerror( "syntax error - cannot backup" );\
		goto yyerrlab;\
	}\
	yychar = newtoken;\
	yystate = *yyps;\
	yylval = newvalue;\
	goto yynewstate;\
}
#define YYRECOVERING()	(!!yyerrflag)
#ifndef YYDEBUG
#	define YYDEBUG	1	/* make debugging available */
#endif

/*
** user known globals
*/
int yydebug;			/* set to 1 to get debugging */

/*
** driver internal defines
*/
#define YYFLAG		(-1000)

/*
** global variables used by the parser
*/
YYSTYPE yyv[ YYMAXDEPTH ];	/* value stack */
int yys[ YYMAXDEPTH ];		/* state stack */

YYSTYPE *yypv;			/* top of value stack */
int *yyps;			/* top of state stack */

int yystate;			/* current state */
int yytmp;			/* extra var (lasts between blocks) */

int yynerrs;			/* number of errors */
int yyerrflag;			/* error recovery flag */
int yychar;			/* current input token number */



/*
** yyparse - return 0 if worked, 1 if syntax error not recovered from
*/
int
yyparse()
{
	register YYSTYPE *yypvt;	/* top of value stack for $vars */

	/*
	** Initialize externals - yyparse may be called more than once
	*/
	yypv = &yyv[-1];
	yyps = &yys[-1];
	yystate = 0;
	yytmp = 0;
	yynerrs = 0;
	yyerrflag = 0;
	yychar = -1;

	goto yystack;
	{
		register YYSTYPE *yy_pv;	/* top of value stack */
		register int *yy_ps;		/* top of state stack */
		register int yy_state;		/* current state */
		register int  yy_n;		/* internal state number info */

		/*
		** get globals into registers.
		** branch to here only if YYBACKUP was called.
		*/
	yynewstate:
		yy_pv = yypv;
		yy_ps = yyps;
		yy_state = yystate;
		goto yy_newstate;

		/*
		** get globals into registers.
		** either we just started, or we just finished a reduction
		*/
	yystack:
		yy_pv = yypv;
		yy_ps = yyps;
		yy_state = yystate;

		/*
		** top of for (;;) loop while no reductions done
		*/
	yy_stack:
		/*
		** put a state and value onto the stacks
		*/
#if YYDEBUG
		/*
		** if debugging, look up token value in list of value vs.
		** name pairs.  0 and negative (-1) are special values.
		** Note: linear search is used since time is not a real
		** consideration while debugging.
		*/
		if ( yydebug )
		{
			register int yy_i;

			printf( "State %d, token ", yy_state );
			if ( yychar == 0 )
				printf( "end-of-file\n" );
			else if ( yychar < 0 )
				printf( "-none-\n" );
			else
			{
				for ( yy_i = 0; yytoks[yy_i].t_val >= 0;
					yy_i++ )
				{
					if ( yytoks[yy_i].t_val == yychar )
						break;
				}
				printf( "%s\n", yytoks[yy_i].t_name );
			}
		}
#endif /* YYDEBUG */
		if ( ++yy_ps >= &yys[ YYMAXDEPTH ] )	/* room on stack? */
		{
			yyerror( "yacc stack overflow" );
			YYABORT;
		}
		*yy_ps = yy_state;
		*++yy_pv = yyval;

		/*
		** we have a new state - find out what to do
		*/
	yy_newstate:
		if ( ( yy_n = yypact[ yy_state ] ) <= YYFLAG )
			goto yydefault;		/* simple state */
#if YYDEBUG
		/*
		** if debugging, need to mark whether new token grabbed
		*/
		yytmp = yychar < 0;
#endif
		if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) )
			yychar = 0;		/* reached EOF */
#if YYDEBUG
		if ( yydebug && yytmp )
		{
			register int yy_i;

			printf( "Received token " );
			if ( yychar == 0 )
				printf( "end-of-file\n" );
			else if ( yychar < 0 )
				printf( "-none-\n" );
			else
			{
				for ( yy_i = 0; yytoks[yy_i].t_val >= 0;
					yy_i++ )
				{
					if ( yytoks[yy_i].t_val == yychar )
						break;
				}
				printf( "%s\n", yytoks[yy_i].t_name );
			}
		}
#endif /* YYDEBUG */
		if ( ( ( yy_n += yychar ) < 0 ) || ( yy_n >= YYLAST ) )
			goto yydefault;
		if ( yychk[ yy_n = yyact[ yy_n ] ] == yychar )	/*valid shift*/
		{
			yychar = -1;
			yyval = yylval;
			yy_state = yy_n;
			if ( yyerrflag > 0 )
				yyerrflag--;
			goto yy_stack;
		}

	yydefault:
		if ( ( yy_n = yydef[ yy_state ] ) == -2 )
		{
#if YYDEBUG
			yytmp = yychar < 0;
#endif
			if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) )
				yychar = 0;		/* reached EOF */
#if YYDEBUG
			if ( yydebug && yytmp )
			{
				register int yy_i;

				printf( "Received token " );
				if ( yychar == 0 )
					printf( "end-of-file\n" );
				else if ( yychar < 0 )
					printf( "-none-\n" );
				else
				{
					for ( yy_i = 0;
						yytoks[yy_i].t_val >= 0;
						yy_i++ )
					{
						if ( yytoks[yy_i].t_val
							== yychar )
						{
							break;
						}
					}
					printf( "%s\n", yytoks[yy_i].t_name );
				}
			}
#endif /* YYDEBUG */
			/*
			** look through exception table
			*/
			{
				register int *yyxi = yyexca;

				while ( ( *yyxi != -1 ) ||
					( yyxi[1] != yy_state ) )
				{
					yyxi += 2;
				}
				while ( ( *(yyxi += 2) >= 0 ) &&
					( *yyxi != yychar ) )
					;
				if ( ( yy_n = yyxi[1] ) < 0 )
					YYACCEPT;
			}
		}

		/*
		** check for syntax error
		*/
		if ( yy_n == 0 )	/* have an error */
		{
			/* no worry about speed here! */
			switch ( yyerrflag )
			{
			case 0:		/* new error */
				yyerror( "syntax error" );
				goto skip_init;
			yyerrlab:
				/*
				** get globals into registers.
				** we have a user generated syntax type error
				*/
				yy_pv = yypv;
				yy_ps = yyps;
				yy_state = yystate;
				yynerrs++;
			skip_init:
			case 1:
			case 2:		/* incompletely recovered error */
					/* try again... */
				yyerrflag = 3;
				/*
				** find state where "error" is a legal
				** shift action
				*/
				while ( yy_ps >= yys )
				{
					yy_n = yypact[ *yy_ps ] + YYERRCODE;
					if ( yy_n >= 0 && yy_n < YYLAST &&
						yychk[yyact[yy_n]] == YYERRCODE)					{
						/*
						** simulate shift of "error"
						*/
						yy_state = yyact[ yy_n ];
						goto yy_stack;
					}
					/*
					** current state has no shift on
					** "error", pop stack
					*/
#if YYDEBUG
#	define _POP_ "Error recovery pops state %d, uncovers state %d\n"
					if ( yydebug )
						printf( _POP_, *yy_ps,
							yy_ps[-1] );
#	undef _POP_
#endif
					yy_ps--;
					yy_pv--;
				}
				/*
				** there is no state on stack with "error" as
				** a valid shift.  give up.
				*/
				YYABORT;
			case 3:		/* no shift yet; eat a token */
#if YYDEBUG
				/*
				** if debugging, look up token in list of
				** pairs.  0 and negative shouldn't occur,
				** but since timing doesn't matter when
				** debugging, it doesn't hurt to leave the
				** tests here.
				*/
				if ( yydebug )
				{
					register int yy_i;

					printf( "Error recovery discards " );
					if ( yychar == 0 )
						printf( "token end-of-file\n" );
					else if ( yychar < 0 )
						printf( "token -none-\n" );
					else
					{
						for ( yy_i = 0;
							yytoks[yy_i].t_val >= 0;
							yy_i++ )
						{
							if ( yytoks[yy_i].t_val
								== yychar )
							{
								break;
							}
						}
						printf( "token %s\n",
							yytoks[yy_i].t_name );
					}
				}
#endif /* YYDEBUG */
				if ( yychar == 0 )	/* reached EOF. quit */
					YYABORT;
				yychar = -1;
				goto yy_newstate;
			}
		}/* end if ( yy_n == 0 ) */
		/*
		** reduction by production yy_n
		** put stack tops, etc. so things right after switch
		*/
#if YYDEBUG
		/*
		** if debugging, print the string that is the user's
		** specification of the reduction which is just about
		** to be done.
		*/
		if ( yydebug )
			printf( "Reduce by (%d) \"%s\"\n",
				yy_n, yyreds[ yy_n ] );
#endif
		yytmp = yy_n;			/* value to switch over */
		yypvt = yy_pv;			/* $vars top of value stack */
		/*
		** Look in goto table for next state
		** Sorry about using yy_state here as temporary
		** register variable, but why not, if it works...
		** If yyr2[ yy_n ] doesn't have the low order bit
		** set, then there is no action to be done for
		** this reduction.  So, no saving & unsaving of
		** registers done.  The only difference between the
		** code just after the if and the body of the if is
		** the goto yy_stack in the body.  This way the test
		** can be made before the choice of what to do is needed.
		*/
		{
			/* length of production doubled with extra bit */
			register int yy_len = yyr2[ yy_n ];

			if ( !( yy_len & 01 ) )
			{
				yy_len >>= 1;
				yyval = ( yy_pv -= yy_len )[1];	/* $$ = $1 */
				yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] +
					*( yy_ps -= yy_len ) + 1;
				if ( yy_state >= YYLAST ||
					yychk[ yy_state =
					yyact[ yy_state ] ] != -yy_n )
				{
					yy_state = yyact[ yypgo[ yy_n ] ];
				}
				goto yy_stack;
			}
			yy_len >>= 1;
			yyval = ( yy_pv -= yy_len )[1];	/* $$ = $1 */
			yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] +
				*( yy_ps -= yy_len ) + 1;
			if ( yy_state >= YYLAST ||
				yychk[ yy_state = yyact[ yy_state ] ] != -yy_n )
			{
				yy_state = yyact[ yypgo[ yy_n ] ];
			}
		}
					/* save until reenter driver code */
		yystate = yy_state;
		yyps = yy_ps;
		yypv = yy_pv;
	}
	/*
	** code supplied by user is placed in this switch
	*/
	switch( yytmp )
	{
		$A
	}
	goto yystack;		/* reset registers in driver code */
}
\EOF\
else
  echo "will not over write ./yypars"
fi
echo "Finished archive 1 of 4"
# if you want to concatenate archives, remove anything after this line
exit 0

glenn@extro.ucc.su.oz (G. Geers [ext 3241]) (06/28/89)

--- cut here --- cut here --- cut here --- cut here --- cut here ---
#!/bin/sh
# This is a shell archive.  Remove anything before the /bin/sh line
# then unpack it by saving it in a file and typing "sh file"
# (Files unpacked will be owned by you and have default permissions).
# Don't worry about trailing garbage - the archive ends with exit
# This archive contains the following files:
#	./yarout.c
#	./yaryfl.c
#	./ycemty.c
#	./ychcpy.c
#	./ychfnd.c
#	./yclopt.c
#	./yclsur.c
#	./ycpact.c
#	./ycpfir.c
#	./ycpres.c
#	./ycpuni.c
#	./ycpycd.c
#	./ycstsh.c
#	./ydefin.c
#	./ydfout.c
#	./yerror.c
#	./yfdtyp.c
#	./yflset.c
#	./yfnact.c
#	./yg2gen.c
#	./yg2out.c
#	./ygin.c
#	./ygtnm.c
#	./ygttok.c
#	./yhdprd.c
#	./ymain.c
#	./ymkfil
#	./ynxti.c
#	./yosmry.c
#	./yothrs.c
#	./youtpt.c
#
if `test ! -s ./yarout.c`
then
echo "writing ./yarout.c"
cat > ./yarout.c << '\EOF\'
/*
 * yarout.c - 
 *
 * HISTORY
 */

#include "y4.h"

int	arout(s, v, n)
char	*s;
int	*v, n;
{
	register i;

	fprintf(ftable, "short %s[]={\n", s);
	for (i = 0; i < n; ) {
		if (i % 10 == 0)
			fprintf(ftable, "\n");
		fprintf(ftable, "%4d", v[i]);
		if (++i == n)
			fprintf(ftable, " };\n");
		else
			fprintf(ftable, ",");
	}
}
\EOF\
else
  echo "will not over write ./yarout.c"
fi
if `test ! -s ./yaryfl.c`
then
echo "writing ./yaryfl.c"
cat > ./yaryfl.c << '\EOF\'
/*
 * yaryfl.c  - set elements 0 through n-1 to c
 *
 * HISTORY
 */

#include "y1.h"


int	aryfil(v, n, c)
int	*v, n, c;
{
	register int	i;

	for (i = 0; i < n; ++i)
		v[i] = c;
}
\EOF\
else
  echo "will not over write ./yaryfl.c"
fi
if `test ! -s ./ycemty.c`
then
echo "writing ./ycemty.c"
cat > ./ycemty.c << '\EOF\'
/*
 * ycemty.c - mark nonterminals which derive the empty string
 *
 * In addition to looking for empty nonterminals, look for nonterminals
 * which don't derive any token strings.  Both of these should be optimized
 * away.
 *
 * HISTORY
 * {1}	12-Apr-83  Bob Denny
 * 	Add symbolic exit status.
 * 
 */
#include "y1.h"

#define EMPTY		1
#define WHOKNOWS	0
#define OK		1

int	cempty()
{
	register i, *p;

	/*
	 * first, use the array pempty to detect productions that can
	 * never be reduced 
	 */

	/* set pempty to WHONOWS */
	aryfil(pempty, nnonter + 1, WHOKNOWS);

	/*
	 * now, look at productions, marking nonterminals which derive
	 * something 
	 */

more:
	PLOOP(0, i) {
		if (pempty[*prdptr[i] - NTBASE])
			continue;
		for (p = prdptr[i] + 1; *p >= 0; ++p) {
			if (*p >= NTBASE && pempty[*p - NTBASE] == WHOKNOWS)
				break;
		}
		if (*p < 0) {
			/* production can be derived */
			pempty[*prdptr[i] - NTBASE] = OK;
			goto more;
		}
	}

	/* now, look at the nonterminals, to see if they are all OK */

	NTLOOP(i) {
		/*
		 * the added production rises or falls as the start symbol
		 * ... 
		 */
		if (i == 0)
			continue;
		if (pempty[i] != OK) {
			fatfl = 0;
			error("nonterminal %s never derives any token string", nontrst[i].name);
		}
	}

	if (nerrors) {
		summary();
		exit(EX_ERR);
	}

	/*
	 * now, compute the pempty array, to see which nonterminals derive
	 * the empty string 
	 */

	/* set pempty to WHOKNOWS */

	aryfil(pempty, nnonter + 1, WHOKNOWS);
	/* loop as long as we keep finding empty nonterminals */

again:
	PLOOP(1, i) {
		if (pempty[*prdptr[i] - NTBASE] == WHOKNOWS) {
			/* not known to be empty */
			for (p = prdptr[i] + 1; *p >= NTBASE && pempty[*p - NTBASE] == EMPTY; ++p)
				;
			if (*p < 0) {
				/*
				 * we have a nontrivially empty
				 * nonterminal 
				 */
				pempty[*prdptr[i] - NTBASE] = EMPTY;
				goto again;	/* got one ... try for
						 * another */
			}
		}
	}
}
\EOF\
else
  echo "will not over write ./ycemty.c"
fi
if `test ! -s ./ychcpy.c`
then
echo "writing ./ychcpy.c"
cat > ./ychcpy.c << '\EOF\'
/*
 * ychcpy.c - copies string q into p, return next free char ptr
 *
 * HISTORY
 */

#include "y1.h"

char	*chcopy(p, q)
char	*p, *q;
{
	while (*p = *q++)
		++p;
	return (p);
}
\EOF\
else
  echo "will not over write ./ychcpy.c"
fi
if `test ! -s ./ychfnd.c`
then
echo "writing ./ychfnd.c"
cat > ./ychfnd.c << '\EOF\'
/*
 * ychfnd.c -
 *
 * HISTORY
 */

#include "y2.h"


int	chfind( t, s )
register char	*s;
{
	int	i;

	if (s[0] == ' ')
		t = 0;
	TLOOP(i) {
		if (!strcmp(s, tokset[i].name)) {
			return (i);
		}
	}
	NTLOOP(i) {
		if (!strcmp(s, nontrst[i].name)) {
			return (i + NTBASE);
		}
	}
	/* cannot find name */
	if (t > 1)
		error("%s should have been defined earlier", s);
	return (defin(t, s));
}
\EOF\
else
  echo "will not over write ./ychfnd.c"
fi
if `test ! -s ./yclopt.c`
then
echo "writing ./yclopt.c"
cat > ./yclopt.c << '\EOF\'
/*
 * yclopt.c -
 *
 * HISTORY
 */

#include "y4.h"

int	callopt()
{

	register i, *p, j, k, *q;

	/* read the arrays from tempfile and set parameters */


	if ((finput = fopen(TEMPNAME, "r")) == NULL)
		error("optimizer cannot open tempfile");
	pgo[0] = 0;
	yypact[0] = 0;
	nstate = 0;
	nnonter = 0;
	for (; ; ) {
		switch (gtnm()) {
		case '\n':
			yypact[++nstate] = (--pmem) - mem0;
		case ',':
			continue;
		case '$':
			break;
		default:
			error("bad tempfile");
		}
		break;
	}

	yypact[nstate] = yypgo[0] = (--pmem) - mem0;

	for (; ; ) {
		switch (gtnm()) {
		case '\n':
			yypgo[++nnonter] = pmem - mem0;
		case '\r':
		case ',':
			continue;
		case -1:	/* EOF */
			break;
		default:
			error("bad tempfile");
		}
		break;
	}

	yypgo[nnonter--] = (--pmem) - mem0;
	for (i = 0; i < nstate; ++i) {

		k = 32000;
		j = 0;
		q = mem0 + yypact[i + 1];
		for (p = mem0 + yypact[i]; p < q; p += 2) {
			if (*p > j)
				j = *p;
			if (*p < k)
				k = *p;
		}
		if (k <= j) {
			/* nontrivial situation */
			/*
			 * temporarily, kill this for compatibility j -=
			 * k;  j is now the range 
			 */
			if (k > maxoff)
				maxoff = k;
		}
		greed[i] = (yypact[i + 1] - yypact[i]) + 2 * j;
		if (j > maxspr)
			maxspr = j;
	}

	/* initialize ggreed table */

	for (i = 1; i <= nnonter; ++i) {
		ggreed[i] = 1;
		j = 0;
		/* minimum entry index is always 0 */
		q = mem0 + yypgo[i + 1] - 1;
		for (p = mem0 + yypgo[i]; p < q; p += 2) {
			ggreed[i] += 2;
			if (*p > j)
				j = *p;
		}
		ggreed[i] = ggreed[i] + 2 * j;
		if (j > maxoff)
			maxoff = j;
	}

	/* now, prepare to put the shift actions into the a array */

	for (i = 0; i < ACTSIZE; ++i)
		a[i] = 0;
	maxa = a;

	for (i = 0; i < nstate; ++i) {
		if (greed[i] == 0 && adb > 1)
			fprintf(ftable, "State %d: null\n", i);
		pa[i] = YYFLAG1;
	}

	while ((i = nxti()) != NOMORE) {
		if (i >= 0)
			stin(i);
		else
			gin(-i);
	}

	if (adb > 2) {
		/* print a array */
		for (p = a; p <= maxa; p += 10) {
			fprintf(ftable, "%4d  ", p - a);
			for (i = 0; i < 10; ++i)
				fprintf(ftable, "%4d  ", p[i]);
			fprintf(ftable, "\n");
		}
	}
	/* write out the output appropriate to the language */

	aoutput();

	osummary();

	fclose(finput);
	ZAPFILE(TEMPNAME);
}
\EOF\
else
  echo "will not over write ./yclopt.c"
fi
if `test ! -s ./yclsur.c`
then
echo "writing ./yclsur.c"
cat > ./yclsur.c << '\EOF\'
/*
 * yclsur.c - generate closure of state i
 *
 * HISTORY
 * {1}	28-Aug-81  Bob Denny
 * 	Modified to make debug code conditionally compile.
 * 
 */

#include "y1.h"


int	closure(i)
{
	int	c, ch, work, k;
	register struct wset *u, *v;
	int	*pi;
	int	**s, **t;
	struct item *q;
	register struct item *p;

	++zzclose;

	/* first, copy kernel of state i to wsets */

	cwp = wsets;
	ITMLOOP(i, p, q) {
		cwp->pitem = p->pitem;
		cwp->flag = 1;	/* this item must get closed */
		SETLOOP(k) cwp->ws.lset[k] = p->look->lset[k];
		WSBUMP(cwp);
	}

	/* now, go through the loop, closing each item */

	work = 1;
	while (work) {
		work = 0;
		WSLOOP(wsets, u) {

			if (u->flag == 0)
				continue;
			c = *(u->pitem);	/* dot is before c */

			if (c < NTBASE) {
				u->flag = 0;
				continue;	/* only interesting case
						 * is where . is before
										 * nonterminal */
			}
			/* compute the lookahead */
			aryfil(clset.lset, tbitset, 0);

			/* find items involving c */
			WSLOOP(u, v) {
				if (v->flag == 1 && *(pi = v->pitem) == c) {
					v->flag = 0;
					if (nolook)
						continue;
					while ((ch = *++pi) > 0) {
						if (ch < NTBASE) {
							/* terminal symbol */
							SETBIT(clset.lset, ch);
							break;
						}
						/* nonterminal symbol */
						setunion(clset.lset, pfirst[ch - NTBASE]->lset);
						if (!pempty[ch - NTBASE])
							break;
					}
					if (ch <= 0)
						setunion(clset.lset, v->ws.lset);
				}
			}

			/* now loop over productions derived from c */

			c -= NTBASE;	/* c is now nonterminal number */

			t = pres[c + 1];
			for (s = pres[c]; s < t; ++s) {
				/* put these items into the closure */
				WSLOOP(wsets, v) {
					/* is the item there */
					if (v->pitem == *s) {
						/* yes, it is there */
						if (nolook)
							goto nexts;
						if (setunion(v->ws.lset, clset.lset))
							v->flag = work = 1;
						goto nexts;
					}
				}

				/* not there; make a new entry */
				if (cwp - wsets + 1 >= WSETSIZE)
					error("working set overflow");
				cwp->pitem = *s;
				cwp->flag = 1;
				if (!nolook) {
					work = 1;
					SETLOOP(k) cwp->ws.lset[k] = clset.lset[k];
				}
				WSBUMP(cwp);
nexts:
				;
			}

		}
	}

	/* have computed closure; flags are reset; return */

	if (cwp > zzcwp)
		zzcwp = cwp;

#ifdef debug
	if (foutput != NULL) {
		fprintf(foutput, "\nState %d, nolook = %d\n", i, nolook);
		WSLOOP(wsets, u) {
			if (u->flag)
				fprintf(foutput, "flag set!\n");
			u->flag = 0;
			fprintf(foutput, "\t%s", writem(u->pitem));
			prlook(&u->ws);
			fprintf(foutput, "\n");
		}
	}
#endif
}
\EOF\
else
  echo "will not over write ./yclsur.c"
fi
if `test ! -s ./ycpact.c`
then
echo "writing ./ycpact.c"
cat > ./ycpact.c << '\EOF\'
/*
 * ycpact.c - copy C action to next ; or closing curly brace
 *
 * HISTORY
 */

#include <stdio.h>
#include <ctype.h>
#include "y2.h"

int	cpyact(offset)
int	offset;
{
	int	brac, c, match, j, s, tok;

	fprintf(faction, "\n# line %d\n", lineno);
	brac = 0;

loop:
	c = unix_getc(finput);
swt:
	switch (c) {
	case ';':
		if (brac == 0) {
			putc(c, faction);
			return;
		}
		goto lcopy;

	case '{':
		brac++;
		goto lcopy;

	case '$':
		s = 1;
		tok = -1;
		c = unix_getc(finput);
		if (c == '<') {
			/* type description */
			ungetc(c, finput);
			if (gettok() != TYPENAME)
				error("bad syntax on $<ident> clause");
			tok = numbval;
			c = unix_getc(finput);
		}
		if (c == '$') {
			fprintf(faction, "yyval");
			if (ntypes) {
				/* put out the proper tag... */
				if (tok < 0)
					tok = fdtype(*prdptr[nprod]);
				fprintf(faction, ".%s", typeset[tok]);
			}
			goto loop;
		}
		if (c == '-') {
			s = -s;
			c = unix_getc(finput);
		}
		if (isdigit(c)) {
			j = 0;
			while (isdigit(c)) {
				j = j * 10 + c - '0';
				c = unix_getc(finput);
			}

			j = j * s - offset;
			if (j > 0) {
				error("Illegal use of $%d", j + offset);
			}
			fprintf(faction, "yypvt[-%d]", -j);
			if (ntypes) {
				/* put out the proper tag */
				if (j + offset <= 0 && tok < 0)
					error("must specify type of $%d", j + offset);
				if (tok < 0)
					tok = fdtype(prdptr[nprod][j + offset]);
				fprintf(faction, ".%s", typeset[tok]);
			}
			goto swt;
		}
		putc('$', faction);
		if (s < 0)
			putc('-', faction);
		goto swt;

	case '}':
		if (--brac)
			goto lcopy;
		putc(c, faction);
		return;


	case '/':		/* look for comments */
		putc(c, faction);
		c = unix_getc(finput);
		if (c != '*')
			goto swt;

		/* it really is a comment */

		putc(c, faction);
		c = unix_getc(finput);
		while (c != EOF) {
			while (c == '*') {
				putc(c, faction);
				if ((c = unix_getc(finput)) == '/')
					goto lcopy;
			}
			putc(c, faction);
			if (c == '\n')
				++lineno;
			c = unix_getc(finput);
		}
		error("EOF inside comment");

	case '\'':		/* character constant */
		match = '\'';
		goto string;

	case '"':		/* character string */
		match = '"';

string:

		putc(c, faction);
		while (c = unix_getc(finput)) {

			if (c == '\\') {
				putc(c, faction);
				c = unix_getc(finput);
				if (c == '\n')
					++lineno;
			} else if (c == match)
				goto lcopy;
			else if (c == '\n')
				error("newline in string or char. const.");
			putc(c, faction);
		}
		error("EOF in string or character constant");

	case -1:		/* EOF */
		error("action does not terminate");

	case '\n':
		++lineno;
		goto lcopy;

	}

lcopy:
	putc(c, faction);
	goto loop;
}
\EOF\
else
  echo "will not over write ./ycpact.c"
fi
if `test ! -s ./ycpfir.c`
then
echo "writing ./ycpfir.c"
cat > ./ycpfir.c << '\EOF\'
/*
 * ycpfir.c - compute an array with the first of nonterminals
 *
 * HISTORY
 * {1}	28-Aug-81  Bob Denny
 * 	Modified to make debug code conditionally compile.
 * 
 */

#include "y1.h"



int	cpfir()
{
	/* compute an array with the first of nonterminals */
	register *p, **s, i, **t, ch, changes;
	int *tmp;

	tmp = &wsets[nnonter];
	zzcwp = tmp;
	NTLOOP(i) {
		aryfil(wsets[i].ws.lset, tbitset, 0);
		t = pres[i + 1];
		for (s = pres[i]; s < t; ++s) {
			/* initially fill the sets */
			for (p = *s; (ch = *p) > 0; ++p) {
				if (ch < NTBASE) {
					SETBIT(wsets[i].ws.lset, ch);
					break;
				} else if (!pempty[ch - NTBASE])
					break;
			}
		}
	}

	/* now, reflect transitivity */

	changes = 1;
	while (changes) {
		changes = 0;
		NTLOOP(i) {
			t = pres[i + 1];
			for (s = pres[i]; s < t; ++s) {
				for (p = *s; (ch = (*p - NTBASE)) >= 0; ++p) {
					changes |= setunion(wsets[i].ws.lset, wsets[ch].ws.lset);
					if (!pempty[ch])
						break;
				}
			}
		}
	}

	NTLOOP(i) pfirst[i] = flset(&wsets[i].ws);
#ifdef debug
	if ((foutput != NULL)) {
		NTLOOP(i) {
			fprintf(foutput, "\n%s: ", nontrst[i].name);
			prlook(pfirst[i]);
			fprintf(foutput, " %d\n", pempty[i]);
		}
	}
#endif
}
\EOF\
else
  echo "will not over write ./ycpfir.c"
fi
if `test ! -s ./ycpres.c`
then
echo "writing ./ycpres.c"
cat > ./ycpres.c << '\EOF\'
/*
 * ycpres.c - compute an array with the beginnings of productions
 *
 * compute an array with the beginnings of productions yielding given
 * nonterminals The array pres points to these lists the array pyield has
 * the lists:  the total size is only NPROD+1 
 *
 * HISTORY 
 * {1}  12-Apr-83 Bob Denny 
 *      Add symbol exit status.
 * 
 */

#include "y1.h"


extern int	*pyield[NPROD];


int	cpres()
{
	register **pmem;
	register c, j, i;

	pmem = pyield;

	NTLOOP(i) {
		c = i + NTBASE;
		pres[i] = pmem;
		fatfl = 0;	/* make undefined  symbols  nonfatal */
		PLOOP(0, j) {
			if (*prdptr[j] == c)
				*pmem++ = prdptr[j] + 1;
		}
		if (pres[i] == pmem) {
			error("nonterminal %s not defined!", nontrst[i].name);
		}
	}
	pres[i] = pmem;
	fatfl = 1;
	if (nerrors) {
		summary();
		exit(EX_ERR);
	}
	if (pmem != &pyield[nprod])
		error("internal Yacc error: pyield %d", pmem - &pyield[nprod]);
}
\EOF\
else
  echo "will not over write ./ycpres.c"
fi
if `test ! -s ./ycpuni.c`
then
echo "writing ./ycpuni.c"
cat > ./ycpuni.c << '\EOF\'
/*
 * ycpuni.c - copy the union declaration & define file (if present) to output
 *
 * HISTORY
 */

#include "y2.h"

int	cpyunion()
{
	int	level, c;
	fprintf(ftable, "\n# line %d\n", lineno);
	fprintf(ftable, "\n#define UNION 1\n");
	fprintf(ftable, "typedef union ");
	if (fdefine)
		fprintf(fdefine, "\ntypedef union ");

	level = 0;
	for (; ; ) {
		if ((c = unix_getc(finput)) < 0)
			error("EOF encountered while processing %%union");
		putc(c, ftable);
		if (fdefine)
			putc(c, fdefine);

		switch (c) {

		case '\n':
			++lineno;
			break;

		case '{':
			++level;
			break;

		case '}':
			--level;
			if (level == 0) {
				/* we are finished copying */
				fprintf(ftable, " YYSTYPE;\n");
				if (fdefine)
					fprintf(fdefine, " YYSTYPE;\nextern YYSTYPE yylval;\n");
				return;
			}
		}
	}
}
\EOF\
else
  echo "will not over write ./ycpuni.c"
fi
if `test ! -s ./ycpycd.c`
then
echo "writing ./ycpycd.c"
cat > ./ycpycd.c << '\EOF\'
/*
 * ycpycd.c - copies code between \{ and \}
 *
 * HISTORY
 */

#include "y2.h"


int	cpycode()
{
	int	c;

	c = unix_getc(finput);
	if (c == '\n') {
		c = unix_getc(finput);
		lineno++;
	}
	fprintf(ftable, "\n# line %d\n", lineno);
	while (c >= 0) {
		if (c == '\\')
			if ((c = unix_getc(finput)) == '}')
				return;
			else
				putc('\\', ftable);
		if (c == '%')
			if ((c = unix_getc(finput)) == '}')
				return;
			else
				putc('%', ftable);
		putc(c, ftable);
		if (c == '\n')
			++lineno;
		c = unix_getc(finput);
	}
	error("eof before %%}");
}
\EOF\
else
  echo "will not over write ./ycpycd.c"
fi
if `test ! -s ./ycstsh.c`
then
echo "writing ./ycstsh.c"
cat > ./ycstsh.c << '\EOF\'
#include "y2.h"
char	*
cstash( s ) 
register char	*s;

{
	char	*temp;

	temp = cnamp;
	do 
	 {
		if ( cnamp >= &cnames[cnamsz] ) 
			error("too many characters in id's and literals" );
		else 
			*cnamp++ = *s;
	} while ( *s++);
	return( temp );
}
\EOF\
else
  echo "will not over write ./ycstsh.c"
fi
if `test ! -s ./ydefin.c`
then
echo "writing ./ydefin.c"
cat > ./ydefin.c << '\EOF\'
#include "y2.h"

defin( t, s ) 
register char	*s;

{
	/*   define s to be a terminal if t=0
        or a nonterminal if t=1         */

	register val;

	if (t) {
		if ( ++nnonter >= NNONTERM ) 
			error("too many nonterminals, limit %d", NNONTERM);
		nontrst[nnonter].name = cstash(s);
		return( NTBASE + nnonter );
	}
	/* must be a token */
	if ( ++ntokens >= NTERMS ) 
		error("too many terminals, limit %d", NTERMS );
	tokset[ntokens].name = cstash(s);

	/* establish value for token */

	if ( s[0] == ' ' && s[2] == '\0' ) /* single character literal */
		val = s[1];
	else if ( s[0] == ' ' && s[1] == '\\' ) {
		/* escape sequence */
		if ( s[3] == '\0' ) {
			/* single character escape sequence */
			switch ( s[2] ) {
				/* character which is escaped */
			case 'n':
				val = '\n';
				break;
			case 'r':
				val = '\r';
				break;
			case 'b':
				val = '\b';
				break;
			case 't':
				val = '\t';
				break;
			case 'f':
				val = '\f';
				break;
			case '\'':
				val = '\'';
				break;
			case '"':
				val = '"';
				break;
			case '\\':
				val = '\\';
				break;
			default:
				error( "invalid escape" );
			}
		} else if ( s[2] <= '7' && s[2] >= '0' ) {
			/* \nnn sequence */
			if ( s[3] < '0' || s[3] > '7' || s[4] < '0' || 
			    s[4] > '7' || s[5] != '\0' ) 
				error("illegal \\nnn construction" );
			val = 64 * s[2] + 8 * s[3] + s[4] - 73 * '0';
			if ( val == 0 ) 
				error( "'\\000' is illegal" );
		}
	} else      {
		val = extval++;
	}
	tokset[ntokens].value = val;
	toklev[ntokens] = 0;
	return( ntokens );
}
\EOF\
else
  echo "will not over write ./ydefin.c"
fi
if `test ! -s ./ydfout.c`
then
echo "writing ./ydfout.c"
cat > ./ydfout.c << '\EOF\'
/*
 * ydfout.c -
 *
 * HISTORY
 */

#include <ctype.h>
#include "y2.h"

int	defout()
{
	/* write out the defines (at the end of the declaration section) */

	register int	i, c;
	register char	*cp;

	for (i = ndefout; i <= ntokens; ++i) {

		cp = tokset[i].name;
		if (*cp == ' ')
			++cp;	/* literals */

		for (; (c = *cp) != '\0'; ++cp) {

			if (islower(c) || isupper(c) || isdigit(c) || c == '_')
				;	/* VOID */
			else
				goto nodef;
		}

		fprintf(ftable, "# define %s %d\n", tokset[i].name, tokset[i].value);
		if (fdefine != NULL)
			fprintf(fdefine, "# define %s %d\n", tokset[i].name, tokset[i].value);

nodef:
		;
	}

	ndefout = ntokens + 1;

}
\EOF\
else
  echo "will not over write ./ydfout.c"
fi
if `test ! -s ./yerror.c`
then
echo "writing ./yerror.c"
cat > ./yerror.c << '\EOF\'
#include "y1.h"

/*
 * 12-Apr-83 (RBD) Add symbolic exit status
 */
/* VARARGS1 */
error(s, a1) 
char	*s;

{
	/* write out error comment */

	++nerrors;
	fprintf( stderr, "\n fatal error: ");
	fprintf( stderr, s, a1);
	fprintf( stderr, ", line %d\n", lineno );
	if ( !fatfl ) 
		return;
	summary();
	exit(EX_ERR);
}
\EOF\
else
  echo "will not over write ./yerror.c"
fi
if `test ! -s ./yfdtyp.c`
then
echo "writing ./yfdtyp.c"
cat > ./yfdtyp.c << '\EOF\'
#include "y2.h"

fdtype( t )
{
	/* determine the type of a symbol */
	register v;
	if ( t >= NTBASE ) 
		v = nontrst[t-NTBASE].tvalue;
	else 
		v = TYPE( toklev[t] );
	if ( v <= 0 ) 
		error( "must specify type for %s", (t >= NTBASE) ? nontrst[t-NTBASE].name : 
		    tokset[t].name );
	return( v );
}
\EOF\
else
  echo "will not over write ./yfdtyp.c"
fi
if `test ! -s ./yflset.c`
then
echo "writing ./yflset.c"
cat > ./yflset.c << '\EOF\'
#include "y1.h"

struct looksets *flset( p )   
struct looksets *p;

{
	/* decide if the lookahead set pointed to by p is known */
	/* return pointer to a perminent location for the set */

	register struct looksets *q;
	int	j, *w;
	register *u, *v;

	for ( q = &lkst[nlset]; q-- > lkst; ) {
		u = p->lset;
		v = q->lset;
		w = &v[tbitset];
		while ( v < w) 
			if ( *u++ != *v++) 
				goto more;
		/* we have matched */
		return( q );
more:
		;
	}
	/* add a new one */
	q = &lkst[nlset++];
	if ( nlset >= LSETSIZE )
		error("too many lookahead sets" );
	SETLOOP(j)
	 {
		q->lset[j] = p->lset[j];
	}
	return( q );
}
\EOF\
else
  echo "will not over write ./yflset.c"
fi
if `test ! -s ./yfnact.c`
then
echo "writing ./yfnact.c"
cat > ./yfnact.c << '\EOF\'
#include "y2.h"

finact()
{
	/* finish action routine */

	fclose(faction);

	fprintf( ftable, "# define YYERRCODE %d\n", tokset[2].value );

}
\EOF\
else
  echo "will not over write ./yfnact.c"
fi
if `test ! -s ./yg2gen.c`
then
echo "writing ./yg2gen.c"
cat > ./yg2gen.c << '\EOF\'
#include "y3.h"

/*
 * yg2gen.3c
 *
 * Modified to make debug code conditionally compile.
 * 28-Aug-81
 * Bob Denny
 */

go2gen(c)

{
	/* output the gotos for nonterminal c */

	int	i, work, cc;
	struct item *p, *q;


	/* first, find nonterminals with gotos on c */

	aryfil( temp1, nnonter + 1, 0 );
	temp1[c] = 1;

	work = 1;
	while ( work ) {

		work = 0;
		PLOOP(0, i)

		 {
			if ( (cc = prdptr[i][1] - NTBASE) >= 0 ) {

				/* cc is a nonterminal */
				if ( temp1[cc] != 0 ) {

					/* cc has a goto on c */
					cc = *prdptr[i] - NTBASE; /* thus, the left side of production i does too */
					if ( temp1[cc] == 0 ) {

						work = 1;
						temp1[cc] = 1;
					}
				}
			}
		}
	}

	/* now, we have temp1[c] = 1 if a goto on c in closure of cc */

#ifdef debug
	if ( foutput != NULL ) {

		fprintf( foutput, "%s: gotos on ", nontrst[c].name );
		NTLOOP(i) if ( temp1[i] ) 
			fprintf( foutput, "%s ", nontrst[i].name);
		fprintf( foutput, "\n");
	}
#endif
	/* now, go through and put gotos into tystate */

	aryfil( tystate, nstate, 0 );
	SLOOP(i)

	 {
		ITMLOOP(i, p, q)

		 {
			if ( (cc = *p->pitem) >= NTBASE ) {

				if ( temp1[cc -= NTBASE] ) {

					/* goto on c is possible */
					tystate[i] = amem[indgo[i]+c];
					break;
				}
			}
		}
	}
}
\EOF\
else
  echo "will not over write ./yg2gen.c"
fi
if `test ! -s ./yg2out.c`
then
echo "writing ./yg2out.c"
cat > ./yg2out.c << '\EOF\'
#include "y3.h"

go2out()
{
	/* output the gotos for the nontermninals */
	int	i, j, k, best, count, cbest, times;

	fprintf( ftemp, "$\n" );  /* mark begining of gotos */

	for ( i = 1; i <= nnonter; ++i ) {
		go2gen(i);

		/* find the best one to make default */

		best = -1;
		times = 0;

		for ( j = 0; j <= nstate; ++j ) {
			/* is j the most frequent */
			if ( tystate[j] == 0 ) 
				continue;
			if ( tystate[j] == best ) 
				continue;

			/* is tystate[j] the most frequent */

			count = 0;
			cbest = tystate[j];

			for ( k = j; k <= nstate; ++k ) 
				if ( tystate[k] == cbest ) 
					++count;

			if ( count > times ) {
				best = cbest;
				times = count;
			}
		}

		/* best is now the default entry */

		zzgobest += (times - 1);
		for ( j = 0; j <= nstate; ++j ) {
			if ( tystate[j] != 0 && tystate[j] != best ) {
				fprintf( ftemp, "%d,%d,", j, tystate[j] );
				zzgoent += 1;
			}
		}

		/* now, the default */

		zzgoent += 1;
		fprintf( ftemp, "%d\n", best );

	}
}
\EOF\
else
  echo "will not over write ./yg2out.c"
fi
if `test ! -s ./ygin.c`
then
echo "writing ./ygin.c"
cat > ./ygin.c << '\EOF\'
#include "y4.h"

gin(i)
{

	register *p, *r, *s, *q1, *q2;

	/* enter gotos on nonterminal i into array a */

	ggreed[i] = 0;

	q2 = mem0 + yypgo[i+1] - 1;
	q1 = mem0 + yypgo[i];

	/* now, find a place for it */

	for ( p = a; p < &a[ACTSIZE]; ++p ) {
		if ( *p ) 
			continue;
		for ( r = q1; r < q2; r += 2 ) {
			s = p + *r + 1;
			if ( *s ) 
				goto nextgp;
			if ( s > maxa ) {
				if ( (maxa = s) > &a[ACTSIZE] ) 
					error( "a array overflow" );
			}
		}
		/* we have found a spot */

		*p = *q2;
		if ( p > maxa ) {
			if ( (maxa = p) > &a[ACTSIZE] ) 
				error( "a array overflow" );
		}
		for ( r = q1; r < q2; r += 2 ) {
			s = p + *r + 1;
			*s = r[1];
		}

		pgo[i] = p - a;
		if ( adb > 1 ) 
			fprintf( ftable, "Nonterminal %d, entry at %d\n" , i, pgo[i] );
		goto nextgi;

nextgp:
		;
	}

	error( "cannot place goto %d\n", i );

nextgi:
	;
}
\EOF\
else
  echo "will not over write ./ygin.c"
fi
if `test ! -s ./ygtnm.c`
then
echo "writing ./ygtnm.c"
cat > ./ygtnm.c << '\EOF\'
/*
 * ygtnm.c -
 *
 * HISTORY
 */

#include <ctype.h>
#include "y4.h"

int	gtnm()
{

	register s, val, c;

	/* read and convert an integer from the standard input */
	/* return the terminating character */
	/* blanks, tabs, and newlines are ignored */

	s = 1;
	val = 0;

	while ((c = unix_getc(finput)) != EOF) {
		if (isdigit(c)) {
			val = val * 10 + c - '0';
		} else if (c == '-')
			s = -1;
		else if (c == '\r')
			continue;
		else
			break;
	}
	*pmem++ = s * val;
	if (pmem > &mem0[MEMSIZE])
		error("out of space");
	return (c);
}
\EOF\
else
  echo "will not over write ./ygtnm.c"
fi
if `test ! -s ./ygttok.c`
then
echo "writing ./ygttok.c"
cat > ./ygttok.c << '\EOF\'
/*
 * ygttok.c -
 *
 * HISTORY
 */

#include <ctype.h>
#include "y2.h"

extern int	peekline; /* number of '\n' seen in lookahead */

int	gettok()
{
	register i, base;
	register c, match, reserve;

begin:
	reserve = 0;
	lineno += peekline;
	peekline = 0;
	c = unix_getc(finput);
	while (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r') {
		if (c == '\n')
			++lineno;
		c = unix_getc(finput);
	}
	if (c == '/') {
		/* skip comment */
		lineno += skipcom();
		goto begin;
	}
	switch (c) {

	case -1:		/* EOF */
		return (ENDFILE);
	case '{':
		ungetc(c, finput);
		return ('=');	/* action ... */
	case '<':		/* get, and look up, a type name (union
						 * member name) */
		i = 0;
		while ((c = unix_getc(finput)) != '>' && c >= 0 && c != '\n') {
			tokname[i] = c;
			if (++i >= NAMESIZE)
				--i;
		}
		if (c != '>')
			error("unterminated < ... > clause");
		tokname[i] = '\0';
		for (i = 1; i <= ntypes; ++i) {
			if (!strcmp(typeset[i], tokname)) {
				numbval = i;
				return (TYPENAME);
			}
		}
		typeset[numbval = ++ntypes] = cstash(tokname);
		return (TYPENAME);

	case '"':
	case '\'':
		match = c;
		tokname[0] = ' ';
		i = 1;
		for (; ; ) {
			c = unix_getc(finput);
			if (c == '\n' || c == EOF)
				error("illegal or missing ' or \"");
			if (c == '\\') {
				c = unix_getc(finput);
				tokname[i] = '\\';
				if (++i >= NAMESIZE)
					--i;
			} else if (c == match)
				break;
			tokname[i] = c;
			if (++i >= NAMESIZE)
				--i;
		}
		break;

	case '%':
	case '\\':

		switch (c = unix_getc(finput)) {

		case '0':
			return (TERM);
		case '<':
			return (LEFT);
		case '2':
			return (BINARY);
		case '>':
			return (RIGHT);
		case '%':
		case '\\':
			return (MARK);
		case '=':
			return (PREC);
		case '{':
			return (LCURLY);
		default:
			reserve = 1;
		}

	default:

		if (isdigit(c)) {
			/* number */
			numbval = c - '0';
			base = (c == '0') ? 8 : 10;
			for (c = unix_getc(finput); isdigit(c); c = getc(finput)) {
				numbval = numbval * base + c - '0';
			}
			ungetc(c, finput);
			return (NUMBER);
		} else if (islower(c) || isupper(c) || c == '_' || c == '.' || c == '$') {
			i = 0;
			while (islower(c) || isupper(c) || isdigit(c) || c == '_' || c == '.' || c == '$') {
				tokname[i] = c;
				if (reserve && isupper(c))
					tokname[i] += 'a' - 'A';
				if (++i >= NAMESIZE)
					--i;
				c = unix_getc(finput);
			}
		} else
			return (c);

		ungetc(c, finput);
	}

	tokname[i] = '\0';

	if (reserve) {
		/* find a reserved word */
		if (!strcmp(tokname, "term"))
			return (TERM);
		if (!strcmp(tokname, "token"))
			return (TERM);
		if (!strcmp(tokname, "left"))
			return (LEFT);
		if (!strcmp(tokname, "nonassoc"))
			return (BINARY);
		if (!strcmp(tokname, "binary"))
			return (BINARY);
		if (!strcmp(tokname, "right"))
			return (RIGHT);
		if (!strcmp(tokname, "prec"))
			return (PREC);
		if (!strcmp(tokname, "start"))
			return (START);
		if (!strcmp(tokname, "type"))
			return (TYPEDEF);
		if (!strcmp(tokname, "union"))
			return (UNION);
		error("invalid escape, or illegal reserved word: %s", tokname);
	}
	/* look ahead to distinguish IDENTIFIER from C_IDENTIFIER */

	c = unix_getc(finput);
	while (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '/') {
		if (c == '\n')
			++peekline;
		else if (c == '/') {
			/* look for comments */
			peekline += skipcom();
		}
		c = unix_getc(finput);
	}
	if (c == ':')
		return (C_IDENTIFIER);
	ungetc(c, finput);
	return (IDENTIFIER);
}
\EOF\
else
  echo "will not over write ./ygttok.c"
fi
if `test ! -s ./yhdprd.c`
then
echo "writing ./yhdprd.c"
cat > ./yhdprd.c << '\EOF\'
#include "y3.h"

hideprod()
{
	/* in order to free up the mem and amem arrays for the optimizer,
        /* and still be able to output yyr1, etc., after the sizes of
        /* the action array is known, we hide the nonterminals
        /* derived by productions in levprd.
        */

	register i, j;

	j = 0;
	levprd[0] = 0;
	PLOOP(1, i)
	 {
		if ( !(levprd[i] & REDFLAG) ) {
			++j;
			if ( foutput != NULL ) {
				fprintf( foutput, "Rule not reduced:   %s\n", writem( prdptr[i] ) );
			}
		}
		levprd[i] = *prdptr[i] - NTBASE;
	}
	if ( j ) 
		fprintf( stdout, "%d rules never reduced\n", j );
}
\EOF\
else
  echo "will not over write ./yhdprd.c"
fi
if `test ! -s ./ymain.c`
then
echo "writing ./ymain.c"
cat > ./ymain.c << '\EOF\'
#include "y1.h"
/*
 * 12-Apr-83 (RBD) Add symbolic exit status
 */
main(argc, argv) 
int	argc;
char	*argv[];

{

	puts("Setup...");
	setup(argc, argv); /* initialize and read productions */
	puts("cpres ...");
	tbitset = NWORDS(ntokens);
	cpres(); /* make table of which productions yield a given nonterminal */
	puts("cempty ...");
	cempty(); /* make a table of which nonterminals can match the empty string */
	puts("cpfir ...");
	cpfir(); /* make a table of firsts of nonterminals */
	puts("stagen ...");
	stagen(); /* generate the states */
	puts("output ...");
	output();  /* write the states and the tables */
	puts("go2out ...");
	go2out();
	puts("hideprod ...");
	hideprod();
	puts("summary ...");
	summary();
	puts("callopt ...");
	callopt();
	puts("others ...");
	others();
	puts("DONE !!!");
	exit(EX_SUC);
}
\EOF\
else
  echo "will not over write ./ymain.c"
fi
if `test ! -s ./ymkfil`
then
echo "writing ./ymkfil"
cat > ./ymkfil << '\EOF\'
CFLAGS   = -Ot -Ml
LDFLAGS  = -Ml -s
OBJECTS  = y1imp.o y2imp.o y3imp.o y4imp.o yaryfl.o ycemty.o ychcpy.o\
           yclsur.o ycpfir.o ycpres.o yerror.o yflset.o ymain.o yothrs.o\
           yprlok.o yptitm.o ysmnam.o ystagn.o ystate.o ystuni.o ysumry.o\
           ywritm.o ychfnd.o ycpact.o ycpuni.o ycpycd.o ycstsh.o ydefin.o\
           ydfout.o yfdtyp.o yfnact.o ygttok.o ysetup.o yskpcm.o yapack.o\
           yg2gen.o yg2out.o yhdprd.o youtpt.o yprcft.o ywarry.o ywract.o\
           ywstat.o yaoput.o yclopt.o ygin.o ygtnm.o ynxti.o yosmry.o\
           ystin.o yarout.o
PROGRAMS = yacc

all: ${PROGRAMS}

clean:
	rm -f ${PROGRAMS}
	rm -f ${OBJECTS}
	rm -f a.out core

yacc: ${OBJECTS}
	cc ${LDFLAGS} ${OBJECTS} -o yacc


dtxtrn.h: 	/usr/include/stdio.h system.h 
y1.h: 		dtxtrn.h 
y1imp.o: 	dtxtrn.h 
y2.h: 		dtxtrn.h 
y2imp.o: 	dtxtrn.h 
y3.h: 		dtxtrn.h 
y3imp.o: 	dtxtrn.h 
y4.h: 		dtxtrn.h 
y4imp.o: 	dtxtrn.h 
yaoput.o: 	y4.h 
yapack.o: 	y3.h 
yarout.o: 	y4.h 
yaryfl.o: 	y1.h 
ycemty.o: 	y1.h 
ychcpy.o: 	y1.h 
ychfnd.o: 	y2.h 
yclopt.o: 	y4.h 
yclsur.o: 	y1.h 
ycpact.o: 	/usr/include/stdio.h /usr/include/ctype.h y2.h 
ycpfir.o: 	y1.h 
ycpres.o: 	y1.h 
ycpuni.o: 	y2.h 
ycpycd.o: 	y2.h 
ycstsh.o: 	y2.h 
ydefin.o: 	y2.h 
ydfout.o: 	/usr/include/ctype.h y2.h 
yerror.o: 	y1.h 
yfdtyp.o: 	y2.h 
yflset.o: 	y1.h 
yfnact.o: 	y2.h 
yg2gen.o: 	y3.h 
yg2out.o: 	y3.h 
ygin.o: 	y4.h 
ygtnm.o: 	/usr/include/ctype.h 	 y4.h 
ygttok.o: 	/usr/include/ctype.h 	 y2.h 
yhdprd.o: 	y3.h 
ymain.o: 	y1.h 
ynxti.o: 	y4.h 
yosmry.o: 	y4.h 
yothrs.o: 	y1.h 
youtpt.o: 	y3.h 
yprcft.o: 	y3.h 
yprlok.o: 	y1.h 
yptitm.o: 	y1.h 
ysetup.o: 	y2.h 
yskpcm.o: 	y2.h 
ysmnam.o: 	y1.h 
ystagn.o: 	y1.h 
ystate.o: 	y1.h 
ystin.o: 	y4.h 
ystuni.o: 	y1.h 
ysumry.o: 	y1.h 
ywarry.o: 	y3.h 
ywract.o: 	y3.h 
ywritm.o: 	y1.h 
ywstat.o: 	y3.h 
\EOF\
else
  echo "will not over write ./ymkfil"
fi
if `test ! -s ./ynxti.c`
then
echo "writing ./ynxti.c"
cat > ./ynxti.c << '\EOF\'
#include "y4.h"

nxti()
{
	/* finds the next i */
	register i, max, maxi;

	max = 0;

	for ( i = 1; i <= nnonter; ++i ) 
		if ( ggreed[i] >= max ) {
			max = ggreed[i];
			maxi = -i;
		}

	for ( i = 0; i < nstate; ++i ) 
		if ( greed[i] >= max ) {
			max = greed[i];
			maxi = i;
		}

	if ( nxdb ) 
		fprintf( ftable, "nxti = %d, max = %d\n", maxi, max );
	if ( max == 0 ) 
		return( NOMORE );
	else 
		return( maxi );
}
\EOF\
else
  echo "will not over write ./ynxti.c"
fi
if `test ! -s ./yosmry.c`
then
echo "writing ./yosmry.c"
cat > ./yosmry.c << '\EOF\'
#include "y4.h"

/*
 * Write summary.
 */

osummary()

{
	register int	i, *p;

	if (foutput == NULL) 
		return;

	i = 0;
	for (p = maxa; p >= a; --p) {

		if (*p == 0) 
			++i;
	}
	fprintf(foutput, "Optimizer space used: input %d/%d, output %d/%d\n",
	    pmem - mem0 + 1, MEMSIZE, maxa - a + 1, ACTSIZE);
	fprintf(foutput, "%d table entries, %d zero\n", (maxa - a) + 1, i);
	fprintf(foutput, "maximum spread: %d, maximum offset: %d\n", maxspr, maxoff);
	fclose(foutput);
}
\EOF\
else
  echo "will not over write ./yosmry.c"
fi
if `test ! -s ./yothrs.c`
then
echo "writing ./yothrs.c"
cat > ./yothrs.c << '\EOF\'
/* Edits:
 *      06-Dec-80 Original code broken out of y1.c.
 *      18-Dec-80 Add conditional code for Decus for tempfile deletion.
 */

#include "y1.h"

int	others()
{
	/* put out other arrays, copy the parsers */
	register c, i, j;

	finput = (FILE * )fopen(PARSER, "r");
	if (finput == (FILE * )NULL)
		error("cannot find parser %s", PARSER);

	warray("yyr1", levprd, nprod);

	aryfil(temp1, nprod, 0);
	PLOOP(1, i) temp1[i] = prdptr[i + 1] - prdptr[i] - 2;
	warray("yyr2", temp1, nprod);

	aryfil(temp1, nstate, -1000);
	TLOOP(i) {
		for (j = tstates[i]; j != 0; j = mstates[j]) {
			temp1[j] = tokset[i].value;
		}
	}
	NTLOOP(i) {
		for (j = ntstates[i]; j != 0; j = mstates[j]) {
			temp1[j] = -i;
		}
	}
	warray("yychk", temp1, nstate);

	warray("yydef", defact, nstate);

	/* copy parser text */

	while ((c = unix_getc(finput)) != EOF) {
		if (c == '$') {
			if ((c = unix_getc(finput)) != 'A')
				putc('$', ftable);
			else {
				/* copy actions */
				faction = fopen(ACTNAME, "r");
				if (faction == NULL)
					error("cannot reopen action tempfile");
				while ((c = unix_getc(faction)) != EOF)
					putc(c, ftable);
				fclose(faction);
				ZAPFILE(ACTNAME);
				c = unix_getc(finput);
			}
		}
		putc(c, ftable);
	}
	fclose(ftable);
}


int	unix_getc(iop)
FILE	*iop;
{
	int	c;

	c = getc(iop);
	/* Stop on Control-Z */
	if (c == '\032')
		return (EOF);
	else
		return (c);
}
\EOF\
else
  echo "will not over write ./yothrs.c"
fi
if `test ! -s ./youtpt.c`
then
echo "writing ./youtpt.c"
cat > ./youtpt.c << '\EOF\'
#include "y3.h"

output()
{
	/* print the output for the states */

	int	i, k, c;
	register struct wset *u, *v;

	fprintf( ftable, "short yyexca[] ={\n" );

	SLOOP(i)
	 {
		/* output the stuff for state i */
		nolook = !(tystate[i] == MUSTLOOKAHEAD);
		closure(i);
		/* output actions */
		nolook = 1;
		aryfil( temp1, ntokens + nnonter + 1, 0 );
		WSLOOP(wsets, u)
		 {
			c = *( u->pitem );
			if ( c > 1 && c < NTBASE && temp1[c] == 0 ) {
				WSLOOP(u, v)
				 {
					if ( c == *(v->pitem) ) 
						putitem( v->pitem + 1, (struct looksets *)0 );
				}
				temp1[c] = state(c);
			} else if ( c > NTBASE && temp1[ (c -= NTBASE) + ntokens ] == 0 ) {
				temp1[ c+ntokens ] = amem[indgo[i]+c];
			}
		}

		if ( i == 1 ) 
			temp1[1] = ACCEPTCODE;

		/* now, we have the shifts; look at the reductions */

		lastred = 0;
		WSLOOP(wsets, u)
		 {
			c = *( u->pitem );
			if ( c <= 0 ) {
				/* reduction */
				lastred = -c;
				TLOOP(k)
				 {
					if ( BIT(u->ws.lset, k) ) {
						if ( temp1[k] == 0 ) 
							temp1[k] = c;
						else if ( temp1[k] < 0 ) {
							/* reduce/reduce conflict */
							if ( foutput != NULL )
								fprintf( foutput,
								    "\n%d: reduce/reduce conflict (red'ns %d and %d ) on %s",
								                            i, -temp1[k], lastred, symnam(k) );
							if ( -temp1[k] > lastred ) 
								temp1[k] = -lastred;
							++zzrrconf;
						} else                     {
							/* potential shift/reduce conflict */
							precftn( lastred, k, i );
						}
					}
				}
			}
		}
		wract(i);
	}

	fprintf( ftable, "\t};\n" );

	wdef( "YYNPROD", nprod );

}
\EOF\
else
  echo "will not over write ./youtpt.c"
fi
echo "Finished archive 2 of 4"
# if you want to concatenate archives, remove anything after this line
exit 0

glenn@extro.ucc.su.oz (G. Geers [ext 3241]) (06/28/89)

--- cut here --- cut here --- cut here --- cut here --- cut here ---
#!/bin/sh
# This is a shell archive.  Remove anything before the /bin/sh line
# then unpack it by saving it in a file and typing "sh file"
# (Files unpacked will be owned by you and have default permissions).
# Don't worry about trailing garbage - the archive ends with exit
# This archive contains the following files:
#	./dtxtrn.h
#	./parse.y
#	./system.h
#	./y1.h
#	./y1imp.c
#	./y2.h
#	./y2imp.c
#	./y3.h
#	./y3imp.c
#	./y4.h
#	./y4imp.c
#	./yaoput.c
#	./yapack.c
#
if `test ! -s ./dtxtrn.h`
then
echo "writing ./dtxtrn.h"
cat > ./dtxtrn.h << '\EOF\'
/*
 * DTXTRN.H  -- Original extern file for UNIX YACC.
 *
 * Modified to call in "decus" or "vax11c" .H files to set up
 * parameters as appropriate.
 */

#include <stdio.h>
#include "system.h"

/*  MANIFEST CONSTANT DEFINITIONS */

/* base of nonterminal internal numbers */
#define NTBASE 010000

/* internal codes for error and accept actions */

#define ERRCODE  8190
#define ACCEPTCODE 8191

/* sizes and limits */

#ifdef HUGETAB
#define ACTSIZE 12000
#define MEMSIZE 12000
#define NSTATES 750
#define NTERMS 127
#define NPROD 600
#define NNONTERM 300
#define TEMPSIZE 1200
#define CNAMSZ 5000
#define LSETSIZE 600
#define WSETSIZE 350
#endif

#ifdef MEDTAB
#define ACTSIZE 4000
#define MEMSIZE 5200
#define NSTATES 600
#define NTERMS 127
#define NPROD 400
#define NNONTERM 200
#define TEMPSIZE 800
#define CNAMSZ 5000
#define LSETSIZE 450
#define WSETSIZE 250
#endif

#ifdef SMALLTAB
#define ACTSIZE 1000
#define MEMSIZE 1500
#define NSTATES 450
#define NTERMS 127
#define NPROD 200
#define NNONTERM 100
#define TEMPSIZE 600
#define CNAMSZ 5000
#define LSETSIZE 200
#define WSETSIZE 125
#endif

#define NAMESIZE 50
#define NTYPES 63

#ifdef WORD32
#define TBITSET ((32+NTERMS)/32)

/* bit packing macros (may be machine dependent) */
#define BIT(a,i) ((a)[(i)>>5] & (1<<((i)&037)))
#define SETBIT(a,i) ((a)[(i)>>5] |= (1<<((i)&037)))

/* number of words needed to hold n+1 bits */
#define NWORDS(n) (((n)+32)/32)

#else

#define TBITSET ((16+NTERMS)/16)

/* bit packing macros (may be machine dependent) */
#define BIT(a,i) ((a)[(i)>>4] & (1<<((i)&017)))
#define SETBIT(a,i) ((a)[(i)>>4] |= (1<<((i)&017)))

/* number of words needed to hold n+1 bits */
#define NWORDS(n) (((n)+16)/16)
#endif

/* relationships which must hold:
        TBITSET ints must hold NTERMS+1 bits...
        WSETSIZE >= NNONTERM
        LSETSIZE >= NNONTERM
        TEMPSIZE >= NTERMS + NNONTERMs + 1
        TEMPSIZE >= NSTATES
        */

/* associativities */

#define NOASC 0  /* no assoc. */
#define LASC 1  /* left assoc. */
#define RASC 2  /* right assoc. */
#define BASC 3  /* binary assoc. */

/* flags for state generation */

#define DONE 0
#define MUSTDO 1
#define MUSTLOOKAHEAD 2

/* flags for a rule having an action, and being reduced */

#define ACTFLAG 04
#define REDFLAG 010

/* output parser flags */
#define YYFLAG1 (-1000)

/* macros for getting associativity and precedence levels */

#define ASSOC(i) ((i)&03)
#define PLEVEL(i) (((i)>>4)&077)
#define TYPE(i)  ((i>>10)&077)

/* macros for setting associativity and precedence levels */

#define SETASC(i,j) i|=j
#define SETPLEV(i,j) i |= (j<<4)
#define SETTYPE(i,j) i |= (j<<10)

/* looping macros */

#define TLOOP(i) for(i=1;i<=ntokens;++i)
#define NTLOOP(i) for(i=0;i<=nnonter;++i)
#define PLOOP(s,i) for(i=s;i<nprod;++i)
#define SLOOP(i) for(i=0;i<nstate;++i)
#define WSBUMP(x) ++x
#define WSLOOP(s,j) for(j=s;j<cwp;++j)
#define ITMLOOP(i,p,q) q=pstate[i+1];for(p=pstate[i];p<q;++p)
#define SETLOOP(i) for(i=0;i<tbitset;++i)

/* I/O descriptors */

#ifndef y2imp
extern FILE *finput;           /* input file */
extern FILE *faction;          /* file for saving actions */
extern FILE *fdefine;           /* file for #defines */
extern FILE *ftable;           /* y.tab.c file */
extern FILE *ftemp;            /* tempfile to pass 2 */
extern FILE *foutput;          /* y.output file */
#endif

/* structure declarations */

struct looksets {
	int	lset[TBITSET];
};

struct item {
	int	*pitem;
	struct looksets *look;
};

struct toksymb {
	char	*name;
	int	value;
};

struct ntsymb {
	char	*name;
	int	tvalue;
};

struct wset {
	int	*pitem;
	int	flag;
	struct looksets ws;
};

#ifndef y2imp
/* token information */
extern int	ntokens ;    /* number of tokens */
extern struct toksymb tokset[];
extern int	toklev[];    /* vector with the precedence of the terminals */
#endif

/* nonterminal information */

#ifndef y2imp
extern int	nnonter ;    /* the number of nonterminals */
extern struct ntsymb nontrst[];
#endif

/* grammar rule information */
#ifndef y2imp
extern int	nprod ;      /* number of productions */
extern int	*prdptr[];   /* pointers to descriptions of productions */
extern int	levprd[] ;   /* contains production levels to break conflicts */
#endif

/* state information */

#ifndef y1imp
extern int	nstate ;             /* number of states */
extern struct item *pstate[];   /* pointers to the descriptions of the states */
extern int	tystate[];   /* contains type information about the states */
#ifndef y3imp
extern int	defact[];    /* the default action of the state */
#endif
extern int	tstates[];   /* the states deriving each token */
extern int	ntstates[];  /* the states deriving each nonterminal */
extern int	mstates[];   /* the continuation of the chains begun in tstates and ntstates */
#endif

/* lookahead set information */

#ifndef y1imp
extern struct looksets lkst[];
extern int	nolook;  /* flag to turn off lookahead computations */
#endif

/* working set information */

#ifndef y1imp
extern struct wset wsets[];
extern struct wset *cwp;
#endif

/* storage for productions */
#ifndef y2imp
extern int	mem0[];
extern int	*mem;
#endif

/* storage for action table */

#ifndef y1imp
extern int	amem[];  /* action table storage */
extern int	*memp ;              /* next free action table position */
extern int	indgo[];             /* index to the stored goto table */

/* temporary vector, indexable by states, terms, or ntokens */

extern int	temp1[];
extern int	lineno; /* current line number */

/* statistics collection variables */

extern int	zzgoent ;
extern int	zzgobest ;
extern int	zzacent ;
extern int	zzexcp ;
extern int	zzclose ;
extern int	zzrrconf ;
extern int	zzsrconf ;
#endif

/* define functions with strange types... */
extern char	*cstash();
extern struct looksets *flset();
extern char	*symnam();
extern char	*writem();

/* default settings for a number of macros */

#define ISIZE 400       /* Specific for static in cpres() */

/* name of yacc tempfiles */

#ifndef TEMPNAME
#define TEMPNAME "yacc.tmp"
#endif

#ifndef ACTNAME
#define ACTNAME "yacc.act"
#endif

/* output file name */

#ifndef OFILE
#define OFILE "ytab.c"
#endif

/* user output file name */

#ifndef FILEU
#define FILEU "y.out"
#endif

/* output file for #defines */

#ifndef FILED
#define FILED "ytab.h"
#endif

/* Size of complete filespec */
#ifndef FNAMESIZE
#define FNAMESIZE 32
#endif

/* command to clobber tempfiles after use */

#ifndef ZAPFILE
#define ZAPFILE(x) unlink(x)
#endif
\EOF\
else
  echo "will not over write ./dtxtrn.h"
fi
if `test ! -s ./parse.y`
then
echo "writing ./parse.y"
cat > ./parse.y << '\EOF\'
/* parse.y - parser for flex input */

/*
 * Copyright (c) 1989 The Regents of the University of California.
 * All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Vern Paxson.
 * 
 * The United States Government has rights in this work pursuant to
 * contract no. DE-AC03-76SF00098 between the United States Department of
 * Energy and the University of California.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by the University of California, Berkeley.  The name of the
 * University may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

%token CHAR NUMBER SECTEND SCDECL XSCDECL WHITESPACE NAME PREVCCL EOF_OP

%{

#include "flexdef.h"

#ifndef lint

static char copyright[] =
    "@(#) Copyright (c) 1989 The Regents of the University of California.\n";
static char CR_continuation[] = "@(#) All rights reserved.\n";

static char rcsid[] =
    "@(#) $Header: parse.y,v 2.1 89/06/20 17:23:54 vern Exp $ (LBL)";

#endif

int pat, scnum, eps, headcnt, trailcnt, anyccl, lastchar, i, actvp, rulelen;
int trlcontxt, xcluflg, cclsorted, varlength, variable_trail_rule;
char clower();

static int madeany = false;  /* whether we've made the '.' character class */
int previous_continued_action;	/* whether the previous rule's action was '|' */

%}

%%
goal            :  initlex sect1 sect1end sect2 initforrule
			{ /* add default rule */
			int def_rule;

			pat = cclinit();
			cclnegate( pat );

			def_rule = mkstate( -pat );

			finish_rule( def_rule, false, 0, 0 );

			for ( i = 1; i <= lastsc; ++i )
			    scset[i] = mkbranch( scset[i], def_rule );

			if ( spprdflt )
			    fputs( "YY_FATAL_ERROR( \"flex scanner jammed\" )",
				   temp_action_file );
			else
			    fputs( "ECHO", temp_action_file );

			fputs( ";\n\tYY_BREAK\n", temp_action_file );
			}
		;

initlex         :
			{
			/* initialize for processing rules */

			/* create default DFA start condition */
			scinstal( "INITIAL", false );
			}
		;
			
sect1		:  sect1 startconddecl WHITESPACE namelist1 '\n'
		|
		|  error '\n'
			{ synerr( "unknown error processing section 1" ); }
		;

sect1end	:  SECTEND
		;

startconddecl   :  SCDECL
			{
			/* these productions are separate from the s1object
			 * rule because the semantics must be done before
			 * we parse the remainder of an s1object
			 */

			xcluflg = false;
			}
		
		|  XSCDECL
			{ xcluflg = true; }
		;

namelist1	:  namelist1 WHITESPACE NAME
			{ scinstal( nmstr, xcluflg ); }

		|  NAME
			{ scinstal( nmstr, xcluflg ); }

		|  error
                        { synerr( "bad start condition list" ); }
		;

sect2           :  sect2 initforrule flexrule '\n'
		|
		;

initforrule     :
			{
			/* initialize for a parse of one rule */
			trlcontxt = variable_trail_rule = varlength = false;
			trailcnt = headcnt = rulelen = 0;
			current_state_type = STATE_NORMAL;
			previous_continued_action = continued_action;
			new_rule();
			}
		;

flexrule        :  scon '^' re eol 
                        {
			pat = link_machines( $3, $4 );
			finish_rule( pat, variable_trail_rule,
				     headcnt, trailcnt );

			for ( i = 1; i <= actvp; ++i )
			    scbol[actvsc[i]] =
				mkbranch( scbol[actvsc[i]], pat );

			if ( ! bol_needed )
			    {
			    bol_needed = true;

			    if ( performance_report )
				fprintf( stderr,
			"'^' operator results in sub-optimal performance\n" );
			    }
			}

		|  scon re eol 
                        {
			pat = link_machines( $2, $3 );
			finish_rule( pat, variable_trail_rule,
				     headcnt, trailcnt );

			for ( i = 1; i <= actvp; ++i )
			    scset[actvsc[i]] = 
				mkbranch( scset[actvsc[i]], pat );
			}

                |  '^' re eol 
			{
			pat = link_machines( $2, $3 );
			finish_rule( pat, variable_trail_rule,
				     headcnt, trailcnt );

			/* add to all non-exclusive start conditions,
			 * including the default (0) start condition
			 */

			for ( i = 1; i <= lastsc; ++i )
			    if ( ! scxclu[i] )
				scbol[i] = mkbranch( scbol[i], pat );

			if ( ! bol_needed )
			    {
			    bol_needed = true;

			    if ( performance_report )
				fprintf( stderr,
			"'^' operator results in sub-optimal performance\n" );
			    }
			}

                |  re eol 
			{
			pat = link_machines( $1, $2 );
			finish_rule( pat, variable_trail_rule,
				     headcnt, trailcnt );

			for ( i = 1; i <= lastsc; ++i )
			    if ( ! scxclu[i] )
				scset[i] = mkbranch( scset[i], pat );
			}

                |  scon EOF_OP
			{ build_eof_action(); }

                |  EOF_OP
			{
			/* this EOF applies only to the INITIAL start cond. */
			actvsc[actvp = 1] = 1;
			build_eof_action();
			}

                |  error
			{ synerr( "unrecognized rule" ); }
		;

scon            :  '<' namelist2 '>'
		;

namelist2       :  namelist2 ',' NAME
                        {
			if ( (scnum = sclookup( nmstr )) == 0 )
			    lerrsf( "undeclared start condition %s", nmstr );

			else
			    actvsc[++actvp] = scnum;
			}

		|  NAME
			{
			if ( (scnum = sclookup( nmstr )) == 0 )
			    lerrsf( "undeclared start condition %s", nmstr );
			else
			    actvsc[actvp = 1] = scnum;
			}

		|  error
			{ synerr( "bad start condition list" ); }
		;

eol             :  '$'
                        {
			if ( trlcontxt )
			    {
			    synerr( "trailing context used twice" );
			    $$ = mkstate( SYM_EPSILON );
			    }
			else
			    {
			    trlcontxt = true;

			    if ( ! varlength )
				headcnt = rulelen;

			    ++rulelen;
			    trailcnt = 1;

			    eps = mkstate( SYM_EPSILON );
			    $$ = link_machines( eps, mkstate( '\n' ) );
			    }
			}

		|
		        {
		        $$ = mkstate( SYM_EPSILON );

			if ( trlcontxt )
			    {
			    if ( varlength && headcnt == 0 )
				/* both head and trail are variable-length */
				variable_trail_rule = true;
			    else
				trailcnt = rulelen;
			    }
		        }
		;

re              :  re '|' series
                        {
			varlength = true;

			$$ = mkor( $1, $3 );
			}

		|  re2 series
			{
			if ( transchar[lastst[$2]] != SYM_EPSILON )
			    /* provide final transition \now/ so it
			     * will be marked as a trailing context
			     * state
			     */
			    $2 = link_machines( $2, mkstate( SYM_EPSILON ) );

			mark_beginning_as_normal( $2 );
			current_state_type = STATE_NORMAL;

			if ( previous_continued_action )
			    {
			    /* we need to treat this as variable trailing
			     * context so that the backup does not happen
			     * in the action but before the action switch
			     * statement.  If the backup happens in the
			     * action, then the rules "falling into" this
			     * one's action will *also* do the backup,
			     * erroneously.
			     */
			    if ( ! varlength || headcnt != 0 )
				{
				fprintf( stderr,
    "flex: warning - trailing context rule at line %d made variable because\n",
					 linenum );
				fprintf( stderr,
					 "      of preceding '|' action\n" );
				}

			    /* mark as variable */
			    varlength = true;
			    headcnt = 0;
			    }

			if ( varlength && headcnt == 0 )
			    { /* variable trailing context rule */
			    /* mark the first part of the rule as the accepting
			     * "head" part of a trailing context rule
			     */
			    /* by the way, we didn't do this at the beginning
			     * of this production because back then
			     * current_state_type was set up for a trail
			     * rule, and add_accept() can create a new
			     * state ...
			     */
			    add_accept( $1, num_rules | YY_TRAILING_HEAD_MASK );
			    }

			$$ = link_machines( $1, $2 );
			}

		|  series
			{ $$ = $1; }
		;


re2		:  re '/'
			{
			/* this rule is separate from the others for "re" so
			 * that the reduction will occur before the trailing
			 * series is parsed
			 */

			if ( trlcontxt )
			    synerr( "trailing context used twice" );
			else
			    trlcontxt = true;

			if ( varlength )
			    /* we hope the trailing context is fixed-length */
			    varlength = false;
			else
			    headcnt = rulelen;

			rulelen = 0;

			current_state_type = STATE_TRAILING_CONTEXT;
			$$ = $1;
			}
		;

series          :  series singleton
                        {
			/* this is where concatenation of adjacent patterns
			 * gets done
			 */
			$$ = link_machines( $1, $2 );
			}

		|  singleton
			{ $$ = $1; }
		;

singleton       :  singleton '*'
                        {
			varlength = true;

			$$ = mkclos( $1 );
			}
			
		|  singleton '+'
			{
			varlength = true;

			$$ = mkposcl( $1 );
			}

		|  singleton '?'
			{
			varlength = true;

			$$ = mkopt( $1 );
			}

		|  singleton '{' NUMBER ',' NUMBER '}'
			{
			varlength = true;

			if ( $3 > $5 || $3 < 0 )
			    {
			    synerr( "bad iteration values" );
			    $$ = $1;
			    }
			else
			    {
			    if ( $3 == 0 )
				$$ = mkopt( mkrep( $1, $3, $5 ) );
			    else
				$$ = mkrep( $1, $3, $5 );
			    }
			}
				
		|  singleton '{' NUMBER ',' '}'
			{
			varlength = true;

			if ( $3 <= 0 )
			    {
			    synerr( "iteration value must be positive" );
			    $$ = $1;
			    }

			else
			    $$ = mkrep( $1, $3, INFINITY );
			}

		|  singleton '{' NUMBER '}'
			{
			/* the singleton could be something like "(foo)",
			 * in which case we have no idea what its length
			 * is, so we punt here.
			 */
			varlength = true;

			if ( $3 <= 0 )
			    {
			    synerr( "iteration value must be positive" );
			    $$ = $1;
			    }

			else
			    $$ = link_machines( $1, copysingl( $1, $3 - 1 ) );
			}

		|  '.'
			{
			if ( ! madeany )
			    {
			    /* create the '.' character class */
			    anyccl = cclinit();
			    ccladd( anyccl, '\n' );
			    cclnegate( anyccl );

			    if ( useecs )
				mkeccl( ccltbl + cclmap[anyccl],
					ccllen[anyccl], nextecm,
					ecgroup, CSIZE );
			    
			    madeany = true;
			    }

			++rulelen;

			$$ = mkstate( -anyccl );
			}

		|  fullccl
			{
			if ( ! cclsorted )
			    /* sort characters for fast searching.  We use a
			     * shell sort since this list could be large.
			     */
			    cshell( ccltbl + cclmap[$1], ccllen[$1] );

			if ( useecs )
			    mkeccl( ccltbl + cclmap[$1], ccllen[$1],
				    nextecm, ecgroup, CSIZE );
				     
			++rulelen;

			$$ = mkstate( -$1 );
			}

		|  PREVCCL
			{
			++rulelen;

			$$ = mkstate( -$1 );
			}

		|  '"' string '"'
			{ $$ = $2; }

		|  '(' re ')'
			{ $$ = $2; }

		|  CHAR
			{
			++rulelen;

			if ( $1 == '\0' )
			    synerr( "null in rule" );

			if ( caseins && $1 >= 'A' && $1 <= 'Z' )
			    $1 = clower( $1 );

			$$ = mkstate( $1 );
			}
		;

fullccl		:  '[' ccl ']'
			{ $$ = $2; }

		|  '[' '^' ccl ']'
			{
			/* *Sigh* - to be compatible Unix lex, negated ccls
			 * match newlines
			 */
#ifdef NOTDEF
			ccladd( $3, '\n' ); /* negated ccls don't match '\n' */
			cclsorted = false; /* because we added the newline */
#endif
			cclnegate( $3 );
			$$ = $3;
			}
		;

ccl             :  ccl CHAR '-' CHAR
                        {
			if ( $2 > $4 )
			    synerr( "negative range in character class" );

			else
			    {
			    if ( caseins )
				{
				if ( $2 >= 'A' && $2 <= 'Z' )
				    $2 = clower( $2 );
				if ( $4 >= 'A' && $4 <= 'Z' )
				    $4 = clower( $4 );
				}

			    for ( i = $2; i <= $4; ++i )
			        ccladd( $1, i );

			    /* keep track if this ccl is staying in alphabetical
			     * order
			     */
			    cclsorted = cclsorted && ($2 > lastchar);
			    lastchar = $4;
			    }
			
			$$ = $1;
			}

		|  ccl CHAR
		        {
			if ( caseins )
			    if ( $2 >= 'A' && $2 <= 'Z' )
				$2 = clower( $2 );

			ccladd( $1, $2 );
			cclsorted = cclsorted && ($2 > lastchar);
			lastchar = $2;
			$$ = $1;
			}

		|
			{
			cclsorted = true;
			lastchar = 0;
			$$ = cclinit();
			}
		;

string		:  string CHAR
                        {
			if ( caseins )
			    if ( $2 >= 'A' && $2 <= 'Z' )
				$2 = clower( $2 );

			++rulelen;

			$$ = link_machines( $1, mkstate( $2 ) );
			}

		|
			{ $$ = mkstate( SYM_EPSILON ); }
		;

%%


/* build_eof_action - build the "<<EOF>>" action for the active start
 *                    conditions
 */

build_eof_action()

    {
    register int i;

    for ( i = 1; i <= actvp; ++i )
	{
	if ( sceof[actvsc[i]] )
	    lerrsf( "multiple <<EOF>> rules for start condition %s",
		    scname[actvsc[i]] );

	else
	    {
	    sceof[actvsc[i]] = true;
	    fprintf( temp_action_file, "case YY_STATE_EOF(%s):\n",
		     scname[actvsc[i]] );
	    }
	}

    line_directive_out( temp_action_file );
    }


/* synerr - report a syntax error
 *
 * synopsis
 *    char str[];
 *    synerr( str );
 */

synerr( str )
char str[];

    {
    syntaxerror = true;
    fprintf( stderr, "Syntax error at line %d: %s\n", linenum, str );
    }


/* yyerror - eat up an error message from the parser
 *
 * synopsis
 *    char msg[];
 *    yyerror( msg );
 */

yyerror( msg )
char msg[];

    {
    }
\EOF\
else
  echo "will not over write ./parse.y"
fi
if `test ! -s ./system.h`
then
echo "writing ./system.h"
cat > ./system.h << '\EOF\'
/*                             *********************
 *                             *  S Y S T E M . H  *
 *                             *********************
 *
 * This file replaces the original "files." header file. It defines, for
 * the IBM PC/XT version, the target parser function source file, overriding
 * file name string defines, and other system-specific definitions and
 * parameters. 
 *
 * Bob Denny    06-Dec-80
 *
 * Edits:
 *              18-Dec-80  ZAPFILE no longer used in Decus Yacc.
 *                         Parser file renamed yypars.c
 *
 *              28-Aug-81  Temp files for RSX have specific version
 *                         numbers of 1 to avoid multi-versions. Rename
 *                         parser info file ".i".
 *
 *              12-Apr-83  Add FNAMESIZE & EX_xxx parameters.
 *
 *Scott Guthery 23-Dec-83  Adapt for the IBM PC/XT & DeSmet C compiler.
 *
 */

/* Define WORD32 if target machine is a 32 bitter */
# undef WORD32

/*
 * Target parser source file
 */
#define PARSER "/usr/lib/yypars"

/*
 * basic size of the Yacc implementation
 */
#define MEDIUM	YES

/*
 * Table size for this Yacc
 */
# define MEDTAB YES

/*
 * Filespec definitions
 */
# define ACTNAME "yacc2.tmp"
# define TEMPNAME "yacc1.tmp"
# define FNAMESIZE 24

/*
 * Exit status values
 */
#define EX_SUC 1
#define EX_WAR 0
#define EX_ERR 2
#define EX_SEV 4
\EOF\
else
  echo "will not over write ./system.h"
fi
if `test ! -s ./y1.h`
then
echo "writing ./y1.h"
cat > ./y1.h << '\EOF\'
/*****************************************************************************/
/*                           *************                                   */
/*                           *  Y 1 . H  *                                   */
/*                           *************                                   */
/*                                                                           */
/* This file contains the external declarations needed to hook Yacc modules  */
/* which were originally in Y1.C to their impure data in Y1IMP.1C. Also does */
/* the include of the original data/external file DTXTRN.H.                  */
/*                                                                           */
/*****************************************************************************/

#include "dtxtrn.h"

/* lookahead computations */

extern int	tbitset;  /* size of lookahead sets */
extern int	nlset; /* next lookahead set index */
extern struct looksets clset;  /* temporary storage for lookahead computations */

/* other storage areas */

extern int	fatfl;               /* if on, error is fatal */
extern int	nerrors;             /* number of errors */

/* storage for information about the nonterminals */

extern int	**pres[ ];           /* vector of pointers to productions yielding each nonterminal */
extern struct looksets *pfirst[ ]; /* vector of pointers to first sets for each nonterminal */
extern int	pempty[ ];           /* vector of nonterminals nontrivially deriving e */

/* accumulators for statistics information */

extern struct wset *zzcwp;
extern int	*zzmemsz;
\EOF\
else
  echo "will not over write ./y1.h"
fi
if `test ! -s ./y1imp.c`
then
echo "writing ./y1imp.c"
cat > ./y1imp.c << '\EOF\'
/*
 * y1imp.c - impure data used by modules originally in y1.c.
 *
 * HISTORY
 */

#define y1imp yes

#include "dtxtrn.h"


/* lookahead computations */

int	tbitset;		/* size of lookahead sets */
struct looksets lkst[LSETSIZE];
int	nlset = 0;		/* next lookahead set index */
int	nolook = 0;		/* flag to suppress lookahead computations */
struct looksets clset;		/* temporary storage for lookahead */


/* working set computations */

struct wset wsets[WSETSIZE];
struct wset *cwp;


/* state information */

int	nstate = 0;		/* number of states */
struct item *pstate[NSTATES+2]; /* pointers to descriptions of states */
int	tystate[NSTATES];	/* contains type information about states */
int	indgo[NSTATES];         /* index to the stored goto table */
int	tstates[NTERMS];	/* states generated by terminal gotos */
int	ntstates[NNONTERM];	/* states generated by nonterminal gotos */
int	mstates[NSTATES];	/* overflow of term/nonterm generation lists */


/* storage for the actions in the parser */

int	amem[ACTSIZE];		/* action table storage */
int	*memp = amem;		/* next free action table position */


/* other storage areas */

int	temp1[TEMPSIZE];	/* temporary storage, indexed by terms + ntokens or states */
int	lineno = 1;		/* current input line number */
int	fatfl = 1;		/* if on, error is fatal */
int	nerrors = 0;		/* number of errors */


/* storage for information about the nonterminals */

int	**pres[NNONTERM+2];  /* vector of pointers to productions yielding each nonterminal */
struct looksets *pfirst[NNONTERM+2];  /* vector of pointers to first sets for each nonterminal */
int	pempty[NNONTERM+1];  /* vector of nonterminals nontrivially deriving e */

/* accumulators for statistics information */

struct wset *zzcwp = wsets;
int	zzgoent = 0;
int	zzgobest = 0;
int	zzacent = 0;
int	zzexcp = 0;
int	zzclose = 0;
int	zzsrconf = 0;
int	*zzmemsz = mem0;
int	zzrrconf = 0;

/* data pulled from internal static to here */
/* declared external only in user module    */

int	*pyield[NPROD];             /* from ycpres */
char	sarr[ISIZE];               /* from ywritm */
\EOF\
else
  echo "will not over write ./y1imp.c"
fi
if `test ! -s ./y2.h`
then
echo "writing ./y2.h"
cat > ./y2.h << '\EOF\'
/*****************************************************************************/
/*                             *************                                 */
/*                             *  Y 2 . H  *                                 */
/*                             *************                                 */
/*                                                                           */
/* This file contains the external declarations needed to hook Yacc modules  */
/* which were originally in Y2.C to their impure data in Y2IMP.2C. Also does */
/* the include of the original data/external file DTXTRN.H.                  */
/*                                                                           */
/*****************************************************************************/

# include "dtxtrn.h"

# define IDENTIFIER 257
# define MARK 258
# define TERM 259
# define LEFT 260
# define RIGHT 261
# define BINARY 262
# define PREC 263
# define LCURLY 264
# define C_IDENTIFIER 265  /* name followed by colon */
# define NUMBER 266
# define START 267
# define TYPEDEF 268
# define TYPENAME 269
# define UNION 270
# define ENDFILE 0

/* communication variables between various I/O routines */

extern char	*infile;            /* input file name */
extern int	numbval;             /* value of an input number */
extern char	tokname[ ];         /* input token name */

/* storage of names */

extern char	cnames[ ];          /* place where token and nonterminal names are stored */
extern int	cnamsz;              /* size of cnames */
extern char	*cnamp;            /* place where next name is to be put in */
extern int	ndefout;             /* number of defined symbols output */

/* storage of types */
extern int	ntypes;              /* number of types defined */
extern char	*typeset[ ];       /* pointers to type tags */

/* symbol tables for tokens and nonterminals */

extern int	start;               /* start symbol */

/* assigned token type values */
extern int	extval;
\EOF\
else
  echo "will not over write ./y2.h"
fi
if `test ! -s ./y2imp.c`
then
echo "writing ./y2imp.c"
cat > ./y2imp.c << '\EOF\'
/*
 * y2imp.c - impure date needed by routines pulled from y2.c
 *
 * HISTORY
 */

#define y2imp YES
#include "dtxtrn.h"


/* communication variables between various I/O routines */

char	*infile;			/* input file name */
int	numbval;		/* value of an input number */
char	tokname[NAMESIZE];	/* input token name */


/* storage of names */

char	cnames[CNAMSZ];		/* token and nonterminal name storage */
int	cnamsz = CNAMSZ;	/* size of cnames */
char	*cnamp = cnames;	/* place where next name is to be put in */
int	ndefout = 3;		/* number of defined symbols output */


/* storage of types */

int	ntypes;			/* number of types defined */
char	*typeset[NTYPES];	/* pointers to type tags */


/* symbol tables for tokens and nonterminals */

int	ntokens = 0;
struct toksymb tokset[NTERMS];
int	toklev[NTERMS];
int	nnonter = -1;
struct ntsymb nontrst[NNONTERM];
int	start;			/* start symbol */


/* assigned token type values */

int	extval = 0;


/* input and output file descriptors */

FILE   *finput;			/* yacc input file */
FILE   *faction;		/* file for saving actions */
FILE   *fdefine;		/* file for # defines */
FILE   *ftable;			/* y.tab.c file */
FILE   *ftemp;			/* tempfile to pass 2 */
FILE   *foutput;		/* y.output file */


/* storage for grammar rules */

int	mem0[MEMSIZE];		/* production storage */
int	*mem = mem0;
int	nprod = 1;		/* number of productions */
int	*prdptr[NPROD];		/* pointers to descriptions of productions */
int	levprd[NPROD];		/* precedence levels for the productions */


/* Statics pulled from modules */

int	peekline;           /* from gettok() */
\EOF\
else
  echo "will not over write ./y2imp.c"
fi
if `test ! -s ./y3.h`
then
echo "writing ./y3.h"
cat > ./y3.h << '\EOF\'
/*****************************************************************************/
/*                             *************                                 */
/*                             *  Y 3 . H  *                                 */
/*                             *************                                 */
/*                                                                           */
/* This file contains the external declarations needed to hook Yacc modules  */
/* which were originally in Y3.C to their impure data in Y3IMP.3C. Also does */
/* the include of the original data/external file DTXTRN.H.                  */
/*                                                                           */
/*****************************************************************************/

#include "dtxtrn.h"

extern int	lastred;   /* the number of the last reduction of a state */
\EOF\
else
  echo "will not over write ./y3.h"
fi
if `test ! -s ./y3imp.c`
then
echo "writing ./y3imp.c"
cat > ./y3imp.c << '\EOF\'
/* 
 * y3imp.c - impure data from modules split from y3.c 
 *
 * HISTORY
 */

#define y3imp YES

#include "dtxtrn.h"

int	lastred;            /* the number of the last reduction of a state */

int	defact[NSTATES];    /* the default actions of states */
\EOF\
else
  echo "will not over write ./y3imp.c"
fi
if `test ! -s ./y4.h`
then
echo "writing ./y4.h"
cat > ./y4.h << '\EOF\'
/*****************************************************************************/
/*                             *************                                 */
/*                             *  Y 4 . H  *                                 */
/*                             *************                                 */
/*                                                                           */
/* This file contains the external declarations needed to hook Yacc modules  */
/* which were originally in Y4.C to their impure data in Y4IMP.4C. Also does */
/* the include of the original data/external file DTXTRN.H.                  */
/*                                                                           */
/*****************************************************************************/

# include "dtxtrn.h"

# define a amem
# define pa indgo
# define yypact temp1
# define greed tystate

# define NOMORE -1000

extern int	*ggreed;
extern int	*pgo;
extern int	*yypgo;

extern int	maxspr;              /* maximum spread of any entry */
extern int	maxoff;              /* maximum offset into a array */
extern int	*pmem;
extern int	*maxa;
extern int	nxdb;
extern int	adb;
\EOF\
else
  echo "will not over write ./y4.h"
fi
if `test ! -s ./y4imp.c`
then
echo "writing ./y4imp.c"
cat > ./y4imp.c << '\EOF\'
/* 
 * y4imp.c - impure data from y4.c modules
 *
 * HISTORY
 */

# include "dtxtrn.h"

# define a amem
# define pa indgo
# define yypact temp1
# define greed tystate

# define NOMORE -1000

int	*ggreed = lkst[0].lset;
int	*pgo = wsets[0].ws.lset;
int	*yypgo = &nontrst[0].tvalue;

int	maxspr = 0;		/* maximum spread of any entry */
int	maxoff = 0;		/* maximum offset into a array */
int	*pmem = mem0;
int	*maxa;
int	nxdb = 0;
int	adb = 0;
\EOF\
else
  echo "will not over write ./y4imp.c"
fi
if `test ! -s ./yaoput.c`
then
echo "writing ./yaoput.c"
cat > ./yaoput.c << '\EOF\'
/*
 * yaoput.c - write out the optimized parser
 *
 * HISTORY
 */

#include "y4.h"

int	aoutput()
{
	fprintf(ftable, "# define YYLAST %d\n", maxa - a + 1);
	arout("yyact", a, (maxa - a) + 1);
	arout("yypact", pa, nstate);
	arout("yypgo", pgo, nnonter + 1);
}
\EOF\
else
  echo "will not over write ./yaoput.c"
fi
if `test ! -s ./yapack.c`
then
echo "writing ./yapack.c"
cat > ./yapack.c << '\EOF\'
/*
 * yapack.c -
 *
 * HISTORY
 * {1}	28-Aug-81  Bob Denny
 * 	Modified to make debug code conditionally compile.
 */

#include "y3.h"


int	apack(p, n )
int	*p;
{
	/* pack state i from temp1 into amem */
	int	off;
	register *pp, *qq, *rr;
	int	*q, *r;

	/*
	 * we don't need to worry about checking because we we will only
	 * look entries known to be there... 
	 */

	/* eliminate leading and trailing 0's */

	q = p + n;
	for (pp = p, off = 0; *pp == 0 && pp <= q; ++pp, --off)	
		/* VOID */;
	if (pp > q)
		return (0);	/* no actions */
	p = pp;

	/* now, find a place for the elements from p to q, inclusive */

	r = &amem[ACTSIZE - 1];
	for (rr = amem; rr <= r; ++rr, ++off) {
		/* try rr */
		for (qq = rr, pp = p; pp <= q; ++pp, ++qq) {
			if (*pp != 0) {
				if (*pp != *qq && *qq != 0)
					goto nextk;
			}
		}

		/* we have found an acceptable k */

#ifdef debug
		if (foutput != NULL)
			fprintf(foutput, "off = %d, k = %d\n", off, rr - amem);
#endif
		for (qq = rr, pp = p; pp <= q; ++pp, ++qq) {
			if (*pp) {
				if (qq > r)
					error("action table overflow");
				if (qq > memp)
					memp = qq;
				*qq = *pp;
			}
		}
#ifdef debug
		if (foutput != NULL) {
			for (pp = amem; pp <= memp; pp += 10) {
				fprintf(foutput, "\t");
				for (qq = pp; qq <= pp + 9; ++qq)
					fprintf(foutput, "%d ", *qq);
				fprintf(foutput, "\n");
			}
		}
#endif
		return (off);
nextk:
		;
	}
	error("no space in action table");
	/* NOTREACHED */
}
\EOF\
else
  echo "will not over write ./yapack.c"
fi
echo "Finished archive 3 of 4"
# if you want to concatenate archives, remove anything after this line
exit 0

glenn@extro.ucc.su.oz (G. Geers [ext 3241]) (06/28/89)

--- cut here --- cut here --- cut here --- cut here --- cut here ---
#!/bin/sh
# This is a shell archive.  Remove anything before the /bin/sh line
# then unpack it by saving it in a file and typing "sh file"
# (Files unpacked will be owned by you and have default permissions).
# Don't worry about trailing garbage - the archive ends with exit
# This archive contains the following files:
#	./HEADER
#	./Makefile
#	./Makefile.msc
#	./README
#	./README.MINIX
#	./cytab.h
#
if `test ! -s ./HEADER`
then
echo "writing ./HEADER"
cat > ./HEADER << '\EOF\'
@From mark@ems.UUCP@munnari.oz Sun Feb  1 18:27:23 1987
Path: ipso!metro!otc!munnari!seismo!rutgers!dayton!ems!mark
@From: mark@ems.UUCP (Mark H. Colburn)
Newsgroups: net.sources
Subject: Public Domain YACC (part 1 of 2)
Keywords: UNIX MS-DOS IBM-PC YACC Finally
Message-ID: <135@ems.UUCP>
Date: 1 Feb 87 07:27:23 GMT
Sender: news@ems.UUCP
Reply-To: mark@ems.UUCP (Mark H. Colburn)
Distribution: world
Organization: EMS/McGraw-Hill, Eden Prairie
Lines: 2363


	Here is a copy of the Public Domain YACC that I promised earlier.
	For those of you who sent me mail, if you still need me to email
	you a copy, please let me know, otherwise I will assume that you
	have pulled it off of the net.

	This version runs on System V and MS-DOS.  I have not been able
	to get access to a BSD machine to test it there.

	Please send any bug reports, fixes, enhancements, comments or 
	suggestions to me so that they can be included in any later 
	releases or patches.

	Have fun.

	Mark H. Colburn          mark@ems.uucp      
	EMS/McGraw-Hill          {rutgers|amdahl|ihnp4}!meccts!ems!mark
	9855 West 78th Street     
	Eden Prairie, MN 55344   (612) 829-8200 x235

#
#     The following files will be created:
#		ysetup.c
#		dtxtrn.h
#		yypars.c
#		ygttok.c
#		ycpact.c
#		yclsur.c
#		yclopt.c
#		y1imp.c
#		y2.h
#		ystagn.c
#		ycemty.c
#		ystate.c
#		Makefile
#		y1.h
#		yywrap.c
#
Lines: 2555
#     The following files will be created:
#		youtpt.c
#		y2imp.c
#		ydefin.c
#		ywract.c
#		yapack.c
#		yothrs.c
#		ywstat.c
#		ystin.c
#		system.h
#		ysumry.c
#		README
#		yg2gen.c
#		y4.h
#		ycpfir.c
#		yg2out.c
#		ycpres.c
#		y3.h
#		ygin.c
#		ymain.c
#		yprcft.c
#		ycpuni.c
#		ydfout.c
#		ywritm.c
#		yflset.c
#		yhdprd.c
#		yptitm.c
#		ycpycd.c
#		ygtnm.c
#		yskpcm.c
#		yosmry.c
#		y4imp.c
#		ynxti.c
#		ychfnd.c
#		yyless.c
#		yarout.c
#		yerror.c
#		ywarry.c
#		yfdtyp.c
#		yprlok.c
#		ystuni.c
#		yaoput.c
#		y3imp.c
#		ycstsh.c
#		ysmnam.c
#		yaryfl.c
#		ychcpy.c
#		yfnact.c
#
\EOF\
else
  echo "will not over write ./HEADER"
fi
if `test ! -s ./Makefile`
then
echo "writing ./Makefile"
cat > ./Makefile << '\EOF\'
# Makefile for MINIX
#

BIN	 = /usr/bin
LIB	 = /usr/lib
CFLAGS   = -O
LDFLAGS  = -i
OBJECTS  = y1imp.s y2imp.s y3imp.s y4imp.s yaryfl.s ycemty.s ychcpy.s\
           yclsur.s ycpfir.s ycpres.s yerror.s yflset.s ymain.s yothrs.s\
           yprlok.s yptitm.s ysmnam.s ystagn.s ystate.s ystuni.s ysumry.s\
           ywritm.s ychfnd.s ycpact.s ycpuni.s ycpycd.s ycstsh.s ydefin.s\
           ydfout.s yfdtyp.s yfnact.s ygttok.s ysetup.s yskpcm.s yapack.s\
           yg2gen.s yg2out.s yhdprd.s youtpt.s yprcft.s ywarry.s ywract.s\
           ywstat.s yaoput.s yclopt.s ygin.s ygtnm.s ynxti.s yosmry.s\
           ystin.s yarout.s
PROGRAMS = yacc

all: ${PROGRAMS}

clean:
	rm -f ${PROGRAMS}
	rm -f ${OBJECTS}
	rm -f a.out core

yacc: ${OBJECTS}
	cc ${LDFLAGS} ${OBJECTS} -o yacc

test: parse.y yacc 
	./yacc -hi parse.y

install: yacc yypars
	cp yacc $(BIN)/yacc
	cp yypars $(LIB)/yypars

dtxtrn.h: 	/usr/include/stdio.h system.h 
y1.h: 		dtxtrn.h 
y1imp.s: 	dtxtrn.h 
y2.h: 		dtxtrn.h 
y2imp.s: 	dtxtrn.h 
y3.h: 		dtxtrn.h 
y3imp.s: 	dtxtrn.h 
y4.h: 		dtxtrn.h 
y4imp.s: 	dtxtrn.h 
yaoput.s: 	y4.h 
yapack.s: 	y3.h 
yarout.s: 	y4.h 
yaryfl.s: 	y1.h 
ycemty.s: 	y1.h 
ychcpy.s: 	y1.h 
ychfnd.s: 	y2.h 
yclopt.s: 	y4.h 
yclsur.s: 	y1.h 
ycpact.s: 	/usr/include/stdio.h /usr/include/ctype.h y2.h 
ycpfir.s: 	y1.h 
ycpres.s: 	y1.h 
ycpuni.s: 	y2.h 
ycpycd.s: 	y2.h 
ycstsh.s: 	y2.h 
ydefin.s: 	y2.h 
ydfout.s: 	/usr/include/ctype.h y2.h 
yerror.s: 	y1.h 
yfdtyp.s: 	y2.h 
yflset.s: 	y1.h 
yfnact.s: 	y2.h 
yg2gen.s: 	y3.h 
yg2out.s: 	y3.h 
ygin.s: 	y4.h 
ygtnm.s: 	/usr/include/ctype.h 	 y4.h 
ygttok.s: 	/usr/include/ctype.h 	 y2.h 
yhdprd.s: 	y3.h 
ymain.s: 	y1.h 
ynxti.s: 	y4.h 
yosmry.s: 	y4.h 
yothrs.s: 	y1.h 
youtpt.s: 	y3.h 
yprcft.s: 	y3.h 
yprlok.s: 	y1.h 
yptitm.s: 	y1.h 
ysetup.s: 	y2.h 
yskpcm.s: 	y2.h 
ysmnam.s: 	y1.h 
ystagn.s: 	y1.h 
ystate.s: 	y1.h 
ystin.s: 	y4.h 
ystuni.s: 	y1.h 
ysumry.s: 	y1.h 
ywarry.s: 	y3.h 
ywract.s: 	y3.h 
ywritm.s: 	y1.h 
ywstat.s: 	y3.h 
\EOF\
else
  echo "will not over write ./Makefile"
fi
if `test ! -s ./Makefile.msc`
then
echo "writing ./Makefile.msc"
cat > ./Makefile.msc << '\EOF\'
CFLAGS   = -OX -FPi
LDFLAGS  = 
OBJECTS  = y1imp.o y2imp.o y3imp.o y4imp.o yaryfl.o ycemty.o ychcpy.o\
           yclsur.o ycpfir.o ycpres.o yerror.o yflset.o ymain.o yothrs.o\
           yprlok.o yptitm.o ysmnam.o ystagn.o ystate.o ystuni.o ysumry.o\
           ywritm.o ychfnd.o ycpact.o ycpuni.o ycpycd.o ycstsh.o ydefin.o\
           ydfout.o yfdtyp.o yfnact.o ygttok.o ysetup.o yskpcm.o yapack.o\
           yg2gen.o yg2out.o yhdprd.o youtpt.o yprcft.o ywarry.o ywract.o\
           ywstat.o yaoput.o yclopt.o ygin.o ygtnm.o ynxti.o yosmry.o\
           ystin.o yarout.o
PROGRAMS = yacc


yacc: 
	cl $LDFLAGS $OBJECTS -o yacc


dtxtrn.h: 	stdio.h system.h 
y1.h: 		dtxtrn.h 
y1imp.o: 	dtxtrn.h 
y2.h: 		dtxtrn.h 
y2imp.o: 	dtxtrn.h 
y3.h: 		dtxtrn.h 
y3imp.o: 	dtxtrn.h 
y4.h: 		dtxtrn.h 
y4imp.o: 	dtxtrn.h 
yaoput.o: 	y4.h 
yapack.o: 	y3.h 
yarout.o: 	y4.h 
yaryfl.o: 	y1.h 
ycemty.o: 	y1.h 
ychcpy.o: 	y1.h 
ychfnd.o: 	y2.h 
yclopt.o: 	y4.h 
yclsur.o: 	y1.h 
ycpact.o: 	stdio.h ctype.h y2.h 
ycpfir.o: 	y1.h 
ycpres.o: 	y1.h 
ycpuni.o: 	y2.h 
ycpycd.o: 	y2.h 
ycstsh.o: 	y2.h 
ydefin.o: 	y2.h 
ydfout.o: 	ctype.h y2.h 
yerror.o: 	y1.h 
yfdtyp.o: 	y2.h 
yflset.o: 	y1.h 
yfnact.o: 	y2.h 
yg2gen.o: 	y3.h 
yg2out.o: 	y3.h 
ygin.o: 	y4.h 
ygtnm.o: 	ctype.h 	 y4.h 
ygttok.o: 	ctype.h 	 y2.h 
yhdprd.o: 	y3.h 
ymain.o: 	y1.h 
ynxti.o: 	y4.h 
yosmry.o: 	y4.h 
yothrs.o: 	y1.h 
youtpt.o: 	y3.h 
yprcft.o: 	y3.h 
yprlok.o: 	y1.h 
yptitm.o: 	y1.h 
ysetup.o: 	y2.h 
yskpcm.o: 	y2.h 
ysmnam.o: 	y1.h 
ystagn.o: 	y1.h 
ystate.o: 	y1.h 
ystin.o: 	y4.h 
ystuni.o: 	y1.h 
ysumry.o: 	y1.h 
ywarry.o: 	y3.h 
ywract.o: 	y3.h 
ywritm.o: 	y1.h 
ywstat.o: 	y3.h 
\EOF\
else
  echo "will not over write ./Makefile.msc"
fi
if `test ! -s ./README`
then
echo "writing ./README"
cat > ./README << '\EOF\'

                                UNIX/MS-DOS YACC

	Here is a copy of a public domain version of YACC.  This version
	is a derivative of the DECUS yacc (at lease some where along the
	it come from there anyways).  When I got it it had been modified
	to run under MS-DOS on IBM-PC's.  I have modified it to, (once
	again) run under UNIX, as well as PC-DOS.

	It runs fine under System V.2 on an Arete 1200, as well as PC-DOS
	3.1.  I do not have access to a Berkley machine, so I have not
	been able to test it in that environment.

	I will post updates and patches to this version of YACC as I work 
	with it more, and as I get comments from other people who use it.
	If you have any enhancements, portability problems or comments,
	please let me know and I will put them in.

	For those of you who have been wanting YACC on a PC, here it is.

	In order to install the package, look at the #defines in system.h
	and dtxtrn.h and modify them to match you machine configuration
	and needs/desires.  Then type make.


	Mark H. Colburn          mark@ems.uucp      
	EMS/McGraw-Hill          {rutgers|amdahl|ihnp4}!meccts!ems!mark
	9855 West 78th Street     
	Eden Prairie, MN 55344   (612) 829-8200 x235
\EOF\
else
  echo "will not over write ./README"
fi
if `test ! -s ./README.MINIX`
then
echo "writing ./README.MINIX"
cat > ./README.MINIX << '\EOF\'
The following program is a public domain implementation of yacc. There were
no modifications required to any of the files (except the Makefile, of 
course). In the current state a MEDIUM sized version of yacc is made. This
is the largest version possible under PC-MINIX.

ST-MINIX users should edit the file system.h and #define HUGE, HUGETAB and 
probably WORD32 if they are using gcc. This will give a gigantic version of 
yacc capable of handling grammars of almost any size.

The program will also compile on almost all versions of UNIX (I've tried
Xenix/286, Ultrix, SysV.3 and UMIPS) and under DOS.

Please read the files HEADER and README for the original info.

The file parse.y used for testing yacc is taken from the flex distribution.

I also noticed a nice irony here: the author works for Mc.Graw-Hill !

			Share and Enjoy,
					Glenn 

Glenn Geers
Department of Theoretical Physics,
University of Sydney,
Sydney, N.S.W., 2006               phone: +61 2 692-3241

email: glenn@extro.ucc.su.oz
\EOF\
else
  echo "will not over write ./README.MINIX"
fi
if `test ! -s ./cytab.h`
then
echo "writing ./cytab.h"
cat > ./cytab.h << '\EOF\'
# define IDENTIFIER 257
# define CONSTANT 258
# define STRING_LITERAL 259
# define SIZEOF 260
# define PTR_OP 261
# define INC_OP 262
# define DEC_OP 263
# define LEFT_OP 264
# define RIGHT_OP 265
# define LE_OP 266
# define GE_OP 267
# define EQ_OP 268
# define NE_OP 269
# define AND_OP 270
# define OR_OP 271
# define MUL_ASSIGN 272
# define DIV_ASSIGN 273
# define MOD_ASSIGN 274
# define ADD_ASSIGN 275
# define SUB_ASSIGN 276
# define LEFT_ASSIGN 277
# define RIGHT_ASSIGN 278
# define AND_ASSIGN 279
# define XOR_ASSIGN 280
# define OR_ASSIGN 281
# define TYPE_NAME 282
# define TYPEDEF 283
# define EXTERN 284
# define STATIC 285
# define AUTO 286
# define REGISTER 287
# define CHAR 288
# define SHORT 289
# define INT 290
# define LONG 291
# define SIGNED 292
# define UNSIGNED 293
# define FLOAT 294
# define DOUBLE 295
# define CONST 296
# define VOLATILE 297
# define VOID 298
# define STRUCT 299
# define UNION 300
# define ENUM 301
# define ELIPSIS 302
# define RANGE 303
# define CASE 304
# define DEFAULT 305
# define IF 306
# define ELSE 307
# define SWITCH 308
# define WHILE 309
# define DO 310
# define FOR 311
# define GOTO 312
# define CONTINUE 313
# define BREAK 314
# define RETURN 315
\EOF\
else
  echo "will not over write ./cytab.h"
fi
echo "Finished archive 4 of 4"
# if you want to concatenate archives, remove anything after this line
exit 0

jds@mimsy.UUCP (James da Silva) (06/29/89)

In article <487@extro.ucc.su.oz> glenn@extro.ucc.su.oz (G. Geers [ext 3241])
writes:
>The next four articles contain a public domain version of yacc.

Bad News, Glenn.  This is NOT a public domain yacc; this is THE yacc, as in
AT&T's yacc.  I strongly urge you to cancel your articles and everyone to
delete their copies.

Real Yacc got onto a DECUS tape by mistake, and has long since been
withdrawn.  Still, since then it has made the rounds and pops up on the net
and on BBSes now and again.

There is no `Public Domain Yacc' that I know of.  Bison is a freely distri-
butable Yacc clone, but it is never refered to as `PD-Yacc'.  If you see
such a thing on a BBS or somewhere, you can be 99.9% sure that it is a
decendant of this rogue DECUS Yacc.

Pass the word...

Jaime
...........................................................................
: domain: jds@mimsy.umd.edu				     James da Silva
: path:   uunet!mimsy!jds

maart@cs.vu.nl (Maarten Litmaath) (06/29/89)

glenn@extro.ucc.su.oz (G. Geers [ext 3241]) writes:
\...
\if `test ! -s ./yprcft.c`
    ^                    ^
I would leave those backquotes out...
-- 
"I HATE arbitrary limits, especially when |Maarten Litmaath @ VU Amsterdam:
   they're small."  (Stephen Savitzky)    |maart@cs.vu.nl, mcvax!botter!maart

john@minster.york.ac.uk (03/21/90)

Please would some kind Minix (PC?) user who has a
working copy of David Clunie's yacc please post the
sources to the net? (presumably having received David's
permission first).

I've tried porting both GNU yacc (bison) and Berkeley
yacc (byacc) to my IBM-PC/XT (now, ST and 386 users, don't
smirk :-) ) but, of course, they won't translate anything
other than the most simple Yacc grammars, even compiled
separate I+D. Berkeley yacc seems particularly heap-space
hungry. The `DECUS' yacc and its derivatives posted to
this newsgroup are apparently modified versions of a
pirate copy of the original AT&T yacc, and so should not
be used or supported by Minix owners.

The archived sources of Clunie-yacc I retrieved from the
archive server at Imperial College, London, seem to require
some work doing to them before they will run under Minix.
Since I imagine many Minix PC users would like a small
(even slow) yacc, someone who has already done the work
and who is willing to post it would surely be much
appreciated. A full source posting is required for those
who don't have Mr. Clunie's original.

--------------------------------------------------------
John A. Murdie			+44 904 432752
Dept. of Comp. Sci.		ukc!minster!john
University of York
England

ghelmer@dsuvax.uucp (Guy Helmer) (03/21/90)

In article <637950680.761@minster.york.ac.uk>, john@minster.york.ac.uk writes:
> Please would some kind Minix (PC?) user who has a
> working copy of David Clunie's yacc please post the
> sources to the net? (presumably having received David's
> permission first).

I ported David's yacc to Minix about six months ago.  I hope I still
have it somewhere on my Minix partition, and if I do, I could mail
it out or post it if there's interest.  Please respond by mail to
my offer.

> John A. Murdie			+44 904 432752
> Dept. of Comp. Sci.		ukc!minster!john

-- 
Guy Helmer         ...!cs.texas.edu!bigtex!uudell!loft386!dsuvax!ghelmer
DSU Computing Services         ghelmer@dsuvax.uucp,  helmer@sdnet.bitnet
"... the quickest way to kill any business is to let the government take
it over." - Alan Abelson