|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.