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