Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
c/old/kc/cc5.c
There are no other files named cc5.c in the archive.
/* cc5.c -- Parser (C) 1981 K. Chen */
#define sc extern
#include "cc.h"
/* --------------------------------------- */
/* type-specifier Ref[1] A.18.2 */
/* --------------------------------------- */
struct TY *typespec()
{
int n;
struct TY *strspec(), *t;
if (csymbol != NULL) {
switch (csymbol->skey) {
case TYPESPEC:
n = token;
nextoken();
return &types[n-INT];
case SUSPEC:
return strspec();
default:
if (token == IDENT && csymbol->sclass == STYPEDEF) {
t = csymbol->sptr;
nextoken();
return t;
}
}
}
return deftype;
}
/* ------------------------------------ */
/* declarator Ref[1] A.18.2 */
/* */
/* tag = 0 normal */
/* = 1 structure tag */
/* = 2 func arguments */
/* ------------------------------------ */
struct SYMBOL *declarator(s, tag)
struct SYMBOL *s;
{
struct SYMBOL *decl0();
scalar = s->sptr;
return decl0(s, tag);
}
/* ------------------------------------- */
/* process external definition */
/* ------------------------------------- */
extdef()
{
struct SYMBOL *s, tempsym, base, *fn;
struct TY *t;
int sctype, narg;
scope = SEXTERN;
sctype = XTERN; /* default storage class */
switch (token) {
case EXTERN:
sctype = SEXTERN;
nextoken();
break;
case STATIC:
sctype = SSTATIC;
nextoken();
break;
case TYPEDEF:
sctype = STYPEDEF;
nextoken();
}
t = typespec();
if (token == SCOLON) {
nextoken();
return;
}
tempsym.sname[0] = '\0';
tempsym.sclass = sctype;
tempsym.svalue = 0;
tempsym.sptr = t;
copysym(&base,&tempsym);
if ((s = declarator(&tempsym,0)) != NULL) {
fn = s;
t = s->sptr;
if (t->ttype == FNDEF) { /* parsed "fnname (" */
narg = 1;
scope = SARG;
while (1) { /* parameter-list */
if (token != IDENT) break;
symcpy(base.sname, csymbol->sname);
if (csymbol->sclass == SUNDEF) freesym(csymbol);
s = creatloc(base.sname);
s->sclass = SARG;
s->svalue = narg++;
s->sptr = &types[INT-INT];
nextoken();
if (token != COMMA) break;
nextoken();
}
expect(RPAREN);
funcdef(fn);
return;
}
if (t->ttype == FUNCTION) { /* parsed "fnname ()" */
if (token != COMMA && token != SCOLON && token != ASGN) {
funcdef(fn);
return;
}
}
if (!eof) datadef(s, &base);
}
}
struct SYMBOL *decl0(s, tag)
struct SYMBOL *s;
{
struct TY t, *u;
while (token == MPLY) {
nextoken();
decl1(s, tag);
t.ttype = PTR;
t.tsize = PTRSIZE;
addtype(s, gettype(&t));
if (token != MPLY) return s;
}
decl1(s, tag);
return s;
}
/* -------------------------- */
/* level 1 declarator */
/* -------------------------- */
decl1(s, tag)
struct SYMBOL *s;
{
struct TY t, *ty;
struct SYMBOL *try, *findsym();
switch (token) {
case IDENT:
if (s->sname[0]) {
error(SYNTAX);
return NULL;
}
if (tag == 1) {
symcpy(s->sname, "#");
symapp(s->sname, csymbol->sname);
freesym(csymbol);
}
else symcpy(s->sname, csymbol->sname);
nextoken();
break;
case LPAREN:
nextoken();
decl0(s, tag);
expect(RPAREN);
break;
default:
return;
}
switch (token) {
case LPAREN:
nextoken();
t.tsize = PTRSIZE;
t.tptr = s->sptr;
if (token == RPAREN) {
nextoken();
t.ttype = FUNCTION;
addtype(s, gettype(&t));
return;
}
if (token == IDENT) {
t.ttype = FNDEF;
addtype(s, gettype(&t));
return;
}
error(SYNTAX);
break;
case LBRACK:
decl2(s, tag);
}
}
/* ---------------------- */
/* declarator[] */
/* ---------------------- */
decl2(s, tag)
struct SYMBOL *s;
{
struct TY t;
nextoken();
t.ttype = (tag == 2) ? PTR : ARRAY;
t.tptr = s->sptr;
t.tsize = (token == RBRACK) ? 0 : pconst();
addtype(s, gettype(&t));
expect(RBRACK);
if (token == LBRACK) decl2(s);
}
/* -------------------------------------------------- */
/* struct-or-union specifier Ref[1] A.18.2 */
/* -------------------------------------------------- */
struct TY *strspec()
{
struct SYMBOL s, *tagname, *findsym();
struct TY p, *pt;
int typ, etyp, hastag;
char *sym, symarray[16];
typ = token;
nextoken();
if (token == IDENT) {
hastag = 1;
symcpy(s.sname, "%");
symapp(s.sname, csymbol->sname);
symcpy(symarray, csymbol->sname);
sym = symarray;
freesym(csymbol);
nextoken();
}
else {
hastag = 0;
symcpy(s.sname, "%%%");
sym = "Untagged struct";
}
if (hastag) {
if (token == LBRACE) { /* struct FOO { */
if ((tagname=findsym(s.sname)) == NULL) {
tagname = creatsym(s.sname); /* FOO undefined */
}
else { /* FOO defined */
if (tagname->sclass == SUNDEF) /* fwrd. ref. */
tagname->sclass = STAG;
else {
etyp = (typ == STRUCT) ? EDSTRUC : EDUNION;
error(etyp, sym);
}
}
p.tsize = sdecllist(typ);
}
else { /* struct FOO */
if ((tagname=findsym(s.sname)) == NULL) {
tagname = creatsym(s.sname); /* FOO undefined */
tagname->sclass = SUNDEF; /* mark as fwrd. ref. */
tagname->svalue = 0;
tagname->sptr = NULL;
return &types[STRUCT-INT];
}
else return tagname->sptr; /* FOO defined */
}
}
else { /* struct */
tagname = creatsym(s.sname);
if (token == LBRACE) /* struct { */
p.tsize = sdecllist(typ);
else { /* struct no-{ */
expect(LBRACE);
recover(SCOLON);
}
}
p.ttype = STRUCT;
p.tptr = NULL;
pt = gettype(&p);
tagname->sclass = STAG;
tagname->svalue = 0;
tagname->sptr = pt;
return pt;
}
/* ------------------------------------------ */
/* struct-decl-list Ref.[1] A.8.5 */
/* ------------------------------------------ */
sdecllist(t)
{
int offset, size, maxsize;
maxsize = offset = 0;
expect(LBRACE);
while (token != RBRACE) {
if (eof) earlyend();
size = sdeclaration(offset);
if (t == UNION) {
offset = 0;
if (size > maxsize) maxsize = size;
}
else
maxsize = (offset += size);
}
nextoken();
return maxsize;
}
/* -------------------------------------------- */
/* struct-declaration Ref.[1] A.8.5 */
/* -------------------------------------------- */
sdeclaration(offset)
{
struct TY *t;
struct SYMBOL base, tempsym;
int size, s;
size = offset;
t = typespec();
base.sname[0] = '\0';
base.sclass = SMEMBER;
base.svalue = 0;
base.sptr = t;
while (1) {
copysym(&tempsym, &base);
s = declstr(&tempsym, offset);
offset += s;
if (token != COMMA) break;
}
expect(SCOLON);
return offset-size;
}
/* ----------------------------------------- */
/* struct-declarator Ref.[1] A.8.5 */
/* ----------------------------------------- */
declstr(s, offset)
struct SYMBOL *s;
{
struct SYMBOL *t, *u, *findsymbol();
t = declarator(s, 1);
u = findsymbol(t->sname);
if (u == NULL) { /* struct member not seen before */
t->sclass = SMEMBER;
t->svalue = offset;
u = creatsym(t->sname);
copysym(u, t);
}
else { /* struct member seen before */
if (offset != u->svalue) error(EDMEM);
}
return tsize(u->sptr);
}
/* -------------------------------------------- */
/* abstract-declarator Ref[1] A.8.7 */
/* -------------------------------------------- */
struct SYMBOL *absdecl(s)
struct SYMBOL *s;
{
struct TY tt;
if (s == NULL) return NULL;
switch (token) {
case LPAREN:
nextoken();
s = absdecl(s);
if (!expect(RPAREN)) {
error(SYNTAX);
return s;
}
break;
case MPLY:
while (token == MPLY) {
nextoken();
tt.ttype = PTR;
tt.tsize = PTRSIZE;
tt.tptr = s->sptr;
s->sptr = gettype(&tt);
}
s = absdecl(s);
break;
default:
return s;
}
/* parse declarator() or declarator[] */
switch (token) {
case LPAREN:
nextoken();
tt.tsize = PTRSIZE;
tt.tptr = s->sptr;
tt.ttype = FUNCTION;
s->sptr = gettype(&tt);
expect(RPAREN);
break;
case LBRACK:
nextoken();
tt.ttype = ARRAY;
tt.tptr = s->sptr;
tt.tsize = (token == RBRACK) ? 0 : pconst();
s->sptr = gettype(&tt);
expect(RBRACK);
break;
}
return s;
}
/* ----------------------------------- */
/* type-name Ref.[1] A.8.7 */
/* ----------------------------------- */
struct TY *typename()
{
struct SYMBOL s, *t;
s.sname[0] = '\0';
s.sclass = s.svalue = 0;
s.sptr = typespec();
t = absdecl(&s);
return t->sptr;
}
/* -------------------------------------------- */
/* function-definition Ref[1] A.18.4 */
/* -------------------------------------------- */
funcdef(s)
struct SYMBOL *s;
{
int n, mtype;
char ident, *c;
struct TY *t, ftype;
struct NODE *nnode, *header, *stmtlist(), *u;
struct SYMBOL *findsym(), *s1, *s2, stemp;
/* check for multiple decl */
t = s->sptr;
ftype.ttype = FUNCTION;
ftype.tsize = tsize(t);
ftype.tptr = t->tptr;
s->sptr = gettype(&ftype);
if ((s1 = findsym(c = s->sname)) == NULL) {
fprintf(stderr, "Cannot find symbol %s.\n", c);
exit(1);
}
if (s->sclass == XTERN) {
s->sclass = SEXTERN;
s->svalue = 1;
}
copysym(s1, s);
header = defnode(N1, 0);
header->left = defnode(N2, IDENT, s1->sptr, 0, s1);
nnode = defnode(N2, FUNCTION, NULL, 0, header);
fprintf(stderr, "[%s]\n", c);
if (token != LBRACE) { /* type-decl-list */
while(1) {
if (token == REGISTER) nextoken(); /* register == NOP */
t = typespec();
while (1) {
stemp.sname[0] = '\0';
stemp.sptr = t;
s1 = declarator(&stemp, 2);
if ((s2 = findsym(s1->sname)) == NULL || s2->sclass != SARG)
error(ENOTARG);
else
s2->sptr = s1->sptr;
if (token != COMMA) break;
nextoken();
}
if (!expect(SCOLON)) recover(SCOLON);
if (token == LBRACE) break;
}
}
maxinit = maxauto = 0;
mtype = maxtype;
scope = SAUTO; /* function-statement */
nextoken();
decllist();
u = nnode->right = stmtlist();
while (u->left != NULL) u = u->left;
u->left = defnode(N3, STATEMENT, NULL, 0, NULL, defnode(N1, RETURN));
gencode(nnode);
expect(RBRACE);
maxtype = mtype; /* flush local types */
ridauto(MAXSYM-1);
}
/* ----------------------------------------- */
/* sc-type, type-specifier, symbol */
/* Ref[1] A.18.4 */
/* ----------------------------------------- */
datadef(s, base)
struct SYMBOL *s, *base;
{
int more;
struct SYMBOL t;
struct NODE *izer(), *z;
z = NULL;
while (1) {
z = defnode(N3, DATA, NULL, 0, z, izer(s));
if (token != COMMA) break;
nextoken();
copysym(&t, base);
s = declarator(&t, 0);
}
expect(SCOLON);
gencode(z);
}
/* ----------------------- */
/* initializer */
/* Ref.[1] A.8.6 */
/* ----------------------- */
struct NODE *izer(s)
struct SYMBOL *s;
{
struct TY *ty, tt;
struct SYMBOL *t, *findsym();
struct NODE *izer0(), *izer1(), *y, *z;
int n, m;
char *c;
z = NULL;
if (token == ASGN) {
nextoken();
ty=s->sptr;
n = tsize(ty);
if (token == LBRACE) {
z = izer1(ty);
if (n == 0) {
tt.ttype = ty->ttype;
tt.tsize = z->nflag;
tt.tptr = ty->tptr;
s->sptr = gettype(&tt);
}
}
else {
z = izer0(ty);
if (n == 0) {
tt.ttype = ty->ttype;
tt.tsize = z->nflag;
tt.tptr = ty->tptr;
s->sptr = gettype(&tt);
}
}
}
t = findsym(c=s->sname);
if (t->sclass == SUNDEF ||
(s->sclass == SAUTO && (t->sclass == SEXTERN || t->sclass == XTERN))) {
switch (s->sclass) {
case SAUTO:
ty = s->sptr;
while (ty->ttype == PTR) {
ty = ty->tptr;
}
if (ty->ttype == FUNCTION) {
if (t->sclass != SEXTERN) {
freesym(t);
creatsym(c); /* create an entry in global table */
s->svalue = 0; /* mark as a declaration (not definition) */
s->sclass = SEXTERN;
}
break;
}
if (t->sclass == SUNDEF) freesym(t);
t = creatloc(c);
s->svalue = maxauto;
maxauto += tsize(s->sptr);
break;
case XTERN:
s->svalue = 1;
s->sclass = SEXTERN;
}
copysym(t, s);
}
else {
ty = s->sptr;
while (ty->ttype == PTR) ty = ty->tptr;
if (ty->ttype != FUNCTION) {
error(EDSYMB, c);
}
}
y = defnode(N2, IDENT, t->sptr, 0, t);
return defnode(N3, IZ, NULL, 0, y, z);
}
struct NODE *izer0(t)
struct TY *t;
{
struct NODE *y, *z, *root;
struct TY *u;
char *c;
int op, m, size;
z = expression();
op = z->nop;
size = tsize(t);
if (op != ICONST && op != SCONST) {
error(ECONST);
}
else {
if (chararray(t)) {
if (op == SCONST) {
c = z->nsconst;
m = 0;
root = NULL;
u = &types[CHAR-INT];
do {
m++;
y = defnode(N2, ICONST, u, 0, NULL);
y->niconst = *c;
if (root == NULL)
z = root = defnode(N3, IZLIST, NULL, 0, NULL, y);
else
z = z->left = defnode(N3, IZLIST, NULL, 0, NULL, y);
} while (*c++);
m = (size) ? size - (m+3)/4 : 0;
}
}
else {
m = (size) ? (size - 1) : 0;
root = (m <= 0) ? z : (z = defnode(N3, IZLIST, NULL, 0, NULL, z));
}
}
if (m > 0) {
y = defnode(N1, BLOCK);
y->niconst = m;
z->left = defnode(N3, IZLIST, NULL, 0, NULL, y);
}
else if (m < 0) error(ESIZE);
return root;
}
struct NODE *izer1(t)
struct TY *t;
{
int size, m;
struct NODE *x, *y, *z, *izlist();
nextoken();
size = tsize(t);
z = izlist(t);
if (token == COMMA) nextoken();
expect(RBRACE);
y = z;
while (y->left != NULL) y = y->left;
m = z->nflag;
if (chararray(t)) m = (m+3)/4;
m = size - m;
if (m > 0) {
x = defnode(N1, BLOCK);
x->niconst = m;
y->left = defnode(N3, IZLIST, NULL, 0, NULL, x);
z->nflag = size;
}
else if (size && m < 0) {
error(ESIZE);
}
return z;
}
struct NODE *izlist(t)
struct TY *t;
{
int n, size, p;
struct TY *ty;
struct NODE *l, *m, *root;
n = 0;
m = root = NULL;
size = tsize(ty=t->tptr);
p = (charpointer(ty)) ? ty : NULL;
while (1) {
l = (token == LBRACE) ? izer1(p) : izer0(p);
if (root == NULL)
m = root = defnode(N3, IZLIST, NULL, 0, NULL, l);
else {
m = m->left = defnode(N3, IZLIST, NULL, 0, NULL, l);
}
n++;
if (token != COMMA) break;
nextoken();
}
root->nflag = n; /* size carried in node.nflag */
return root;
}
/* ----------------------------------------- */
/* parse for a constant expression */
/* ----------------------------------------- */
pconst()
{
struct NODE *e;
e = expression();
if (e->nop != ICONST) {
error(ECONST);
return 0;
}
return e->niconst;
}
/* ----------------------------------------- */
/* declaration-list Ref.[1] A.18.3 */
/* ----------------------------------------- */
decllist()
{
int n;
while (csymbol != NULL) {
if ((n = csymbol->sclass) == SRW) {
n = csymbol->skey;
if (n != TYPESPEC && n != SCSPEC && n != SUSPEC) return;
}
else {
if (n != STYPEDEF) return;
}
decln();
}
}
/* -------------------------------------- */
/* declaration Ref.[1] A.18.2 */
/* -------------------------------------- */
decln()
{
int n;
struct SYMBOL s;
n = 0;
switch (token) {
case AUTO:
n = scope;
break;
case STATIC:
n = SSTATIC;
break;
case EXTERN:
n = SEXTERN;
break;
case REGISTER:
/* n = SREGISTER; */
n = scope;
break;
case TYPEDEF:
n = STYPEDEF;
break;
default:
s.sclass = scope;
}
if (n) {
nextoken();
s.sclass = n;
}
s.sptr = typespec();
s.sname[0] = 0;
idecllist(&s);
expect(SCOLON);
}
/* ----------------------------------------------- */
/* init-declarator-list Ref.[1] A.18.2 */
/* ----------------------------------------------- */
idecllist(base)
struct SYMBOL *base;
{
struct SYMBOL t, *s;
struct NODE *y,*z;
int savemax;
z = NULL;
while (1) {
copysym(&t, base);
s = declarator(&t, 0);
y = izer(s);
if (scope == SAUTO) {
z = defnode(N3, DATA, NULL, 0, z, y);
}
if (token != COMMA) break;
nextoken();
}
savemax = maxnode;
gencode(z);
maxnode = savemax;
}
/* ---------------------------------------- */
/* statement-list Ref.[1] A.18.3 */
/* ---------------------------------------- */
struct NODE *stmtlist()
{
struct NODE *n, *statement(), *m, *root;
n = NULL;
while (1) {
m = defnode(N3, STATEMENT, NULL, 0, NULL, statement());
n = (n == NULL) ? (root = m) : (n->left = m);
if (token == RBRACE) return root;
}
}