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

Defined functions

chfind defined in line 388; used 4 times
chstash defined in line 266; used 5 times
cpyact defined in line 431; used 1 times
cpycode defined in line 409; used 2 times
defin defined in line 189; used 4 times
defout defined in line 236; used 2 times
finact defined in line 170; used 1 times
gettok defined in line 272; used 3 times
setup defined in line 13; used 1 times

Defined macros

BINARY defined in line 6; used 5 times
C_IDENTIFIER defined in line 10; used 1 times
IDENTIFIER defined in line 2; used 2 times
LCURLY defined in line 9; used 1 times
LEFT defined in line 5; used 3 times
MARK defined in line 3; used 2 times
NUMBER defined in line 11; used 1 times
PREC defined in line 8; used 3 times
RIGHT defined in line 7; used 3 times
TERM defined in line 4; used 5 times
Last modified: 1975-05-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1294
Valid CSS Valid XHTML 1.0 Strict