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

unix.superglobalmegacorp.com

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