Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
c/old/kc/cc4.c
There are no other files named cc4.c in the archive.
/* cc4.c -- Lexical Analyser (C) 1981 K. Chen */
#define sc extern
#include "cc.h"
typedef int _m[4];
_m _plus = {ASPLUS, INC, PLUS};
_m _minus = {ASMINUS, DEC, MEMBER, MINUS};
_m _and = {ASAND, LAND, AND};
_m _or = {ASOR, LOR, OR};
_m _xor = {ASXOR, XOR};
_m _asgn = {EQUAL, ASGN};
_m _less = {LSHFT, LEQ, LESS};
_m _great = {RSHFT, GEQ, GREAT};
_m _not = {NEQ, NOT};
_m _mply = {ASMPLY, MPLY};
_m _mod = {ASMOD, MOD};
/* ------------------------ */
/* get next token */
/* ------------------------ */
nextoken()
{
int t;
if (tokstack) {
t = tstack[tokstack].ttoken;
csymbol = (t == IDENT) ? tstack[tokstack].tsym : NULL;
tokstack--;
return token = t;
}
csymbol = NULL;
while (map[ch] == SPACE) nextc();
if (ch <= 0) {
eof = 1;
return token = EOF;
}
else
switch (token = map[ch]) {
case IDENT:
return getident();
case CONST:
case SQUOTE:
case DQUOTE:
return token = getconst();
case OR:
return multiple("=|", _or);
case AND:
return multiple("=&", _and);
case XOR:
return multiple("=", _xor);
case PLUS:
return multiple("=+", _plus);
case ASGN:
return multiple("=", _asgn);
case GREAT:
if (multiple(">=", _great) == RSHFT) {
if (ch == '=') {
ch = nextc();
token = ASRSH;
}
}
return token;
case LESS:
if (multiple("<=", _less) == LSHFT) {
if (ch == '=') {
ch = nextc();
token = ASLSH;
}
}
return token;
case NOT:
return multiple("=", _not);
case MINUS:
return multiple("=->", _minus);
case MPLY:
return multiple("=", _mply);
case MOD:
return multiple("=", _mod);
case DIV:
switch (ch = nextc()) {
case '*':
comment();
return nextoken();
case '=':
ch = nextc();
return token = ASDIV;
default:
return token = DIV;
}
default:
ch = nextc();
return token;
}
}
/* ---------------------- */
/* push a token */
/* ---------------------- */
tokpush(t, s)
struct SYMBOL *s;
{
tokstack++;
tstack[tokstack].ttoken = token;
tstack[tokstack].tsym = csymbol;
token = t;
csymbol = s;
}
/* -------------------------------- */
/* multiple symbol tokens */
/* -------------------------------- */
multiple(s, t)
char *s;
int *t;
{
ch = nextc();
while (*s) {
if (*s++ == ch) {
ch = nextc();
return token = *t;
}
t++;
}
return token = *t;
}
/* ---------------------------- */
/* scan past comments */
/* ---------------------------- */
comment()
{
ch = nextc();
while (!eof) {
while (ch == '*') {
ch = nextc();
if (ch == '/') {
ch = nextc();
return;
}
}
ch = nextc();
}
earlyend();
}
/* ------------------------ */
/* get identifier */
/* ------------------------ */
getident()
{
int i, n;
char ss[32], *s;
struct SYMBOL *findsymbol(), *creatsym();
s = ss;
do {
*s++ = ch;
ch = nextc();
} while (map[ch] == IDENT || map[ch] == CONST);
*s = 0;
csymbol = findsymbol(ss);
if (csymbol != NULL) {
switch (csymbol->sclass) {
case SRW:
return token = csymbol->stoken;
case SMACRO:
i = 0; /* number of arguments */
if (ch == '(') {
n = maclevel+1;
while (1) {
nextc();
skipblanks();
if (ch == ')') break;
mac[n].marg[i++] = cpool;
while (!eof && ch != ',' && ch != ')') {
*cpool++ = ch;
nextc();
}
*cpool++ = ' ';
*cpool++ = '\0';
if (ch == ')') break;
}
nextc();
}
pushc(ch);
if (maclevel) {
mac[maclevel].mptr = macptr;
}
maclevel++;
symcpy(mac[maclevel].mname, ss);
if (csymbol->svalue != i) {
error(ENARGS);
fprintf(stderr," %d expected %d seen.\n",
mac[maclevel].svalue, i);
}
macptr = csymbol->smptr;
nextc();
return nextoken();
}
return token = IDENT;
}
csymbol = creatsym(ss);
csymbol->sclass = SUNDEF;
return token = IDENT;
}
/* ------------------------------------------------ */
/* parse constant integer, char or string */
/* ------------------------------------------------ */
getconst()
{
int l, v;
struct TY t, *gettype();
switch (ch) {
case '\'':
nextc();
constant.ctype = &types[INT-INT];
constant.cvalue = cchar();
constant.csptr = NULL;
if (ch != '\'')
error (ECHAR);
else nextc();
return CONST;
case '"':
nextc();
t.ttype = PTR;
t.tsize = PTRSIZE;
t.tptr = &types[CHAR-INT];
constant.ctype = gettype(&t);
constant.cvalue = 0;
constant.csptr = cpool;
while (!eof && ch != '"') {
*cpool++ = cchar();
}
*cpool++ = '\0';
if (ch != '"')
error (EEOF);
else nextc();
return CONST;
default:
l = ch - '0';
if (ch == '0') {
nextc();
if (ch == 'x' || ch == 'X') {
nextc();
while ((v = hex (ch)) >= 0) {
l = (l<<4) + v;
nextc();
}
}
else {
while ((v = oct (ch)) >= 0) {
l = (l<<3) + v;
nextc();
}
}
}
else {
nextc();
while (map[ch] == CONST) {
l = l*10 + ch - '0';
nextc();
}
}
constant.ctype = &types[INT-INT];
constant.cvalue = l ;
constant.csptr = NULL;
return CONST;
}
}
/* ---------------------------------- */
/* parse character constant */
/* ref[1] Appendix A.2.4.3 */
/* ---------------------------------- */
cchar()
{
int c, v;
if (ch == '\\') {
nextc();
switch (ch) {
case 'b':
c = '\b';
break;
case 'f':
c = '\f';
break;
case 'n':
c = '\n';
break;
case 'r':
c = '\r';
break;
case 't':
c = '\t';
break;
case '\'':
c = '\'';
break;
case '"':
c = '"';
break;
case '\\':
c = '\\';
break;
default:
if ((v = oct(ch)) >= 0) {
c = v;
nextc();
if ((v = oct(ch)) >= 0) {
c = (c<<3) + v;
nextc();
if ((v = oct(ch)) >= 0) {
c = (c<<3) + v;
nextc();
}
}
return c;
}
else c = ch;
}
}
else c = ch;
nextc();
return c;
}
/* --------------------------------- */
/* return hex value, or -1 */
/* --------------------------------- */
hex(c)
{
switch (map[c]) {
case CONST:
return c - '0';
case IDENT:
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
else if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
}
return (-1);
}
/* ---------------------------------- */
/* return octal value or -1 */
/* ---------------------------------- */
oct(c)
{
if (c >= '0' && c <= '7') {
return c - '0';
}
return (-1);
}