USG_PG3/usr/source/lil/lex.c
#include "common"
int peek -1; /* holds returned lookahead character */
char name[NSIZE]; /* name buffer */
get() {int c;
c = (peek < 0) ? getchar() : peek;
peek = (c == '\0') ? '\0' : -1;
if (c == '\n') line++;
return (c);
}
putback(c)
int c;
{if ((peek = c) == '\n') --line;
}
alf(c) int c;
{return ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z'
|| c == '.' || c == '_'
? TRUE : FALSE);
}
num(c) int c;
{return ('0' <= c && c <= '9' ? TRUE : FALSE);
}
op(c) int c;
{int i, j;
for (i = 0; j = "=+-<>?*/&~!|^"[i]; i++)
if (j == c) return ("=+-<>?*/&!!^^"[i]);
return (FALSE);
}
strend(c)
int c;
{if (c == '\'') return (TRUE);
if (c == '\n' || c == '\0')
{putback(c);
error("unbalanced '");
return (TRUE); }
return (FALSE);
}
strc(c) int c;
{if (c != '\\') return (c);
if (strend(c = get())) return ('\'');
if (c == '0') return (000);
else if (c == 'a') return (006);
else if (c == 'e') return (004);
else if (c == 'n') return (012);
else if (c == 'p') return (033);
else if (c == 'r') return (015);
else if (c == 't') return (011);
else return (c);
}
char tname[NSIZE + 2];
char *sn(p)
char *p;
{int i;
for (i = 0; i < NSIZE && (tname[i] = *p++); i++) ;
tname[i] = '\0';
return (tname);
}
compare(p1, p2)
char *p1, *p2;
{int i;
i = 0;
do if (*p1 != *p2++) return (FALSE);
while (*p1++ && ++i < NSIZE);
return (TRUE);
}
struct symbol *lookup(p1, n)
struct symbol *p1;
char *n;
{struct symbol *p;
for (p = sptop; p != p1; p = p->prev)
if (compare(p->name, n)) return (p);
return (FALSE);
}
struct symbol *add(s, f, t, v, z)
char *s;
int f, t, v, z;
{struct symbol *p;
int i;
if (--space < 0)
{if ((p = sbrk(100 * sizeof *p)) < 0)
{error("symbol table full");
exit(TRUE); }
if (symtab == NULL) symtab = p;
space = 99;
}
p = &symtab[spused++];
p->prev = sptop;
sptop = p;
for (i = 0; i < NSIZE && (p->name[i] = s[i]); i++) ;
while (i < NSIZE) p->name[i++] = '\0';
p->flags = f;
p->type = t;
p->value = v;
p->bias = test(p, DEFF) ? 0 : p - symtab;
p->size = z;
return (p);
}
lex() {int c, cop, escape, i;
struct symbol *p;
escape = FALSE;
e.flags = e.value = e.bias = 0;
e.size = 2;
e.prev = e.tbran = e.fbran = NULL;
while (c = get()) {
if (c == ' ' || c == '\t' || c == '\n') continue;
if (c == '%')
{while ((c = get()) != '\n' && c) ;
continue; }
if (c == ';') return (SCOLON);
if (c == ',') return (COMMA);
if (c == '0')
{e.flags = DEFF;
do e.value = (e.value << 3) + (c - '0');
while (num(c = get()));
putback(c);
return (CON);
}
if (c == '\'')
{e.flags = DEFF;
if (strend(c = get())) return (CON);
e.value = strc(c);
if (strend(c = get())) return (CON);
e.value =| strc(c) << 8;
if (strend(c = get())) return (CON);
putback(c);
return (STRING);
}
if (c == '[') return (LBRAK);
if (c == ']') return (RBRAK);
if (c == '(' || c == '{') return (LPAREN);
if (c == ')' || c == '}') return (RPAREN);
if (c == '"') return (QUOTES);
if (c == '\0') return (EOF);
if (c == '\\')
{escape = !escape;
continue; }
if (c == 021)
{debug = (debug + 1) % 3;
continue; }
if (c == 001)
{--line;
continue; }
if (cop = op(c))
{i = 0;
do if (i < NSIZE) name[i++] = cop;
while (cop = op(c = get()));
if (i < NSIZE) name[i] = '\0';
putback(c);
if (e.value = lookup(NULL, name)) return ((e.value)->type);
error("illegal operator %s", sn(name));
setvb(&e, NOP, 0);
return (OP);
}
if (alf(c))
{i = 0;
do if (i < NSIZE) name[i++] = c;
while (alf(c = get()) || num(c));
if (i < NSIZE) name[i] = '\0';
putback(c);
if ((p = lookup(NULL, name)) == NULL)
{e.flags =| DCLF;
return (MEM); }
if (escape && p->type < KOND)
{p->type = MEM;
p->flags = p->value = p->bias = 0;
p->size = 2; }
e.flags = p->flags & ATTR;
e.value = p;
e.size = p->size;
return (p->type);
}
if (num(c))
{e.flags = DEFF;
do e.value = (e.value * 10) + (c - '0');
while (num(c = get()));
putback(c);
return (CON);
}
error("illegal character %o", c);
}
}
dostring(p1)
struct at *p1;
{int c, i;
gen(i = p1->value, 0);
while (strend(c = get()) == FALSE)
{i = strc(c);
if (strend(c = get()))
{gen(i, 0);
return (i); }
gen(i =| (strc(c) << 8), 0);
}
return (i);
}