# 2.11BSD#431 - /usr/src/ucb/PORT/pascal/eyacc/ey2.c

##### Functions

    chfind            X
    chstash           X
    cpyact            X
    cpycode           X
    defin             X
    defout            X
    finact            X
    gettok            X
    setup             X

##### Macros

    BINARY            X
    C_IDENTIFIER      X
    IDENTIFIER        X
    LCURLY            X
    LEFT              X
    MARK              X
    NUMBER            X
    PREC              X
    RIGHT             X
    TERM              X

       1: /*
       2:  * Copyright (c) 1979 Regents of the University of California.
       3:  * All rights reserved.  The Berkeley software License Agreement
       4:  * specifies the terms and conditions for redistribution.
       5:  */
       6:
       7: #ifndef lint
       8: static char sccsid[] = "@(#)ey2.c	5.1 (Berkeley) 4/29/85";
       9: #endif not lint
      10:
      11: # include "ey.h"
      12: # define IDENTIFIER 257
      13: # define MARK 258
      14: # define TERM 259
      15: # define LEFT 260
      16: # define BINARY 261
      17: # define RIGHT 262
      18: # define PREC 263
      19: # define LCURLY 264
      20: # define C_IDENTIFIER 265  /* name followed by colon */
      21: # define NUMBER 266
      22:
      23: FILE    *copen();
      24:
      25: setup(argc,argv) int argc; char *argv[];
      26: {   int i,j,lev,t;
      27:     int c;
      28:
      29:     foutput = stdout;
      30:     i = 1;
      31:     while( argc >= 2  && argv[1][0] == '-' ) {
      32:         while( *++(argv[1]) ){
      33:             switch( *argv[1] ){
      34:             case 'v':
      35:             case 'V':
      36:                 foutput = copen("y.output", 'w' );
      37:                 if( foutput == 0 ) error( "cannot open y.output");
      38:                 continue;
      39:             case 'o':
      40:             case 'O':
      41:                 oflag = 1;
      42:                 continue;
      43:             case 'r':
      44:             case 'R':
      45:                 oflag = 1;
      46:                 rflag = 1;
      47:                 continue;
      48:             default:  error( "illegal option: %c", *argv[1]);
      49:                 }
      50:             }
      51:         argv++;
      52:         argc--;
      53:         }
      54:
      55:     ftable = copen( oflag ? "yacc.tmp" : "y.tab.c" , 'w' );
      56:     if( ftable==0 ) error( "cannot open table file" );
      57:     if( argc > 1 ) { cin = copen( argv[1], 'r' );
      58:     if( cin == 0 ) error( "cannot open input" );
      59:     }
      60:     settab();
      61:     fprintf( cout , "#\n");
      62:     ctokn = "$end";
      63:     defin(0);  /* eof */
      64:     extval = 0400;  /* beginning of assigned values */
      65:     ctokn = "error";
      66:     defin(0);
      67:     ctokn = "$accept";
      68:     defin(1);
      69:     mem=mem0;
      70:     cnamp = cnames;
      71:     lev=0;
      72:     i=0;
      73:
      74:     while( ( t = gettok() ) != EOF ) {
      75:         switch( t ){
      76:             case IDENTIFIER:    j = chfind(0);
      77:                     trmlev[j] = lev;
      78:                     continue;
      79:             case ',':
      80:             case ';':       continue;
      81:             case TERM:      lev=0; continue;
      82:             case LEFT:      lev=(++i<<3)|01; continue;
      83:             case BINARY:    lev=(++i<<3)|02; continue;
      84:             case RIGHT: lev=(++i<<3)|03; continue;
      85:             case MARK:
      86:                     defout();
      87:                     if( rflag ){ /* RATFOR */
      88:                         fprintf( cout ,  "define yyerrok yyerrf = 0\n" );
      89:                         fprintf( cout ,  "define yyclearin yychar = -1\n" );
      90:                         fprintf( cout ,  "subroutine yyactr(yyprdn)\n");
      91:                         fprintf( cout ,  "common/yycomn/yylval,yyval,yypv,yyvalv(150)\n" );
      92:                         fprintf( cout ,  "common/yylcom/yychar,yyerrf,yydebu\n" );
      93:                         fprintf( cout ,  "integer yychar, yyerrf, yydebu\n" );
      94:                         fprintf( cout ,  "integer yyprdn,yyval,yylval,yypv,yyvalv\n" );
      95:                         }
      96:                     else {
      97:                         fprintf( cout ,  "#define yyclearin yychar = -1\n" );
      98:                         fprintf( cout ,  "#define yyerrok yyerrflag = 0\n" );
      99:                         fprintf( cout ,  "extern int yychar, yyerrflag;\n" );
     100:                         fprintf( cout , "\nint yyval 0;\nint *yypv;\nint yylval 0;");
     101:                         fprintf( cout , "\nyyactr(__np__){\n");
     102:                         }
     103:                     break;
     104:             case LCURLY:    defout();
     105:                     cpycode();
     106:                     continue;
     107:             case NUMBER:
     108:                 trmset[j].value = numbval;
     109:                 if( j < ndefout && j>2 )
     110:                     error("please define type # of %s earlier", trmset[j].name );
     111:                 continue;
     112:             default:    error("bad precedence syntax, input %d", t );
     113:             }
     114:         break;
     115:         }
     116:     prdptr[0]=mem;
     117:     /* added production */
     118:     *mem++ = NTBASE;
     119:     *mem++ = NTBASE+1;
     120:     *mem++ = 1;
     121:     *mem++ = 0;
     122:     prdptr[1]=mem;
     123:     i=0;
     124:
     125:     /* i is 0 when a rule can begin, 1 otherwise */
     126:
     127:     for(;;) switch( t=gettok() ) {
     128:     case C_IDENTIFIER:      if( mem == prdptr[1] ) {  /* first time */
     129:                         if( rflag ){
     130:                             fprintf( cout ,  "goto 1000\n" );
     131:                             }
     132:                         else fprintf( cout , "\nswitch(__np__){\n");
     133:                         }
     134:                 if( i != 0 ) error( "previous rule not terminated" );
     135:                 *mem = chfind(1);
     136:                 if( *mem < NTBASE )error( "token illegal on lhs of grammar rule" );
     137:                 i=1;
     138:                 ++mem;
     139:                 continue;
     140:     case IDENTIFIER:
     141:             *mem=chfind(1);
     142:             if(*mem < NTBASE)levprd[nprod]=trmlev[*mem];
     143:             mem++;
     144:             if(i==0) error("missing :");
     145:             continue;
     146:     case '=':       levprd[nprod] |= 04;
     147:                 if( i==0 ) error("semicolon preceeds action");
     148:             fprintf( cout ,  rflag?"\n%d ":"\ncase %d:", nprod );
     149:             cpyact();
     150:             fprintf( cout ,  rflag ? " return" : " break;" );
     151:     case '|':
     152:     case ';':       if(i){
     153:                 *mem++ = -nprod;
     154:                 prdptr[++nprod] = mem;
     155:                 levprd[nprod]=0;
     156:                 i=0;}
     157:             if (t=='|'){i=1;*mem++ = *prdptr[nprod-1];}
     158:             continue;
     159:     case 0:     /* End Of File */
     160:     case EOF:
     161:     case MARK:  if( i != 0 ) error( "rule not terminated before %%%% or EOF" );
     162:             settab();
     163:             finact();
     164:             /* copy the programs which follow the rules */
     165:             if( t == MARK ){
     166:                 while (( c=fgetc( cin)) != EOF ) fputc(c,cout);
     167:                 }
     168:             return;
     169:     case PREC:
     170:         if( i==0 ) error( "%%prec must appear inside rule" );
     171:         if( gettok()!=IDENTIFIER)error("illegal %%prec syntax" );
     172:         j=chfind(2);
     173:         if(j>=NTBASE)error("nonterminal %s illegal after %%prec", nontrst[j-NTBASE].name);
     174:         levprd[nprod]=trmlev[j];
     175:         continue;
     176:     case LCURLY:
     177:         if( i!=0 ) error( "%%{ appears within a rule" );
     178:         cpycode();
     179:         continue;
     180:     default: error( "syntax error, input %d", t  );
     181:     }
     182: }
     183:
     184: finact(){
     185:     /* finish action routine */
     186:     register i;
     187:
     188:     if( rflag ){
     189:
     190:         fprintf( cout ,  "\n1000 goto(" );
     191:         for( i=1; i<nprod; ++i ){
     192:             fprintf( cout ,  "%d,", (levprd[i]&04)==0?999:i );
     193:             }
     194:         fprintf( cout ,  "999),yyprdn\n" );
     195:         fprintf( cout ,  "999 return\nend\n" );
     196:         fprintf( cout ,  "define YYERRCODE %d\n", trmset[2].value );
     197:         }
     198:     else {
     199:         fprintf( cout ,  "\n}\n}\n" );
     200:         fprintf( cout ,  "int yyerrval %d;\n", trmset[2].value );
     201:         }
     202:     }
     203: defin(t) {
     204: /*	define ctokn to be a terminal if t=0
     205: 	or a nonterminal if t=1		*/
     206:     char *cp,*p;
     207:     int c;
     208:
     209:
     210:         if (t) {
     211:           if( ++nnonter >= ntlim ) error("too many nonterminals, limit %d",ntlim);
     212:       nontrst[nnonter].name = ctokn;
     213:       return( NTBASE + nnonter );
     214:           }
     215:         else {
     216:           if( ++nterms >= tlim ) error("too many terminals, limit %d",tlim );
     217:           trmset[nterms].name = ctokn;
     218:     if( ctokn[0]==' ' && ctokn[2]=='\0' ) /* single character literal */
     219:         trmset[nterms].value = ctokn[1];
     220:     else if ( ctokn[0]==' ' && ctokn[1]=='\\' ) { /* escape sequence */
     221:         if( ctokn[3] == '\0' ){ /* single character escape sequence */
     222:             switch ( ctokn[2] ){
     223:                  /* character which is escaped */
     224:             case 'n': trmset[nterms].value = '\n'; break;
     225:             case 'r': trmset[nterms].value = '\r'; break;
     226:             case 'b': trmset[nterms].value = '\b'; break;
     227:             case 't': trmset[nterms].value = '\t'; break;
     228:             case '\'': trmset[nterms].value = '\''; break;
     229:             case '"': trmset[nterms].value = '"'; break;
     230:             case '\\': trmset[nterms].value = '\\'; break;
     231:             default: error( "invalid escape" );
     232:                 }
     233:             }
     234:         else if( ctokn[2] <= '7' && ctokn[2]>='0' ){ /* \nnn sequence */
     235:             if( ctokn[3]<'0' || ctokn[3] > '7' || ctokn[4]<'0' ||
     236:                 ctokn[4]>'7' || ctokn[5] != '\0' ) error("illegal \\nnn construction" );
     237:             trmset[nterms].value = 64*(ctokn[2]-'0')+8*(ctokn[3]-'0')+ctokn[4]-'0';
     238:             if( trmset[nterms].value == 0 ) error( "'\\000' is illegal" );
     239:             }
     240:         }
     241:     else {
     242:         trmset[nterms].value = extval++;
     243:
     244:         }
     245:     trmlev[nterms] = 0;
     246:     return( nterms );
     247:           }
     248: }
     249:
     250: defout(){ /* write out the defines (at the end of the declaration section) */
     251:
     252:     _REGISTER int i, c;
     253:     _REGISTER char *cp;
     254:
     255:     for( i=ndefout; i<=nterms; ++i ){
     256:
     257:         cp = trmset[i].name;
     258:         if( *cp == ' ' ) ++cp;  /* literals */
     259:
     260:         for( ; (c= *cp)!='\0'; ++cp ){
     261:
     262:             if( c>='a' && c<='z' ||
     263:                 c>='A' && c<='Z' ||
     264:                 c>='0' && c<='9' ||
     265:                 c=='_' )  ; /* VOID */
     266:             else goto nodef;
     267:             }
     268:
     269:         /* define it */
     270:
     271:         fprintf( cout ,  "%c define %s %d\n", rflag?' ':'#', trmset[i].name, trmset[i].value );
     272:
     273:     nodef:  ;
     274:         }
     275:
     276:     ndefout = nterms+1;
     277:
     278:     }
     279:
     280: chstash( c ){
     281:   /* put character away into cnames */
     282:   if( cnamp >= &cnames[cnamsz] ) error("too many characters in id's and literals" );
     283:   else *cnamp++ = c;
     284:   }
     285:
     286: int gettok() {
     287:     int j, base;
     288:     static int peekline; /* number of '\n' seen in lookahead */
     289:     auto int c, match, reserve;
     290:
     291: begin:
     292:     reserve = 0;
     293:         if( peekc>=0 ) {
     294:         c = peekc;
     295:         lineno += peekline;
     296:         peekc = -1;
     297:         peekline = 0;
     298:         }
     299:         else c = fgetc( cin);
     300:         while( c==' ' || c=='\n' || c=='\t' || c == '\014'){
     301:           if( c == '\n' ) ++lineno;
     302:           c=fgetc( cin);
     303:           }
     304:     if (c=='/')
     305:         {if (fgetc( cin)!='*')error("illegal /");
     306:         c=fgetc( cin);
     307:         while(c != EOF) {
     308:             if( c == '\n' ) ++lineno;
     309:             if (c=='*')
     310:                 {if((c=fgetc( cin))=='/')break;}
     311:             else c=fgetc( cin);}
     312:         if (!c) return(0);
     313:         goto begin;}
     314:     j=0;
     315:     switch(c){
     316:     case '"':
     317:     case '\'':  match = c;
     318:             ctokn = cnamp;
     319:             chstash( ' ' );
     320:             while(1){
     321:                 c = fgetc( cin);
     322:                 if( c == '\n' || c == '\0' )
     323:                     error("illegal or missing ' or \"");
     324:                 if( c == '\\' ){
     325:                     c = fgetc( cin);
     326:                     chstash( '\\' );
     327:                     }
     328:                 else if( c == match ) break;
     329:                 chstash( c );
     330:                 }
     331:             break;
     332:     case '%':
     333:     case '\\':  switch(c=fgetc( cin))
     334:         {case '0':  return(TERM);
     335:         case '<':   return(LEFT);
     336:         case '2':   return(BINARY);
     337:         case '>':   return(RIGHT);
     338:         case '%':
     339:         case '\\':  return(MARK);
     340:         case '=':   return(PREC);
     341:         case '{':   return(LCURLY);
     342:         default:    reserve = 1;
     343:         }
     344:     default:    if( c >= '0' && c <= '9' ){ /* number */
     345:                 numbval = c-'0' ;
     346:                 base = (c=='0') ? 8 : 10 ;
     347:                 for( c=fgetc( cin); c>='0' && c<='9'; c=fgetc( cin) ){
     348:                     numbval = numbval*base + c - '0';
     349:                     }
     350:                 peekc = c;
     351:                 return(NUMBER);
     352:                 }
     353:             else if( (c>='a'&&c<='z')||(c>='A'&&c<='Z')||c=='_'||c=='.'||c=='$'){
     354:                 ctokn = cnamp;
     355:                 while(  (c>='a'&&c<='z') ||
     356:                     (c>='A'&&c<='Z') ||
     357:                     (c>='0'&&c<='9') ||
     358:                     c=='_' || c=='.' || c=='$' ) {
     359:                     chstash( c );
     360:                     if( peekc>=0 ) { c = peekc; peekc = -1; }
     361:                     else c = fgetc( cin);
     362:                     }
     363:                 }
     364:             else return(c);
     365:
     366:             peekc=c;
     367:             }
     368:     chstash( '\0' );
     369:
     370:     if( reserve ){ /* find a reserved word */
     371:         if( compare("term")) return( TERM );
     372:         if( compare("TERM")) return( TERM );
     373:         if( compare("token")) return( TERM );
     374:         if( compare("TOKEN")) return( TERM );
     375:         if( compare("left")) return( LEFT );
     376:         if( compare("LEFT")) return( LEFT );
     377:         if( compare("nonassoc")) return( BINARY );
     378:         if( compare("NONASSOC")) return( BINARY );
     379:         if( compare("binary")) return( BINARY );
     380:         if( compare("BINARY")) return( BINARY );
     381:         if( compare("right")) return( RIGHT );
     382:         if( compare("RIGHT")) return( RIGHT );
     383:         if( compare("prec")) return( PREC );
     384:         if( compare("PREC")) return( PREC );
     385:         error("invalid escape, or illegal reserved word: %s", ctokn );
     386:         }
     387:
     388:     /* look ahead to distinguish IDENTIFIER from C_IDENTIFIER */
     389:
     390:   look:
     391:     while( peekc==' ' || peekc=='\t' || peekc == '\n' || peekc == '\014' )
     392:     {
     393:         if( peekc == '\n' ) ++peekline;
     394:         peekc = fgetc( cin);
     395:     }
     396:
     397:     if( peekc != ':' ) return( IDENTIFIER );
     398:     peekc = -1;
     399:     lineno += peekline;
     400:     peekline = 0;
     401:     return( C_IDENTIFIER );
     402: }
     403: chfind(t)
     404:
     405: {   int i,j;
     406:
     407:     if (ctokn[0]==' ')t=0;
     408:     for(i=1;i<=nterms;i++)
     409:         if(compare(trmset[i].name)){
     410:             cnamp = ctokn;
     411:             return( i );
     412:             }
     413:     for(i=1;i<=nnonter;i++)
     414:         if(compare(nontrst[i].name)) {
     415:             cnamp = ctokn;
     416:             return( i+NTBASE );
     417:             }
     418:     /* cannot find name */
     419:     if( t>1 && ctokn[0] != ' ' )
     420:         error( "%s should have been defined earlier", ctokn );
     421:     return( defin( t ) );
     422:     }
     423:
     424: cpycode(){ /* copies code between \{ and \} */
     425:
     426:     int c;
     427:     c = fgetc( cin);
     428:     if( c == '\n' ) {
     429:         c = fgetc( cin);
     430:         lineno++;
     431:         }
     432:     while( c != EOF ){
     433:         if( c=='\\' )
     434:             if( (c=fgetc( cin)) == '}' ) return;
     435:             else fputc('\\',cout);
     436:         if( c=='%' )
     437:             if( (c=fgetc( cin)) == '}' ) return;
     438:             else fputc('%',cout);
     439:         fputc( c, cout );
     440:         if( c == '\n' ) ++lineno;
     441:         c = fgetc( cin);
     442:         }
     443:     error("eof before %%}");
     444:     }
     445:
     446: cpyact(){ /* copy C action to the next ; or closing } */
     447:     int brac, c, match, *i, j, s;
     448:
     449:     brac = 0;
     450:
     451: loop:
     452:     c = fgetc( cin);
     453: swt:
     454:     switch( c ){
     455:
     456: case ';':
     457:         if( brac == 0 ){
     458:             fputc( c, cout );
     459:             return;
     460:             }
     461:         goto lcopy;
     462:
     463: case '{':
     464:         brac++;
     465:         goto lcopy;
     466:
     467: case '$':
     468:         s = 1;
     469:         c = fgetc( cin);
     470:         if( c == '$' ){
     471:             fprintf( cout , "yyval");
     472:             goto loop;
     473:             }
     474:         if( c == '-' ){
     475:             s = -s;
     476:             c = fgetc( cin);
     477:             }
     478:         if( c>='0' && c <= '9' ){
     479:             j=0;
     480:             while( c>='0' && c<= '9' ){
     481:                 j= j*10+c-'0';
     482:                 c = fgetc( cin);
     483:                 }
     484:             if( rflag ) fprintf( cout ,  "yyvalv(yypv%c%d)", s==1?'+':'-', j );
     485:             else fprintf( cout , "yypv[%d]", s*j );
     486:             goto swt;
     487:             }
     488:         fputc( '$' , cout);
     489:         if( s<0 ) fputc('-', cout);
     490:         goto swt;
     491:
     492: case '}':
     493:         brac--;
     494:         if( brac == 0 ){
     495:             fputc( c , cout);
     496:             return;
     497:             }
     498:         goto lcopy;
     499:
     500: case '/':   /* look for comments */
     501:         fputc( c ,cout);
     502:         c = fgetc( cin);
     503:         if( c != '*' ) goto swt;
     504:
     505:         /* it really is a comment */
     506:
     507:         fputc( c , cout);
     508:         while( (c=fgetc( cin)) != EOF ){
     509:             if( c=='*' ){
     510:                 fputc( c , cout);
     511:                 if( (c=fgetc( cin)) == '/' ) goto lcopy;
     512:                 }
     513:             fputc( c , cout);
     514:             }
     515:         error( "EOF inside comment" );
     516:
     517: case '\'':  /* character constant */
     518:         match = '\'';
     519:         goto string;
     520:
     521: case '"':   /* character string */
     522:         match = '"';
     523:
     524:     string:
     525:
     526:         fputc( c , cout);
     527:         while( (c=fgetc( cin)) != EOF ){
     528:
     529:             if( c=='\\' ){
     530:                 fputc( c , cout);
     531:                 c=fgetc( cin);
     532:                 }
     533:             else if( c==match ) goto lcopy;
     534:             fputc( c , cout);
     535:             }
     536:         error( "EOF in string or character constant" );
     537:
     538: case '\0':
     539:         error("action does not terminate");
     540: case '\n':  ++lineno;
     541:         goto lcopy;
     542:
     543:         }
     544:
     545: lcopy:
     546:     fputc( c , cout);
     547:     goto loop;
     548:     }

#### Defined functions

chfind defined in line 403; used 4 times

- in line 76, 135, 141, 172

chstash defined in line 280; used 5 times

- in line 319, 326-329(2), 359, 368

cpyact defined in line 446; used 1 times

- in line 149

cpycode defined in line 424; used 2 times

- in line 105, 178

defin defined in line 203; used 4 times

- in line 63-68(3), 421

defout defined in line 250; used 2 times

- in line 86, 104

finact defined in line 184; used 1 times

- in line 163

gettok defined in line 286; used 3 times

- in line 74, 127, 171

setup defined in line 25; used 1 times

- in /usr/src/ucb/PORT/pascal/eyacc/ey1.c line 82

#### Defined variables

sccsid defined in line 8; never used

#### Defined macros

BINARY defined in line 16; used 5 times

- in line 336, 377-380(4)

C_IDENTIFIER defined in line 20; used 1 times

- in line 401

IDENTIFIER defined in line 12; used 2 times

- in line 171, 397

LCURLY defined in line 19; used 1 times

- in line 341

LEFT defined in line 15; used 3 times

- in line 335, 375-376(2)

MARK defined in line 13; used 2 times

- in line 165, 339

NUMBER defined in line 21; used 1 times

- in line 351

PREC defined in line 18; used 3 times

- in line 340, 383-384(2)

RIGHT defined in line 17; used 3 times

- in line 337, 381-382(2)

TERM defined in line 14; used 5 times

- in line 334, 371-374(4)

Last modified: 1985-04-30 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2248 |