v19i092: wacco - A C++ LL parser generator, Part05/06
Parag Patel
parag at hpsdeb.sde.hp.com
Sun May 19 04:02:00 AEST 1991
Submitted-by: Parag Patel <parag at 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 at 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 at uunet.uu.net.
More information about the Comp.sources.misc
mailing list