|
|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 5415 (0x1527)
Types: TextFile
Notes: UNIX file
Names: »lex3.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦f4b8d8c84⟧ UNIX Filesystem
└─⟦this⟧ »cmd/lex/lex3.c«
/*
* lex3.c
* output and table generating routines
*/
#include "lex.h"
/* VARARGS */
output(s)
char *s;
{
fprintf (fileout, "%r", &s);
}
/* VARARGS 2 */
loutput(i, s)
char *s;
{
while (i--)
putc('\t', fileout);
fprintf (fileout, "%r\n", &s);
}
/*
* estimate the size of the working space
* the generated automata would require, worst case.
* this is non-optimum, but fast.
* optimum could be a thousand times slower to save a few bytes
*/
ltable()
{
register c, i, l;
register lookflag;
l = 0;
i = 0;
lookflag = 0;
while (i < nxt) {
c = 0;
do {
switch(nfa[i][0]) {
case LX_LINK:
case LX_JUMP:
c += mark(nfa[i][1]);
case LX_BLIN:
case LX_ELIN:
case LX_SCON:
if (nfa[i][0] != LX_JUMP)
c += mark(i+1);
++c;
nfa[i][0] = -nfa[i][0];
break;
case LX_LOOK:
case -LX_LOOK:
lookflag = 1;
if (c > l)
l = c;
c = mark(i+1);
break;
case LX_STOP:
if (nfa[i][1])
nfa[i][1] = 0;
else
++c;
}
} while (nfa[i++][0] != LX_STOP);
if (c > l)
l = c;
}
++l;
for (i=0; i<nxt; ++i)
if (nfa[i][0] < 0)
nfa[i][0] = -nfa[i][0];
loutput(0, "int *yy_clist[0%o];", l);
loutput(0, "int *yy_nlist[0%o];", l);
if (lookflag == 0)
return;
loutput(0, "int *yy_llist[0%o];", l);
}
/*
* used by ltable, mark a state as counted
*/
mark(state)
{
switch (nfa[state][0]) {
case LX_STOP:
if (nfa[state][1]++)
break;
case LX_LOOK:
case LX_ACPT:
case LX_CHAR:
case LX_CLAS:
case LX_ANYC:
nfa[state][0] = -nfa[state][0];
return (1);
}
return (0);
}
stats()
{
fprintf(stderr, "rules: %d\tstates: %d\tclasses: %d\n",
actn, nxt, clas);
}
/*
* put out #defines for start conditions
*/
sdefns()
{
register struct def *pd;
pd = scnstart;
while ((pd=pd->d_next) != NULL)
loutput(0, "#define\t%s\t\t0%o", pd->d_name, pd->d_data);
}
/*
* put out #defines for contexts
*/
xdefns()
{
register struct def *pd;
register i = 0;
for (pd=ctxstart; pd!=NULL; pd=pd->d_next)
++i;
loutput(0, "#define\tyyswitch(x)\tyyctxt((x),(0%o))", i);
i = 0;
pd = ctxstart;
while ((pd=pd->d_next) != NULL)
loutput(0, "#define\t%s\t\t0%o", pd->d_name, ++i);
}
/*
* table of nfa starting locations for contexts
*/
xtable()
{
register struct def *pd;
loutput(0, "int yy_ctxtab[] = {");
output("00");
pd = ctxstart;
while ((pd=pd->d_next) != NULL)
output(",0%o", pd->d_data);
output("\n");
loutput(0, "};");
}
/*
* character class tables, here we convert the vertical
* class storage to horizontal to save space
*/
btable()
{
register unsigned char *index;
register bit;
register b, n, i, t;
if (classptr == NULL)
return;
b = 1;
loutput(0, "int yy_lxctab[] = {");
for (n=0; n<clas; ++n) {
index = classptr + classindex(n);
bit = classbit(n);
t = 0;
i = 0;
while (i <= MAXUCHAR) {
if (index[i]&bit)
t |= b;
if ((b<<=1) == 0) {
output("0%o", t);
if (n+1<clas || i<MAXUCHAR)
output(",");
if (++i%(8*NBINT) == 0)
output("\n");
b = 1;
t = 0;
} else
++i;
}
}
loutput(0, "};");
/*
* output the bit selector table
*/
loutput(0, "int yy_lxbtab[] = {");
i = 0;
while (i < NBINT) {
output("01<<0%02o", i);
if (++i < NBINT)
output(",");
if (i%(NBINT/2) == 0)
output("\n");
}
loutput(0, "};");
}
/*
* output the actual automata table
* each state is packed into an int with the low four bits
* being the opcode, the high twelve being the data
*/
ptable()
{
register i,s;
loutput(0, "int yy_lextab[] = {");
for (s=0,i=0; i<nxt; ++s,++i) {
if (i)
output(",");
if (s && s%8 == 0)
output("\n");
output("0%o", nfa[i][0] | (nfa[i][1]<<LR_SHFT));
}
output("\n");
loutput(0, "};");
}
/*
* put a human readable form of the automaton onto stderr
* undocumented, but useful for debugging and sort of interesting
*/
printnfa()
{
register i;
for (i=0; i<nxt; ++i) {
fprintf(stderr, "%d:\t", i);
switch (nfa[i][0]) {
case LX_STOP:
fprintf(stderr, "stop");
break;
case LX_LINK:
fprintf(stderr, "link ");
if (nfa[i][1] > 0)
putc('+', stderr);
fprintf(stderr, "%d", nfa[i][1]);
break;
case LX_JUMP:
fprintf(stderr, "jump ");
if (nfa[i][1] > 0)
putc('+', stderr);
fprintf(stderr, "%d", nfa[i][1]);
break;
case LX_LOOK:
fprintf(stderr, "look");
break;
case LX_ACPT:
fprintf(stderr, "acpt %d", nfa[i][1]);
break;
case LX_CHAR:
fprintf(stderr, "char ");
if (nfa[i][1] == EOF)
fprintf(stderr, "EOF");
else {
putc('\'', stderr);
if (iscntrl(nfa[i][1])) switch (nfa[i][1]) {
case '\b':
fprintf(stderr, "\\b");
break;
case '\f':
fprintf(stderr, "\\f");
break;
case '\n':
fprintf(stderr, "\\n");
break;
case '\r':
fprintf(stderr, "\\r");
break;
case '\t':
fprintf(stderr, "\\t");
break;
default:
fprintf(stderr, "\\%03o", nfa[i][1]);
} else
putc(nfa[i][1], stderr);
putc('\'', stderr);
}
break;
case LX_CLAS:
fprintf(stderr, "clas %d", nfa[i][1]);
break;
case LX_BLIN:
fprintf(stderr, "blin");
break;
case LX_ELIN:
fprintf(stderr, "elin");
break;
case LX_ANYC:
fprintf(stderr, "anyc");
break;
case LX_SCON:
fprintf(stderr, "scon %d", nfa[i][1]);
break;
case LX_TERM:
fprintf(stderr, "term");
break;
default:
fprintf(stderr, "undefined");
}
putc('\n', stderr);
}
}