parag@hpsdeb.sde.hp.com (Parag Patel) (05/19/91)
Submitted-by: Parag Patel <parag@hpsdeb.sde.hp.com> Posting-number: Volume 19, Issue 89 Archive-name: wacco/part02 #!/bin/sh # do not concatenate these parts, unpack them in order with /bin/sh # file gen.C continued # if test ! -r _shar_seq_.tmp; then echo 'Please unpack part 1 first!' exit 1 fi (read Scheck if test "$Scheck" != 2; then echo Please unpack part "$Scheck" next! exit 1 else exit 0 fi ) < _shar_seq_.tmp || exit 1 if test ! -f _shar_wnt_.tmp; then echo 'x - still skipping gen.C' else echo 'x - continuing file gen.C' sed 's/^X//' << 'SHAR_EOF' >> 'gen.C' && X putf("\t\ttok = w_gettoken();\n"); X putf("\t\tif (tok == expect)\n\t\t\tbreak;\n\t\tlevel++;\n"); X putf("\t}\t\n\ttok = -1;\n\treturn expect;\n}\n\n"); X X if (exportedname) X for (i = 0; i < numnonterms(); i++) X { X sym = getnonterm(i); X if (sym->type != NONTERMINAL || !sym->export) X continue; X dumpexport(sym); X } X else X dumpexport(startsymbol); X putf("\n"); X X i = 1; X for (Setiter setiter(settab); setiter; setiter++) X { X Set &set = setiter(); X printset(strbldf("_resync%d", set.id = i++), *set.set); X } X putf("\n"); X X Bitset set(numsymbols()); X for (i = 0; i < numnonterms(); i++) X { X sym = getnonterm(i); X if (sym->type != NONTERMINAL) X { X if (dumpcode) X mkcode("", sym); X continue; X } X if (optimize && sym->usecount < 2 && !sym->export) X { X if (sym->usecount != 1) X error("Warning - non-terminal %s is never used", sym->name); X continue; X } X X putf("static _f%s(resynclink &_lnk, int *_resync%s)\n", X mkname(sym), mktype(sym, ", ", " &_rr")); X putf("{\n\tresynclink _link(_lnk, _resync);\n"); X if ((saveret = (sym->usedret & RET_CODE) ? TRUE : FALSE)) X putf("\tint _rc;\n"); X putf("\n"); X X if (sym->resync != NULL) X { X putf("\t{ "); X //printset("_skip", *sym->resync); X putf("\t (void)scantoken(-1, _link, _resync%d); }\n\n", X sym->resync->id); X } X X if (sym->node != NULL && sym->node->or == NULL) X { X genstmt("\t", sym->node); X putf("\n\treturn RETOK;\n}\n\n"); X continue; X } X X boolean donedefault = FALSE; X putf("\tswitch (w_nexttoken())\n\t{\n"); X for (n = sym->node; n != NULL; n = n->or) X { X set.clear(); X for (symnode *s = n; s != NULL; s = s->next) X { X if (s->sym->type == CODE) X continue; X set |= *s->sym->first; X if (!s->sym->first->isin(EMPTY)) X break; X } X X if (set.size() == 0 || (set.size() == 1 && set.isin(EMPTY))) X { X donedefault = TRUE; X putf("\tdefault:\n"); X genstmt("\t\t", n); X if (!sym->first->isin(EMPTY)) X putf("\t\treturn w_scanerr(\"illegal %s\");\n", X mkerrname(sym)); X } X else X { X printcase("\t", set); X putf("\t\t{\n"); X genstmt("\t\t\t", n); X putf("\t\t}\n"); X } X putf("\t\tbreak;\n"); X } X X if (!donedefault && !sym->first->isin(EMPTY)) X { X putf("\tdefault:\n"); X putf("\t\treturn w_scanerr(\"illegal %s\");\n", X mkerrname(sym)); X } X X putf("\t}\n\treturn RETOK;\n}\n\n"); X } } X X void gencode(char *infile) { X inputfile = infile; X X fp = makefile(headername); X currfile = headername; X curr_lineno = 1; X genheader(); X fclose(fp); X cmpandmv(headername); X X fp = makefile(parsername); X currfile = parsername; X curr_lineno = 1; X genparser(headername); X fclose(fp); X cmpandmv(parsername); X X if (!gotlexstr) X return; X X fp = makefile(scannername); X currfile = scannername; X curr_lineno = 1; X genscanner(headername); X fclose(fp); X cmpandmv(scannername); } SHAR_EOF echo 'File gen.C is complete' && chmod 0444 gen.C || echo 'restore of gen.C failed' Wc_c="`wc -c < 'gen.C'`" test 18803 -eq "$Wc_c" || echo 'gen.C: original size 18803, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= io.C ============== if test -f 'io.C' -a X"$1" != X"-c"; then echo 'x - skipping io.C (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting io.C (Text)' sed 's/^X//' << 'SHAR_EOF' > 'io.C' && // Copyright (c) 1991 by Parag Patel. All Rights Reserved. static const char rcs_id[] = "$Header: io.C,v 1.13 91/02/22 16:08:20 hmgr Exp $"; X #include "defs.h" #include "toks.h" #include <stdarg.h> X X #define UNPUT 300 #define MAXERR 36 X X struct errstack { X int col; X boolean skip; X char *err; X errstack() { col = -1; skip = FALSE; err = NULL; } }; 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; } }; ***********/ X X extern char yytext[]; extern int yylex(); X static char filename[100]; static FILE *fp = stdin; X static int line = -1; static int col = 0; static char linebuf[200] = { '\0' }; static int lineloc = 0; static int ubuf[UNPUT]; static int top = 0; X static int tokcol = 0; static errstack errstk[MAXERR]; static int numerrs = 0; X X void w_flusherrs() { X line++; X if (numerrs <= 0) X return; X X fprintf(stderr, "%d:\t%s", line, linebuf); X if (linebuf[strlen(linebuf) - 1] != '\n') X fprintf(stderr, "\n"); X fprintf(stderr, "\t"); X X int i; X int pcol = 0; X for (i = 0; i < numerrs; i++) X { X for (; pcol < errstk[i].col - 1; pcol++) X fprintf(stderr, linebuf[pcol] == '\t' ? "\t" : X (errstk[i].skip ? "*" : " ")); X X if (i > 0 && errstk[i].col == errstk[i - 1].col) X continue; X X if (linebuf[pcol++] == '\t') X fprintf(stderr, "\t"); X X fprintf(stderr, errstk[i].skip ? "*" : "^"); X } X fprintf(stderr, "\n"); X X int last = -1; X for (i = 0; i < numerrs; i++) X { X if (errstk[i].skip) X continue; X /* ** if (last >= 0 && errstk[i].col == errstk[last].col && X strncmp(errstk[i].err, errstk[last].err, 5) == 0) continue; X last = i; ** */ X X fprintf(stderr, "\t"); X for (int j = 0; j < errstk[i].col - 1; j++) X fprintf(stderr, linebuf[j] == '\t' ? "\t" : " "); X X if (linebuf[j] == '\t') X fprintf(stderr, "\t"); X fprintf(stderr, "%s\n", errstk[i].err); X } X X numerrs = 0; } X X extern int w_numerrors; extern "C" int w_vscanerr(const char *fmt, va_list ap); int w_vscanerr(const char *fmt, va_list ap) { X w_numerrors++; X X if (numerrs >= MAXERR) X { X w_flusherrs(); X line--; X } X X if (errstk[numerrs].err == NULL) X errstk[numerrs].err = strnew(150); X X if (fmt == NULL) X { X errstk[numerrs].skip = TRUE; X errstk[numerrs].col = col; X } X else X { X errstk[numerrs].skip = FALSE; X errstk[numerrs].col = tokcol; X vsprintf(errstk[numerrs].err, (char *)fmt, ap); X } X numerrs++; X return RETERR; } X int w_scanerr(const char *fmt, ...) { X if (fmt == NULL) X { X w_flusherrs(); X return RETERR; X } X X va_list ap; X va_start(ap, fmt); X w_vscanerr(fmt, ap); X va_end(ap); X return RETERR; } X X int w_input() { X int c; X X if (top > 0) X return ubuf[--top]; X c = linebuf[lineloc++]; X while (c == '\0') X { X w_flusherrs(); X lineloc = 0; X tokcol = col = 0; X *linebuf = '\0'; X if (fgets(linebuf, sizeof linebuf - 2, fp) == NULL) X return END; X c = linebuf[lineloc++]; X } X col++; X return c; } X X int w_unput(int c) { X if (top >= UNPUT) X { X fprintf(stderr, "Cannot w_unput any more characters"); X exit(11); X } X ubuf[top++] = c; X return 0; } X X void w_output(int c) { X putchar(c); } X X void w_closefile() { X if (fp == NULL) X return; X fclose(fp); } X X int w_openfile(char *fname) { X if (fp != NULL) X w_closefile(); X if ((fp = fopen(fname, "r")) == NULL) X return RETERR; X strncpy(filename, fname, sizeof filename - 1); X return RETOK; } X X FILE *w_getfile() { X return fp; } X void w_setfile(FILE *f) { X fp = f; X *filename = '\0'; } X int w_currcol() { X return col; } X int w_currline() { X return line + 1; } X char *w_getcurrline() { X return linebuf; } X X int w_gettoken() { X int ret = yylex(); X tokcol = col - strlen(yytext); X return ret; } SHAR_EOF chmod 0444 io.C || echo 'restore of io.C failed' Wc_c="`wc -c < 'io.C'`" test 3832 -eq "$Wc_c" || echo 'io.C: original size 3832, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= main.C ============== if test -f 'main.C' -a X"$1" != X"-c"; then echo 'x - skipping main.C (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting main.C (Text)' sed 's/^X//' << 'SHAR_EOF' > 'main.C' && // Copyright (c) 1991 by Parag Patel. All Rights Reserved. static const char rcs_id[] = "$Header: main.C,v 1.22 91/02/22 16:05:39 hmgr Exp $"; X #include "version.C" X #include "defs.h" #include "toks.h" #include <osfcn.h> #include <stdarg.h> X #ifdef BSD #include <sys/wait.h> #endif X // externs for getopt() extern char *optarg; extern int optind; X // These vars are modified from the command line boolean optimize = TRUE; boolean dumpcode = TRUE; boolean statonly = FALSE; boolean docompare = TRUE; boolean casesensitive = FALSE; boolean dargstyle = TRUE; boolean genlineinfo = TRUE; char *headername = "tokens.h"; char *scannername = "scanner.l"; char *parsername = "parser.C"; X // just other globals here boolean exportedname = FALSE; X implement_array(charbuf, char); implement_array(charvec, char*); X X static charbuf buf; static charvec vec; X #define issep(c) (strchr(sep, (c)) != NULL) #define notsep(c) (strchr(sep, (c)) == NULL) X char **strsep(const char *str, const char *sep, int whsp, int *retnum) { X buf.reset(strlen(str) + 1); X register char *s = buf.getarr(); X strcpy(s, str); X X register int num = 0; X while (*s != '\0') X { X if (whsp) // skip leading separators? X while (*s != '\0' && issep(*s)) X s++; X X vec[num++] = s; X X // find next separator X while (*s != '\0' && notsep(*s)) X s++; X if (*s != '\0') X *s++ = '\0'; X } X X vec[num] = NULL; X X if (retnum != NULL) X *retnum = num; X X return &vec[0]; } X const char * strbldf(const char *format, ...) { X static char buff[4][1024]; X static int curr = 0; X if (++curr > 3) X curr = 0; X X va_list ap; X va_start(ap, format); X vsprintf(buff[curr], (char*)format, ap); X va_end(ap); X return buff[curr]; } X X int error(char *fmt, ...) { X va_list ap; X X w_numerrors++; X va_start(ap, fmt); X vfprintf(stderr, fmt, ap); X fprintf(stderr, ".\n"); X va_end(ap); X return RETERR; } X void quit(char *fmt, ...) { X va_list ap; X X va_start(ap, fmt); X vfprintf(stderr, fmt, ap); X fprintf(stderr, "!\n"); X va_end(ap); X exit(1); } X X static unsigned prime[] = { X 11, X 23, X 47, X 97, X 197, X 397, X 797, X 1597, X 3203, X 6421, X 12853, X 25717, X 51437, X 102877, X 205759, X 411527, X 823117, X 1646237, X 3292489, X 6584983, X 13169977, X 26339969, X 52679969, X 105359939, X 210719881, X 421439783, X 842879579 }; const N = sizeof prime/sizeof *prime; X unsigned table_bump(unsigned hs) { X if (hs < prime[N - 2]) X for (int i = 0; i < N; i++) X if (prime[i] > 2 * hs) X return prime[i]; X X return prime[N - 1]; } X X static void dumpset(Bitset &set) { X Bitsetiter si(set); X symbol *s; X int id; X X printf("("); X while ((id = si()) >= 0) X { X if (id == END || id == EMPTY) X continue; X s = getsymbol(id); X printf(" %s", s->name); X } X if (set.isin(EMPTY)) X printf(" []"); X else if (set.isin(END)) X printf(" $"); X printf(" )\n"); } X static void dump(void) { X symbol *sym; X symnode *n1, *n2; X int i; X char *s; X X for (i = START; i < numsymbols(); i++) X { X sym = getsymbol(i); X if (sym->type == NONTERMINAL) X { X if (sym->lexstr == NULL) X printf("%s", sym->name); X else X printf("%s (%s)", sym->lexstr, sym->name); X if (sym->rettype != NULL) X printf("<%s>", sym->rettype); X printf(" use=%d usedret=%d", sym->usecount, sym->usedret); X if (sym->toempty) X printf(" ==> []"); X printf("\n"); X s = "\t:"; X for (n1 = sym->node; n1 != NULL; n1 = n1->or) X { X for (n2 = n1; n2 != NULL; n2 = n2->next) X { X if (n2->sym->type == CODE) X printf("%s {%s}\n", s, n2->sym->code); X else X { X printf("%s %s[%d] = ", s, n2->sym->name, X n2->resync->id); X dumpset(*n2->resync->set); X } X s = "\t "; X } X s = "\t|"; X } X printf("\t;\n"); X } X else if (sym->type == TERMINAL) X { X printf("[%s]", sym->name); X if (sym->lexstr != NULL) X printf(" == %s", sym->lexstr); X printf("\n"); X } X else X { X printf("%s == {%s}\n", sym->name, sym->code); X continue; X } X X printf("FIRST(%s) = ", sym->name); X dumpset(*sym->first); X X printf("FOLLOW(%s) = ", sym->name); X dumpset(*sym->follow); X X if (sym->resync != NULL) X { X printf("SKIP-SET(%s[%d]) = ", sym->name, sym->resync->id); X dumpset(*sym->resync->set); X } X X printf("\n"); X } } X X static char *tmpname = ".wacco.tmp"; X FILE *makefile(char *fname) { X if (docompare) X fname = tmpname; X FILE *fp = fopen(fname, "w"); X if (fp == NULL) X quit("Cannot open %s for writing!", fname); X return fp; } X void cmpandmv(char *file) { X if (!docompare) X return; X #ifdef BSD X int pid = fork(); #else X pid_t pid = fork(); #endif X if (pid == 0) X { X execlp("cmp", "cmp", "-s", file, tmpname, NULL); X exit(-1); X } X #ifdef BSD X union wait stat; X int w; #else X int stat; X pid_t w; #endif X do X w = wait(&stat); X while (w != pid && w >= 0); X #ifdef BSD X if (stat.w_termsig == 0 && stat.w_retcode == 0) X return; #else X if (stat == 0) X return; #endif X X unlink(file); X if (link(tmpname, file) < 0) X quit("Cannot link %s to %s", tmpname, file); X unlink(tmpname); } X X void getoptions(int argc, char *argv[]) { X int opt; X X while ((opt = getopt(argc, argv, "dciah:s:p:OCL")) != EOF) X switch (opt) X { X Case 'd': X statonly = TRUE; X X Case 'c': X docompare = FALSE; X X Case 'i': X casesensitive = TRUE; X X Case 'a': X dargstyle = FALSE; X X Case 'h': X headername = strdup(optarg); X X Case 's': X scannername = strdup(optarg); X X Case 'p': X parsername = strdup(optarg); X X Case 'O': X optimize = FALSE; X X Case 'C': X dumpcode = FALSE; X X Case 'L': X genlineinfo = FALSE; X X Default: X quit( "Usage: %s [-dlciOCL] [-h header] [-p parser] [-s scanner] [file]", argv[0]); X } } X X int main(int argc, char *argv[]) { X getoptions(argc, argv); X X initsym(); X X char *infile = NULL; X FILE *fp = stdin; X if (optind < argc) X { X fp = fopen(infile = argv[optind], "r"); X if (fp == NULL) X quit("Cannot open file %s for reading", argv[optind]); X } X w_setfile(fp); X X if (!program()) X return 1; X X if (startsymbol == NULL && !exportedname) X quit("No start symbol defined"); X X buildsets(); X check(); X X if (w_numerrors > 0) X quit("Not generating any w_output files"); X X if (statonly) X { X dump(); X return 0; X } X X gencode(infile); X if (docompare) X unlink(tmpname); X return 0; } SHAR_EOF chmod 0444 main.C || echo 'restore of main.C failed' Wc_c="`wc -c < 'main.C'`" test 6362 -eq "$Wc_c" || echo 'main.C: original size 6362, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parse.C ============== if test -f 'parse.C' -a X"$1" != X"-c"; then echo 'x - skipping parse.C (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp 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" rm -f _shar_wnt_.tmp fi # ============= read.C ============== if test -f 'read.C' -a X"$1" != X"-c"; then echo 'x - skipping read.C (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp 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" rm -f _shar_wnt_.tmp fi # ============= scan.C ============== if test -f 'scan.C' -a X"$1" != X"-c"; then echo 'x - skipping scan.C (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp 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" rm -f _shar_wnt_.tmp fi # ============= sym.C ============== if test -f 'sym.C' -a X"$1" != X"-c"; then echo 'x - skipping sym.C (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting sym.C (Text)' sed 's/^X//' << 'SHAR_EOF' > 'sym.C' && // Copyright (c) 1991 by Parag Patel. All Rights Reserved. static const char rcs_id[] = "$Header: sym.C,v 1.14 91/02/22 16:06:42 hmgr Exp $"; X #include "defs.h" #ifdef BSD # define BITSPERBYTE 8 # define BITS(type) (BITSPERBYTE * (int)sizeof(type)) #else # include <values.h> #endif X inline static unsigned sethash(Bitset *key) { X return key->hash(); } X // This is from the "dragon" Compilers book. // It is much better than the above but somewhat slower. // static unsigned strhash(register const char *p) { X register unsigned h = 0; X register g; X while (*p != '\0') X { X h = (h << 4) + (unsigned)*p++; X if (g = h & (0xF << BITS(unsigned) - 4)) X { X h ^= g >> BITS(unsigned) - 4; X h ^= g; X } X } X return h; } X X typedef Bitset *Bitsetptr; implement_table(Settab, Setiter, Set, Bitsetptr, sethash); Settab settab; X X typedef const char *charptr; declare_table(symtab, symiter, symbol, charptr); implement_table(symtab, symiter, symbol, charptr, strhash); X typedef symbol *symptr; declare_array(symptrarr,symptr); implement_array(symptrarr, symptr); X symbol *startsymbol = NULL; symbol *startcode = NULL; X static symtab symlist; static symptrarr symids, nonterms, terms; X X symbol::symbol(const char *n) { X name = strdup(n); X type = TERMINAL; X X rettype = NULL; X lexstr = NULL; // realname X code = NULL; X X usedret = 0; // lexdef, line X X toempty = FALSE; X usecount = 0; X export = FALSE; X mkstruct = FALSE; X X first = new Bitset; X follow = new Bitset; X resync = NULL; // list X X node = NULL; } X X symnode::symnode() { X sym = NULL; X alias = NULL; X next = NULL; X or = NULL; X resync = NULL; // list } X resynclist::resynclist(char *n) { X if (n == NULL) X name = NULL; X else X name = strdup(n); X first = follow = 0; X paren = 0; X next = NULL; } X X int numsymbols() { X return symlist.size(); } X symbol * getsymbol(int id) { X if (id < 0 || id >= symids.size()) X return NULL; X return symids[id]; } X int numterms() { X return terms.size(); } X int numnonterms() { X return nonterms.size(); } X symbol * getterm(int id) { X if (id < 0 || id >= terms.size()) X return NULL; X return terms[id]; } X symbol * getnonterm(int id) { X if (id < 0 || id >= nonterms.size()) X return NULL; X return nonterms[id]; } X X symbol * addsymbol(const char *name) { X if (!symlist.insert(name)) X return &symlist(); X X symbol & s = symlist(); X static int idnum = 0; X s.id = idnum; X symids[idnum++] = &s; X s.first = new Bitset; X s.follow = new Bitset; X return &s; } X void addterm(symbol *s) { X if (s == NULL) X return; X X terms[s->parserid = (int)terms.size()] = s; } X void addnonterm(symbol *s) { X if (s == NULL) X return; X X nonterms[s->parserid = (int)nonterms.size()] = s; X s->parserid = -1 - s->parserid; X if (s->type == TERMINAL) X { X s->type = NONTERMINAL; X s->realname = s->name; X } } X symbol * findsymbol(const char *name) { X if (symlist.find(name)) X return &symlist(); X return NULL; } X void initsym() { X symbol *s; X X s = addsymbol("$ END"); // id == 0 == END X s = addsymbol("[]"); // id == 1 == EMPTY } SHAR_EOF chmod 0444 sym.C || echo 'restore of sym.C failed' Wc_c="`wc -c < 'sym.C'`" test 3130 -eq "$Wc_c" || echo 'sym.C: original size 3130, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= table.h ============== if test -f 'table.h' -a X"$1" != X"-c"; then echo 'x - skipping table.h (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting table.h (Text)' sed 's/^X//' << 'SHAR_EOF' > 'table.h' && // Copyright (c) 1991 by Parag Patel. All Rights Reserved. // $Header: table.h,v 1.5 91/05/17 16:30:00 hmgr Exp $ X #ifndef GENERICH #include <generic.h> #endif X #include <stddef.h> X #define table_node(table) name2(table,node) #define table_key(table) name2(table,key) X typedef unsigned TABLE_BUMP(unsigned); extern unsigned table_bump(unsigned); X X #define declare_table(table,iterator,symbol,key) \ typedef key table_key(table); \ struct table_node(table) \ { \ X table_node(table) *next; \ X symbol sym; \ X table_node(table)(key k, table_node(table) *tail) \ X : sym(k) { next = tail; } \ X table_node(table)(symbol &s, table_node(table) *tail) \ X : sym(s) { next = tail; } \ }; \ class table \ { \ X unsigned hash_size; \ X unsigned threshold; \ X unsigned numnode; \ X table_node(table) **vec; \ X table_node(table) *curr; \ X friend class iterator; \ X unsigned (*bump)(unsigned); \ X void resize(unsigned =0); \ X void delnode(table_node(table) **); \ X boolean insertsym(symbol&); \ public: \ X table(unsigned hs =0, TABLE_BUMP *bump_function =NULL); \ X table(table&); \ X ~table(); \ X boolean find(key); \ X boolean insert(key); \ X boolean remove(key); \ X boolean operator+=(key k) { return insert(k); } \ X boolean operator-=(key k) { return remove(k); } \ X boolean operator==(key k) { return find(k); } \ X boolean operator!=(key k) { return !find(k); } \ X symbol &operator[](key); \ X symbol &get(); \ X symbol &operator()(); \ X symbol &operator*(); \ X symbol *operator->(); \ X table& clear(); \ X table& operator=(table&); \ X boolean operator==(table&); \ X table& operator+=(table&); \ X table& operator-=(table&); \ X table& operator&=(table&); \ X unsigned size(); \ }; \ class iterator \ { \ X table *parent; \ X table_node(table) *curr; \ X unsigned index; \ X void transfer(table *); \ X friend class table; \ public: \ X iterator(); \ X iterator(table &); \ X ~iterator(); \ X table &operator=(table &); \ X boolean operator==(iterator &); \ X boolean operator!=(iterator &); \ X operator boolean(); \ X symbol &get(); \ X symbol &operator()(); \ X symbol &operator*(); \ X symbol *operator->(); \ X symbol &operator++(); \ X void remove(); \ }; \ inline symbol &table::operator[](key k) \ { \ X void(insert(k)); \ X return curr->sym; \ } \ inline symbol &table::get() \ { \ X if (curr != NULL) \ X return curr->sym; \ X else \ X return *(symbol *)NULL; \ } \ inline symbol &table::operator()() { return get(); } \ inline symbol &table::operator*() { return get(); } \ inline symbol *table::operator->() { return &get(); } \ inline unsigned table::size() \ { \ X return numnode; \ } \ inline iterator::iterator() \ { \ X parent = NULL; \ X curr = NULL; \ } \ inline iterator::iterator(table &t) \ { \ X parent = NULL; \ X this->transfer(&t); \ } \ inline iterator::~iterator() \ SHAR_EOF true || echo 'restore of table.h failed' fi echo 'End of part 2' echo 'File table.h is continued in part 3' echo 3 > _shar_seq_.tmp 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.