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.