Annotation of coherent/d/bin/cc/c/n0/lex.c, revision 1.1.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.