v19i093: wacco - A C++ LL parser generator, Part06/06
Parag Patel
parag at hpsdeb.sde.hp.com
Sun May 19 04:02:14 AEST 1991
Submitted-by: Parag Patel <parag at hpsdeb.sde.hp.com>
Posting-number: Volume 19, Issue 93
Archive-name: wacco/part06
---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is part 06 of wacco
# ============= gen.C ==============
if test -f 'gen.C' -a X"$1" != X"-c"; then
echo 'x - skipping gen.C (File already exists)'
else
echo 'x - extracting gen.C (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'gen.C' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
static const char rcs_id[] = "$Header: gen.C,v 1.29 91/02/22 16:08:02 hmgr Exp $";
X
#include "defs.h"
#include "toks.h"
#include <stdarg.h>
X
X
static FILE *fp = NULL;
static long curr_lineno = 1;
static const char *currfile = NULL;
static const char *inputfile = NULL;
X
static void putf(char *fmt, ...)
{
X va_list ap;
X char buf[1024];
X
X va_start(ap, fmt);
X vsprintf(buf, fmt, ap);
X va_end(ap);
X int nl = 0;
X for (char *s = buf; *s != '\0'; s++)
X if (*s == '\n')
X nl++;
X curr_lineno += nl;
X fputs(buf, fp);
}
X
inline static void put(int ch)
{
X putc(ch, fp);
X if (ch == '\n')
X curr_lineno++;
}
X
X
static boolean saveret = FALSE;
static char *mkretcode(symbol *s)
{
X s = NULL;
X return saveret ? "_rc = " : "(void)";
}
X
static const char *mkname(symbol *sym)
{
X if (*sym->name != '"')
X return sym->name;
X if (*sym->name == '\'' && sym->type == TERMINAL)
X return sym->name;
X return strbldf("_S%d/*%s*/", sym->id, sym->name);
}
X
static const char *mkerrname(symbol *sym)
{
X if (sym->type == NONTERMINAL && sym->realname != NULL)
X return sym->realname;
X return mkname(sym);
}
X
X
static void printset(const char *name, Bitset &set)
{
X Bitsetiter si(set);
X symbol *s;
X int id;
X char *pre = "";
X
X putf("static %s[] = { ", name);
X while ((id = si()) >= 0)
X {
X if (id == EMPTY)
X putf("%s_EMPTY", pre);
X // continue;
X else if (id == END)
X putf("%sEOI", pre);
X else
X {
X s = getsymbol(id);
X putf("%s%s", pre, mkname(s));
X }
X pre = ", ";
X }
X putf("%s-1 };\n", pre);
}
X
static void printcase(char *pre, Bitset &set)
{
X Bitsetiter si(set);
X symbol *s;
X int id;
X
X while ((id = si()) >= 0)
X {
X if (id == EMPTY)
X continue;
X
X putf("%scase ", pre);
X if (id == END)
X putf("EOI");
X else
X {
X s = getsymbol(id);
X putf("%s", mkname(s));
X }
X putf(":\n");
X }
}
X
inline static boolean dotype(symbol *sym)
{
X if ((sym->usedret & RET_VALUE) || sym->rettype != NULL)
X return TRUE;
X else
X return FALSE;
}
X
static const char *mktype(symbol *sym, char *pre = "", char *post = NULL)
{
X if (!dotype(sym))
X return "";
X char *name;
X if (sym->rettype == NULL)
X name = "int";
X else
X {
X name = sym->rettype;
X if (sym->mkstruct)
X {
X if (sym->realname != NULL && sym->realname != sym->name
X && sym->rettype == findsymbol(sym->realname)->rettype)
X return strbldf("%s_T%s%s", pre, sym->realname, post);
X return strbldf("%s_T%s%s", pre, sym->name, post);
X }
X }
X return strbldf("%s%s%s", pre, name, post);
}
X
static const char *mkvoidtype(symbol *sym, char *pre = "", char *post = NULL)
{
X const char *type = mktype(sym, pre, post);
X if (*type == '\0')
X type = "void";
X return type;
}
X
static void mkstruct(symbol *sym)
{
X if (!dotype(sym) || !sym->mkstruct)
X return;
X char *name = sym->name;
X if (sym->realname != NULL && sym->realname != sym->name)
X {
X symbol *real = findsymbol(sym->realname);
X if (real->rettype == sym->rettype)
X {
X if (dotype(real))
X return;
X name = sym->realname;
X }
X }
X putf("\nstruct _T%s\n{\n", name);
X putf("\t%s;\n};\n", sym->rettype);
}
X
static void mkcode(char *pre, symbol *code)
{
X if (code == NULL || code->code == NULL)
X return;
X
X if (genlineinfo)
X putf("#line %d \"%s\"\n", code->line, inputfile);
X else
X putf("/* #line %d */\n", code->line);
X putf("%s%s;\n", pre, code->code);
X if (genlineinfo)
X putf("#line %d \"%s\"\n", curr_lineno + 1, currfile);
}
X
static const char *mkvarname(symnode *start, symnode *node)
{
X if (node->alias != NULL)
X return node->alias;
X
X int count = 0;
X boolean addnum = FALSE;
X char *name = node->sym->name;
X
X if (node->sym->realname != NULL && node->sym->name != node->sym->realname)
X {
X name = "_";
X for (symnode *n = start; n != node; n = n->next)
X if (n->sym->type == NONTERMINAL && n->sym->realname != NULL
X && n->sym->name != n->sym->realname)
X count++;
X for (n = n->next; n != NULL; n = n->next)
X if (n->sym->type == NONTERMINAL && n->sym->realname != NULL
X && n->sym->name != n->sym->realname)
X addnum = TRUE;
X }
X else
X {
X for (symnode *n = start; n != node; n = n->next)
X if (n->sym == node->sym)
X count++;
X for (n = n->next; n != NULL; n = n->next)
X if (n->sym == node->sym)
X addnum = TRUE;
X }
X if (addnum || count > 0)
X return strbldf("%s%d", name, count + 1);
X return name;
}
X
X
static void genstmt(char *pre, symnode *node)
{
X symbol *s;
X symnode *n;
X
X for (n = node; n != NULL; n = n->next)
X {
X if (n->sym->type != NONTERMINAL || n->sym->id == EMPTY
X || !dotype(n->sym))
X continue;
X putf("%s%s _rv%s;\n", pre, mktype(n->sym), mkvarname(node, n));
X }
X
X for (n = node; n != NULL; n = n->next)
X {
X s = n->sym;
X if (s->type == CODE)
X {
X if (dumpcode)
X mkcode(pre, s);
X continue;
X }
X if (s->id == EMPTY)
X continue;
X
X if (s->type == TERMINAL)
X putf("%s%sscantoken(%s, _link, _resync%d);\n",
X pre, mkretcode(s), mkname(s), n->resync->id);
X else if (optimize && s->usecount == 1 && !s->export)
X {
X symbol *sym = s;
X symnode *nn = n;
X Bitset set(numsymbols());
X
X putf("%s{\n", pre);
X if (dotype(s))
X putf("%s = _rv%s;\n", mktype(sym, pre, " &_rr"),
X mkvarname(node, nn));
X else
X putf("%s\n", mktype(sym, pre, " _rr;"));
X putf("%sresynclink &_lnk = _link;\n", pre);
X putf("%sresynclink _link(_lnk, _resync%d);\n\n",
X pre, nn->resync->id);
X
X if (sym->resync != NULL)
X putf("%s (void)scantoken(-1, _link, _resync%d);\n\n",
X pre, sym->resync->id);
X
X if (sym->node != NULL && sym->node->or == NULL)
X {
X genstmt("\t\t\t", sym->node);
X putf("\n%s}\n\n", pre);
X // putf("\n%sreturn RETOK;\n}\n\n", pre);
X continue;
X }
X
X boolean donedefault = FALSE;
X putf("%sswitch (w_nexttoken())\n\t{\n", pre);
X for (symnode *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("%s\tdefault:\n", pre);
X genstmt("\t\t", n);
X if (!sym->first->isin(EMPTY))
X putf("%s\t\tw_scanerr(\"illegal %s\");\n",
X pre, 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("%s\tdefault:\n", pre);
X putf("%s\t\tw_scanerr(\"illegal %s\");\n",
X pre, mkerrname(sym));
X }
X putf("%s}", pre);
X putf(" }\n");
X }
X else if (dotype(s))
X putf("%s%s_f%s(_link, _resync%d, _rv%s);\n",
X pre, mkretcode(s), mkname(s),
X n->resync->id, mkvarname(node, n));
X else
X putf("%s%s_f%s(_link, _resync%d);\n",
X pre, mkretcode(s), mkname(s), n->resync->id);
X // putf(" }\n");
X }
}
X
X
static void genheader(void)
{
X symbol *sym;
X int i;
X
X putf("#ifndef _T_O_K_E_N_S_\n#define _T_O_K_E_N_S_\n\n");
X
X putf("#ifndef NULL\n#include <stdio.h>\n#endif\n\n");
X putf("#define RETOK 1\n");
X putf("#define RETERR 0\n\n");
X
X putf("enum tokenids\n{\n");
X putf("\tEOI = 0,\n");
X putf("\t_EMPTY = 256, /* nothing uses this yet */\n");
X boolean doid = TRUE;
X for (i = START; i < numsymbols(); i++)
X {
X sym = getsymbol(i);
X if (sym->type != TERMINAL || *sym->name == '\'')
X continue;
X if (doid)
X putf("\t%s = 257,\n", mkname(sym));
X else
X putf("\t%s,\n", mkname(sym));
X doid = FALSE;
X }
X putf("};\n\n");
X
X if (gotlexstr)
X {
X putf("#ifdef __cplusplus\n");
X putf("extern \"C\" {\n");
X putf("extern int yylex(void);\n");
X putf("}\n");
X putf("#else\n");
X putf("extern int yylex();\n");
X putf("#endif\n\n");
X
X putf("#ifdef FLEX_SCANNER\n");
X putf("# undef YY_INPUT\n");
X putf("# define YY_INPUT(buf,result,max_size) \\\n");
X putf(" result = (buf[0] = w_input()) == EOI ? YY_NULL : 1;\n");
X putf("#else\n");
X putf("# undef input\n");
X putf("# define input w_input\n");
X putf("# undef unput\n");
X putf("# define unput w_unput\n");
X putf("#endif\n\n");
X
X }
X
X putf("extern int w_numerrors;\n");
X putf("#ifdef __cplusplus\n");
X putf("extern \"C\" {\n");
X putf("extern int w_scanerr(const char *, ...);\n");
X putf("extern void w_flusherrs(void);\n");
X putf("extern void w_closefile(void);\n");
X putf("extern int w_openfile(char *);\n");
X putf("extern FILE *w_getfile(void);\n");
X putf("extern void w_setfile(FILE *);\n");
X putf("extern int w_currcol(void);\n");
X putf("extern int w_currline(void);\n");
X putf("extern char *w_getcurrline(void);\n");
X putf("extern int w_input(void);\n");
X putf("extern int w_unput(int);\n");
X putf("extern void w_output(int);\n");
X putf("extern int w_gettoken(void);\n");
X putf("extern int w_nexttoken(void);\n");
X putf("extern void w_skiptoken(void);\n");
X putf("extern char *w_tokenname(int);\n");
X putf("}\n");
X putf("#else\n");
X putf("extern int w_scanerr();\n");
X putf("extern void w_flusherrs();\n");
X putf("extern void w_closefile();\n");
X putf("extern int w_openfile();\n");
X putf("extern FILE *w_getfile();\n");
X putf("extern void w_setfile();\n");
X putf("extern int w_currcol();\n");
X putf("extern int w_currline();\n");
X putf("extern char *w_getcurrline();\n");
X putf("extern int w_input();\n");
X putf("extern int w_unput();\n");
X putf("extern void w_output();\n");
X putf("extern int w_gettoken();\n");
X putf("extern int w_nexttoken();\n");
X putf("extern void w_skiptoken();\n");
X putf("extern char *w_tokenname();\n");
X putf("#endif\n\n");
X
X if (exportedname)
X {
X for (i = 0; i < numnonterms(); i++)
X {
X sym = getnonterm(i);
X if (sym->type != NONTERMINAL || !sym->export)
X continue;
X mkstruct(sym);
X putf("#ifdef __cplusplus\n");
X putf("extern \"C\" { int %s(%s); }\n", mkname(sym),
X mkvoidtype(sym, "", " &"));
X putf("#else\n");
X putf("extern int %s();\n", mkname(sym));
X putf("#endif\n");
X }
X }
X else
X {
X mkstruct(startsymbol);
X putf("#ifdef __cplusplus\n");
X putf("extern \"C\" { int %s(%s); }\n", mkname(startsymbol),
X mkvoidtype(startsymbol, "", " &"));
X putf("#else\n");
X putf("extern int %s();\n", mkname(startsymbol));
X putf("#endif\n");
X }
X
X putf("\n\n#endif /* _T_O_K_E_N_S_ */\n");
}
X
X
static void genscanner(char *header)
{
X symbol *sym;
X int i, c;
X boolean nl = TRUE;
X
X // scan past the definition section
X while ((c = w_input()) != END)
X {
X if (nl && c == '%')
X {
X int t = w_input();
X if (t == '%')
X break;
X put(c);
X c = t;
X }
X put(c);
X nl = c == '\n';
X }
X
X // dump out our header stuff here
X putf("%%{\n");
X putf("#include \"%s\"\n", header);
X putf("%%}\n");
X
X putf("%%%%\n");
X
X // print the lexical values from the grammer
X for (i = START; i < numsymbols(); i++)
X {
X symbol *sym = getsymbol(i);
X if (sym->type != TERMINAL || sym->lexdef || sym->lexstr == NULL)
X continue;
X if (casesensitive || sym->name[0] != '"')
X putf("%s", sym->lexstr);
X else
X {
X for (char *s = sym->lexstr + 1;
X *s != '\0' && !(*s == '"' && *(s + 1) == '\0');
X s++)
X if (isalpha(*s))
X putf("[%c%c]",
X islower(*s) ? toupper(*s) : *s,
X isupper(*s) ? tolower(*s) : *s);
X else if (*s == '\\' && *(s+1) == '"')
X ;
X else
X putf("\\%c", *s);
X }
X putf("\t{ return (int)%s; }\n", mkname(sym));
X sym->lexdef = TRUE;
X }
X
X // now add the rules at the bottom of the source
X if (c != END)
X while ((c = w_input()) != END)
X {
X if (nl && c == '%')
X {
X int t = w_input();
X if (t == '%')
X break;
X put(c);
X c = t;
X }
X else if (nl && c == '$')
X {
X char *name = getword();
X if (name == NULL)
X quit("Unexpected end-of-w_input");
X sym = findsymbol(name);
X
X if (sym == NULL)
X error("Symbol %s not in grammer", name);
X if (sym->lexstr != NULL)
X error("Symbol %s lexical string redefined in lex section",
X name);
X
X while ((c = w_input()) == ' ' || c == '\t')
X ;
X if (c == '\n' || c == END)
X putf("\n");
X else
X {
X for (; c != END && c != '\n'; c = w_input())
X put(c);
X putf("\t{ return (int)%s; }", name);
X }
X sym->lexdef = TRUE;
X }
X put(c);
X nl = c == '\n';
X }
X
X // check for missing tokens
X for (i = START; i < numsymbols(); i++)
X {
X sym = getsymbol(i);
X if (sym->type != TERMINAL || sym->lexdef)
X continue;
X if (sym->lexstr == NULL)
X error("Lexical value for symbol %s is not defined", mkname(sym));
X }
X
X putf("%%%%\n");
X
X // now copy the rest (user code)
X if (c != END)
X while ((c = w_input()) != END)
X put(c);
}
X
X
static void dumpexport(symbol *sym)
{
X putf("int %s(%s)\n{\n", mkname(sym),
X mkvoidtype(sym, "", " &ret"));
X putf("\tresynclink _link;\n\t");
X printset("_follow", *sym->follow);
X putf("\tint _rval;\n");
X putf("\tint _savnum = w_numerrors;\n\n");
X putf("\tw_numerrors = 0;\n");
X putf("\t_rval = _f%s(_link, _follow%s);\n",
X mkname(sym), dotype(sym) ? ", ret" : "");
X putf("\tswitch (w_nexttoken())\n\t{\n");
X printcase("\t", *sym->follow);
X putf("\t\tbreak;\n");
X putf("\tdefault:\n");
X putf("\t\t_rval = w_scanerr(\"expected end of %s\");\n",
X mkname(sym));
X putf("\t}\n");
X putf("\tif (w_numerrors > 0) _rval = RETERR;\n");
X putf("\tw_numerrors += _savnum;\n");
X putf("\tw_scanerr(NULL);\n");
X putf("\treturn _rval;\n");
X putf("}\n\n");
}
X
X
static void genparser(char *header)
{
X symbol *sym;
X symnode *n;
X int i;
X
X putf("#define YYTEXT_DECL unsigned char yytext[]\n\n");
X mkcode("", startcode);
X putf("\n#include \"%s\"\n\n", header);
X putf("extern YYTEXT_DECL;\n");
X putf("int w_numerrors = 0;\n\n");
X
X putf("\nstruct resynclink\n{\n\tresynclink *prev;\n");
X putf("\tint *resync;\n");
X putf("\tresynclink() { prev = 0; resync = 0; }\n");
X putf("\tresynclink(resynclink &p, int *s)");
X putf(" { prev = &p; resync = s; }\n");
X putf("};\n");
X
X for (i = 0; i < numnonterms(); i++)
X {
X sym = getnonterm(i);
X if (sym->type != NONTERMINAL)
X continue;
X if (!sym->export)
X mkstruct(sym);
X if (optimize && sym->usecount == 1 && !sym->export)
X continue;
X putf("static _f%s(resynclink &, int *%s);\n", mkname(sym),
X mktype(sym, ", ", " &"));
X }
X putf("\n");
X
X putf("static char *_toknams[] =\n{\n");
X putf("\t\"[]\",\n");
X for (i = START; i < numsymbols(); i++)
X {
X sym = getsymbol(i);
X if (sym->type != TERMINAL || *sym->name == '\'')
X continue;
X char *str = sym->lexstr;
X
X if (str == NULL)
X putf("\t\"%s\",\n", mkname(sym));
X else if (isalpha(*str))
X putf("\t\"%s\",\n", str);
X else if (*str == '"' && str[strlen(str) - 1] == '"')
X putf("\t%s,\n", sym->lexstr);
X else
X putf("\t\"%s\",\n", mkname(sym));
X }
X putf("};\n\n");
X
X putf("char *w_tokenname(int tok)\n{\n");
X putf("\tstatic char buf[6];\n\n");
X putf("\tif (tok > 255)\n");
X putf("\t\treturn _toknams[tok - 256];\n");
X putf("\tif (tok == 0)\n");
X putf("\t\treturn \"EOI\";\n");
X putf("\tbuf[0] = '`'; buf[1] = tok; buf[2] = '\\\'';\n");
X putf("\treturn buf;\n");
X putf("}\n\n");
X
X putf("static int tok = -1;\n\n");
X
X putf("int w_nexttoken()\n");
X putf("{\n\tif (tok < 0)\n\t\ttok = w_gettoken();\n");
X putf("\treturn tok;\n}\n\n");
X
X putf("void w_skiptoken()\n{\n\ttok = -1;\n}\n\n");
X
X putf("static int scantoken(int expect, resynclink &lnk, int *resync)\n");
X putf("{\n\tresynclink rlink(lnk, resync);\n\tresynclink *link;\n\n");
X putf("\tif (tok < 0)\n\t\ttok = w_gettoken();\n");
X putf("\tif (expect >= 0 && tok != expect)\n");
X putf("\t\tw_scanerr(\"expected %%s\", w_tokenname(expect));\n");
X putf("\tint level = 1;\n");
X putf("\twhile (tok != expect)\n\t{\n");
X putf("\t\tint l = level;\n");
X putf("\t\tfor (link = &rlink; link != NULL && l-- > 0;");
X putf(" link = link->prev)\n");
X putf("\t\t\tfor (int i = 0; link->resync[i] >= 0; i++)\n");
X putf("\t\t\t\tif (tok == link->resync[i])\n");
X putf("\t\t\t\t\treturn -1;\n\n");
X putf("\t\tw_scanerr(NULL);\n");
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
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"
fi
# ============= io.C ==============
if test -f 'io.C' -a X"$1" != X"-c"; then
echo 'x - skipping io.C (File already exists)'
else
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"
fi
# ============= version.C ==============
if test -f 'version.C' -a X"$1" != X"-c"; then
echo 'x - skipping version.C (File already exists)'
else
echo 'x - extracting version.C (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'version.C' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
X
static char *const whatid = "@(#)wacco 1.1 (17 May 1991)";
SHAR_EOF
chmod 0444 version.C ||
echo 'restore of version.C failed'
Wc_c="`wc -c < 'version.C'`"
test 120 -eq "$Wc_c" ||
echo 'version.C: original size 120, current size' "$Wc_c"
fi
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