REPOST: v19i089: wacco - A C++ LL parser generator, Part02/06
Parag Patel
parag at hpsdeb.sde.hp.com
Sun May 19 15:42:48 AEST 1991
Submitted-by: Parag Patel <parag at 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 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