Annotation of researchv8dc/cmd/ccom/common/scan.c, revision 1.1.1.1

1.1       root        1: /* @(#) scan.c: 1.2 2/27/84                            */
                      2: 
                      3: # include "mfile1.h"
                      4: # include <ctype.h>
                      5: /* temporarily */
                      6: 
                      7: /* character-set translation */
                      8: # ifndef CCTRANS
                      9: # define CCTRANS(x) (x)
                     10: # endif
                     11: 
                     12: int flflag = 0;
                     13: # ifndef FLOATCVT
                     14: double atof();
                     15: # define FLOATCVT(x) atof(x)
                     16: # endif
                     17: 
                     18: # ifndef ASMBUF
                     19: # define ASMBUF 200
                     20: # endif
                     21: char asmbuf[ASMBUF];
                     22: char *asmp;
                     23: int asm_esc = 0; /* asm escaped used in file */
                     24: /* lexical actions */
                     25: 
                     26: # define A_ERR 0               /* illegal character */
                     27: # define A_LET 1               /* saw a letter */
                     28: # define A_DIG 2               /* saw a digit */
                     29: # define A_1C 3                        /* return a single character */
                     30: # define A_STR 4               /* string */
                     31: # define A_CC 5                        /* character constant */
                     32: # define A_BCD 6               /* GCOS BCD constant */
                     33: # define A_SL 7                        /* saw a / */
                     34: # define A_DOT 8               /* saw a . */
                     35: # define A_PL 9                /* + */
                     36: # define A_MI 10               /* - */
                     37: # define A_EQ 11               /* = */
                     38: # define A_NOT 12              /* ! */
                     39: # define A_LT 13               /* < */
                     40: # define A_GT 14               /* > */
                     41: # define A_AND 16              /* & */
                     42: # define A_OR 17               /* | */
                     43: # define A_WS 18               /* whitespace (not \n) */
                     44: # define A_NL 19               /* \n */
                     45: 
                     46: /* character classes */
                     47: 
                     48: # define LEXLET 01
                     49: # define LEXDIG 02
                     50: # define LEXOCT 04
                     51: # define LEXHEX 010
                     52: # define LEXWS 020
                     53: # define LEXDOT 040
                     54: 
                     55: /* reserved word actions */
                     56: 
                     57: # define AR_TY 0               /* type word */
                     58: # define AR_RW 1               /* simple reserved word */
                     59: # define AR_CL 2               /* storage class word */
                     60: # define AR_S 3                /* struct */
                     61: # define AR_U 4                /* union */
                     62: # define AR_E 5                /* enum */
                     63: # define AR_A 6                /* asm */
                     64: 
                     65: /* text buffer */
                     66: # define LXTSZ BUFSIZ          /* lots of room for FLEXNAMES */
                     67: char yytext[LXTSZ];
                     68: char * lxgcp;
                     69: /* If TRUNCATE is undefined, let -T determine whether symbols are truncated.
                     70: ** Otherwise, forcibly truncate all names.
                     71: */
                     72: 
                     73: static int truncate_flag =
                     74: #ifndef        TRUNCATE
                     75: 0;             /* truncate based on -T (non-zero to truncate */
                     76: #else
                     77: 1;             /* force all names <= NCHNAM chars */
                     78: #endif
                     79: 
                     80: int zflag = 0;
                     81: 
                     82: 
                     83: /* ARGSUSED */
                     84: mainp1( argc, argv )
                     85: int argc;
                     86: char *argv[];
                     87: {
                     88:        /* control multiple files */
                     89: 
                     90:        register i;
                     91:        register char *cp;
                     92:        extern int idebug, bdebug, tdebug, edebug, ddebug, xdebug, opdebug;
                     93:        extern int asdebug, nowarn, proflag, bothdebug, syncstdio, Pflag;
                     94:        extern unsigned int maxoffset;
                     95:        int fdef = 0;
                     96: 
                     97:        unsigned int temp = 1;
                     98:        i = 0;
                     99:        do {
                    100:                temp <<= 1;
                    101:                ++i;
                    102:        } while ( temp != 0 );
                    103:        maxoffset = 1 << (i-1);
                    104: 
                    105:        for( i=1; i<argc; ++i ) {
                    106:                if( *(cp=argv[i]) == '-' && *++cp == 'X' ) {
                    107:                        while( *++cp ) switch(++syncstdio, *cp) {
                    108:                        case 'P': ++Pflag; break;
                    109:                        case 'B':
                    110:                                ++bothdebug; break;
                    111:                        case 'd':
                    112:                                ++ddebug; break;
                    113:                        case 'i':
                    114:                                ++idebug; break;
                    115:                        case 'b':
                    116:                                ++bdebug; break;
                    117:                        case 't':
                    118:                                ++tdebug; break;
                    119:                        case 'e':
                    120:                                ++edebug; break;
                    121:                        case 'x':
                    122:                                ++xdebug; break;
                    123:                        case 'o':
                    124:                                ++opdebug; break;
                    125:                        case 'p':
                    126:                                ++proflag; break;
                    127:                        case 's':
                    128:                                ++asdebug; --syncstdio; break;
                    129:                        case 'w':
                    130:                                ++nowarn; --syncstdio; break;
                    131:                        case 'z':       /* stin file debug info */
                    132:                                ++zflag; break;
                    133:                        case 'T':       /* truncate names */
                    134:                                ++truncate_flag; break;
                    135:                        default:
                    136:                                cerror( "bad option: X%c", *cp );
                    137:                        }
                    138:                } else {
                    139:                        if( *(argv[i]) != '-' ) switch( fdef++ ) {
                    140:                        case 0:
                    141:                                close(0);
                    142:                                if (open(argv[i], 0) == 0) break;
                    143:                                fprintf(stderr, "ccom: can't open %s\n", argv[i]);
                    144:                                exit(1);
                    145: 
                    146:                        case 1:
                    147:                                if (freopen(argv[i], "w", stdout)) break;
                    148:                                fprintf(stderr, "ccom: can't open %s\n", argv[i]);
                    149:                                exit(1);
                    150: 
                    151:                        default:
                    152:                                ;
                    153:                        }
                    154:                }
                    155:        }
                    156:        if (isatty(1)) ++syncstdio;
                    157: 
                    158:        p2init( argc, argv );
                    159: 
                    160:        for( i=0; i<SYMTSZ; ++i ) stab[i].stype = TNULL;
                    161: 
                    162:        lxinit();
                    163:        tinit();
                    164:        mkdope();
                    165: 
                    166:        /* dimension table initialization */
                    167: 
                    168:        dimtab[NULL] = 0;
                    169:        dimtab[VOID] = 0;
                    170:        dimtab[CHAR] = SZCHAR;
                    171:        dimtab[INT] = SZINT;
                    172:        dimtab[FLOAT] = SZFLOAT;
                    173:        dimtab[DOUBLE] = SZDOUBLE;
                    174:        dimtab[LONG] = SZLONG;
                    175:        dimtab[SHORT] = SZSHORT;
                    176:        dimtab[UCHAR] = SZCHAR;
                    177:        dimtab[USHORT] = SZSHORT;
                    178:        dimtab[UNSIGNED] = SZINT;
                    179:        dimtab[ULONG] = SZLONG;
                    180:        /* starts past any of the above */
                    181:        curdim = 16;
                    182:        reached = 1;
                    183: 
                    184:        yyparse();
                    185:        yyaccpt();
                    186: 
                    187: # ifdef GDEBUG
                    188:        ejsdb();
                    189: # endif
                    190: # ifdef ENDJOB
                    191:        ENDJOB(nerrors?1:0);
                    192: # endif
                    193:        return(nerrors?1:0);
                    194: 
                    195: }
                    196: 
                    197: # ifdef ibm
                    198: 
                    199: # define CSMASK 0377
                    200: # define CSSZ 256
                    201: 
                    202: # else
                    203: 
                    204: # define CSMASK 0177
                    205: # define CSSZ 128
                    206: 
                    207: # endif
                    208: 
                    209: /*
                    210: *      We buffer the input on a line by line basis
                    211: *      so that we can output the ``C'' source as comments
                    212: *      in the assembly language
                    213: */
                    214: int    asdebug = 0;
                    215: static char    linebuf[BUFSIZ+1];
                    216: static char    *linecp = &linebuf[0], *endcp = &linebuf[0];
                    217: #undef ungetc
                    218: #undef getchar
                    219: 
                    220: #define        getchar()       (*linecp ? *linecp++ : eatline() )
                    221: #define        ungetchar()     --linecp
                    222: #define        ungetc(c)       *--linecp=(c)
                    223: 
                    224: eatline()
                    225: {
                    226:        static int savechar; char *index(), *memcpy();
                    227:        register n; register char *cp;
                    228:        if (asdebug) for (*linecp = savechar, n = 0;;) {
                    229:                if ((cp = index(linecp, '\n')) || (cp = endcp-1, n)) {
                    230:                        savechar = *++cp;
                    231:                        *cp = '\0';
                    232:                        spitline(linecp);
                    233:                        return *linecp++;
                    234:                }
                    235:                linecp = memcpy(linebuf, linecp, n = endcp - linecp);
                    236:                if ((n = read(0, endcp = linebuf + n, BUFSIZ - n)) <= 0) {
                    237:                        *(endcp = linebuf) = '\0';
                    238:                        return EOF;
                    239:                }
                    240:                *(endcp += n) = '\0';
                    241:        } else {
                    242:                if ((n = read(0, linebuf, BUFSIZ)) <= 0) {
                    243:                        (linecp = linebuf)[0] = 0;
                    244:                        return EOF;
                    245:                } else {
                    246:                        (linecp = linebuf)[n] = 0;
                    247:                        return *linecp++;
                    248:                }
                    249:        }
                    250: }
                    251: 
                    252: /*
                    253: ** add the original C line to the assembler output as comment,
                    254: ** unless it is empty.
                    255: */
                    256: #define        MARKERCNT       20      /* how often to spit out line markers */
                    257: spitline(l)
                    258: register char *l;
                    259: {
                    260:        extern int lineno;
                    261: 
                    262:        if( !(lineno%MARKERCNT) )
                    263:                printx( "%s -- line %d %s\n", COMMENTSTR, lineno, ftitle );
                    264:                                /* line marker */
                    265:        while( isspace( *l ) )
                    266:                l++;
                    267:        if( *l )
                    268:                printx( "%s %s", COMMENTSTR, l );
                    269: }
                    270: 
                    271: short lxmask[CSSZ+1];
                    272: 
                    273: lxenter( s, m )
                    274: register char *s;
                    275: register short m;
                    276: {
                    277:        /* enter a mask into lxmask */
                    278:        register c;
                    279: 
                    280:        while( c= *s++ ) lxmask[c+1] |= m;
                    281: 
                    282: }
                    283: 
                    284: 
                    285: # define lxget(c,m) (lxgcp=yytext,lxmore(c,m))
                    286: 
                    287: lxmore( c, m )
                    288: register c, m;
                    289: {
                    290:        register char *cp;
                    291: 
                    292:        *(cp = lxgcp) = c;
                    293:        while ((c = getchar()), lxmask[c+1]&m) {
                    294:                if( cp < &yytext[LXTSZ-1])
                    295:                        *++cp = c;
                    296:        }
                    297:        ungetchar();
                    298:        *(lxgcp = cp+1) = '\0';
                    299: }
                    300: 
                    301: struct lxdope
                    302: {
                    303:        short lxch;     /* the character */
                    304:        short lxact;    /* the action to be performed */
                    305:        short lxtok;    /* the token number to be returned */
                    306:        short lxval;    /* the value to be returned */
                    307: } lxdope[] =
                    308: {
                    309:        '$',    A_ERR,  0,      0,      /* illegal characters go here... */
                    310:        '_',    A_LET,  0,      0,      /* letters point here */
                    311:        '0',    A_DIG,  0,      0,      /* digits point here */
                    312:        ' ',    A_WS,   0,      0,      /* whitespace goes here */
                    313:        '\n',   A_NL,   0,      0,
                    314:        '"',    A_STR,  0,      0,      /* character string */
                    315:        '\'',   A_CC,   0,      0,      /* character constant */
                    316:        '`',    A_BCD,  0,      0,      /* GCOS BCD constant */
                    317:        '(',    A_1C,   LP,     0,
                    318:        ')',    A_1C,   RP,     0,
                    319:        '{',    A_1C,   LC,     0,
                    320:        '}',    A_1C,   RC,     0,
                    321:        '[',    A_1C,   LB,     0,
                    322:        ']',    A_1C,   RB,     0,
                    323:        '*',    A_1C,   MUL,    MUL,
                    324:        '?',    A_1C,   QUEST,  0,
                    325:        ':',    A_1C,   COLON,  0,
                    326:        '+',    A_PL,   PLUS,   PLUS,
                    327:        '-',    A_MI,   MINUS,  MINUS,
                    328:        '/',    A_SL,   DIVOP,  DIV,
                    329:        '%',    A_1C,   DIVOP,  MOD,
                    330:        '&',    A_AND,  AND,    AND,
                    331:        '|',    A_OR,   OR,     OR,
                    332:        '^',    A_1C,   ER,     ER,
                    333:        '!',    A_NOT,  UNOP,   NOT,
                    334:        '~',    A_1C,   UNOP,   COMPL,
                    335:        ',',    A_1C,   CM,     CM,
                    336:        ';',    A_1C,   SM,     0,
                    337:        '.',    A_DOT,  STROP,  DOT,
                    338:        '<',    A_LT,   RELOP,  LT,
                    339:        '>',    A_GT,   RELOP,  GT,
                    340:        '=',    A_EQ,   ASSIGN, ASSIGN,
                    341:        -1,     A_1C,   0,      0,
                    342: };
                    343: 
                    344: struct lxdope *lxcp[CSSZ+1];
                    345: 
                    346: lxinit()
                    347: {
                    348:        register struct lxdope *p;
                    349:        register i;
                    350:        register char *cp;
                    351:        /* set up character classes */
                    352: 
                    353:        lxenter( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_", LEXLET );
                    354:        lxenter( "0123456789", LEXDIG );
                    355:        lxenter( "0123456789abcdefABCDEF", LEXHEX );
                    356:        /* \013 should become \v someday; \013 is OK for ASCII and EBCDIC */
                    357:        lxenter( " \t\r\b\f\013", LEXWS );
                    358:        lxenter( "01234567", LEXOCT );
                    359:        lxmask['.'+1] |= LEXDOT;
                    360:        lxhinit();
                    361: 
                    362:        /* make lxcp point to appropriate lxdope entry for each character */
                    363: 
                    364:        /* initialize error entries */
                    365: 
                    366:        for( i= 0; i<=CSSZ; ++i ) lxcp[i] = lxdope;
                    367: 
                    368:        /* make unique entries */
                    369: 
                    370:        for( p=lxdope; ; ++p )
                    371:        {
                    372:                lxcp[p->lxch+1] = p;
                    373:                if( p->lxch < 0 ) break;
                    374:        }
                    375: 
                    376:        /* handle letters, digits, and whitespace */
                    377:        /* by convention, first, second, and third places */
                    378: 
                    379:        cp = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
                    380:        while( *cp ) lxcp[*cp++ + 1] = &lxdope[1];
                    381:        cp = "123456789";
                    382:        while( *cp ) lxcp[*cp++ + 1] = &lxdope[2];
                    383:        cp = "\t\b\r\f\013";
                    384:        while( *cp ) lxcp[*cp++ + 1] = &lxdope[3];
                    385: 
                    386:        /* first line might have title */
                    387:        lineno = 1;
                    388:        lxtitle();
                    389: 
                    390: }
                    391: 
                    392: int lxmatch;  /* character to be matched in char or string constant */
                    393: 
                    394: lxstr(ct)
                    395: register ct;
                    396: {
                    397:        /* match a string or character constant, up to lxmatch */
                    398: 
                    399:        register c, val, i = 0;
                    400: 
                    401:        while ((c = getchar()) != lxmatch) {
                    402:                switch( c ) {
                    403: 
                    404:                case EOF:
                    405:                        uerror( "lxstr() unexpected EOF" );
                    406:                        break;
                    407: 
                    408:                case '\n':
                    409:                        uerror( "newline in string or char constant" );
                    410:                        ++lineno;
                    411:                        break;
                    412: 
                    413:                case '\\':
                    414:                        switch (c = getchar()) {
                    415:                        case '\n':
                    416:                                ++lineno; continue;
                    417:                        default:
                    418:                                val = c; goto mkcc;
                    419:                        case 'n':
                    420:                                val = '\n'; goto mkcc;
                    421:                        case 'r':
                    422:                                val = '\r'; goto mkcc;
                    423:                        case 'b':
                    424:                                val = '\b'; goto mkcc;
                    425:                        case 't':
                    426:                                val = '\t'; goto mkcc;
                    427:                        case 'f':
                    428:                                val = '\f'; goto mkcc;
                    429:                        case 'v':
                    430:                                val = '\013'; goto mkcc;
                    431:                        case '0': case '1': case '2': case '3':
                    432:                        case '4': case '5': case '6': case '7':
                    433:                                val = c-'0';
                    434:                                c = getchar();  /* try for 2 */
                    435:                                if (lxmask[c+1] & LEXOCT) {
                    436:                                        val = (val<<3) | (c-'0');
                    437:                                        c = getchar();  /* try for 3 */
                    438:                                        if (lxmask[c+1] & LEXOCT)
                    439:                                                val = (val<<3) | (c-'0');
                    440:                                        else
                    441:                                                ungetchar();
                    442:                                } else
                    443:                                        ungetchar();
                    444:                                goto mkcc1;
                    445:                        }
                    446:                default:
                    447:                        val =c;
                    448: mkcc:
                    449:                        val = CCTRANS(val);
                    450: mkcc1:
                    451:                        if (lxmatch == '\'') {
                    452:                                /* it is, after all, a "character" constant */
                    453:                                val = ccast((CONSZ)val,CHAR);
                    454:                                if (i == 0)
                    455:                                        lastcon = val;
                    456:                                else {
                    457: # ifdef MAKECC
                    458:                                        MAKECC( val, i );
                    459: # else
                    460: # ifdef RTOLBYTES
                    461:                                        lastcon <<= SZCHAR;
                    462:                                        lastcon |= (val&BITMASK(SZCHAR));
                    463: # else
                    464:                                        lastcon &= BITMASK(SZCHAR*i);
                    465:                                        lastcon |= val << (SZCHAR*i);
                    466: # endif
                    467: # endif
                    468:                                }
                    469:                        } else {
                    470:                                 /* stash the byte into the string */
                    471:                                if (strflg) {
                    472:                                        if (ct==0 || i<ct)
                    473:                                                putbyte( val );
                    474:                                        else
                    475:                                                if( i == ct )
                    476:                                                        werror(
                    477:                                "non-null byte ignored in string initializer" );
                    478:                                } else
                    479:                                        bycode( val, i );
                    480:                        }
                    481:                        ++i;
                    482:                        continue;
                    483:                }
                    484:                break;
                    485:        }
                    486:        /* end of string or char constant */
                    487: 
                    488:        if (lxmatch == '"') {
                    489:                if (strflg) {   /* end the string */
                    490:                        if (ct==0 || i<ct)
                    491:                                putbyte( 0 );  /* the null at the end */
                    492:                } else {        /* the initializer gets a null byte */
                    493:                        bycode( 0, i++ );
                    494:                        bycode( -1, i );
                    495:                        dimtab[curdim] = i;  /* in case of later sizeof ... */
                    496:                }
                    497:        } else {        /* end the character constant */
                    498:                if (i == 0)
                    499:                        uerror( "empty character constant" );
                    500:                if (i>(SZINT/SZCHAR) || ((pflag||hflag)&&i>1))
                    501:                        uerror( "too many characters in character constant" );
                    502:        }
                    503: }
                    504: 
                    505: lxcom()
                    506: {
                    507:        register c;
                    508:        /* saw a /*: process a comment */
                    509: 
                    510:        for (;;) {
                    511:                switch (c = getchar()) {
                    512: 
                    513:                case EOF:
                    514:                        uerror( "lxcom() unexpected EOF" );
                    515:                        return;
                    516: 
                    517:                case '\n':
                    518:                        ++lineno;
                    519: 
                    520:                default:
                    521:                        continue;
                    522: 
                    523:                case '*':
                    524:                        if( (c = getchar()) == '/' ) return;
                    525:                        else ungetchar();
                    526:                        continue;
                    527: 
                    528:                }
                    529:        }
                    530: }
                    531: 
                    532: #define Return(e)      return(yylval.lineno = lineno, (e))
                    533: 
                    534: yylex()
                    535: {
                    536:        for(;;)
                    537:        {
                    538: 
                    539:                register lxchar;
                    540:                register struct lxdope *p;
                    541:                register struct symtab *sp;
                    542:                register char *cp;
                    543:                register id;
                    544: 
                    545:                switch( (p = lxcp[(lxchar = getchar())+1])->lxact )
                    546:                {
                    547: 
                    548: onechar:
                    549:                        ungetc( lxchar );
                    550: 
                    551:                case A_1C:
                    552:                        /* eat up a single character, and return an opcode */
                    553: 
                    554:                        yylval.intval = p->lxval;
                    555:                        Return( p->lxtok );
                    556: 
                    557:                case A_ERR:
                    558:                        uerror( "illegal character: %03o (octal)", lxchar );
                    559:                        break;
                    560: 
                    561:                case A_LET:
                    562:                        /* collect an identifier, and check for reserved word */
                    563:                        lxget( lxchar, LEXLET|LEXDIG );
                    564: 
                    565:                        /* 0 means some kind of low level error, >0 reserved,
                    566:                        ** <0 means id
                    567:                        */
                    568:                        if( (lxchar=lxres()) > 0 ) Return( lxchar );
                    569:                        if( lxchar== 0 ) continue;
                    570: 
                    571:                        if (truncate_flag )
                    572:                                yytext[NCHNAM] = '\0';  /* truncate name */
                    573:                        id = lookup( hash(yytext),
                    574:                                        /* tag name for struct/union/enum */
                    575:                                (stwart&TAGNAME)? STAG:
                    576:                                        /* member name for struct/union */
                    577:                                (stwart&(INSTRUCT|INUNION|FUNNYNAME))?SMOS:0 );
                    578:                        sp = &stab[id];
                    579:                        if( sp->sclass == TYPEDEF && !stwart )
                    580:                        {
                    581:                                stwart = instruct;
                    582:                                yylval.nodep = mkty( sp->stype, sp->dimoff,
                    583:                                sp->sizoff );
                    584:                                Return( TYPE );
                    585:                        }
                    586:                        stwart = (stwart&SEENAME) ? instruct : 0;
                    587:                        yylval.intval = id;
                    588:                        Return( NAME );
                    589: 
                    590:                case A_DIG:
                    591:                        /* collect a digit string, then look at last one... */
                    592:                        lastcon = 0;
                    593:                        lxget( lxchar, LEXDIG );
                    594:                        switch( lxchar = getchar() )
                    595:                        {
                    596: 
                    597:                        case 'x':
                    598:                        case 'X':
                    599:                                if( yytext[0] != '0' && !yytext[1] )
                    600:                                        uerror( "illegal hex constant" );
                    601:                                lxmore( lxchar, LEXHEX );
                    602:                                /* convert the value */
                    603:                                {
                    604:                                        for( cp = yytext+2; *cp; ++cp )
                    605:                                        {
                    606:                                                /* this code won't work for all character sets,
                    607:                                                ** but seems ok for ascii and ebcdic
                    608:                                                */
                    609:                                                lastcon <<= 4;
                    610:                                                if( isdigit( *cp ) )
                    611:                                                        lastcon += *cp-'0';
                    612:                                                else if( isupper( *cp ) )
                    613:                                                        lastcon += *cp - 'A'+ 10;
                    614:                                                else
                    615:                                                        lastcon += *cp - 'a'+ 10;
                    616:                                        }
                    617:                                }
                    618: 
                    619: hexlong:
                    620:                                /* hex and octal constants are long if they
                    621:                                ** fit within 0177777
                    622:                                */
                    623:                                if( lastcon & ~0177777L ) yylval.intval = 1;
                    624:                                else yylval.intval = 0;
                    625: 
                    626:                                goto islong;
                    627: 
                    628:                        case '.':
                    629:                                lxmore( lxchar, LEXDIG );
                    630: 
                    631: getfp:
                    632:                                if( (lxchar = getchar()) == 'e' || lxchar == 'E' )
                    633:                                {
                    634:                                         /* exponent */
                    635:                                case 'e':
                    636:                                case 'E':
                    637:                                        if( (lxchar = getchar()) == '+' ||
                    638:                                            lxchar == '-' )
                    639:                                        {
                    640:                                                *lxgcp++ = 'e';
                    641:                                        }
                    642:                                        else
                    643:                                        {
                    644:                                                ungetc(lxchar);
                    645:                                                lxchar = 'e';
                    646:                                        }
                    647:                                        lxmore( lxchar, LEXDIG );
                    648:                                        /* now have the whole thing... */
                    649:                                }
                    650:                                else
                    651:                                {
                    652:                                          /* no exponent */
                    653:                                        ungetc( lxchar );
                    654:                                }
                    655: # ifdef NOFLOAT
                    656:                                if( !flflag )
                    657:                                {
                    658:                                        flflag = 1;
                    659:                                        werror( "sorry, no floating point" );
                    660:                                }
                    661:                                for( cp = yytext; *cp; ++cp )
                    662:                                {
                    663:                                        if( *cp == 'e' || *cp == 'E' ||
                    664:                                            *cp == '.' )
                    665:                                        {
                    666:                                                *cp = '\0';
                    667:                                                break;
                    668:                                        }
                    669:                                }
                    670:                                goto conv10;
                    671: # else
                    672:                                flflag = 1;
                    673:                                dcon = FLOATCVT(yytext);
                    674:                                Return( FCON );
                    675: # endif
                    676: 
                    677:                        default:
                    678:                                ungetc( lxchar );
                    679:                                if( yytext[0] == '0' )
                    680:                                {
                    681:                                        /* convert in octal */
                    682:                                        for( cp = yytext+1; *cp; ++cp )
                    683:                                        {
                    684:                                                lastcon <<= 3;
                    685:                                                lastcon += *cp - '0';
                    686:                                        }
                    687:                                        goto hexlong;
                    688:                                }
                    689:                                else
                    690:                                {
                    691:                                        /* convert in decimal */
                    692: # ifdef NOFLOAT
                    693: conv10:
                    694: # endif
                    695:                                        for( cp = yytext; *cp; ++cp )
                    696:                                        {
                    697:                                                lastcon = lastcon*10 + *cp - '0';
                    698:                                        }
                    699:                                }
                    700: 
                    701:                                /* decide if it is long or not (decimal case) */
                    702: 
                    703:                                /* if it is positive and fits in 15 bits,
                    704:                                ** or negative and and fits in 15 bits
                    705:                                ** with an extended sign, it is int;
                    706:                                ** otherwise long
                    707:                                */
                    708:                                /* if there is an l or L following,
                    709:                                ** all bets are off...
                    710:                                */
                    711: 
                    712:                                {
                    713:                                        register CONSZ v;
                    714:                                        v = lastcon & ~077777L;
                    715:                                        if( v == 0 || v == ~077777L )
                    716:                                                yylval.intval = 0;
                    717:                                        else yylval.intval = 1;
                    718:                                }
                    719: 
                    720: islong:
                    721:                                /* finally, look for trailing L or l */
                    722:                                if( (lxchar=getchar()) == 'L' || lxchar == 'l' )
                    723:                                                yylval.intval = 1;
                    724:                                else ungetc( lxchar );
                    725:                                Return( ICON );
                    726:                        }
                    727: 
                    728:                case A_DOT:
                    729:                        /* a dot: if followed by a digit, floating point */
                    730:                        lxchar = getchar();
                    731:                        if( lxmask[lxchar+1] & LEXDIG )
                    732:                        {
                    733:                                ungetc(lxchar);
                    734:                                lxget( '.', LEXDIG );
                    735:                                goto getfp;
                    736:                        }
                    737:                        stwart = FUNNYNAME;
                    738:                        goto onechar;
                    739: 
                    740:                case A_STR:
                    741:                        /* string constant */
                    742:                        lxmatch = '"';
                    743:                        Return( STRING );
                    744: 
                    745:                case A_CC:
                    746:                        /* character constant */
                    747:                        lxmatch = '\'';
                    748:                        lastcon = 0;
                    749:                        lxstr(0);
                    750:                        yylval.intval = 0;
                    751:                        Return( ICON );
                    752: 
                    753:                case A_SL:
                    754:                        /* / */
                    755:                        if( (lxchar = getchar()) != '*' ) goto onechar;
                    756:                        lxcom();
                    757:                case A_WS:
                    758:                        continue;
                    759: 
                    760:                case A_NL:
                    761:                        ++lineno;
                    762:                        lxtitle();
                    763:                        continue;
                    764: 
                    765:                case A_NOT:
                    766:                        /* ! */
                    767:                        if( (lxchar = getchar()) != '=' ) goto onechar;
                    768:                        yylval.intval = NE;
                    769:                        Return( EQUOP );
                    770: 
                    771:                case A_MI:
                    772:                        /* - */
                    773:                        if( (lxchar = getchar()) == '-' )
                    774:                        {
                    775:                                yylval.intval = DECR;
                    776:                                Return( INCOP );
                    777:                        }
                    778:                        if( lxchar != '>' ) goto onechar;
                    779:                        stwart = FUNNYNAME;
                    780:                        yylval.intval=STREF;
                    781:                        Return( STROP );
                    782: 
                    783:                case A_PL:
                    784:                        /* + */
                    785:                        if( (lxchar = getchar()) != '+' ) goto onechar;
                    786:                        yylval.intval = INCR;
                    787:                        Return( INCOP );
                    788: 
                    789:                case A_AND:
                    790:                        /* & */
                    791:                        if( (lxchar = getchar()) != '&' ) goto onechar;
                    792:                        Return( yylval.intval = ANDAND );
                    793: 
                    794:                case A_OR:
                    795:                        /* | */
                    796:                        if( (lxchar = getchar()) != '|' ) goto onechar;
                    797:                        Return( yylval.intval = OROR );
                    798: 
                    799:                case A_LT:
                    800:                        /* < */
                    801:                        if( (lxchar = getchar()) == '<' )
                    802:                        {
                    803:                                yylval.intval = LS;
                    804:                                Return( SHIFTOP );
                    805:                        }
                    806:                        if( lxchar != '=' ) goto onechar;
                    807:                        yylval.intval = LE;
                    808:                        Return( RELOP );
                    809: 
                    810:                case A_GT:
                    811:                        /* > */
                    812:                        if( (lxchar = getchar()) == '>' )
                    813:                        {
                    814:                                yylval.intval = RS;
                    815:                                Return(SHIFTOP );
                    816:                        }
                    817:                        if( lxchar != '=' ) goto onechar;
                    818:                        yylval.intval = GE;
                    819:                        Return( RELOP );
                    820: 
                    821:                case A_EQ:
                    822:                        /* = */
                    823:                        switch( lxchar = getchar() )
                    824:                        {
                    825: 
                    826:                        case '=':
                    827:                                yylval.intval = EQ;
                    828:                                Return( EQUOP );
                    829: 
                    830:                        default:
                    831:                                goto onechar;
                    832: 
                    833:                        }
                    834: 
                    835: 
                    836:                default:
                    837:                        cerror( "yylex error, character %03o (octal)", lxchar );
                    838: 
                    839:                }
                    840: 
                    841:                /* ordinarily, repeat here... */
                    842:                cerror( "out of switch in yylex" );
                    843: 
                    844:        }
                    845: 
                    846: }
                    847: 
                    848: struct lxrdope
                    849: {
                    850:        /* dope for reserved, in alphabetical order */
                    851: 
                    852:        char *lxrch;    /* name of reserved word */
                    853:        short lxhash;
                    854:        short lxract;   /* reserved word action */
                    855:        short lxrval;   /* value to be returned */
                    856: } lxrdope[] =
                    857: {
                    858:        "asm",          0,      AR_A,   0,
                    859:        "auto",         0,      AR_CL,  AUTO,
                    860:        "break",        0,      AR_RW,  BREAK,
                    861:        "case",         0,      AR_RW,  CASE,
                    862:        "char",         0,      AR_TY,  CHAR,
                    863:        "continue",     0,      AR_RW,  CONTINUE,
                    864:        "default",      0,      AR_RW,  DEFAULT,
                    865:        "do",           0,      AR_RW,  DO,
                    866:        "double",       0,      AR_TY,  DOUBLE,
                    867:        "else",         0,      AR_RW,  ELSE,
                    868:        "enum",         0,      AR_E,   ENUM,
                    869:        "extern",       0,      AR_CL,  EXTERN,
                    870: #ifdef ONEFLOAT
                    871:        "float",        0,      AR_TY,  DOUBLE,
                    872: #else
                    873:        "float",        0,      AR_TY,  FLOAT,
                    874: #endif
                    875:        "for",          0,      AR_RW,  FOR,
                    876:        "fortran",      0,      AR_CL,  FORTRAN,
                    877:        "goto",         0,      AR_RW,  GOTO,
                    878:        "if",           0,      AR_RW,  IF,
                    879:        "int",          0,      AR_TY,  INT,
                    880:        "long",         0,      AR_TY,  LONG,
                    881:        "register",     0,      AR_CL,  REGISTER,
                    882:        "return",       0,      AR_RW,  RETURN,
                    883:        "short",        0,      AR_TY,  SHORT,
                    884:        "sizeof",       0,      AR_RW,  SIZEOF,
                    885:        "static",       0,      AR_CL,  STATIC,
                    886:        "struct",       0,      AR_S,   0,
                    887:        "switch",       0,      AR_RW,  SWITCH,
                    888:        "typedef",      0,      AR_CL,  TYPEDEF,
                    889:        "union",        0,      AR_U,   0,
                    890:        "unsigned",     0,      AR_TY,  UNSIGNED,
                    891:        "void",         0,      AR_TY,  VOID,
                    892:        "while",        0,      AR_RW,  WHILE,
                    893:        0,              0,      0,      0,
                    894: };
                    895: 
                    896: #define HASH(s)        (((lxrch0[(s)[0]&037]<<4) | lxrch2[(s)[2]&037]) & 0377)
                    897: 
                    898: unsigned char lxrch0[040], lxrch2[040], lxrindx[0400];
                    899: 
                    900: lxhinit()
                    901: {
                    902:        register struct lxrdope *lp; struct lxrdope dptemp;
                    903:        register char *s; register j;
                    904:        int k0, k2;
                    905:        for (lp = lxrdope; s = lp->lxrch; ++lp) {
                    906:                ++lxrch0[s[0] & 037];
                    907:                ++lxrch2[s[2] & 037];
                    908:        }
                    909:        for (k0=k2=j=0; j<040; j++) {
                    910:                if (lxrch0[j]) lxrch0[j] = ++k0;
                    911:                if (lxrch2[j]) lxrch2[j] = ++k2;
                    912:        }
                    913:        for (lp = lxrdope; s = lp->lxrch; ++lp)
                    914:                lp->lxhash = HASH(s);
                    915:        do {
                    916:                j = 0;
                    917:                for (lp = lxrdope+1; lp->lxrch; ++lp)
                    918:                        if (lp->lxhash < (lp-1)->lxhash) {
                    919:                                dptemp = *lp;
                    920:                                *lp = *(lp-1);
                    921:                                *(lp-1) = dptemp;
                    922:                                ++j;
                    923:                        }
                    924:        } while (j);
                    925:        for (k0 = 1, lp = lxrdope; s = lp->lxrch; ++lp, ++k0)
                    926:                if (lxrindx[j = lp->lxhash] == 0)
                    927:                        lxrindx[j] = k0;
                    928: /*
                    929:        for (lp = lxrdope; lp->lxrch; ++lp)
                    930:                printf("%d %d %s\n", lxrindx[lp->lxhash], lp->lxhash, lp->lxrch);
                    931: */
                    932: }
                    933: 
                    934: lxres()
                    935: {
                    936:        /*
                    937:        ** check to see of yytext is reserved; if so,
                    938:        ** do the appropriate action and return
                    939:        ** otherwise, return -1
                    940:        */
                    941:        register c;
                    942:        register struct lxrdope *p;
                    943: 
                    944:        if (yytext[1] == 0) return -1;
                    945: 
                    946:        if ((c = HASH(yytext)) == 0 || (c = lxrindx[c]) == 0) return -1;
                    947: 
                    948:        p = lxrdope + c - 1;
                    949:        do if (strcmp(yytext, p->lxrch) == 0) switch (p->lxract) {
                    950: 
                    951:        case AR_TY:     /* type word */
                    952:                stwart = instruct;
                    953:                yylval.nodep = mkty( (TWORD)p->lxrval, 0, p->lxrval );
                    954:                if (p->lxrval==FLOAT || p->lxrval==DOUBLE) {
                    955: # ifdef NOFLOAT
                    956:                        if (!flflag)
                    957:                                werror( "sorry, no floating point" );
                    958:                        yylval.nodep->tn.type = LONG;
                    959: # endif
                    960:                        flflag = 1;
                    961:                }
                    962:                return( TYPE );
                    963: 
                    964:        case AR_RW:     /* ordinary reserved word */
                    965:                return( yylval.intval = p->lxrval );
                    966: 
                    967:        case AR_CL:     /* class word */
                    968:                yylval.intval = p->lxrval;
                    969:                return( CLASS );
                    970: 
                    971:        case AR_S:      /* struct */
                    972:                stwart = INSTRUCT|SEENAME|TAGNAME;
                    973:                yylval.intval = INSTRUCT;
                    974:                return( STRUCT );
                    975: 
                    976:        case AR_U:      /* union */
                    977:                stwart = INUNION|SEENAME|TAGNAME;
                    978:                yylval.intval = INUNION;
                    979:                return( STRUCT );
                    980: 
                    981:        case AR_E:      /* enums */
                    982:                stwart = SEENAME|TAGNAME;
                    983:                return( yylval.intval = ENUM );
                    984: 
                    985:        case AR_A:      /* asm */
                    986:                asm_esc = 1; /* warn the world! */
                    987:                lxget(' ', LEXWS);
                    988:                if (getchar() != '(') goto badasm;
                    989:                lxget(' ', LEXWS);
                    990:                if (getchar() != '"') goto badasm;
                    991:                asmp = asmbuf;
                    992:                while ((c = getchar()) != '"') {
                    993:                        if (c=='\n' || c==EOF) goto badasm;
                    994:                        *asmp++ = c;
                    995:                        if (asmp >= &asmbuf[ASMBUF-1])
                    996:                                uerror( "asm > %d chars", ASMBUF);
                    997:                }
                    998:                lxget(' ', LEXWS);
                    999:                if( getchar() != ')' ) goto badasm;
                   1000:                *asmp++ = '\0';
                   1001:                return( ASM );
                   1002: badasm:
                   1003:                uerror( "bad asm construction" );
                   1004:                return( 0 );
                   1005: 
                   1006:        default:
                   1007:                cerror("bad AR_?? action");
                   1008:        } while ((++p)->lxhash == c);
                   1009:        return -1;
                   1010: }
                   1011: 
                   1012: lxtitle()
                   1013: {
                   1014:        /* called after a newline; set linenumber and file name */
                   1015: 
                   1016:        register c, val; register char *cp;
                   1017: 
                   1018:        for(;;) {       /* might be several such lines in a row */
                   1019:                if ((c = getchar()) != '#') {
                   1020:                        if (c != EOF) ungetchar();
                   1021:                        return;
                   1022:                }
                   1023:                lxget( ' ', LEXWS);
                   1024:                val = 0;
                   1025:                for (c = getchar(); isdigit(c); c = getchar())
                   1026:                        val = val*10+ c - '0';
                   1027:                ungetchar();
                   1028:                lineno = val;
                   1029:                lxget(' ', LEXWS);
                   1030:                if ((c = getchar()) != '\n') {
                   1031:                        cp = ftitle; *cp++ = c;
                   1032:                        while ((c=getchar()) != '\n')
                   1033:                                *cp++ = c;
                   1034:                        *cp = '\0';
                   1035:                }
                   1036:        }
                   1037: }
                   1038: 
                   1039: # ifndef MYASMOUT
                   1040: asmout()
                   1041: {
                   1042: #ifdef GDEBUG
                   1043:        dbline();
                   1044: #endif
                   1045:        printx("%s\n%s\n%s\n", ASM_COMMENT, asmbuf, ASM_END);
                   1046: }
                   1047: # endif

unix.superglobalmegacorp.com

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