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

Defined functions

Finact defined in line 180; used 1 times
chFind defined in line 399; used 4 times
chstash defined in line 277; used 5 times
cpyact defined in line 442; used 1 times
cpycode defined in line 420; used 2 times
deFout defined in line 247; used 2 times
defin defined in line 200; used 4 times
gettok defined in line 283; used 3 times
setup defined in line 17; used 1 times

Defined macros

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