# 2.11BSD#431 - /usr/src/lib/mip/scan.c

##### Functions

    hash              X
    lxcom             X
    lxenter           X
    lxinit            X
    lxmore            X
    lxres             X
    lxstr             X
    lxtitle           X
    mainp1            X
    savestr           X
    yylex             X

##### Variables

    asm_esc           X
    fpe_sigvec        X
    htab              X
    lxcp              X
    lxdope            X
    lxgcp             X
    lxmask            X
    lxmatch           X
    lxrdope           X
    oldway            X
    saveleft          X
    savetab           X
    yytext            X

##### Macros

    AR_A              X
    AR_CL             X
    AR_E              X
    AR_RW             X
    AR_S              X
    AR_TY             X
    AR_U              X
    A_1C              X
    A_AND             X
    A_BCD             X
    A_CC              X
    A_DIG             X
    A_DOT             X
    A_EQ              X
    A_ERR             X
    A_GT              X
    A_LET             X
    A_LT              X
    A_MI              X
    A_NL              X
    A_NOT             X
    A_OR              X
    A_PL              X
    A_SL              X
    A_STR             X
    A_WS              X
    CSMASK            X
    CSSZ              X
    HASHINC           X
    LEXDIG            X
    LEXDOT            X
    LEXHEX            X
    LEXLET            X
    LEXOCT            X
    LEXWS             X
    LXTSZ             X
    MAXHASH           X
    NSAVETAB          X
    lxget             X

##### struct's

    ht                X
    lxdope            X
    lxrdope           X

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

#### Defined functions

hash defined in line 1093; used 2 times

- in line 527
- in /usr/src/lib/mip/manifest.h line 91

lxcom defined in line 434; used 1 times

- in line 688

lxenter defined in line 204; used 5 times

- in line 278-283(5)

lxinit defined in line 272; used 1 times

- in line 158

lxmore defined in line 215; used 4 times

- in line 213, 554, 577, 591

lxres defined in line 871; used 1 times

- in line 524

lxstr defined in line 316; used 3 times

- in line 657
- in /usr/src/lib/mip/pftn.c line 957, 969

lxtitle defined in line 995; used 2 times

- in line 310, 694

mainp1 defined in line 75; never used
savestr defined in line 1060; used 3 times

- in line 1143
- in /usr/src/lib/mip/cgram.y line 213
- in /usr/src/lib/mip/manifest.h line 92

yylex defined in line 498; never used

#### Defined variables

asm_esc defined in line 13; used 1 times

- in line 958

fpe_sigvec defined in line 67; used 2 times

- in line 179-180(2)

htab defined in line 1091; used 2 times

- in line 1122(2)

lxcp defined in line 270; used 6 times

- in line 290-295(2), 303-307(3), 506

lxdope defined in line 233; used 5 times

- in line 290-294(2), 303-307(3)

lxgcp defined in line 62; used 4 times

- in line 213-218(2), 225, 585

lxmask defined in line 202; used 7 times

- in line 208, 219, 284, 381-384(2), 640, 766

lxmatch defined in line 314; used 5 times

- in line 324, 399, 417, 650-655(2)

lxrdope defined in line 835; used 1 times

- in line 920

oldway defined in line 68; used 1 times

- in line 128

saveleft defined in line 1058; used 6 times

- in line 1067-1071(5), 1078

savetab defined in line 1057; used 5 times

- in line 1071-1077(5)

sccsid defined in line 2; never used
yytext defined in line 61; used 46 times

- in line 213, 220, 463-465(4), 471, 480, 490, 527-529(2), 553-558(3), 597-604(3), 613, 671-676(3), 879, 921
- in /usr/src/lib/mip/scan.c line 213, 220, 463-465(4), 471, 480, 490, 527-529(2), 553-558(3), 597-604(3), 613, 671-676(3), 879, 921

#### Defined struct's

ht defined in line 1087; used 2 times

- in line 1100(2)

lxdope defined in line 228; used 6 times

- in line 270-273(4), 502(2)

lxrdope defined in line 829; used 2 times

- in line 877(2)

#### Defined macros

AR_A defined in line 53; used 1 times

- in line 837

AR_CL defined in line 49; used 6 times

- in line 838, 846-851(2), 857-863(3)

AR_E defined in line 52; used 1 times

- in line 848

AR_RW defined in line 48; used 13 times

- in line 839-860(12), 867

AR_S defined in line 50; used 1 times

- in line 859

AR_TY defined in line 47; used 8 times

- in line 840-843(2), 850-855(3), 861-866(3)

AR_U defined in line 51; used 1 times

- in line 865

A_1C defined in line 19; used 15 times

- in line 243-267(15)

A_AND defined in line 31; used 1 times

- in line 256

A_BCD defined in line 22; used 1 times

- in line 242

A_CC defined in line 21; used 1 times

- in line 241

A_DIG defined in line 18; used 1 times

- in line 237

A_DOT defined in line 24; used 1 times

- in line 263

A_EQ defined in line 27; used 1 times

- in line 266

A_ERR defined in line 16; used 1 times

- in line 235

A_GT defined in line 30; used 1 times

- in line 265

A_LET defined in line 17; used 1 times

- in line 236

A_LT defined in line 29; used 1 times

- in line 264

A_MI defined in line 26; used 1 times

- in line 253

A_NL defined in line 34; used 1 times

- in line 239

A_NOT defined in line 28; used 1 times

- in line 259

A_OR defined in line 32; used 1 times

- in line 257

A_PL defined in line 25; used 1 times

- in line 252

A_SL defined in line 23; used 1 times

- in line 254

A_STR defined in line 20; used 1 times

- in line 240

A_WS defined in line 33; used 1 times

- in line 238

CSMASK defined in line 197; never used
CSSZ defined in line 198; used 3 times

- in line 202, 270, 290

HASHINC defined in line 1086; used 6 times

- in line 1113, 1125-1129(2), 1140, 1151-1152(2)

LEXDIG defined in line 39; used 9 times

- in line 279, 459, 523, 548, 577, 591, 640-642(2), 766

LEXDOT defined in line 43; used 2 times

- in line 284, 766

LEXHEX defined in line 41; used 2 times

- in line 280, 554

LEXLET defined in line 38; used 7 times

- in line 278, 459, 470, 479, 489, 523, 766

LEXOCT defined in line 40; used 3 times

- in line 283, 381-384(2)

LEXWS defined in line 42; used 6 times

- in line 282, 959-961(2), 974, 1015, 1024

LXTSZ defined in line 59; used 3 times

- in line 61, 220, 665

MAXHASH defined in line 1085; used 2 times

- in line 1091, 1122

NSAVETAB defined in line 1056; used 1 times

- in line 1068

lxget defined in line 213; used 12 times

- in line 459, 470, 479, 489, 523, 548, 642, 959-961(2), 974, 1015, 1024

Last modified: 1995-01-18 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2955 |