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

unix.superglobalmegacorp.com

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