P8000/WEGA/contrib/ingres/dbs/src/yyyacc/y2.c

718 lines
12 KiB
C

# include <stdio.h>
# include "../conf/gen.h"
# include "y.h"
extern FILE *Fout, *Fin;
extern FILE *copen();
# define IDENTIFIER 257
# define MARK 258
# define TERM 259
# define LEFT 260
# define BINARY 261
# define RIGHT 262
# define PREC 263
# define LCURLY 264
# define C_IDENTIFIER 265 /* name followed by colon */
# define NUMBER 266
# ifdef ESER_PSU
# define DEV_NULL "/NULLFILE"
# else
# define DEV_NULL "/dev/null"
# endif
setup(argc, argv)
register int argc;
register char **argv;
{
register int i;
register int j;
register int lev;
register int t;
register int c;
Foutput = (FILE *) 0;
i = 1;
while (argc >= 2 && argv[1][0] == '-')
{
while (*++(argv[1]))
{
switch(*argv[1])
{
case 'v':
case 'V':
Foutput = copen("y.output", "w");
continue;
case 's':
case 'S':
sflag = 1;
continue;
default:
error("illegal option: %c", *argv[1]);
}
}
argv++;
argc--;
}
if (Foutput == (FILE *) 0)
Foutput = copen(DEV_NULL, "w");
ftable = copen("y.tab.c", "w");
if (argc > 1)
cin = copen(argv[1], "r");
settab();
fprintf(Fout, "#\n");
ctokn = "$end";
defin(0); /* eof */
extval = 0400; /* beginning of assigned values */
ctokn = "error";
defin(0);
ctokn = "$accept";
defin(1);
mem = mem0;
cnamp = cnames;
lev = 0;
i = 0;
while (t = gettok())
{
switch(t)
{
case IDENTIFIER:
j = chFind(0);
trmlev[j] = lev;
continue;
case ',':
case ';':
continue;
case TERM:
lev = 0;
continue;
case LEFT:
lev = (++i << 3) | 01;
continue;
case BINARY:
lev = (++i << 3) | 02;
continue;
case RIGHT:
lev = (++i << 3) | 03;
continue;
case MARK:
deFout();
fprintf(Fout, "# define\tyyclearin\t\t(yychar = -1)\n");
fprintf(Fout, "# define\tyyerrok\t\t\t(yyerrflag = 0)\n");
fprintf(Fout, "extern int\tyychar;\n");
fprintf(Fout, "extern int\tyyerrflag;\n");
fprintf(Fout, "\nchar\t\t*yyval = (char *) 0;\n");
fprintf(Fout, "char\t\t**yypv;\n");
fprintf(Fout, "char\t\t*yylval = (char *) 0;\n");
fprintf(Fout, "\nyyactr(__np__)\n");
fprintf(Fout, "register int\t__np__;\n");
fprintf(Fout, "{\n");
break;
case LCURLY:
deFout();
cpycode();
continue;
case NUMBER:
trmset[j].value = numbval;
if (j < ndeFout && j > 2)
error("please define type # of %s earlier", trmset[j].name);
continue;
default:
error("bad precedence syntax, input %d", t);
}
break;
}
prdptr[0] = mem;
/* added production */
*mem++ = NTBASE;
*mem++ = NTBASE+1;
*mem++ = 1;
*mem++ = 0;
prdptr[1] = mem;
i = 0;
/* i is 0 when a rule can begin, 1 otherwise */
for ( ; ; )
{
switch(t = gettok())
{
case C_IDENTIFIER:
if (mem == prdptr[1]) /* first time */
fprintf(Fout, "switch(__np__){\n");
if (i != 0)
error("previous rule not terminated");
*mem = chFind(1);
if (*mem < NTBASE)
error("token illegal on lhs of grammar rule");
i = 1;
++mem;
continue;
case IDENTIFIER:
*mem = chFind(1);
if (*mem < NTBASE)
levprd[nprod] = trmlev[*mem];
mem++;
if (i == 0)
error("missing :");
continue;
case '=':
levprd[nprod] |= 04;
if (i == 0)
error("semicolon preceeds action");
fprintf(Fout, "\n case %d:", nprod);
cpyact();
fprintf(Fout, " break;");
case '|':
case ';':
if (i)
{
*mem++ = -nprod;
prdptr[++nprod] = mem;
levprd[nprod] = 0;
i = 0;
}
if (t == '|')
{
i = 1;
*mem++ = *prdptr[nprod - 1];
}
continue;
case 0: /* End Of File */
case MARK:
if (i != 0)
error("rule not terminated before %%%% or EOF");
settab();
Finact();
/* copy the programs which follow the rules */
if (t == MARK)
while ((c = getc(Fin)) > 0)
putc(c, Fout);
return;
case PREC:
if (i == 0)
error("%%prec must appear inside rule");
if (gettok() != IDENTIFIER)
error("illegal %%prec syntax");
j = chFind(2);
if (j >= NTBASE)
error("nonterminal %s illegal after %%prec",
nontrst[j - NTBASE].name);
levprd[nprod] = trmlev[j];
continue;
case LCURLY:
if (i != 0)
error("%%{ appears within a rule");
cpycode();
continue;
default:
error("syntax error, input %d", t );
}
}
}
Finact()
{
/* Finish action routine */
/* ------- The next line is an DBS customization ------- */
fprintf(Fout, "\n}\nreturn (0);\n}\n");
fprintf(Fout, "int\t\tyyerrval = %d;\n", trmset[2].value);
}
defin(t)
register int t;
{
/* define ctokn to be a terminal if t = 0
or a nonterminal if t = 1 */
if (t)
{
if (++nnonter >= ntlim)
error("too many nonterminals, limit %d", ntlim);
nontrst[nnonter].name = ctokn;
return (NTBASE + nnonter);
}
else
{
if (++nterms >= tlim)
error("too many terminals, limit %d", tlim);
trmset[nterms].name = ctokn;
if (ctokn[0] == ' ' && ctokn[2]=='\0') /* single character literal */
trmset[nterms].value = ctokn[1];
else if (ctokn[0] == ' ' && ctokn[1]=='\\')
{ /* escape sequence */
if (ctokn[3] == '\0')
{ /* single character escape sequence */
switch (ctokn[2])
{
/* character which is escaped */
case 'n':
trmset[nterms].value = '\n';
break;
case 'r':
trmset[nterms].value = '\r';
break;
case 'b':
trmset[nterms].value = '\b';
break;
case 't':
trmset[nterms].value = '\t';
break;
case '\'':
trmset[nterms].value = '\'';
break;
case '"':
trmset[nterms].value = '"';
break;
case '\\':
trmset[nterms].value = '\\';
break;
default:
error("invalid escape");
}
}
else if (ctokn[2] <= '7' && ctokn[2] >= '0')
{ /* \nnn sequence */
if (ctokn[3] < '0' || ctokn[3] > '7' || ctokn[4] < '0' ||
ctokn[4] > '7' || ctokn[5] != '\0')
error("illegal \\nnn construction");
trmset[nterms].value = 64 * (ctokn[2] - '0') + 8 * (ctokn[3] - '0') + ctokn[4] - '0';
if (trmset[nterms].value == 0)
error("'\\000' is illegal");
}
}
else
trmset[nterms].value = extval++;
trmlev[nterms] = 0;
return (nterms);
}
}
deFout()
{
/* write out the defines (at the end of the declaration section) */
register int i;
register int c;
register char *cp;
for (i = ndeFout; i <= nterms; ++i)
{
cp = trmset[i].name;
if (*cp == ' ')
++cp; /* literals */
for ( ; (c= *cp) != '\0'; ++cp)
{
if (c >= 'a' && c <= 'z' ||
c >= 'A' && c <= 'Z' ||
c >= '0' && c <= '9' ||
c == '_')
; /* VOID */
else
goto nodef;
}
/* define it */
fprintf(Fout, "# define\t%-20s\t%d\n", trmset[i].name, trmset[i].value);
nodef:
;
}
ndeFout = nterms + 1;
}
chstash(c)
register int c;
{
/* put character away into cnames */
if (cnamp >= &cnames[cnamsz])
error("too many characters in id's and literals");
else
*cnamp++ = c;
}
gettok()
{
register int base;
register int c;
register int match;
register int reserve;
static int peekline; /* number of '\n' seen in lookahead */
begin:
reserve = 0;
if (peekc >= 0)
{
c = peekc;
lineno += peekline;
peekc = -1;
peekline = 0;
}
else
c = getc(Fin);
while (c == ' ' || c=='\n' || c=='\t')
{
if (c == '\n')
++lineno;
c = getc(Fin);
}
if (c == '/')
{
if (getc(Fin) != '*')
error("illegal /");
c = getc(Fin);
while (c)
{
if (c == '\n')
++lineno;
if (c == '*')
{
if ((c = getc(Fin)) == '/')
break;
}
else
c = getc(Fin);
}
if (!c)
return (0);
goto begin;
}
switch(c)
{
case '"':
case '\'':
match = c;
ctokn = cnamp;
chstash(' ');
while (1)
{
c = getc(Fin);
if (c == '\n' || c == '\0')
error("illegal or missing ' or \"");
if (c == '\\')
{
c = getc(Fin);
chstash('\\');
}
else if (c == match)
break;
chstash(c);
}
break;
case '%':
case '\\':
switch(c = getc(Fin))
{
case '0':
return (TERM);
case '<':
return (LEFT);
case '2':
return (BINARY);
case '>':
return (RIGHT);
case '%':
case '\\':
return (MARK);
case '=':
return (PREC);
case '{':
return (LCURLY);
default:
reserve = 1;
}
default:
if (c >= '0' && c <= '9')
{ /* number */
numbval = c - '0' ;
base = (c == '0')? 8: 10;
for (c = getc(Fin); c >= '0' && c <= '9'; c = getc(Fin))
numbval = numbval * base + c - '0';
peekc = c;
return (NUMBER);
}
else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == '.' || c == '$')
{
ctokn = cnamp;
while ( (c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') ||
c == '_' || c =='.' || c =='$')
{
chstash(c);
if (peekc >= 0)
{
c = peekc;
peekc = -1;
}
else
c = getc(Fin);
}
}
else
return (c);
peekc = c;
}
chstash('\0');
if (reserve)
{ /* Find a reserved word */
if (compare("term"))
return (TERM);
if (compare("TERM"))
return (TERM);
if (compare("token"))
return (TERM);
if (compare("TOKEN"))
return (TERM);
if (compare("left"))
return (LEFT);
if (compare("LEFT"))
return (LEFT);
if (compare("nonassoc"))
return (BINARY);
if (compare("NONASSOC"))
return (BINARY);
if (compare("binary"))
return (BINARY);
if (compare("BINARY"))
return (BINARY);
if (compare("right"))
return (RIGHT);
if (compare("RIGHT"))
return (RIGHT);
if (compare("prec"))
return (PREC);
if (compare("PREC"))
return (PREC);
error("invalid escape, or illegal reserved word: %s", ctokn);
}
/* look ahead to distinguish IDENTIFIER from C_IDENTIFIER */
while (peekc == ' ' || peekc=='\t' || peekc == '\n')
{
if (peekc == '\n')
++peekline;
peekc = getc(Fin);
}
if (peekc != ':')
return (IDENTIFIER);
peekc = -1;
lineno += peekline;
peekline = 0;
return (C_IDENTIFIER);
}
chFind(t)
register int t;
{
register int i;
if (ctokn[0] == ' ')
t = 0;
for (i = 1; i <= nterms; i++)
if (compare(trmset[i].name))
{
cnamp = ctokn;
return (i);
}
for (i = 1; i <= nnonter; i++)
if (compare(nontrst[i].name))
{
cnamp = ctokn;
return (i + NTBASE);
}
/* cannot Find name */
if (t > 1 && ctokn[0] != ' ')
error("%s should have been defined earlier", ctokn);
return (defin(t));
}
cpycode()
{
/* copies code between \{ and \} */
register int c;
c = getc(Fin);
if (c == '\n')
{
c = getc(Fin);
lineno++;
}
while (c)
{
if (c == '\\')
if ((c = getc(Fin)) == '}')
return;
else
putc('\\', Fout);
if (c == '%')
if ((c = getc(Fin)) == '}')
return;
else
putc('%', Fout);
putc(c, Fout);
if (c == '\n')
++lineno;
c = getc(Fin);
}
error("eof before %%}");
}
cpyact()
{
/* copy C action to the next ; or closing } */
register int brac;
register int c;
register int match;
register int j;
register int s;
brac = 0;
loop:
c = getc(Fin);
swt:
switch(c)
{
case ';':
if (brac == 0)
{
putc(c, Fout);
return;
}
goto lcopy;
case '{':
brac++;
goto lcopy;
case '$':
s = 1;
c = getc(Fin);
if (c == '$')
{
fprintf(Fout, "yyval");
goto loop;
}
if (c == '-')
{
s = -s;
c = getc(Fin);
}
if (c >= '0' && c <= '9')
{
j = 0;
while (c >= '0' && c <= '9')
{
j = j * 10 + c - '0';
c = getc(Fin);
}
fprintf(Fout, "yypv[%d]", s * j);
goto swt;
}
putc('$', Fout);
if (s < 0)
putc('-', Fout);
goto swt;
case '}':
brac--;
if (brac == 0)
{
putc(c, Fout);
return;
}
goto lcopy;
case '/': /* look for comments */
putc(c, Fout);
c = getc(Fin);
if (c != '*') goto swt;
/* it really is a comment */
putc(c, Fout);
while ((c = getc(Fin)) > 0)
{
if (c == '*')
{
putc(c, Fout);
if ((c = getc(Fin)) == '/')
goto lcopy;
}
putc(c, Fout);
}
error("EOF inside comment");
case '\'': /* character constant */
match = '\'';
goto string;
case '"': /* character string */
match = '"';
string:
putc(c, Fout);
while ((c = getc(Fin)) > 0)
{
if (c == '\\')
{
putc(c, Fout);
c = getc(Fin);
}
else if (c == match)
goto lcopy;
putc(c, Fout);
}
error("EOF in string or character constant");
case '\0':
error("action does not terminate");
case '\n':
++lineno;
goto lcopy;
}
lcopy:
putc(c, Fout);
goto loop;
}