# 2.11BSD#431 - /usr/src/usr.bin/yacc/y2.c

##### Functions

    chfind            X
    cpyact            X
    cpycode           X
    cpyunion          X
    cstash            X
    defin             X
    defout            X
    fdtype            X
    finact            X
    gettok            X
    setup             X
    skipcom           X

##### Variables

    cnames            X
    cnamp             X
    cnamsz            X
    extval            X
    infile            X
    levprd            X
    mem               X
    mem0              X
    ndefout           X
    nnonter           X
    nontrst           X
    nprod             X
    ntokens           X
    ntypes            X
    numbval           X
    prdptr            X
    start             X
    toklev            X
    tokname           X
    tokset            X
    typeset           X

##### Macros

    BINARY            X
    C_IDENTIFIER      X
    ENDFILE           X
    IDENTIFIER        X
    LCURLY            X
    LEFT              X
    MARK              X
    NUMBER            X
    PREC              X
    RIGHT             X
    START             X
    TERM              X
    TYPEDEF           X
    TYPENAME          X
    UNION             X

       1: #if !defined(lint) && defined(DOSCCS)
       2: static char sccsid[] = "@(#)y2.c	4.1.1	(2.11BSD)	1995/05/11";
       3: #endif
       4:
       5: # include "dextern"
       6: # define IDENTIFIER 257
       7: # define MARK 258
       8: # define TERM 259
       9: # define LEFT 260
      10: # define RIGHT 261
      11: # define BINARY 262
      12: # define PREC 263
      13: # define LCURLY 264
      14: # define C_IDENTIFIER 265  /* name followed by colon */
      15: # define NUMBER 266
      16: # define START 267
      17: # define TYPEDEF 268
      18: # define TYPENAME 269
      19: # define UNION 270
      20: # define ENDFILE 0
      21:
      22:     /* communication variables between various I/O routines */
      23:
      24: char *infile;   /* input file name */
      25: int numbval;    /* value of an input number */
      26: char tokname[NAMESIZE]; /* input token name */
      27:
      28:     /* storage of names */
      29:
      30: char cnames[CNAMSZ];    /* place where token and nonterminal names are stored */
      31: int cnamsz = CNAMSZ;    /* size of cnames */
      32: char * cnamp = cnames;  /* place where next name is to be put in */
      33: int ndefout = 3;  /* number of defined symbols output */
      34:
      35:     /* storage of types */
      36: int ntypes; /* number of types defined */
      37: char * typeset[NTYPES]; /* pointers to type tags */
      38:
      39:     /* symbol tables for tokens and nonterminals */
      40:
      41: int ntokens = 0;
      42: struct toksymb tokset[NTERMS];
      43: int toklev[NTERMS];
      44: int nnonter = -1;
      45: struct ntsymb nontrst[NNONTERM];
      46: int start;  /* start symbol */
      47:
      48:     /* assigned token type values */
      49: int extval = 0;
      50:
      51:     /* input and output file descriptors */
      52:
      53: FILE * finput;      /* yacc input file */
      54: FILE * faction;     /* file for saving actions */
      55: FILE * fdefine;     /* file for # defines */
      56: FILE * ftable;      /* y.tab.c file */
      57: FILE * ftemp;       /* tempfile to pass 2 */
      58: FILE * foutput;     /* y.output file */
      59:
      60:     /* storage for grammar rules */
      61:
      62: int mem0[MEMSIZE] ; /* production storage */
      63: int *mem = mem0;
      64: int nprod= 1;   /* number of productions */
      65: int *prdptr[NPROD]; /* pointers to descriptions of productions */
      66: int levprd[NPROD] ; /* precedence levels for the productions */
      67:
      68:
      69: setup(argc,argv) int argc; char *argv[];
      70: {   int i,lev, ty;
      71:     register int t, j;
      72:     int c;
      73:     int *p;
      74:     char actname[8];
      75:
      76:     foutput = NULL;
      77:     fdefine = NULL;
      78:     i = 1;
      79:     while( argc >= 2  && argv[1][0] == '-' ) {
      80:         while( *++(argv[1]) ){
      81:             switch( *argv[1] ){
      82:             case 'v':
      83:             case 'V':
      84:                 foutput = fopen(FILEU, "w" );
      85:                 if( foutput == NULL ) error( "cannot open y.output" );
      86:                 continue;
      87:             case 'D':
      88:             case 'd':
      89:                 fdefine = fopen( FILED, "w" );
      90:                 continue;
      91:             case 'o':
      92:             case 'O':
      93:                 fprintf( stderr, "`o' flag now default in yacc\n" );
      94:                 continue;
      95:
      96:             case 'r':
      97:             case 'R':
      98:                 error( "Ratfor Yacc is dead: sorry...\n" );
      99:
     100:             default:
     101:                 error( "illegal option: %c", *argv[1]);
     102:                 }
     103:             }
     104:         argv++;
     105:         argc--;
     106:         }
     107:
     108:     ftable = fopen( OFILE, "w" );
     109:     if( ftable == NULL ) error( "cannot open table file" );
     110:
     111:     ftemp = fopen( TEMPNAME, "w" );
     112:     faction = fopen( ACTNAME, "w" );
     113:     if( ftemp==NULL || faction==NULL ) error( "cannot open temp file" );
     114:
     115:     if( argc < 2 || ((finput=fopen( infile=argv[1], "r" )) == NULL ) ){
     116:         error( "cannot open input file" );
     117:         }
     118:
     119:     cnamp = cnames;
     120:     defin(0,"$end");
     121:     extval = 0400;
     122:     defin(0,"error");
     123:     defin(1,"$accept");
     124:     mem=mem0;
     125:     lev = 0;
     126:     ty = 0;
     127:     i=0;
     128:
     129:     /* sorry -- no yacc parser here.....
     130: 		we must bootstrap somehow... */
     131:
     132:     for( t=gettok();  t!=MARK && t!= ENDFILE; ){
     133:         switch( t ){
     134:
     135:         case ';':
     136:             t = gettok();
     137:             break;
     138:
     139:         case START:
     140:             if( (t=gettok()) != IDENTIFIER ){
     141:                 error( "bad %%start construction" );
     142:                 }
     143:             start = chfind(1,tokname);
     144:             t = gettok();
     145:             continue;
     146:
     147:         case TYPEDEF:
     148:             if( (t=gettok()) != TYPENAME ) error( "bad syntax in %%type" );
     149:             ty = numbval;
     150:             for(;;){
     151:                 t = gettok();
     152:                 switch( t ){
     153:
     154:                 case IDENTIFIER:
     155:                     if( (t=chfind( 1, tokname ) ) < NTBASE ) {
     156:                         j = TYPE( toklev[t] );
     157:                         if( j!= 0 && j != ty ){
     158:                             error( "type redeclaration of token %s",
     159:                                 tokset[t].name );
     160:                             }
     161:                         else SETTYPE( toklev[t],ty);
     162:                         }
     163:                     else {
     164:                         j = nontrst[t-NTBASE].tvalue;
     165:                         if( j != 0 && j != ty ){
     166:                             error( "type redeclaration of nonterminal %s",
     167:                                 nontrst[t-NTBASE].name );
     168:                             }
     169:                         else nontrst[t-NTBASE].tvalue = ty;
     170:                         }
     171:                 case ',':
     172:                     continue;
     173:
     174:                 case ';':
     175:                     t = gettok();
     176:                     break;
     177:                 default:
     178:                     break;
     179:                     }
     180:                 break;
     181:                 }
     182:             continue;
     183:
     184:         case UNION:
     185:             /* copy the union declaration to the output */
     186:             cpyunion();
     187:             t = gettok();
     188:             continue;
     189:
     190:         case LEFT:
     191:         case BINARY:
     192:         case RIGHT:
     193:             ++i;
     194:         case TERM:
     195:             lev = t-TERM;  /* nonzero means new prec. and assoc. */
     196:             ty = 0;
     197:
     198:             /* get identifiers so defined */
     199:
     200:             t = gettok();
     201:             if( t == TYPENAME ){ /* there is a type defined */
     202:                 ty = numbval;
     203:                 t = gettok();
     204:                 }
     205:
     206:             for(;;) {
     207:                 switch( t ){
     208:
     209:                 case ',':
     210:                     t = gettok();
     211:                     continue;
     212:
     213:                 case ';':
     214:                     break;
     215:
     216:                 case IDENTIFIER:
     217:                     j = chfind(0,tokname);
     218:                     if( lev ){
     219:                         if( ASSOC(toklev[j]) ) error( "redeclaration of precedence of %s", tokname );
     220:                         SETASC(toklev[j],lev);
     221:                         SETPLEV(toklev[j],i);
     222:                         }
     223:                     if( ty ){
     224:                         if( TYPE(toklev[j]) ) error( "redeclaration of type of %s", tokname );
     225:                         SETTYPE(toklev[j],ty);
     226:                         }
     227:                     if( (t=gettok()) == NUMBER ){
     228:                         tokset[j].value = numbval;
     229:                         if( j < ndefout && j>2 ){
     230:                             error( "please define type number of %s earlier",
     231:                                 tokset[j].name );
     232:                             }
     233:                         t=gettok();
     234:                         }
     235:                     continue;
     236:
     237:                     }
     238:
     239:                 break;
     240:                 }
     241:
     242:             continue;
     243:
     244:         case LCURLY:
     245:             defout();
     246:             cpycode();
     247:             t = gettok();
     248:             continue;
     249:
     250:         default:
     251:             error( "syntax error" );
     252:
     253:             }
     254:
     255:         }
     256:
     257:     if( t == ENDFILE ){
     258:         error( "unexpected EOF before %%" );
     259:         }
     260:
     261:     /* t is MARK */
     262:
     263:     defout();
     264:
     265:         fprintf( ftable,  "#define yyclearin yychar = -1\n" );
     266:         fprintf( ftable,  "#define yyerrok yyerrflag = 0\n" );
     267:         fprintf( ftable,  "extern int yychar;\nextern short yyerrflag;\n" );
     268:         fprintf( ftable,  "#ifndef YYMAXDEPTH\n#define YYMAXDEPTH 150\n#endif\n" );
     269:         if( !ntypes ) fprintf( ftable,  "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n" );
     270:         fprintf( ftable,  "YYSTYPE yylval, yyval;\n" );
     271:
     272:     prdptr[0]=mem;
     273:     /* added production */
     274:     *mem++ = NTBASE;
     275:     *mem++ = start;  /* if start is 0, we will overwrite with the lhs of the first rule */
     276:     *mem++ = 1;
     277:     *mem++ = 0;
     278:     prdptr[1]=mem;
     279:
     280:     while( (t=gettok()) == LCURLY ) cpycode();
     281:
     282:     if( t != C_IDENTIFIER ) error( "bad syntax on first rule" );
     283:
     284:     if( !start ) prdptr[0][1] = chfind(1,tokname);
     285:
     286:     /* read rules */
     287:
     288:     while( t!=MARK && t!=ENDFILE ){
     289:
     290:         /* process a rule */
     291:
     292:         if( t == '|' ){
     293:             *mem++ = *prdptr[nprod-1];
     294:             }
     295:         else if( t == C_IDENTIFIER ){
     296:             *mem = chfind(1,tokname);
     297:             if( *mem < NTBASE ) error( "token illegal on LHS of grammar rule" );
     298:             ++mem;
     299:             }
     300:         else error( "illegal rule: missing semicolon or | ?" );
     301:
     302:         /* read rule body */
     303:
     304:
     305:         t = gettok();
     306:     more_rule:
     307:         while( t == IDENTIFIER ) {
     308:             *mem = chfind(1,tokname);
     309:             if( *mem<NTBASE ) levprd[nprod] = toklev[*mem];
     310:             ++mem;
     311:             t = gettok();
     312:             }
     313:
     314:
     315:         if( t == PREC ){
     316:             if( gettok()!=IDENTIFIER) error( "illegal %%prec syntax" );
     317:             j = chfind(2,tokname);
     318:             if( j>=NTBASE)error("nonterminal %s illegal after %%prec", nontrst[j-NTBASE].name);
     319:             levprd[nprod]=toklev[j];
     320:             t = gettok();
     321:             }
     322:
     323:         if( t == '=' ){
     324:             levprd[nprod] |= ACTFLAG;
     325:             fprintf( faction, "\ncase %d:", nprod );
     326:             cpyact( mem-prdptr[nprod]-1 );
     327:             fprintf( faction, " break;" );
     328:             if( (t=gettok()) == IDENTIFIER ){
     329:                 /* action within rule... */
     330:
     331:                 sprintf( actname, "$$%d", nprod );
     332:                 j = chfind(1,actname);  /* make it a nonterminal */
     333:
     334:                 /* the current rule will become rule number nprod+1 */
     335:                 /* move the contents down, and make room for the null */
     336:
     337:                 for( p=mem; p>=prdptr[nprod]; --p ) p[2] = *p;
     338:                 mem += 2;
     339:
     340:                 /* enter null production for action */
     341:
     342:                 p = prdptr[nprod];
     343:
     344:                 *p++ = j;
     345:                 *p++ = -nprod;
     346:
     347:                 /* update the production information */
     348:
     349:                 levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
     350:                 levprd[nprod] = ACTFLAG;
     351:
     352:                 if( ++nprod >= NPROD ) error( "more than %d rules", NPROD );
     353:                 prdptr[nprod] = p;
     354:
     355:                 /* make the action appear in the original rule */
     356:                 *mem++ = j;
     357:
     358:                 /* get some more of the rule */
     359:
     360:                 goto more_rule;
     361:                 }
     362:
     363:             }
     364:
     365:         while( t == ';' ) t = gettok();
     366:
     367:         *mem++ = -nprod;
     368:
     369:         /* check that default action is reasonable */
     370:
     371:         if( ntypes && !(levprd[nprod]&ACTFLAG) && nontrst[*prdptr[nprod]-NTBASE].tvalue ){
     372:             /* no explicit action, LHS has value */
     373:             register tempty;
     374:             tempty = prdptr[nprod][1];
     375:             if( tempty < 0 ) error( "must return a value, since LHS has a type" );
     376:             else if( tempty >= NTBASE ) tempty = nontrst[tempty-NTBASE].tvalue;
     377:             else tempty = TYPE( toklev[tempty] );
     378:             if( tempty != nontrst[*prdptr[nprod]-NTBASE].tvalue ){
     379:                 error( "default action causes potential type clash" );
     380:                 }
     381:             }
     382:
     383:         if( ++nprod >= NPROD ) error( "more than %d rules", NPROD );
     384:         prdptr[nprod] = mem;
     385:         levprd[nprod]=0;
     386:
     387:         }
     388:
     389:     /* end of all rules */
     390:
     391:     finact();
     392:     if( t == MARK ){
     393:         fprintf( ftable, "\n# line %d \"%s\"\n", lineno, infile );
     394:         while( (c=getc(finput)) != EOF ) putc( c, ftable );
     395:         }
     396:     fclose( finput );
     397:     }
     398:
     399: finact(){
     400:     /* finish action routine */
     401:
     402:     fclose(faction);
     403:
     404:     fprintf( ftable, "# define YYERRCODE %d\n", tokset[2].value );
     405:
     406:     }
     407:
     408: defin( t, s ) register char  *s; {
     409: /*	define s to be a terminal if t=0
     410: 	or a nonterminal if t=1		*/
     411:
     412:     register val;
     413:
     414:     if (t) {
     415:         if( ++nnonter >= NNONTERM ) error("too many nonterminals, limit %d",NNONTERM);
     416:         nontrst[nnonter].name = cstash(s);
     417:         return( NTBASE + nnonter );
     418:         }
     419:     /* must be a token */
     420:     if( ++ntokens >= NTERMS ) error("too many terminals, limit %d",NTERMS );
     421:     tokset[ntokens].name = cstash(s);
     422:
     423:     /* establish value for token */
     424:
     425:     if( s[0]==' ' && s[2]=='\0' ) /* single character literal */
     426:         val = s[1];
     427:     else if ( s[0]==' ' && s[1]=='\\' ) { /* escape sequence */
     428:         if( s[3] == '\0' ){ /* single character escape sequence */
     429:             switch ( s[2] ){
     430:                      /* character which is escaped */
     431:             case 'n': val = '\n'; break;
     432:             case 'r': val = '\r'; break;
     433:             case 'b': val = '\b'; break;
     434:             case 't': val = '\t'; break;
     435:             case 'f': val = '\f'; break;
     436:             case '\'': val = '\''; break;
     437:             case '"': val = '"'; break;
     438:             case '\\': val = '\\'; break;
     439:             default: error( "invalid escape" );
     440:                 }
     441:             }
     442:         else if( s[2] <= '7' && s[2]>='0' ){ /* \nnn sequence */
     443:             if( s[3]<'0' || s[3] > '7' || s[4]<'0' ||
     444:                 s[4]>'7' || s[5] != '\0' ) error("illegal \\nnn construction" );
     445:             val = 64*s[2] + 8*s[3] + s[4] - 73*'0';
     446:             if( val == 0 ) error( "'\\000' is illegal" );
     447:             }
     448:         }
     449:     else {
     450:         val = extval++;
     451:         }
     452:     tokset[ntokens].value = val;
     453:     toklev[ntokens] = 0;
     454:     return( ntokens );
     455:     }
     456:
     457: defout(){ /* write out the defines (at the end of the declaration section) */
     458:
     459:     register int i, c;
     460:     register char *cp;
     461:
     462:     for( i=ndefout; i<=ntokens; ++i ){
     463:
     464:         cp = tokset[i].name;
     465:         if( *cp == ' ' ) ++cp;  /* literals */
     466:
     467:         for( ; (c= *cp)!='\0'; ++cp ){
     468:
     469:             if( islower(c) || isupper(c) || isdigit(c) || c=='_' );  /* VOID */
     470:             else goto nodef;
     471:             }
     472:
     473:         fprintf( ftable, "# define %s %d\n", tokset[i].name, tokset[i].value );
     474:         if( fdefine != NULL ) fprintf( fdefine, "# define %s %d\n", tokset[i].name, tokset[i].value );
     475:
     476:     nodef:  ;
     477:         }
     478:
     479:     ndefout = ntokens+1;
     480:
     481:     }
     482:
     483: char *
     484: cstash( s ) register char *s; {
     485:     char *temp;
     486:
     487:     temp = cnamp;
     488:     do {
     489:         if( cnamp >= &cnames[cnamsz] ) error("too many characters in id's and literals" );
     490:         else *cnamp++ = *s;
     491:         }  while ( *s++ );
     492:     return( temp );
     493:     }
     494:
     495: gettok() {
     496:     register i, base;
     497:     static int peekline; /* number of '\n' seen in lookahead */
     498:     register c, match, reserve;
     499:
     500: begin:
     501:     reserve = 0;
     502:     lineno += peekline;
     503:     peekline = 0;
     504:     c = getc(finput);
     505:     while( c==' ' || c=='\n' || c=='\t' || c=='\f' ){
     506:         if( c == '\n' ) ++lineno;
     507:         c=getc(finput);
     508:         }
     509:     if( c == '/' ){ /* skip comment */
     510:         lineno += skipcom();
     511:         goto begin;
     512:         }
     513:
     514:     switch(c){
     515:
     516:     case EOF:
     517:         return(ENDFILE);
     518:     case '{':
     519:         ungetc( c, finput );
     520:         return( '=' );  /* action ... */
     521:     case '<':  /* get, and look up, a type name (union member name) */
     522:         i = 0;
     523:         while( (c=getc(finput)) != '>' && c>=0 && c!= '\n' ){
     524:             tokname[i] = c;
     525:             if( ++i >= NAMESIZE ) --i;
     526:             }
     527:         if( c != '>' ) error( "unterminated < ... > clause" );
     528:         tokname[i] = '\0';
     529:         for( i=1; i<=ntypes; ++i ){
     530:             if( !strcmp( typeset[i], tokname ) ){
     531:                 numbval = i;
     532:                 return( TYPENAME );
     533:                 }
     534:             }
     535:         typeset[numbval = ++ntypes] = cstash( tokname );
     536:         return( TYPENAME );
     537:
     538:     case '"':
     539:     case '\'':
     540:         match = c;
     541:         tokname[0] = ' ';
     542:         i = 1;
     543:         for(;;){
     544:             c = getc(finput);
     545:             if( c == '\n' || c == EOF )
     546:                 error("illegal or missing ' or \"" );
     547:             if( c == '\\' ){
     548:                 c = getc(finput);
     549:                 tokname[i] = '\\';
     550:                 if( ++i >= NAMESIZE ) --i;
     551:                 }
     552:             else if( c == match ) break;
     553:             tokname[i] = c;
     554:             if( ++i >= NAMESIZE ) --i;
     555:             }
     556:         break;
     557:
     558:     case '%':
     559:     case '\\':
     560:
     561:         switch(c=getc(finput)) {
     562:
     563:         case '0':   return(TERM);
     564:         case '<':   return(LEFT);
     565:         case '2':   return(BINARY);
     566:         case '>':   return(RIGHT);
     567:         case '%':
     568:         case '\\':  return(MARK);
     569:         case '=':   return(PREC);
     570:         case '{':   return(LCURLY);
     571:         default:    reserve = 1;
     572:             }
     573:
     574:     default:
     575:
     576:         if( isdigit(c) ){ /* number */
     577:             numbval = c-'0' ;
     578:             base = (c=='0') ? 8 : 10 ;
     579:             for( c=getc(finput); isdigit(c) ; c=getc(finput) ){
     580:                 numbval = numbval*base + c - '0';
     581:                 }
     582:             ungetc( c, finput );
     583:             return(NUMBER);
     584:             }
     585:         else if( islower(c) || isupper(c) || c=='_' || c=='.' || c=='$' ){
     586:             i = 0;
     587:             while( islower(c) || isupper(c) || isdigit(c) || c=='_' || c=='.' || c=='$' ){
     588:                 tokname[i] = c;
     589:                 if( reserve && isupper(c) ) tokname[i] += 'a'-'A';
     590:                 if( ++i >= NAMESIZE ) --i;
     591:                 c = getc(finput);
     592:                 }
     593:             }
     594:         else return(c);
     595:
     596:         ungetc( c, finput );
     597:         }
     598:
     599:     tokname[i] = '\0';
     600:
     601:     if( reserve ){ /* find a reserved word */
     602:         if( !strcmp(tokname,"term")) return( TERM );
     603:         if( !strcmp(tokname,"token")) return( TERM );
     604:         if( !strcmp(tokname,"left")) return( LEFT );
     605:         if( !strcmp(tokname,"nonassoc")) return( BINARY );
     606:         if( !strcmp(tokname,"binary")) return( BINARY );
     607:         if( !strcmp(tokname,"right")) return( RIGHT );
     608:         if( !strcmp(tokname,"prec")) return( PREC );
     609:         if( !strcmp(tokname,"start")) return( START );
     610:         if( !strcmp(tokname,"type")) return( TYPEDEF );
     611:         if( !strcmp(tokname,"union")) return( UNION );
     612:         error("invalid escape, or illegal reserved word: %s", tokname );
     613:         }
     614:
     615:     /* look ahead to distinguish IDENTIFIER from C_IDENTIFIER */
     616:
     617:     c = getc(finput);
     618:     while( c==' ' || c=='\t'|| c=='\n' || c=='\f' || c== '/' ) {
     619:         if( c == '\n' ) ++peekline;
     620:         else if( c == '/' ){ /* look for comments */
     621:             peekline += skipcom();
     622:             }
     623:         c = getc(finput);
     624:         }
     625:     if( c == ':' ) return( C_IDENTIFIER );
     626:     ungetc( c, finput );
     627:     return( IDENTIFIER );
     628: }
     629:
     630: fdtype( t ){ /* determine the type of a symbol */
     631:     register v;
     632:
     633:     if( t >= NTBASE ) v = nontrst[t-NTBASE].tvalue;
     634:     else v = TYPE( toklev[t] );
     635:     if( v <= 0 ) error( "must specify type for %s", (t>=NTBASE)?nontrst[t-NTBASE].name:
     636:             tokset[t].name );
     637:     return( v );
     638:     }
     639:
     640: chfind( t, s ) register char *s; {
     641:     int i;
     642:
     643:     if (s[0]==' ')t=0;
     644:     TLOOP(i){
     645:         if(!strcmp(s,tokset[i].name)){
     646:             return( i );
     647:             }
     648:         }
     649:     NTLOOP(i){
     650:         if(!strcmp(s,nontrst[i].name)) {
     651:             return( i+NTBASE );
     652:             }
     653:         }
     654:     /* cannot find name */
     655:     if( t>1 )
     656:         error( "%s should have been defined earlier", s );
     657:     return( defin( t, s ) );
     658:     }
     659:
     660: cpyunion(){
     661:     /* copy the union declaration to the output, and the define file if present */
     662:
     663:     int level, c;
     664:     fprintf( ftable, "\n# line %d \"%s\"\n", lineno, infile );
     665:     fprintf( ftable, "typedef union " );
     666:     if( fdefine ) fprintf( fdefine, "\ntypedef union " );
     667:
     668:     level = 0;
     669:     for(;;){
     670:         if( (c=getc(finput)) < 0 ) error( "EOF encountered while processing %%union" );
     671:         putc( c, ftable );
     672:         if( fdefine ) putc( c, fdefine );
     673:
     674:         switch( c ){
     675:
     676:         case '\n':
     677:             ++lineno;
     678:             break;
     679:
     680:         case '{':
     681:             ++level;
     682:             break;
     683:
     684:         case '}':
     685:             --level;
     686:             if( level == 0 ) { /* we are finished copying */
     687:                 fprintf( ftable, " YYSTYPE;\n" );
     688:                 if( fdefine ) fprintf( fdefine, " YYSTYPE;\nextern YYSTYPE yylval;\n" );
     689:                 return;
     690:                 }
     691:             }
     692:         }
     693:     }
     694:
     695: cpycode(){ /* copies code between \{ and \} */
     696:     register int c;
     697:
     698:     c = getc(finput);
     699:     if( c == '\n' ) {
     700:         c = getc(finput);
     701:         lineno++;
     702:         }
     703:     fprintf( ftable, "\n# line %d \"%s\"\n", lineno, infile );
     704:     while( c>=0 ){
     705:         if( c=='\\' )
     706:             if( (c=getc(finput)) == '}' ) return;
     707:             else putc('\\', ftable );
     708:         if( c=='%' )
     709:             if( (c=getc(finput)) == '}' ) return;
     710:             else putc('%', ftable );
     711:         putc( c , ftable );
     712:         if( c == '\n' ) ++lineno;
     713:         c = getc(finput);
     714:         }
     715:     error("eof before %%}" );
     716:     }
     717:
     718: skipcom(){ /* skip over comments */
     719:     register int c, i=0;  /* i is the number of lines skipped */
     720:
     721:     /* skipcom is called after reading a / */
     722:
     723:     if( getc(finput) != '*' ) error( "illegal comment" );
     724:     c = getc(finput);
     725:     while( c != EOF ){
     726:         while( c == '*' ){
     727:             if( (c=getc(finput)) == '/' ) return( i );
     728:             }
     729:         if( c == '\n' ) ++i;
     730:         c = getc(finput);
     731:         }
     732:     error( "EOF inside comment" );
     733:     /* NOTREACHED */
     734:     }
     735:
     736: cpyact(offset){ /* copy C action to the next ; or closing } */
     737:     register int c;
     738:     int brac, match, j, s, tok;
     739:
     740:     fprintf( faction, "\n# line %d \"%s\"\n", lineno, infile );
     741:
     742:     brac = 0;
     743:
     744: loop:
     745:     c = getc(finput);
     746: swt:
     747:     switch( c ){
     748:
     749: case ';':
     750:         if( brac == 0 ){
     751:             putc( c , faction );
     752:             return;
     753:             }
     754:         goto lcopy;
     755:
     756: case '{':
     757:         brac++;
     758:         goto lcopy;
     759:
     760: case '$':
     761:         s = 1;
     762:         tok = -1;
     763:         c = getc(finput);
     764:         if( c == '<' ){ /* type description */
     765:             ungetc( c, finput );
     766:             if( gettok() != TYPENAME ) error( "bad syntax on $<ident> clause" );
     767:             tok = numbval;
     768:             c = getc(finput);
     769:             }
     770:         if( c == '$' ){
     771:             fprintf( faction, "yyval");
     772:             if( ntypes ){ /* put out the proper tag... */
     773:                 if( tok < 0 ) tok = fdtype( *prdptr[nprod] );
     774:                 fprintf( faction, ".%s", typeset[tok] );
     775:                 }
     776:             goto loop;
     777:             }
     778:         if( c == '-' ){
     779:             s = -s;
     780:             c = getc(finput);
     781:             }
     782:         if( isdigit(c) ){
     783:             j=0;
     784:             while( isdigit(c) ){
     785:                 j= j*10+c-'0';
     786:                 c = getc(finput);
     787:                 }
     788:
     789:             j = j*s - offset;
     790:             if( j > 0 ){
     791:                 error( "Illegal use of $%d", j+offset );
     792:                 }
     793:
     794:             fprintf( faction, "yypvt[-%d]", -j );
     795:             if( ntypes ){ /* put out the proper tag */
     796:                 if( j+offset <= 0 && tok < 0 ) error( "must specify type of $%d", j+offset );
     797:                 if( tok < 0 ) tok = fdtype( prdptr[nprod][j+offset] );
     798:                 fprintf( faction, ".%s", typeset[tok] );
     799:                 }
     800:             goto swt;
     801:             }
     802:         putc( '$' , faction );
     803:         if( s<0 ) putc('-', faction );
     804:         goto swt;
     805:
     806: case '}':
     807:         if( --brac ) goto lcopy;
     808:         putc( c, faction );
     809:         return;
     810:
     811:
     812: case '/':   /* look for comments */
     813:         putc( c , faction );
     814:         c = getc(finput);
     815:         if( c != '*' ) goto swt;
     816:
     817:         /* it really is a comment */
     818:
     819:         putc( c , faction );
     820:         c = getc(finput);
     821:         while( c != EOF ){
     822:             while( c=='*' ){
     823:                 putc( c , faction );
     824:                 if( (c=getc(finput)) == '/' ) goto lcopy;
     825:                 }
     826:             putc( c , faction );
     827:             if( c == '\n' )++lineno;
     828:             c = getc(finput);
     829:             }
     830:         error( "EOF inside comment" );
     831:
     832: case '\'':  /* character constant */
     833:         match = '\'';
     834:         goto string;
     835:
     836: case '"':   /* character string */
     837:         match = '"';
     838:
     839:     string:
     840:
     841:         putc( c , faction );
     842:         while( c=getc(finput) ){
     843:
     844:             if( c=='\\' ){
     845:                 putc( c , faction );
     846:                 c=getc(finput);
     847:                 if( c == '\n' ) ++lineno;
     848:                 }
     849:             else if( c==match ) goto lcopy;
     850:             else if( c=='\n' ) error( "newline in string or char. const." );
     851:             putc( c , faction );
     852:             }
     853:         error( "EOF in string or character constant" );
     854:
     855: case EOF:
     856:         error("action does not terminate" );
     857:
     858: case '\n':  ++lineno;
     859:         goto lcopy;
     860:
     861:         }
     862:
     863: lcopy:
     864:     putc( c , faction );
     865:     goto loop;
     866:     }

#### Defined functions

chfind defined in line 640; used 8 times

- in line 143, 155, 217, 284, 296, 308, 317, 332

cpyact defined in line 736; used 1 times

- in line 326

cpycode defined in line 695; used 2 times

- in line 246, 280

cpyunion defined in line 660; used 1 times

- in line 186

cstash defined in line 483; used 4 times

- in line 416-421(2), 535
- in /usr/src/usr.bin/yacc/dextern line 223

defin defined in line 408; used 4 times

- in line 120-123(3), 657

defout defined in line 457; used 2 times

- in line 245, 263

fdtype defined in line 630; used 2 times

- in line 773, 797

finact defined in line 399; used 1 times

- in line 391

gettok defined in line 495; used 22 times

- in line 132-151(6), 175, 187, 200-203(2), 210, 227, 233, 247, 280, 305, 311-320(3), 328, 365, 766

setup defined in line 69; used 1 times

- in /usr/src/usr.bin/yacc/y1.c line 52

skipcom defined in line 718; used 2 times

- in line 510, 621

#### Defined variables

cnames defined in line 30; used 3 times

- in line 32, 119, 489

cnamp defined in line 32; used 4 times

- in line 119, 487-490(3)

cnamsz defined in line 31; used 1 times

- in line 489

extval defined in line 49; used 2 times

- in line 121, 450

infile defined in line 24; used 5 times

- in line 115, 393, 664, 703, 740

levprd defined in line 66; used 22 times

- in line 309, 319-324(2), 349-350(3), 371, 385
- in /usr/src/usr.bin/yacc/y1.c line 73
- in /usr/src/usr.bin/yacc/y2.c line 309, 319-324(2), 349-350(3), 371, 385
- in /usr/src/usr.bin/yacc/y3.c line 238, 281, 402-404(2), 410

mem defined in line 63; used 43 times

- in line 124, 272-278(6), 293-298(4), 308-310(4), 326, 337-338(2), 356, 367, 384
- in /usr/src/usr.bin/yacc/y1.c line 476
- in /usr/src/usr.bin/yacc/y2.c line 124, 272-278(6), 293-298(4), 308-310(4), 326, 337-338(2), 356, 367, 384

mem0 defined in line 62; used 8 times

- in line 63, 124
- in /usr/src/usr.bin/yacc/y1.c line 162, 173, 391
- in /usr/src/usr.bin/yacc/y2.c line 63, 124
- in /usr/src/usr.bin/yacc/y4.c line 8

ndefout defined in line 33; used 3 times

- in line 229, 462, 479

nnonter defined in line 44; used 23 times

- in line 415-417(3)
- in /usr/src/usr.bin/yacc/dextern line 115
- in /usr/src/usr.bin/yacc/y1.c line 169, 271, 406, 442, 491, 523
- in /usr/src/usr.bin/yacc/y2.c line 415-417(3)
- in /usr/src/usr.bin/yacc/y3.c line 24, 132, 188, 369
- in /usr/src/usr.bin/yacc/y4.c line 37, 61, 74, 98, 246, 288

nontrst defined in line 45; used 31 times

- in line 164-169(3), 318, 371-378(3), 416, 633-635(2), 650
- in /usr/src/usr.bin/yacc/y1.c line 128, 150, 254, 306, 429, 519
- in /usr/src/usr.bin/yacc/y2.c line 164-169(3), 318, 371-378(3), 416, 633-635(2), 650
- in /usr/src/usr.bin/yacc/y3.c line 210-211(2)
- in /usr/src/usr.bin/yacc/y4.c line 15

nprod defined in line 64; used 58 times

- in line 293, 309, 319-331(5), 337-353(8), 367-385(8), 773, 797
- in /usr/src/usr.bin/yacc/dextern line 116
- in /usr/src/usr.bin/yacc/y1.c line 73-77(3), 170, 263(2)
- in /usr/src/usr.bin/yacc/y2.c line 293, 309, 319-331(5), 337-353(8), 367-385(8), 773, 797
- in /usr/src/usr.bin/yacc/y3.c line 70

ntokens defined in line 41; used 21 times

- in line 420-421(2), 452-454(3), 462, 479
- in /usr/src/usr.bin/yacc/dextern line 114
- in /usr/src/usr.bin/yacc/y1.c line 53, 168
- in /usr/src/usr.bin/yacc/y2.c line 420-421(2), 452-454(3), 462, 479
- in /usr/src/usr.bin/yacc/y3.c line 24, 33-34(2), 368

ntypes defined in line 36; used 6 times

- in line 269, 371, 529, 535, 772, 795

numbval defined in line 25; used 9 times

- in line 149, 202, 228, 531-535(2), 577-580(3), 767

prdptr defined in line 65; used 44 times

- in line 272, 278, 284, 293, 326, 337-342(2), 353, 371-378(3), 384, 773, 797
- in /usr/src/usr.bin/yacc/y1.c line 76(2), 127, 251(2), 412-417(3), 448-451(3), 478
- in /usr/src/usr.bin/yacc/y2.c line 272, 278, 284, 293, 326, 337-342(2), 353, 371-378(3), 384, 773, 797
- in /usr/src/usr.bin/yacc/y3.c line 195-197(2), 407-410(2)

sccsid defined in line 2; never used
start defined in line 46; used 3 times

- in line 143, 275, 284

toklev defined in line 43; used 25 times

- in line 156-161(2), 219-225(5), 309, 319, 377, 453, 634
- in /usr/src/usr.bin/yacc/y2.c line 156-161(2), 219-225(5), 309, 319, 377, 453, 634
- in /usr/src/usr.bin/yacc/y3.c line 239

tokname defined in line 26; used 30 times

- in line 143, 155, 217-224(3), 284, 296, 308, 317, 524-535(4), 541, 549-553(2), 588-589(2), 599-612(12)

tokset defined in line 42; used 30 times

- in line 159, 228-231(2), 404, 421, 452, 464, 473-474(4), 636, 645
- in /usr/src/usr.bin/yacc/y1.c line 82, 150
- in /usr/src/usr.bin/yacc/y2.c line 159, 228-231(2), 404, 421, 452, 464, 473-474(4), 636, 645
- in /usr/src/usr.bin/yacc/y3.c line 317-321(2)

typeset defined in line 37; used 4 times

- in line 530-535(2), 774, 798

#### Defined macros

BINARY defined in line 11; used 3 times

- in line 565, 605-606(2)

C_IDENTIFIER defined in line 14; used 3 times

- in line 282, 295, 625

ENDFILE defined in line 20; used 4 times

- in line 132, 257, 288, 517

IDENTIFIER defined in line 6; used 5 times

- in line 140, 307, 316, 328, 627

LCURLY defined in line 13; used 2 times

- in line 280, 570

LEFT defined in line 9; used 2 times

- in line 564, 604

MARK defined in line 7; used 4 times

- in line 132, 288, 392, 568

NUMBER defined in line 15; used 2 times

- in line 227, 583

PREC defined in line 12; used 3 times

- in line 315, 569, 608

RIGHT defined in line 10; used 2 times

- in line 566, 607

START defined in line 16; used 1 times

- in line 609

TERM defined in line 8; used 4 times

- in line 195, 563, 602-603(2)

TYPEDEF defined in line 17; used 1 times

- in line 610

TYPENAME defined in line 18; used 5 times

- in line 148, 201, 532-536(2), 766

UNION defined in line 19; used 1 times

- in line 611

Last modified: 1995-05-12 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2190 |