Annotation of coherent/b/bin/c/n0/lex.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * This file contains all of the lexical analysis routines
        !             3:  * for the portable C compiler.
        !             4:  */
        !             5: #ifdef   vax
        !             6: #include "INC$LIB:cc0.h"
        !             7: #else
        !             8: #include "cc0.h"
        !             9: #endif
        !            10: 
        !            11: /*
        !            12:  * Character classes.
        !            13:  * Indexed by ASCII character code.
        !            14:  */
        !            15: unsigned char ct[] = {
        !            16:        JUNK,   JUNK,   JUNK,   JUNK,   JUNK,   JUNK,   JUNK,   JUNK,
        !            17:        JUNK,   SKIP,   SKIP,   SKIP,   SKIP,   SKIP,   JUNK,   JUNK,
        !            18:        JUNK,   JUNK,   JUNK,   JUNK,   JUNK,   JUNK,   JUNK,   JUNK,
        !            19:        JUNK,   JUNK,   JUNK,   JUNK,   JUNK,   JUNK,   JUNK,   JUNK,
        !            20:        SKIP,   NOT,    STRING, SHARP,  JUNK,   REM,    AND,    QUOTE,
        !            21:        LPAREN, RPAREN, MUL,    ADD,    COMMA,  SUB,    DOT,    DIV,
        !            22:        CON,    CON,    CON,    CON,    CON,    CON,    CON,    CON,
        !            23:        CON,    CON,    COLON,  SEMI,   LT,     ASSIGN, GT,     QUEST,
        !            24:        JUNK,   ID,     ID,     ID,     ID,     ID,     ID,     ID,
        !            25:        ID,     ID,     ID,     ID,     ID,     ID,     ID,     ID,
        !            26:        ID,     ID,     ID,     ID,     ID,     ID,     ID,     ID,
        !            27:        ID,     ID,     ID,     LBRACK, BACKDIV,RBRACK, XOR,    ID,
        !            28:        JUNK,   ID,     ID,     ID,     ID,     ID,     ID,     ID,
        !            29:        ID,     ID,     ID,     ID,     ID,     ID,     ID,     ID,
        !            30:        ID,     ID,     ID,     ID,     ID,     ID,     ID,     ID,
        !            31:        ID,     ID,     ID,     LBRACE, OR,     RBRACE, COM,    JUNK,
        !            32:        HIGH0,  HIGH0,  HIGH0,  HIGH0,  HIGH0,  HIGH0,  HIGH0,  HIGH0,
        !            33:        HIGH0,  HIGH0,  HIGH0,  HIGH0,  HIGH0,  HIGH0,  HIGH0,  HIGH0,
        !            34:        HIGH0,  HIGH0,  HIGH0,  HIGH0,  HIGH0,  HIGH0,  HIGH0,  HIGH0,
        !            35:        HIGH0,  HIGH0,  HIGH0,  HIGH0,  HIGH0,  HIGH0,  HIGH0,  HIGH0,
        !            36:        HIGH1,  HIGH1,  HIGH1,  HIGH1,  HIGH1,  HIGH1,  HIGH1,  HIGH1,
        !            37:        HIGH1,  HIGH1,  HIGH1,  HIGH1,  HIGH1,  HIGH1,  HIGH1,  HIGH1,
        !            38:        HIGH1,  HIGH1,  HIGH1,  HIGH1,  HIGH1,  HIGH1,  HIGH1,  HIGH1,
        !            39:        HIGH1,  HIGH1,  HIGH1,  HIGH1,  HIGH1,  HIGH1,  HIGH1,  HIGH1,
        !            40:        HIGH2,  HIGH2,  HIGH2,  HIGH2,  HIGH2,  HIGH2,  HIGH2,  HIGH2,
        !            41:        HIGH2,  HIGH2,  HIGH2,  HIGH2,  HIGH2,  HIGH2,  HIGH2,  HIGH2,
        !            42:        HIGH2,  HIGH2,  HIGH2,  HIGH2,  HIGH2,  HIGH2,  HIGH2,  HIGH2,
        !            43:        HIGH2,  HIGH2,  HIGH2,  HIGH2,  HIGH2,  HIGH2,  HIGH2,  HIGH2,
        !            44:        HIGH3,  HIGH3,  HIGH3,  HIGH3,  HIGH3,  HIGH3,  HIGH3,  HIGH3,
        !            45:        HIGH3,  HIGH3,  HIGH3,  HIGH3,  HIGH3,  HIGH3,  HIGH3,  HIGH3,
        !            46:        HIGH3,  HIGH3,  HIGH3,  HIGH3,  HIGH3,  HIGH3,  HIGH3,  HIGH3,
        !            47:        HIGH3,  HIGH3,  HIGH3,  HIGH3,  HIGH3,  HIGH3,  HIGH3,  HIGH3
        !            48: };
        !            49: 
        !            50: /*
        !            51:  * Read and decode the next token of the input.
        !            52:  * The token is returned and stored in 's'.
        !            53:  * Identifiers are packed into 'id'
        !            54:  * and their hash table slot is stashed in 'idhash'.
        !            55:  * Integers are returned in 'ival',
        !            56:  * long integers in 'lval' and doubles in 'dval'.
        !            57:  */
        !            58: lex()
        !            59: {
        !            60:        register SYM    *sp;
        !            61:        register int    c;
        !            62:        register int    n;
        !            63: 
        !            64:        for (;;) {
        !            65:                if ((c=get()) < 0)
        !            66:                        return (s = EOF);
        !            67:                switch (s = ct[c]) {
        !            68: 
        !            69:                case SKIP:
        !            70:                        continue;
        !            71: 
        !            72:                case QUOTE:
        !            73:                        n = 0;
        !            74:                        lval = 0;
        !            75:                        instring = c;           /* to allow high-bit chars */
        !            76:                        while ((c = getmap('\'')) >= 0) {
        !            77:                                lval <<= 8;
        !            78:                                lval |= c;
        !            79:                                ++n;
        !            80:                        }
        !            81:                        instring = 0;
        !            82:                        ival = lval;
        !            83:                        tval = T_INT;
        !            84:                        s = ICON;
        !            85: #if 0
        !            86:                        switch (n) {
        !            87:                        case 0:
        !            88:                                cwarn("empty character constant");
        !            89:                                break;
        !            90:                        case 2:
        !            91:                                cwarn("multiple character constant");
        !            92:                                tval = T_INT;
        !            93:                                break;
        !            94:                        case 1:
        !            95:                                break;
        !            96:                        case 3:
        !            97:                        case 4:
        !            98:                                cwarn("character constant promoted to long");
        !            99:                                tval = T_LONG;
        !           100:                                s = LCON;
        !           101:                                break;
        !           102:                        default:
        !           103:                                cerror("character constant overflows long");
        !           104:                                tval = T_LONG;
        !           105:                                s = LCON;
        !           106:                                break;
        !           107:                        }
        !           108: #else
        !           109:                        if (n != 1)
        !           110:                                cerror("multiple character constant");
        !           111: #endif
        !           112:                        break;
        !           113: 
        !           114:                case ADD:
        !           115:                        if (nextis('+'))
        !           116:                                s = INCBEF;
        !           117:                        break;
        !           118: 
        !           119:                case SUB:
        !           120:                        if (nextis('-'))
        !           121:                                s = DECBEF;
        !           122:                        else if (nextis('>'))
        !           123:                                s = ARROW;
        !           124:                        break;
        !           125: 
        !           126:                case LT:
        !           127:                        if (nextis('='))
        !           128:                                s = LE;
        !           129:                        else if (nextis('<'))
        !           130:                                s = SHL;
        !           131:                        break;
        !           132: 
        !           133:                case GT:
        !           134:                        if (nextis('='))
        !           135:                                s = GE;
        !           136:                        else if (nextis('>'))
        !           137:                                s = SHR;
        !           138:                        break;
        !           139: 
        !           140:                case ASSIGN:
        !           141:                        if (nextis('='))
        !           142:                                s = EQ;
        !           143:                        break;
        !           144: 
        !           145:                case NOT:
        !           146:                        if (nextis('='))
        !           147:                                s = NE;
        !           148:                        break;
        !           149: 
        !           150:                case AND:
        !           151:                        if (nextis('&'))
        !           152:                                s = ANDAND;
        !           153:                        break;
        !           154: 
        !           155:                case OR:
        !           156:                        if (nextis('|'))
        !           157:                                s = OROR;
        !           158:                        break;
        !           159: 
        !           160:                case DOT:
        !           161:                        c = get();
        !           162:                        if (c<0 || ct[c]!=CON) {
        !           163:                                unget(c);
        !           164:                                break;
        !           165:                        }
        !           166:                        getnum(c, 1);
        !           167:                        break;
        !           168: 
        !           169:                case CON:
        !           170:                        getnum(c, 0);
        !           171:                        break;
        !           172: 
        !           173:                case ID:
        !           174:                        if (expand(c))
        !           175:                                continue;
        !           176:                        for (sp = idp->t_sym; sp != NULL; sp = sp->s_sp)
        !           177:                                if (sp->s_slevel == SL_KEY) {
        !           178:                                        s = sp->s_value;
        !           179:                                        break;
        !           180:                                }
        !           181:                        break;
        !           182: 
        !           183:                case JUNK:
        !           184:                case HIGH0:
        !           185:                case HIGH1:
        !           186:                case HIGH2:
        !           187:                case HIGH3:
        !           188:                        cerror("illegal character (%d decimal)", c);
        !           189:                        continue;
        !           190: 
        !           191:                }
        !           192:                if ((s>=ADD && s<=SHR) && nextis('='))
        !           193:                        s += AADD-ADD;
        !           194:                return (s);
        !           195:        }
        !           196: }
        !           197: 
        !           198: /*
        !           199:  * Test if the next character in the input is 'n'.
        !           200:  * If it is, eat it up and return true;
        !           201:  * otherwise put it back and return false.
        !           202:  */
        !           203: nextis(n) int n;
        !           204: {
        !           205:        register int    c;
        !           206: 
        !           207:        if ((c = get()) == n)
        !           208:                return (1);
        !           209:        unget(c);
        !           210:        return (0);
        !           211: }
        !           212: 
        !           213: /*
        !           214:  * Get the next non blank character from the input.
        !           215:  * This is for cpp, so we do not pass newline.
        !           216:  */
        !           217: getnb()
        !           218: {
        !           219:        register int c;
        !           220: 
        !           221:        while ((c = get())==' ' || c=='\t')
        !           222:                ;
        !           223:        return (c);
        !           224: }
        !           225: 
        !           226: /*
        !           227:  * Get the next non-skip character.
        !           228:  * Different from getnb() which chokes
        !           229:  * on newline.
        !           230:  */
        !           231: getskip()
        !           232: {
        !           233:        register int c;
        !           234: 
        !           235:        while ((c = get()) > 0 && ct[c] == SKIP)
        !           236:                ;
        !           237:        return c;
        !           238: }
        !           239: 
        !           240: /*
        !           241:  * Peek ahead in the input (ignoring whitespace)
        !           242:  * to see if the next character is 'n'.
        !           243:  * True return it it is.
        !           244:  * The character is left in the input stream.
        !           245:  * This routine is used to look for the ':' after labels
        !           246:  * and the '(' after undefined names in expressions.
        !           247:  */
        !           248: spnextis(n) int n;
        !           249: {
        !           250:        register int    c;
        !           251: 
        !           252:        while ((c=get()) >= 0) {
        !           253:                if (ct[c] != SKIP) {
        !           254:                        unget(c);
        !           255:                        if (c == n)
        !           256:                                return (1);
        !           257:                        return (0);
        !           258:                }
        !           259:        }
        !           260:        return (0);
        !           261: }
        !           262: 
        !           263: /*
        !           264:  * This routine is like lex(), except that it correctly skips
        !           265:  * over any strings in the input.
        !           266:  * Used during error recovery.
        !           267:  */
        !           268: skip()
        !           269: {
        !           270:        if (s == STRING)
        !           271:                while (getmap('\"') >= 0)
        !           272:                        ;
        !           273:        lex();
        !           274: }
        !           275: 
        !           276: /*
        !           277:  * Read the next character from a string or a character constant.
        !           278:  * Return -1 when either end of file or the delimiter 'd' is encountered.
        !           279:  */
        !           280: getmap(d) int d;
        !           281: {
        !           282:        register int    c, n, v;
        !           283: 
        !           284:        if ((c=get()) == d)
        !           285:                return (-1);
        !           286:        if (c<0 || c=='\n') {
        !           287:                unget(c);
        !           288:                cerror("nonterminated string or character constant");
        !           289:                return (-1);
        !           290:        }
        !           291:        if (c == '\\') {
        !           292:                c = get();
        !           293:                switch (c) {
        !           294: 
        !           295:                case 'a':
        !           296:                        c = '\07';
        !           297:                        break;
        !           298: 
        !           299:                case 'b':
        !           300:                        c = '\b';
        !           301:                        break;
        !           302: 
        !           303:                case 'f':
        !           304:                        c = '\f';
        !           305:                        break;
        !           306: 
        !           307:                case 'n':
        !           308:                        c = '\n';
        !           309:                        break;
        !           310: 
        !           311:                case 'r':
        !           312:                        c = '\r';
        !           313:                        break;
        !           314: 
        !           315:                case 't':
        !           316:                        c = '\t';
        !           317:                        break;
        !           318: 
        !           319:                case 'v':
        !           320:                        c = '\013';
        !           321:                        break;
        !           322: 
        !           323:                case 'x':
        !           324:                        notbook();
        !           325:                        c = get();
        !           326:                        n = 0;
        !           327:                        v = 0;
        !           328:                        while (++n<=3
        !           329:                                && ( (c>='0' && c<='9')
        !           330:                                  || (c>='A' && c<='F')
        !           331:                                  || (c>='a' && c<='f') )) {
        !           332:                                v <<= 4;
        !           333:                                if (c>='0' && c<='9')
        !           334:                                        v += c - '0';
        !           335:                                else if (c>='A' && c<='F')
        !           336:                                        v += c - 'A' + 10;
        !           337:                                else
        !           338:                                        v += c - 'a' + 10;
        !           339:                                c = get();
        !           340:                        }
        !           341:                        unget(c);
        !           342:                        c = v;
        !           343:                        break;
        !           344: 
        !           345:                case '0':
        !           346:                case '1':
        !           347:                case '2':
        !           348:                case '3':
        !           349:                case '4':
        !           350:                case '5':
        !           351:                case '6':
        !           352:                case '7':
        !           353:                        n = 0;
        !           354:                        v = 0;
        !           355:                        while (++n<=3 && c>='0' && c<='7') {
        !           356:                                v = (v<<3) + c - '0';
        !           357:                                c = get();
        !           358:                        }
        !           359:                        unget(c);
        !           360:                        c = v;
        !           361:                        break;
        !           362:                }
        !           363:        }
        !           364:        return (c);
        !           365: }
        !           366: 
        !           367: /*
        !           368:  * Read an identifier into id[]
        !           369:  * and set idhash.
        !           370:  */
        !           371: getid(ch) int ch;
        !           372: {
        !           373:        {
        !           374:                register char *p;
        !           375:                register int c;
        !           376:                c = ch;
        !           377:                p = id;
        !           378:                idhash = 0;
        !           379:                idsize = 0;
        !           380:                idhide = -1;    /* Universal */
        !           381:                do {
        !           382:                        if (p < &id[NCSYMB-1]) {
        !           383:                                *p++ = c;
        !           384:                                idhash += c;
        !           385:                                idsize += 1;
        !           386:                        }
        !           387:                        if ((c = get()) >= SET0) {
        !           388:                                idhide = hideint(c, idhide);
        !           389:                                c = get();
        !           390:                        }
        !           391:                } while (c>=0 && (ct[c]==ID || ct[c]==CON));
        !           392:                unget(c);
        !           393:                if (idhide == -1)
        !           394:                        idhide = SET0;  /* Empty */
        !           395:                *p++ = 0;
        !           396:                *p++ = 0;
        !           397:                *p++ = 0;
        !           398:        }
        !           399:        {
        !           400:                register TOK *tp, **tpp;
        !           401: 
        !           402:                idhash %= NHASH;
        !           403:                for (tpp = hash0+idhash; (tp = *tpp) != NULL; tpp = &tp->t_tp)
        !           404:                        if (ideq(tp))
        !           405:                                break;
        !           406:                if (tp == NULL)
        !           407:                        *tpp = tp = newtoken();
        !           408:                idp = tp;
        !           409:        }
        !           410: }
        !           411: 
        !           412: setid(cp) char *cp;
        !           413: {
        !           414:        {
        !           415:                register char *p1, *p2;
        !           416:                register int c;
        !           417: 
        !           418:                p1 = cp;
        !           419:                p2 = id;
        !           420:                idhash = 0;
        !           421:                idsize = 0;
        !           422:                while (c = *p1++) {
        !           423:                        if (p2 < &id[NCSYMB-1]) {
        !           424:                                *p2++ = c;
        !           425:                                idhash += c;
        !           426:                                idsize += 1;
        !           427:                        }
        !           428:                }
        !           429:                *p2 = 0;
        !           430:        }
        !           431:        {
        !           432:                register TOK *tp, **tpp;
        !           433: 
        !           434:                idhash %= NHASH;
        !           435:                for (tpp = hash0+idhash; (tp = *tpp) != NULL; tpp = &tp->t_tp)
        !           436:                        if (ideq(tp))
        !           437:                                break;
        !           438:                if (tp == NULL)
        !           439:                        *tpp = tp = newtoken();
        !           440:                idp = tp;
        !           441:        }
        !           442: }
        !           443: 
        !           444: /*
        !           445:  * Read number into id[].
        !           446:  * Set 's' appropriately.
        !           447:  */
        !           448: getnum(c, dotf) register int c; int dotf;
        !           449: {
        !           450:        register char   *np;
        !           451:        int             expf, sgnf, ntlf, base;
        !           452:        int             islong, isunsigned, isfloat;
        !           453:        long            n;
        !           454:        static char ulong[] = "unsigned long";
        !           455: #      define slong    (ulong+9)
        !           456: #if    NATIVEFP
        !           457:        double          d;
        !           458:        char            *cp, *dp;
        !           459:        extern double   atof();
        !           460: #endif
        !           461: 
        !           462:        expf = 0;
        !           463:        ntlf = 0;
        !           464:        sgnf = 1;
        !           465:        base = 10;
        !           466:        islong = 0;
        !           467:        isunsigned = 0;
        !           468:        isfloat = 0;
        !           469:        np = id;
        !           470:        n = 0;
        !           471:        if (dotf)
        !           472:                *np++ = '.';
        !           473:        if (dotf==0 && c=='0') {
        !           474:                base = 8;
        !           475:                if ((c = get()) == 'x' || c == 'X') {
        !           476:                        *np++ = '0';
        !           477:                        *np++ = c;
        !           478:                        base = 16;
        !           479:                        c = get();
        !           480:                } else {
        !           481:                        unget(c);
        !           482:                        c = '0';
        !           483:                }
        !           484:        }
        !           485:        do {
        !           486:                if (base!=16 && c=='.') {
        !           487:                        if (dotf++)
        !           488:                                break;
        !           489:                } else if (c=='+' || c=='-') {
        !           490:                        if (sgnf++)
        !           491:                                break;
        !           492:                } else if (base!=16 && (c=='e' || c=='E')) {
        !           493:                        if (expf++)
        !           494:                                break;
        !           495:                        sgnf = 0;
        !           496:                } else if (c<'0' || c>'9') {
        !           497:                        if (base != 16)
        !           498:                                break;
        !           499:                        if (!((c>='A' && c<='F') || (c>='a' && c<='f')))
        !           500:                                break;
        !           501:                } else
        !           502:                        ++sgnf;
        !           503:                if (np < &id[NCSYMB-1])
        !           504:                        *np++ = c;
        !           505:                else
        !           506:                        ntlf = 1;
        !           507:                if (base == 8)
        !           508:                        n <<= 3;
        !           509:                else if (base == 10)
        !           510:                        n = (n<<3) + (n<<1);
        !           511:                else
        !           512:                        n <<= 4;
        !           513:                if (c>='A' && c<='F')
        !           514:                        c -= 'A'-10;
        !           515:                else if (c>='a' && c<='f')
        !           516:                        c -= 'a'-10;
        !           517:                else
        !           518:                        c -= '0';
        !           519:                n += c;
        !           520:        } while ((c = get()) >= 0);
        !           521:        for (;;) {
        !           522:                if (c=='l' || c=='L') {
        !           523:                        ++islong;
        !           524:                        *np++ = c;
        !           525:                        c = get();
        !           526:                } else if (c == 'u' || c == 'U') {
        !           527:                        ++isunsigned;
        !           528:                        *np++ = c;
        !           529:                        c = get();
        !           530:                } else if (c == 'f' || c == 'F') {
        !           531:                        ++isfloat;
        !           532:                        *np++ = c;
        !           533:                        c = get();
        !           534:                } else {
        !           535:                        unget(c);
        !           536:                        *np = 0;
        !           537:                        break;
        !           538:                }
        !           539:        }
        !           540:        s = ICON;
        !           541:        tval = T_INT;
        !           542:        ival = lval = n;
        !           543:        if (ntlf) {
        !           544:                cerror("number has too many digits");
        !           545:                return;
        !           546:        }
        !           547:        if (dotf || expf || isfloat) {
        !           548:                if (isunsigned || (isfloat+islong > 1)) {
        !           549:                        cerror("illegal floating constant suffix");
        !           550:                        return;
        !           551:                }
        !           552:                tval = isfloat ? T_FLOAT : islong ? T_LDOUBLE : T_DOUBLE;
        !           553: #if    NATIVEFP
        !           554:                d = atof(id);
        !           555:                for (dp = (char *)dval, cp = ((char *)&d)+sizeof(double)-1; cp >= &d; )
        !           556:                        *dp++ = *cp--;
        !           557: #else
        !           558:                dvalread((char *)dval, id);
        !           559: #endif
        !           560:                s = DCON;
        !           561:                return;
        !           562:        }
        !           563:        if (isunsigned > 1 || islong > 1) {
        !           564:                cerror("illegal integer constant suffix");
        !           565:                return;
        !           566:        }
        !           567:        np = NULL;
        !           568:        if (islong) {
        !           569:                s = LCON;
        !           570:                tval = T_LONG;
        !           571:                if (isunsigned || (n&SLMASK) != 0)
        !           572:                        tval = T_ULONG;
        !           573:        } else if (isunsigned) {
        !           574:                tval = T_UINT;
        !           575:                if ((n&UIMASK) != 0) {
        !           576:                        s = LCON;
        !           577:                        tval = T_ULONG;
        !           578:                        np = ulong;
        !           579:                }
        !           580:        } else if (base == 10 && (n&SIMASK) != 0) {
        !           581:                s = LCON;
        !           582:                tval = T_LONG;
        !           583:                np = slong;
        !           584:                if ((n&SLMASK) != 0) {
        !           585:                        tval = T_ULONG;
        !           586:                        np = ulong;
        !           587:                }
        !           588:        } else if ((n&SIMASK) != 0) {
        !           589:                tval = T_UINT;
        !           590:                if ((n&UIMASK) != 0) {
        !           591:                        s = LCON;
        !           592:                        tval = T_LONG;
        !           593:                        np = slong;
        !           594:                        if ((n&SLMASK) != 0) {
        !           595:                                tval = T_ULONG;
        !           596:                                np = ulong;
        !           597:                        }
        !           598:                }
        !           599:        }
        !           600:        if (tval == T_ULONG) {
        !           601:                /* Test for unsigned long overflow */
        !           602:                /* and set np = NULL if a diagnostic is given */
        !           603:                ;
        !           604:        }
        !           605:        if (incpp == 0 && np != NULL && isvariant(VSLCON))
        !           606:                cwarn("\"%s\" promoted to %s", id, np);
        !           607: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.