[comp.sources.misc] v19i092: wacco - A C++ LL parser generator, Part05/06

parag@hpsdeb.sde.hp.com (Parag Patel) (05/19/91)

Submitted-by: Parag Patel <parag@hpsdeb.sde.hp.com>
Posting-number: Volume 19, Issue 92
Archive-name: wacco/part05

---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is part 05 of wacco
# ============= parse.C ==============
if test -f 'parse.C' -a X"$1" != X"-c"; then
	echo 'x - skipping parse.C (File already exists)'
else
echo 'x - extracting parse.C (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parse.C' &&
#line 1 "wacco.w"
// Copyright (c) 1991 by Parag Patel.  All Rights Reserved.
static const char rcs_id[] = "$Header: parse.C,v 1.9 91/02/22 16:06:58 hmgr Exp $";
X
#define YYTEXT_DECL unsigned char yytext[]
X
#line 1
X
#undef YYTEXT_DECL
#define YYTEXT_DECL char yytext[]
X
#include "defs.h"
X
struct nodedat
{
X	symbol *sym;
X	union
X	{
X		symnode *node;
X		char *alias;
X	};
X	nodedat *prev;
X	nodedat() { sym = NULL; node = NULL; prev = NULL; }
};
X
;
X
#include "toks.h"
X
extern YYTEXT_DECL;
int w_numerrors = 0;
X
X
struct resynclink
{
X	resynclink *prev;
X	int *resync;
X	resynclink() { prev = 0; resync = 0; }
X	resynclink(resynclink &p, int *s) { prev = &p; resync = s; }
};
static _fprogram(resynclink &, int *);
static _fstatlist(resynclink &, int *);
static _fidtype(resynclink &, int *, char* &);
static _fconcatlist(resynclink &, int *, nodedat &);
static _forlist(resynclink &, int *, nodedat &);
static _fexprlist(resynclink &, int *, nodedat &);
static _fresyncset(resynclink &, int *, resynclist* &);
static _fresynclist(resynclink &, int *, resynclist* &);
static _fsettype(resynclink &, int *, int &);
static _fcount(resynclink &, int *, int &);
static _falias(resynclink &, int *, char* &);
static _fcode(resynclink &, int *, symbol* &);
X
static char *_toknams[] =
{
X	"[]",
X	"DIRECTIVE",
X	"ID",
X	"EXPORT",
X	"NULLSYM",
X	"STRING",
X	"CHARACTER",
X	"INT",
X	"BLOCKCODE",
};
X
char *w_tokenname(int tok)
{
X	static char buf[6];
X
X	if (tok > 255)
X		return _toknams[tok - 256];
X	if (tok == 0)
X		return "EOI";
X	buf[0] = '`'; buf[1] = tok; buf[2] = '\'';
X	return buf;
}
X
static int tok = -1;
X
int w_nexttoken()
{
X	if (tok < 0)
X		tok = w_gettoken();
X	return tok;
}
X
void w_skiptoken()
{
X	tok = -1;
}
X
static int scantoken(int expect, resynclink &lnk, int *resync)
{
X	resynclink rlink(lnk, resync);
X	resynclink *link;
X
X	if (tok < 0)
X		tok = w_gettoken();
X	if (expect >= 0 && tok != expect)
X		w_scanerr("expected %s", w_tokenname(expect));
X	int level = 1;
X	while (tok != expect)
X	{
X		int l = level;
X		for (link = &rlink; link != NULL && l-- > 0; link = link->prev)
X			for (int i = 0; link->resync[i] >= 0; i++)
X				if (tok == link->resync[i])
X					return -1;
X
X		w_scanerr(NULL);
X		tok = w_gettoken();
X		if (tok == expect)
X			break;
X		level++;
X	}	
X	tok = -1;
X	return expect;
}
X
int program()
{
X	resynclink _link;
X	static _follow[] = { EOI, -1 };
X	int rval;
X	int savnum = w_numerrors;
X
X	w_numerrors = 0;
X	rval = _fprogram(_link, _follow);
X	switch (w_nexttoken())
X	{
X	case EOI:
X		break;
X	default:
X		rval = w_scanerr("expected end of program");
X	}
X	if (w_numerrors > 0) rval = RETERR;
X	w_numerrors += savnum;
X	w_scanerr(NULL);
X	return rval;
}
X
X
static _resync1[] = { _EMPTY, ID, '|', NULLSYM, STRING, CHARACTER, '#', '=', '(', ')', '{', BLOCKCODE, -1 };
static _resync2[] = { _EMPTY, INT, '*', '=', -1 };
static _resync3[] = { -1 };
static _resync4[] = { ']', -1 };
static _resync5[] = { _EMPTY, ID, '{', BLOCKCODE, -1 };
static _resync6[] = { _EMPTY, '|', -1 };
static _resync7[] = { _EMPTY, ID, '[', NULLSYM, STRING, CHARACTER, '#', '(', '{', BLOCKCODE, -1 };
static _resync8[] = { _EMPTY, '+', '-', -1 };
static _resync9[] = { _EMPTY, '=', ')', -1 };
static _resync10[] = { _EMPTY, ID, ':', NULLSYM, STRING, CHARACTER, '#', '(', '{', BLOCKCODE, -1 };
static _resync11[] = { ID, INT, -1 };
static _resync12[] = { STRING, -1 };
static _resync13[] = { _EMPTY, EXPORT, ':', '[', -1 };
static _resync14[] = { '{', -1 };
static _resync15[] = { _EMPTY, '|', '=', ')', -1 };
static _resync16[] = { _EMPTY, INT, '*', -1 };
static _resync17[] = { _EMPTY, ID, '+', '-', NULLSYM, STRING, CHARACTER, '#', -1 };
static _resync18[] = { _EMPTY, ',', -1 };
static _resync19[] = { _EMPTY, ID, '|', NULLSYM, STRING, CHARACTER, '#', '(', ')', '{', BLOCKCODE, -1 };
static _resync20[] = { _EMPTY, ID, ']', '+', '-', NULLSYM, STRING, CHARACTER, '#', -1 };
static _resync21[] = { _EMPTY, ID, '<', -1 };
static _resync22[] = { _EMPTY, ID, NULLSYM, STRING, CHARACTER, '#', '(', -1 };
static _resync23[] = { _EMPTY, ID, '=', -1 };
static _resync24[] = { CHARACTER, -1 };
static _resync25[] = { '+', -1 };
static _resync26[] = { DIRECTIVE, -1 };
static _resync27[] = { BLOCKCODE, -1 };
static _resync28[] = { _EMPTY, ID, ',', '+', '-', NULLSYM, STRING, CHARACTER, '#', -1 };
static _resync29[] = { ';', -1 };
static _resync30[] = { _EMPTY, EXPORT, '<', -1 };
static _resync31[] = { _EMPTY, ID, ':', '[', NULLSYM, STRING, CHARACTER, '#', '(', '{', BLOCKCODE, -1 };
static _resync32[] = { '*', -1 };
static _resync33[] = { ID, -1 };
static _resync34[] = { NULLSYM, -1 };
static _resync35[] = { _EMPTY, ID, -1 };
static _resync36[] = { _EMPTY, ID, '[', ']', '+', '-', NULLSYM, STRING, CHARACTER, '#', -1 };
static _resync37[] = { _EMPTY, ';', '|', -1 };
static _resync38[] = { EXPORT, -1 };
static _resync39[] = { '{', BLOCKCODE, -1 };
static _resync40[] = { _EMPTY, ':', '[', -1 };
static _resync41[] = { _EMPTY, ID, '<', NULLSYM, STRING, CHARACTER, '#', '(', '{', BLOCKCODE, -1 };
static _resync42[] = { _EMPTY, ID, '<', '|', NULLSYM, STRING, CHARACTER, '#', '(', '{', BLOCKCODE, -1 };
static _resync43[] = { _EMPTY, '#', INT, '*', '=', -1 };
static _resync44[] = { INT, -1 };
static _resync45[] = { '-', -1 };
static _resync46[] = { '<', -1 };
static _resync47[] = { _EMPTY, '=', -1 };
static _resync48[] = { _EMPTY, ID, NULLSYM, STRING, CHARACTER, '#', '(', '{', BLOCKCODE, -1 };
static _resync49[] = { _EMPTY, EXPORT, '[', -1 };
static _resync50[] = { _EMPTY, '#', INT, '*', -1 };
static _resync51[] = { _EMPTY, ID, '|', NULLSYM, STRING, CHARACTER, '#', '(', '{', BLOCKCODE, -1 };
static _resync52[] = { ID, INT, '=', -1 };
static _resync53[] = { _EMPTY, DIRECTIVE, '{', BLOCKCODE, -1 };
X
static _fprogram(resynclink &_lnk, int *_resync)
{
X	resynclink _link(_lnk, _resync);
X
X	symbol* _rvcode;
X	{
X
X	resynclink &_lnk = _link;
X	resynclink _link(_lnk, _resync53);
X
X	switch (w_nexttoken())
X	{
X	case DIRECTIVE:
X		{
X			(void)scantoken(DIRECTIVE, _link, _resync26);
#line 27
X			
X			int argc;
X			char **argv = strsep(yytext, " \t", TRUE, &argc);
X			getoptions(argc, argv);
X		;
X		}
X		break;
X		default:
X		break;
X	} }
#line 22
X	 _rvcode = NULL; ;
X	(void)_fcode(_link, _resync5, _rvcode);
#line 22
X	 startcode = _rvcode; ;
X	(void)_fstatlist(_link, _resync35);
X
X	return RETOK;
}
X
static _fstatlist(resynclink &_lnk, int *_resync)
{
X	resynclink _link(_lnk, _resync);
X
X	switch (w_nexttoken())
X	{
X	case ID:
X		{
X			symbol* _rvstatement;
X			symbol* _rvcode;
X			{
X			symbol* &_rr = _rvstatement;
X			resynclink &_lnk = _link;
X			resynclink _link(_lnk, _resync5);
X
X			char* _rvidtype;
X			boolean _rv_;
X			resynclist* _rvresyncset;
X			nodedat _rvconcatlist;
X			nodedat _rvorlist;
X			(void)scantoken(ID, _link, _resync21);
#line 42
X			
X			_rr = addsymbol(yytext);
X			if (_rr->type == TERMINAL)
X				(void)addnonterm(_rr);
X			if (startsymbol == NULL) 
X			{
X				startsymbol = _rr;
X				_rr->usecount += 2;
X			}
X		;
X			(void)_fidtype(_link, _resync30, _rvidtype);
#line 53
X			
X			if (_rr->rettype != NULL && _rvidtype != NULL &&
X					strcmp(_rr->rettype, _rvidtype) != 0)
X				w_scanerr("Two types defined for %s", _rr->name);
X
X			if (_rr->rettype == NULL)
X				_rr->rettype = _rvidtype;
X			else
X				delete _rvidtype;
X		;
X			{
X			boolean &_rr = _rv_;
X			resynclink &_lnk = _link;
X			resynclink _link(_lnk, _resync13);
X
X			switch (w_nexttoken())
X	{
X	case EXPORT:
X		{
X			(void)scantoken(EXPORT, _link, _resync38);
#line 63
X			 _rr = TRUE; ;
X		}
X		break;
X				default:
#line 63
X		 _rr = FALSE; ;
X		break;
X			} }
#line 64
X			
X			if (_rv_)
X			{
X				exportedname = _rr->export = TRUE;
X				_rr->usecount += 2;
X			}
X		;
X			(void)_fresyncset(_link, _resync31, _rvresyncset);
X			(void)scantoken(':', _link, _resync10);
#line 72
X			
X			_rr->list = _rvresyncset;
X			nodedat end;
X			end.sym = _rvconcatlist.sym = _rvorlist.sym = _rr;
X			_rvconcatlist.prev = _rvorlist.prev = &end;
X		;
X			(void)_fconcatlist(_link, _resync51, _rvconcatlist);
#line 79
X			
X			symnode *node = _rr->node;
X			if (node != NULL)
X			{
X				while (node->or != NULL)
X					node = node->or;
X				node->or = _rvconcatlist.node;
X			}
X			else
X				node = _rr->node = _rvconcatlist.node;
X		;
X			(void)_forlist(_link, _resync37, _rvorlist);
#line 91
X			
X			if (node == NULL)
X				_rr->node = _rvorlist.node;
X			else if (node->or == NULL)
X				node->or = _rvorlist.node;
X			else
X				node->or->or = _rvorlist.node;
X		;
X			(void)scantoken(';', _link, _resync29);
X
X			}
X
#line 36
X			 _rvcode = NULL; ;
X			(void)_fcode(_link, _resync5, _rvcode);
#line 36
X			 addnonterm(_rvcode); ;
X			(void)_fstatlist(_link, _resync35);
X		}
X		break;
X	default:
X		break;
X	}
X	return RETOK;
}
X
static _fidtype(resynclink &_lnk, int *_resync, char* &_rr)
{
X	resynclink _link(_lnk, _resync);
X
X	switch (w_nexttoken())
X	{
X	case '<':
X		{
X			(void)scantoken('<', _link, _resync46);
#line 103
X			 _rr = readtype(); ;
X		}
X		break;
X	default:
#line 104
X		 _rr = NULL; ;
X		break;
X	}
X	return RETOK;
}
X
static _fconcatlist(resynclink &_lnk, int *_resync, nodedat &_rr)
{
X	resynclink _link(_lnk, _resync);
X
X	switch (w_nexttoken())
X	{
X	case ID:
X	case NULLSYM:
X	case STRING:
X	case CHARACTER:
X	case '#':
X	case '(':
X	case '{':
X	case BLOCKCODE:
X		{
X			symbol* _rvcode;
X			nodedat _rvexprlist;
#line 108
X			
X			_rvcode = _rvexprlist.sym = _rr.sym;
X			_rvexprlist.prev = _rr.prev;
X		;
X			(void)_fcode(_link, _resync48, _rvcode);
X			(void)_fexprlist(_link, _resync22, _rvexprlist);
#line 113
X			
X			if (_rvcode == NULL)
X				_rr.node = _rvexprlist.node;
X			else
X			{
X				_rr.node = new symnode;
X				_rr.node->sym = _rvcode;
X				_rr.node->next = _rvexprlist.node;
X			}
X		;
X		}
X		break;
X	default:
X		break;
X	}
X	return RETOK;
}
X
static _forlist(resynclink &_lnk, int *_resync, nodedat &_rr)
{
X	resynclink _link(_lnk, _resync);
X
X	switch (w_nexttoken())
X	{
X	case '|':
X		{
X			nodedat _rvconcatlist;
X			nodedat _rvorlist;
#line 127
X			
X			_rvconcatlist.sym = _rvorlist.sym = _rr.sym;
X			_rvconcatlist.prev = _rvorlist.prev = _rr.prev;
X		;
X			(void)scantoken('|', _link, _resync51);
X			(void)_fconcatlist(_link, _resync51, _rvconcatlist);
X			(void)_forlist(_link, _resync6, _rvorlist);
#line 132
X			
X			_rr.node = _rvconcatlist.node;
X			if (_rr.node == NULL)
X				_rr.node = _rvorlist.node;
X			else
X				_rr.node->or = _rvorlist.node;
X		;
X		}
X		break;
X	default:
X		break;
X	}
X	return RETOK;
}
X
static _fexprlist(resynclink &_lnk, int *_resync, nodedat &_rr)
{
X	resynclink _link(_lnk, _resync);
X
X	switch (w_nexttoken())
X	{
X	case ID:
X	case NULLSYM:
X	case STRING:
X	case CHARACTER:
X	case '#':
X	case '(':
X		{
X			nodedat _rvexpression;
X			resynclist* _rvresyncset;
X			symbol* _rvcode;
X			nodedat _rvexprlist;
#line 144
X			
X			_rvexpression.sym = _rvcode = _rvexprlist.sym = _rr.sym;
X			_rvexpression.prev = _rvexprlist.prev = _rr.prev;
X		;
X			{
X			nodedat &_rr = _rvexpression;
X			resynclink &_lnk = _link;
X			resynclink _link(_lnk, _resync7);
X
X			switch (w_nexttoken())
X	{
X	case ID:
X		{
X			char* _rvalias;
X			(void)scantoken(ID, _link, _resync23);
#line 215
X			 _rr.sym = addsymbol(yytext);  _rr.sym->usecount++; ;
X			(void)_falias(_link, _resync47, _rvalias);
#line 216
X			 _rr.alias = _rvalias; ;
X		}
X		break;
X	case NULLSYM:
X		{
X			(void)scantoken(NULLSYM, _link, _resync34);
#line 217
X			 _rr.sym = getsymbol(EMPTY); ;
X		}
X		break;
X	case '#':
X		{
X			int _rvcount;
X			char* _rvalias;
X			(void)scantoken('#', _link, _resync43);
X			(void)_fcount(_link, _resync2, _rvcount);
X			(void)_falias(_link, _resync47, _rvalias);
#line 219
X			
X			nodedat *p = _rr.prev;
X			for (int i = 0; p != NULL && (_rvcount < 0 || i < _rvcount); i++)
X			{
X				_rr.sym = p->sym;
X				p = p->prev;
X			}
X			if (_rvcount > 0 && i < _rvcount)
X				w_scanerr("not that many parentheses");
X			_rr.sym->usecount++;
X			_rr.alias = _rvalias;
X		;
X		}
X		break;
X	case STRING:
X		{
X			(void)scantoken(STRING, _link, _resync12);
#line 232
X			
X			_rr.sym = addsymbol(yytext);
X			_rr.sym->lexstr = _rr.sym->name;
X			gotlexstr = TRUE;
X		;
X		}
X		break;
X	case CHARACTER:
X		{
X			(void)scantoken(CHARACTER, _link, _resync24);
#line 238
X			
X			_rr.sym = addsymbol(yytext);
X			if (_rr.sym->lexstr == NULL)
X			{
X				char *s = strdup(yytext);
X				s[0] = s[strlen(s) - 1] = '"';
X				_rr.sym->lexstr = s;
X			}
X		;
X		}
X		break;
X	case '(':
X		{
X			char* _rvidtype;
X			nodedat _rvconcatlist;
X			nodedat _rvorlist;
X			char* _rvalias;
X			(void)scantoken('(', _link, _resync41);
X			(void)_fidtype(_link, _resync42, _rvidtype);
#line 248
X			
X			char *type = _rr.sym->rettype;
X			char *name = _rr.sym->realname;
X			static int num = 1;
X
X			addnonterm(_rr.sym = addsymbol(strbldf("_P%d", num++)));
X			_rr.sym->type = NONTERMINAL;
X			_rr.sym->rettype = _rvidtype == NULL ? type : _rvidtype;
X			_rr.sym->realname = name;
X			_rr.sym->usecount++;
X
X			_rvconcatlist.sym = _rvorlist.sym = _rr.sym;
X			_rvconcatlist.prev = _rvorlist.prev = &_rr;
X		;
X			(void)_fconcatlist(_link, _resync1, _rvconcatlist);
X			(void)_forlist(_link, _resync15, _rvorlist);
X			(void)scantoken(')', _link, _resync9);
X			(void)_falias(_link, _resync47, _rvalias);
#line 263
X			
X			_rr.sym->node = _rvconcatlist.node;
X			if (_rr.sym->node == NULL)
X				_rr.sym->node = _rvorlist.node;
X			else
X				_rr.sym->node->or = _rvorlist.node;
X			_rr.alias = _rvalias;
X		;
X		}
X		break;
X				default:
X					w_scanerr("illegal expression");
X			} }
X			(void)_fresyncset(_link, _resync7, _rvresyncset);
X			(void)_fcode(_link, _resync48, _rvcode);
X			(void)_fexprlist(_link, _resync22, _rvexprlist);
#line 149
X			
X			_rr.node = new symnode;
X			_rr.node->sym = _rvexpression.sym;
X			_rr.node->alias = _rvexpression.alias;
X			_rr.node->next = _rvexprlist.node;
X			_rr.node->list = _rvresyncset;
X			if (_rvcode != NULL)
X			{
X				_rr.node->next = new symnode;
X				_rr.node->next->sym = _rvcode;
X				_rr.node->next->next = _rvexprlist.node;
X			}
X		;
X		}
X		break;
X	default:
X		break;
X	}
X	return RETOK;
}
X
static _fresyncset(resynclink &_lnk, int *_resync, resynclist* &_rr)
{
X	resynclink _link(_lnk, _resync);
X
X	switch (w_nexttoken())
X	{
X	case '[':
X		{
X			resynclist* _rvresynclist;
X			(void)scantoken('[', _link, _resync36);
X			(void)_fresynclist(_link, _resync20, _rvresynclist);
X			(void)scantoken(']', _link, _resync4);
#line 166
X			 _rr = _rvresynclist; ;
X		}
X		break;
X	default:
#line 167
X		 _rr = NULL; ;
X		break;
X	}
X	return RETOK;
}
X
static _fresynclist(resynclink &_lnk, int *_resync, resynclist* &_rr)
{
X	resynclink _link(_lnk, _resync);
X
X	resynclist* _rvresyncitem;
X	resynclist* _rv_;
X	{
X	resynclist* &_rr = _rvresyncitem;
X	resynclink &_lnk = _link;
X	resynclink _link(_lnk, _resync28);
X
X			int _rvfirst;
X			resynclist* _rvresyncid;
X			int _rvfollow;
X			(void)_fsettype(_link, _resync17, _rvfirst);
X			{
X			resynclist* &_rr = _rvresyncid;
X			resynclink &_lnk = _link;
X			resynclink _link(_lnk, _resync17);
X
X			switch (w_nexttoken())
X	{
X	case ID:
X		{
X			(void)scantoken(ID, _link, _resync33);
#line 194
X			 _rr = new resynclist(yytext); ;
X		}
X		break;
X	case NULLSYM:
X		{
X			(void)scantoken(NULLSYM, _link, _resync34);
#line 195
X			 _rr = new resynclist(NULL); ;
X		}
X		break;
X	case STRING:
X		{
X			(void)scantoken(STRING, _link, _resync12);
#line 196
X			 _rr = new resynclist(yytext); ;
X		}
X		break;
X	case CHARACTER:
X		{
X			(void)scantoken(CHARACTER, _link, _resync24);
#line 197
X			 _rr = new resynclist(yytext); ;
X		}
X		break;
X	case '#':
X		{
X			int _rvcount;
X			(void)scantoken('#', _link, _resync50);
X			(void)_fcount(_link, _resync16, _rvcount);
#line 198
X			 _rr = new resynclist(NULL);
X						_rr->paren = _rvcount == 0 ? 1 : _rvcount; ;
X		}
X		break;
X				default:
X					w_scanerr("illegal resyncid");
X			} }
X			(void)_fsettype(_link, _resync8, _rvfollow);
#line 180
X			
X			_rr = _rvresyncid;
X			_rr->first = _rvfirst == 0 && _rvfollow == 0 ? 1 : _rvfirst;
X			_rr->follow = _rvfollow;
X		;
X
X	}
X
X	{
X	resynclist* &_rr = _rv_;
X	resynclink &_lnk = _link;
X	resynclink _link(_lnk, _resync18);
X
X	switch (w_nexttoken())
X	{
X	case ',':
X		{
X			resynclist* _rvresynclist;
X			(void)scantoken(',', _link, _resync28);
X			(void)_fresynclist(_link, _resync17, _rvresynclist);
#line 171
X			 _rr=_rvresynclist; ;
X		}
X		break;
X		default:
#line 171
X		 _rr = NULL; ;
X		break;
X	} }
#line 172
X	
X				_rr = _rvresyncitem;
X				_rr->next = _rv_;
X			;
X
X	return RETOK;
}
X
static _fsettype(resynclink &_lnk, int *_resync, int &_rr)
{
X	resynclink _link(_lnk, _resync);
X
X	switch (w_nexttoken())
X	{
X	case '+':
X		{
X			(void)scantoken('+', _link, _resync25);
#line 188
X			 _rr = 1; ;
X		}
X		break;
X	case '-':
X		{
X			(void)scantoken('-', _link, _resync45);
#line 189
X			 _rr = -1; ;
X		}
X		break;
X	default:
#line 190
X		 _rr = 0; ;
X		break;
X	}
X	return RETOK;
}
X
static _fcount(resynclink &_lnk, int *_resync, int &_rr)
{
X	resynclink _link(_lnk, _resync);
X
X	switch (w_nexttoken())
X	{
X	case INT:
X		{
X			(void)scantoken(INT, _link, _resync44);
#line 203
X			 _rr = atoi(yytext); ;
X		}
X		break;
X	case '*':
X		{
X			(void)scantoken('*', _link, _resync32);
#line 204
X			 _rr = -1; ;
X		}
X		break;
X	default:
#line 205
X		 _rr = 0; ;
X		break;
X	}
X	return RETOK;
}
X
static _falias(resynclink &_lnk, int *_resync, char* &_rr)
{
X	resynclink _link(_lnk, _resync);
X
X	switch (w_nexttoken())
X	{
X	case '=':
X		{
X			char* _rv_;
X			(void)scantoken('=', _link, _resync52);
X			{
X			char* &_rr = _rv_;
X			resynclink &_lnk = _link;
X			resynclink _link(_lnk, _resync11);
X
X			switch (w_nexttoken())
X	{
X	case ID:
X		{
X			(void)scantoken(ID, _link, _resync33);
#line 209
X			 _rr = yytext; ;
X		}
X		break;
X	case INT:
X		{
X			(void)scantoken(INT, _link, _resync44);
#line 209
X			 _rr = yytext; ;
X		}
X		break;
X				default:
X					w_scanerr("illegal alias");
X			} }
#line 210
X			 _rr = strdup(_rv_); ;
X		}
X		break;
X	default:
#line 211
X		 _rr = NULL; ;
X		break;
X	}
X	return RETOK;
}
X
static _fcode(resynclink &_lnk, int *_resync, symbol* &_rr)
{
X	resynclink _link(_lnk, _resync);
X
X	switch (w_nexttoken())
X	{
X	case '{':
X	case BLOCKCODE:
X		{
X			char* _rv_;
#line 274
X			
X			int rettype = 0;
X			int line = w_currline();
X		;
X			{
X			char* &_rr = _rv_;
X			resynclink &_lnk = _link;
X			resynclink _link(_lnk, _resync39);
X
X			switch (w_nexttoken())
X	{
X	case '{':
X		{
X			(void)scantoken('{', _link, _resync14);
#line 279
X			 _rr = readcode(rettype); ;
X		}
X		break;
X	case BLOCKCODE:
X		{
X			(void)scantoken(BLOCKCODE, _link, _resync27);
#line 280
X			 _rr = readblockcode(rettype); ;
X		}
X		break;
X				default:
X					w_scanerr("illegal code");
X			} }
#line 282
X			
X			if (_rr != NULL)
X				_rr->usedret = rettype;
X
X			_rr = new symbol;
X			_rr->name = "<code>";
X			_rr->type = CODE;
X			_rr->code = _rv_;
X			_rr->line = line;
X		;
X		}
X		break;
X	default:
#line 292
X		 _rr = NULL; ;
X		break;
X	}
X	return RETOK;
}
X
SHAR_EOF
chmod 0444 parse.C ||
echo 'restore of parse.C failed'
Wc_c="`wc -c < 'parse.C'`"
test 18403 -eq "$Wc_c" ||
	echo 'parse.C: original size 18403, current size' "$Wc_c"
fi
# ============= scan.C ==============
if test -f 'scan.C' -a X"$1" != X"-c"; then
	echo 'x - skipping scan.C (File already exists)'
else
echo 'x - extracting scan.C (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'scan.C' &&
// Copyright (c) 1991 by Parag Patel.  All Rights Reserved.
static const char rcs_id[] = "$Header: scan.C,v 1.7 91/02/22 16:07:07 hmgr Exp $";
X
#include "defs.h"
#include "toks.h"
X
#define isvalpha(c) (isalpha(c) || (c) == '_')
#define isodigit(c) (isdigit(c) && (c) < '8')
X
X
#define TEXTSIZE 1024
char yytext[TEXTSIZE];
char *text = NULL;
X
X
static void
blockcomment()
{
X	register char c = w_input();
X
loop:
X	while (c != '*' && c != END)
X		c = w_input();
X	if (c != END)
X		c = w_input();
X	if (c != '/' && c != END)
X		goto loop;
}
X
static void
linecomment()
{
X	for (register char c = w_input(); c != '\n' && c != END; c = w_input())
X		;
}
X
static void
docomment()
{
X	register char c = w_input();
X	if (c == '/')
X		linecomment();
X	else if (c == '*')
X		blockcomment();
X	else
X	{
X		w_unput(c);
X		error("ERROR:  comment expected here");
X	}
}
X
static int
doident(register int c)
{
X	for (; isvalpha(c) || isdigit(c); c = w_input())
X		*text++ = c;
X	w_unput(c);
X	return ID;
}
X
X
static int
donum(register int c)
{
X	for (; isdigit(c); c = w_input())
X		*text++ = c;
X	w_unput(c);
X	return INT;
}
X
X
static int
doquote()
{
X	register int c = w_input();
X	if (isodigit(c))
X	{
X		register int c2 = c;
X		for (c = 0; isodigit(c2); c2 = w_input())
X			c = (c << 3) | (c2 - '0');
X		w_unput(c2);
X	}
X	else
X		switch (c)
X		{
X		Case 'n':
X			c = '\n';
X		Case 't':
X			c = '\t';
X		Case 'v':
X			c = '\v';
X		Case 'b':
X			c = '\b';
X		Case 'r':
X			c = '\r';
X		Case 'f':
X			c = '\f';
X		Case '\\':
X			c = '\\';
X		Case '\'':
X			c = '\'';
X
X		Case 'e':
X			c = '\033';
X		Case '?':
X			c = '\177';
X		Case '^':
X			c = w_input();
X			if (c == '?')
X				c = '\177';
X			else if (islower(c))
X				c -= 'a' + 1;
X			else if (c >= '@' && c <= '_')
X				c -= '@';
X			else
X			{
X				w_unput(c);
X				c = '^';
X			}
X
X		Default:
X			;
X		}
X	return c;
}
X
X
static int
dochar()
{
X	register int c;
X
X	*text++ = '\'';
X	c = w_input();
X	if (c == '\\')
X		c = doquote();
X	if (c == '\'' || c == '"')
X	    *text++ = '\\';
X	*text++ = c;
X	if (w_input() != '\'')
X		error("ERROR:  \' expected here");
X	*text++ = '\'';
X	return CHARACTER;
}
X
X
static int
dostr()
{
X	register int c;
X
X	*text++ = '"';
X	for (c = w_input(); c != '"' && c != END; c = w_input())
X	{
X		if (c == '\\')
X			c = doquote();
X		if (c == '"')
X		    *text++ = '\\';
X		*text++ = c;
X	}
X	if (c != '"')
X		error("ERROR:  \" expected here");
X	*text++ = '"';
X	return STRING;
}
X
static int
doopt()
{
X	int c = w_input();
X	if (c == '{') /*}*/
X		return BLOCKCODE;
X
X	(void)doident(c);
X	*text = '\0';
X	if (strcmp(yytext, "opt") == 0)
X	{
X		*text++ = ' ';
X		register char c = w_input();
X		while (isspace(c))
X			c = w_input();
X		for (; c != '\n' && c != END; c = w_input())
X			*text++ = c;
X		return DIRECTIVE;
X	}
X	else if (strcmp(yytext, "export") == 0)
X		return EXPORT;
X	//else if (strcmp(yytext, "scan") == 0)
X	//	return SCANNER;
X	else
X	{
X		error("ERROR:  illegal %% char");
X		return ID;
X	}
}
X
int
yylex()
{
X	register int c;
X	int ret;
X
X	while ((c = w_input()) != END)
X	{
X		while (isspace(c))
X			c = w_input();
X		text = yytext;
X
X		if (isvalpha(c))
X			ret = doident(c);
X		else if (isdigit(c))
X			ret = donum(c);
X		else switch (c)
X		{
X		case '[':
X			c = w_input();
X			if (c == ']')
X				ret = NULLSYM;
X			else
X			{
X				w_unput(c);
X				ret = '[';
X			}
X			break;
X		case '$':
X			c = w_input();
X			if (c != '$')
X			{
X				w_unput(c);
X				error("ERROR:  expected $$ here");
X				continue;
X			}
X			gotlexstr = TRUE;
X			ret = EOI;
X			break;
X		case ']': case '<': case '{':
X		case '#': case '*': case '=': 
X		case '(': case ')': case ':': case ';':
X		case '|': case ',': case '+': case '-':
X			ret = c;
X			break;
X		case '/':
X			docomment();
X			continue;
X		case '%':
X			ret = doopt();
X			break;
X		case '\'':
X			ret = dochar();
X			break;
X		case '"':
X			ret = dostr();
X			break;
X		case END:
X			ret = EOI;
X			break;
X		default:
X			error("Illegal character 0x%X in file (ignored).", c);
X		}
X
X		*text = '\0';
X		return ret;
X	}
X	return EOI;
}
SHAR_EOF
chmod 0444 scan.C ||
echo 'restore of scan.C failed'
Wc_c="`wc -c < 'scan.C'`"
test 3884 -eq "$Wc_c" ||
	echo 'scan.C: original size 3884, current size' "$Wc_c"
fi
# ============= build.C ==============
if test -f 'build.C' -a X"$1" != X"-c"; then
	echo 'x - skipping build.C (File already exists)'
else
echo 'x - extracting build.C (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'build.C' &&
// Copyright (c) 1991 by Parag Patel.  All Rights Reserved.
static const char rcs_id[] = "$Header: build.C,v 1.5 91/02/22 16:07:15 hmgr Exp $";
X
#include "defs.h"
X
X
static void markempty()
{
X	symbol *sym, *s;
X	symnode *or, *next, *node;
X	int i, num;
X	boolean done;
X
X	num = numsymbols();
X	do
X	{
X		done = TRUE;
X		for (i = START; i < num; i++)
X		{
X			sym = getsymbol(i);
X			if (sym->type != NONTERMINAL)
X				continue;
X
X			for (or = sym->node; or != NULL; or = or->or)
X			{
X				for (node = or; node != NULL; node = node->next)
X					if (node->sym->type != CODE)
X						break;
X				if (node == NULL)
X					continue;
X
X				s = node->sym;
X				if (s->id == EMPTY && !sym->toempty)
X				{
X					sym->toempty = TRUE;
X					done = FALSE;
X				}
X
X				for (next = node; next != NULL; next = next->next)
X					if (next->sym->type != CODE && !next->sym->toempty)
X						break;
X
X				if (next == NULL && !sym->toempty)
X				{
X					sym->toempty = TRUE;
X					done = FALSE;
X				}
X			}
X		}
X	} while (!done);
}
X
X
static void first()
{
X	symbol *sym, *s;
X	symnode *or, *next, *node;
X	int i, num;
X	boolean done;
X
X	num = numsymbols();
X	do
X	{
X		done = TRUE;
X		for (i = START; i < num; i++)
X		{
X			sym = getsymbol(i);
X			if (sym->type == CODE)
X				continue;
X
X			if (sym->type == TERMINAL)
X			{
X				if (sym->first->isin(sym->id))
X					continue;
X				*sym->first += sym->id;
X				done = FALSE;
X				continue;
X			}
X
X			for (or = sym->node; or != NULL; or = or->or)
X			{
X				for (node = or; node != NULL; node = node->next)
X					if (node->sym->type != CODE)
X						break;
X				if (node == NULL)
X					continue;
X
X				s = node->sym;
X				if (s->id == EMPTY)
X				{
X					if (!sym->first->isin(EMPTY))
X					{
X						*sym->first += EMPTY;
X						done = FALSE;
X					}
X					continue;
X				}
X
X				for (next = node; next != NULL; next = next->next)
X				{
X					s = next->sym;
X					if (s->type == CODE)
X						continue;
X
X					if (!(*s->first <= *sym->first))
X					{
X						*sym->first |= *s->first;
X						done = FALSE;
X					}
X					if (!s->toempty)
X						break;
X				}
X			}
X		}
X	} while (!done);
}
X
X
static void follow()
{
X	symbol *sym, *s;
X	symnode *or, *node, *next, *n;
X	int i, num;
X	boolean done;
X	Bitset set;
X
X	num = numsymbols();
X	*startsymbol->follow += END;
X	do
X	{
X		done = TRUE;
X		for (i = START; i < num; i++)
X		{
X			sym = getsymbol(i);
X			if (sym->type != NONTERMINAL)
X				continue;
X
X			for (or = sym->node; or != NULL; or = or->or)
X			{
X				for (node = or; node != NULL; node = node->next)
X				{
X					s = node->sym;
X					if (s->type == CODE)
X						continue;
X
X					for (next = node->next; next != NULL; next = next->next)
X						if (next->sym->type != CODE)
X							break;
X
X					for (n = next; n != NULL; n = n->next)
X						if (n->sym->type != CODE && !n->sym->toempty)
X							break;
X
X					if (n == NULL)
X					{
X						if (*sym->follow <= *s->follow)
X							continue;
X						*s->follow |= *sym->follow;
X						done = FALSE;
X					}
X
X					if (next != NULL)
X					{
X						set = *next->sym->first;
X						set -= EMPTY;
X						if (!(set <= *s->follow))
X						{
X							*s->follow |= set;
X							done = FALSE;
X						}
X					}
X				}
X			}
X		}
X	} while (!done);
}
X
X
static void mksymresync(symbol *sym)
{
X	if (sym->list == NULL)
X		return;
X
X	Bitset *set = new Bitset;
X
X	resynclist *x;
X	for (resynclist *r = sym->list; r != NULL; x = r, r = r->next, delete x)
X	{
X		symbol *s;
X		if (r->name != NULL)
X		{
X			s = findsymbol(r->name);
X			if (s == NULL)
X			{
X				error("Symbol \"%s\" doesn't exist for \"%s\" resync set",
X						r->name, sym->name);
X				continue;
X			}
X		}
X		else if (r->paren == 0)
X			s = getsymbol(EMPTY);
X		else
X		{
X			error("Cannot handle paren groups in skip-set for \"%s\"",
X					sym->name);
X			continue;
X		}
X
X		if (r->first > 0 || (r->first == 0 && r->follow == 0))
X			*set |= *s->first;
X		else if (r->first < 0)
X			*set -= *s->first;
X
X		if (r->follow > 0)
X			*set |= *s->follow;
X		else if (r->follow < 0)
X			*set -= *s->follow;
X	}
X	sym->resync = &settab[set];
}
X
X
static void mkresync(symbol *sym, symnode *start, symnode *n)
{
X	Bitset *set = new Bitset;
X
X	symnode *t = n;
X	for (int i = 0; t != NULL && i <= 3; t = t->next, i++)
X		*set |= *t->sym->first;
X
X	resynclist *x;
X	for (resynclist *r = n->list; r != NULL; x = r, r = r->next, delete x)
X	{
X		symbol *s;
X		if (r->name != NULL)
X		{
X			s = findsymbol(r->name);
X			if (s == NULL)
X			{
X				for (symnode *t = start; t != NULL; t = t->next)
X					if (t->alias != NULL && strcmp(t->alias, r->name) == 0)
X						break;
X				if (t != NULL)
X					s = t->sym;
X			}
X			if (s == NULL)
X			{
X				error("Symbol \"%s\" doesn't exist for \"%s\" resync set",
X						r->name, sym->name);
X				continue;
X			}
X		}
X		else if (r->paren == 0)
X			s = getsymbol(EMPTY);
X		else
X		{
X			for (symnode *t = start; t != NULL; t = t->next)
X				if (t->sym->realname != NULL 
X						&& t->sym->realname != t->sym->name)
X					if (--(*r).paren <= 0)
X						break;
X			if (t == NULL)
X			{
X				error("Paren group %d does not exist in rule for \"%s\"",
X						r->paren, sym->name);
X				continue;
X			}
X			s = t->sym;
X		}
X
X		if (r->first > 0 || (r->first == 0 && r->follow == 0))
X			*set |= *s->first;
X		else if (r->first < 0)
X			*set -= *s->first;
X
X		if (r->follow > 0)
X			*set |= *s->follow;
X		else if (r->follow < 0)
X			*set -= *s->follow;
X	}
X	n->resync = &settab[set];
}
X
static void resync()
{
X	int i;
X	symbol *sym;
X	int num = numsymbols();
X	symnode *or;
X
X	for (i = START; i < num; i++)
X	{
X		sym = getsymbol(i);
X		if (sym->type == CODE)
X			continue;
X
X		mksymresync(sym);
X		for (or = sym->node; or != NULL; or = or->or)
X			for (symnode *n = or; n != NULL; n = n->next)
X				mkresync(sym, or, n);
X	}
}
X
X
void buildsets()
{
X	markempty();
X	first();
X	follow();
X	resync();
}
SHAR_EOF
chmod 0444 build.C ||
echo 'restore of build.C failed'
Wc_c="`wc -c < 'build.C'`"
test 5614 -eq "$Wc_c" ||
	echo 'build.C: original size 5614, current size' "$Wc_c"
fi
# ============= check.C ==============
if test -f 'check.C' -a X"$1" != X"-c"; then
	echo 'x - skipping check.C (File already exists)'
else
echo 'x - extracting check.C (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'check.C' &&
// Copyright (c) 1991 by Parag Patel.  All Rights Reserved.
static const char rcs_id[] = "$Header: check.C,v 1.6 91/02/22 16:07:20 hmgr Exp $";
X
#include "defs.h"
X
X
static void dostruct(symbol *sym)
{
X	if (sym->rettype == NULL)
X		return;
X	if (dargstyle)
X	{
X		sym->mkstruct = strpbrk(sym->rettype, ",;") != NULL;
X		return;
X	}
X	for (char *s = sym->rettype; *s != '\0'; s++)
X		if (*s == ',')
X		{
X			sym->mkstruct = TRUE;
X			*s = ';';
X		}
}
X
X
void check()
{
X	int i;
X	symbol *sym;
X	symnode *n;
X	Bitset curr(numsymbols());
X	Bitset set(numsymbols());
X	Bitset t(numsymbols());
X
X	if (!exportedname && !startsymbol->export)
X		startsymbol->export = TRUE;
X
X	for (i = 0; i < numnonterms(); i++)
X	{
X		sym = getnonterm(i);
X		if (sym->type != NONTERMINAL)
X			continue;
X		
X		dostruct(sym);
X		if (sym->mkstruct && sym->export)
X			error("Non-simple type for exported non-terminal \"%s\"",
X				sym->name);
X
X		curr.clear();
X		for (n = sym->node; n != NULL; n = n->or)
X		{
X			set.clear();
X			boolean isfirst = TRUE;
X			for (symnode *s = n; s != NULL; s = s->next)
X			{
X				if (s->sym->type == CODE)
X					continue;
X				if (isfirst)
X					if (s->sym == sym)
X						if (sym->realname != NULL && sym->name != sym->realname)
X							error("Head recursion in grouped rules for \"%s\"",
X									sym->realname);
X						else
X							error("Head recursion in rules for \"%s\"",
X									sym->name);
X				isfirst = FALSE;
X				set |= *s->sym->first;
X				if (!s->sym->first->isin(EMPTY))
X					break;
X			}
X			t = curr;
X			t &= set;
X			if (t.size() == 0 || (t.size() == 1 && t.isin(EMPTY)))
X				curr |= set;
X			else if (sym->type == NONTERMINAL && sym->realname != NULL
X					&& sym->name != sym->realname)
X				error("Ambiguous [non-LL(1)] grouped rules in \"%s\"",
X						sym->realname);
X			else
X				error("Ambiguous [non-LL(1)] rules for \"%s\"", sym->name);
X		}
X
X		for (symnode *or = sym->node; or != NULL; or = or->or)
X			for (n = or; n != NULL; n = n->next)
X				if (n->sym->type == TERMINAL && n->alias != NULL)
X					if (sym->realname != NULL && sym->name != sym->realname)
X						error(
"Alias \"%s\" defined for terminal \"%s\" in grouped rules for \"%s\"",
X							n->alias, n->sym->name, sym->realname);
X					else
X						error(
"Alias \"%s\" defined for terminal \"%s\" in rules for \"%s\"",
X							n->alias, n->sym->name, sym->name);
X	}
}
SHAR_EOF
chmod 0444 check.C ||
echo 'restore of check.C failed'
Wc_c="`wc -c < 'check.C'`"
test 2302 -eq "$Wc_c" ||
	echo 'check.C: original size 2302, current size' "$Wc_c"
fi
# ============= read.C ==============
if test -f 'read.C' -a X"$1" != X"-c"; then
	echo 'x - skipping read.C (File already exists)'
else
echo 'x - extracting read.C (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'read.C' &&
// Copyright (c) 1991 by Parag Patel.  All Rights Reserved.
static const char rcs_id[] = "$Header: read.C,v 1.9 91/02/22 16:07:28 hmgr Exp $";
X
#include "defs.h"
#include "toks.h"
X
boolean gotlexstr = FALSE;
X
static charbuf codebuf;
X
X
void readccomment()
{
X	int	c, t;
X
X	c = w_input();
X	while (c != END)
X		if (c == '*')
X		{
X			t = w_input();
X			if (t == '/')
X				break;
X			c = t;
X		}
X		else
X			c = w_input();
X	if (c == END)
X		w_scanerr("expected \"*/\"");
}
X
X
char *readtype()
{
X	int len = 0;
X	int c, t;
X	int count = 0;
X
X	while ((c = w_input()) != END)
X	{
X		switch (c)
X		{
X		case '"':
X		case '\'':
X			codebuf[len++] = c;
X			while ((t = w_input()) != c && c != END)
X			{
X				codebuf[len++] = t;
X				if (t == '\\')
X					codebuf[len++] = w_input();
X			}
X			break;
X
X		case '<':
X			count++;
X			break;
X		case '>':
X			count--;
X			break;
X		default:
X			;
X		}
X
X		if (count < 0)
X			break;
X		codebuf[len++] = c;
X	}
X	if (c == END)
X		w_scanerr("expected \">\"");
X	
X	char *usercode = strnew(len);
X	for (int i = 0; i < len; i++)
X		usercode[i] = codebuf[i];
X	usercode[len] = '\0';
X
X	return usercode;
}
X
X
char *readcode(int &usedret)
{
X    int len = 0;
X    int c, t;
X    int count = 0;
X
X    while ((c = w_input()) != END)
X    {
X	switch (c)
X	{
X	case '/': 
X	    codebuf[len++] = c;
X	    c = w_input();
X
X	    if (c == '/')
X	    {
X		codebuf[len++] = c;
X		while ((c = w_input()) != '\n' && c != END)
X		    codebuf[len++] = c;
X	    }
X	    else if (c == '*')
X	    {
X		codebuf[len++] = c;
X		t = w_input();
X		while (t != END)
X		{
X		    codebuf[len++] = t;
X		    c = w_input();
X		    if (t == '*' && c == '/')
X			break;
X		    t = c;
X		}
X	    }
X	    break;
X
X	case '"': 
X	case '\'': 
X	    codebuf[len++] = c;
X	    while ((t = w_input()) != c && c != END)
X	    {
X		codebuf[len++] = t;
X		if (t == '\\')
X		    codebuf[len++] = w_input();
X	    }
X	    break;
X
X	case '$': 
X	    c = w_input();
X	    if (c == '$')
X		usedret |= RET_VALUE;
X	    else if (c == '?')
X	    {
X		usedret |= RET_CODE;
X		optimize = FALSE;
X	    }
X	    codebuf[len++] = '_';
X	    codebuf[len++] = 'r';
X	    if (c == '$' || c == '?')
X		c = (c == '$' ? 'r' : 'c');
X	    else
X		codebuf[len++] = 'v';
X	    break;
X
X	case '{': 
X	    count++;
X	    break;
X	case '}': 
X	    count--;
X	    break;
X	default: 
X	    ;
X	}
X
X	if (count < 0)
X	    break;
X	codebuf[len++] = c;
X    }
X    if (c == END)
X	w_scanerr(/*{*/ "expected \"}\"");
X
X    char *usercode = strnew(len);
X    for (int i = 0; i < len; i++)
X	usercode[i] = codebuf[i];
X    usercode[len] = '\0';
X
X    return usercode;
}
X
char *readblockcode(int &usedret)
{
X    int len = 0;
X    int c;
X    boolean done = FALSE;
X
X    while ((c = w_input()) != END)
X    {
X	switch (c)
X	{
X	case '$': 
X	    c = w_input();
X	    if (c == '$')
X		usedret |= RET_VALUE;
X	    else if (c == '?')
X	    {
X		usedret |= RET_CODE;
X		optimize = FALSE;
X	    }
X	    codebuf[len++] = '_';
X	    codebuf[len++] = 'r';
X	    if (c == '$' || c == '?')
X		c = (c == '$' ? 'r' : 'c');
X	    else
X		codebuf[len++] = 'v';
X	    break;
X
X	case '%':
X	    c = w_input();
X	    if (c == '}')
X		done = TRUE;
X	    else
X		codebuf[len++] = '%';
X
X	default: 
X	    ;
X	}
X
X	if (done)
X	    break;
X	codebuf[len++] = c;
X    }
X    if (c == END)
X	w_scanerr(/*{*/ "expected \"%%}\"");
X
X    char *usercode = strnew(len);
X    for (int i = 0; i < len; i++)
X	usercode[i] = codebuf[i];
X    usercode[len] = '\0';
X
X    return usercode;
}
X
X
char *getword()
{
X	int c;
X	char *s;
X	static char buf[100];
X
X	c = w_input();
X	while (isspace(c))
X		c = w_input();
X	if (c == END)
X		return NULL;
X
X	*(s = buf) = '\0';
X
X	for (; c != END && !isspace(c); c = w_input())
X		*s++ = c;
X	w_unput(c);
X
X	*s = '\0';
X	return buf;
}
SHAR_EOF
chmod 0444 read.C ||
echo 'restore of read.C failed'
Wc_c="`wc -c < 'read.C'`"
test 3603 -eq "$Wc_c" ||
	echo 'read.C: original size 3603, current size' "$Wc_c"
fi
true || echo 'restore of gen.C failed'
echo End of part 5, continue with part 6
exit 0

exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.