|
|
1.1 ! root 1: # include "dextern" ! 2: # define IDENTIFIER 257 ! 3: # define MARK 258 ! 4: # define TERM 259 ! 5: # define LEFT 260 ! 6: # define RIGHT 261 ! 7: # define BINARY 262 ! 8: # define PREC 263 ! 9: # define LCURLY 264 ! 10: # define C_IDENTIFIER 265 /* name followed by colon */ ! 11: # define NUMBER 266 ! 12: # define START 267 ! 13: # define TYPEDEF 268 ! 14: # define TYPENAME 269 ! 15: # define UNION 270 ! 16: # define ENDFILE 0 ! 17: ! 18: /* communication variables between various I/O routines */ ! 19: ! 20: char *infile; /* input file name */ ! 21: int numbval; /* value of an input number */ ! 22: char tokname[NAMESIZE]; /* input token name */ ! 23: ! 24: /* storage of names */ ! 25: ! 26: char cnames[CNAMSZ]; /* place where token and nonterminal names are stored */ ! 27: int cnamsz = CNAMSZ; /* size of cnames */ ! 28: char * cnamp = cnames; /* place where next name is to be put in */ ! 29: int ndefout = 3; /* number of defined symbols output */ ! 30: char *tempname, *actname; ! 31: extern char *mktemp(); ! 32: ! 33: /* storage of types */ ! 34: int ntypes; /* number of types defined */ ! 35: char * typeset[NTYPES]; /* pointers to type tags */ ! 36: ! 37: /* symbol tables for tokens and nonterminals */ ! 38: ! 39: int ntokens = 0; ! 40: struct toksymb tokset[NTERMS]; ! 41: int toklev[NTERMS]; ! 42: int nnonter = -1; ! 43: struct ntsymb nontrst[NNONTERM]; ! 44: int start; /* start symbol */ ! 45: ! 46: /* assigned token type values */ ! 47: int extval = 0; ! 48: ! 49: /* input and output file descriptors */ ! 50: ! 51: FILE * finput; /* yacc input file */ ! 52: FILE * faction; /* file for saving actions */ ! 53: FILE * fdefine; /* file for # defines */ ! 54: FILE * fdebug; /* file for debugging strings */ ! 55: FILE * ftable; /* y.tab.c file */ ! 56: FILE * ftemp; /* tempfile to pass 2 */ ! 57: FILE * foutput; /* y.output file */ ! 58: char * ytabc = OFILE; /* name of y.tab.c */ ! 59: ! 60: /* storage for grammar rules */ ! 61: ! 62: int mem0[MEMSIZE] ; /* production storage */ ! 63: int *mem = mem0; ! 64: int nprod= 1; /* number of productions */ ! 65: int *prdptr[NPROD]; /* pointers to descriptions of productions */ ! 66: int levprd[NPROD] ; /* precedence levels for the productions */ ! 67: ! 68: ! 69: setup(argc,argv) int argc; char *argv[]; ! 70: { int i,j,lev,t, ty; ! 71: int c, ytab = 0; ! 72: int *p; ! 73: int vflag = 0; ! 74: int Dflag = 0; ! 75: int dflag = 0; ! 76: int sflag = 0; ! 77: int stem = 0; ! 78: char *stemc = "y"; ! 79: char actnm[8]; ! 80: char buf[512]; ! 81: ! 82: foutput = NULL; ! 83: fdefine = NULL; ! 84: i = 1; ! 85: while( argc >= 2 && argv[1][0] == '-' ) { ! 86: while( *++(argv[1]) ){ ! 87: switch( *argv[1] ){ ! 88: case 'v': ! 89: case 'V': ! 90: vflag++; ! 91: continue; ! 92: case 'D': ! 93: Dflag++; ! 94: continue; ! 95: case 'd': ! 96: dflag++; ! 97: continue; ! 98: case 'o': ! 99: ytab++; ! 100: argv++; ! 101: ytabc = argv[1]; ! 102: goto beg; ! 103: case 's': ! 104: stem++; ! 105: argv++; ! 106: stemc = argv[1]; ! 107: goto beg; ! 108: case 'r': ! 109: case 'R': ! 110: error( "Ratfor Yacc is dead: sorry...\n" ); ! 111: ! 112: default: ! 113: error( "illegal option: %c", *argv[1]); ! 114: } ! 115: } ! 116: beg: ! 117: argv++; ! 118: argc--; ! 119: } ! 120: openup(stemc, Dflag, dflag, vflag, ytab, ytabc); ! 121: ! 122: ftemp = fopen( (tempname = mktemp(TEMPNAME)), "w" ); ! 123: faction = fopen( (actname = mktemp(ACTNAME)), "w" ); ! 124: if( ftemp==NULL || faction==NULL ) error( "cannot open temp file" ); ! 125: ! 126: if( argc < 2 || ((finput=fopen( infile=argv[1], "r" )) == NULL ) ){ ! 127: error( "cannot open input file" ); ! 128: } ! 129: ! 130: cnamp = cnames; ! 131: defin(0,"$end"); ! 132: extval = 0400; /* this junky number is known where fdebug is used */ ! 133: defin(0,"error"); ! 134: defin(1,"$accept"); ! 135: mem=mem0; ! 136: lev = 0; ! 137: ty = 0; ! 138: i=0; ! 139: ! 140: /* sorry -- no yacc parser here..... ! 141: we must bootstrap somehow... */ ! 142: ! 143: for( t=gettok(); t!=MARK && t!= ENDFILE; ){ ! 144: switch( t ){ ! 145: ! 146: case ';': ! 147: t = gettok(); ! 148: break; ! 149: ! 150: case START: ! 151: if( (t=gettok()) != IDENTIFIER ){ ! 152: error( "bad %%start construction" ); ! 153: } ! 154: start = chfind(1,tokname); ! 155: t = gettok(); ! 156: continue; ! 157: ! 158: case TYPEDEF: ! 159: if( (t=gettok()) != TYPENAME ) error( "bad syntax in %%type" ); ! 160: ty = numbval; ! 161: for(;;){ ! 162: t = gettok(); ! 163: switch( t ){ ! 164: ! 165: case IDENTIFIER: ! 166: if( (t=chfind( 1, tokname ) ) < NTBASE ) { ! 167: j = TYPE( toklev[t] ); ! 168: if( j!= 0 && j != ty ){ ! 169: error( "type redeclaration of token %s", ! 170: tokset[t].name ); ! 171: } ! 172: else SETTYPE( toklev[t],ty); ! 173: } ! 174: else { ! 175: j = nontrst[t-NTBASE].tvalue; ! 176: if( j != 0 && j != ty ){ ! 177: error( "type redeclaration of nonterminal %s", ! 178: nontrst[t-NTBASE].name ); ! 179: } ! 180: else nontrst[t-NTBASE].tvalue = ty; ! 181: } ! 182: case ',': ! 183: continue; ! 184: ! 185: case ';': ! 186: t = gettok(); ! 187: break; ! 188: default: ! 189: break; ! 190: } ! 191: break; ! 192: } ! 193: continue; ! 194: ! 195: case UNION: ! 196: /* copy the union declaration to the output */ ! 197: cpyunion(); ! 198: t = gettok(); ! 199: continue; ! 200: ! 201: case LEFT: ! 202: case BINARY: ! 203: case RIGHT: ! 204: ++i; ! 205: case TERM: ! 206: lev = t-TERM; /* nonzero means new prec. and assoc. */ ! 207: ty = 0; ! 208: ! 209: /* get identifiers so defined */ ! 210: ! 211: t = gettok(); ! 212: if( t == TYPENAME ){ /* there is a type defined */ ! 213: ty = numbval; ! 214: t = gettok(); ! 215: } ! 216: for(;;) { ! 217: switch( t ){ ! 218: ! 219: case ',': ! 220: t = gettok(); ! 221: continue; ! 222: ! 223: case ';': ! 224: break; ! 225: ! 226: case IDENTIFIER: ! 227: j = chfind(0,tokname); ! 228: if( j >= NTBASE ){ ! 229: error( "%s defined earlier as nonterminal", tokname ); ! 230: } ! 231: if( lev ){ ! 232: if( ASSOC(toklev[j]) ) error( "redeclaration of precedence of %s", tokname ); ! 233: SETASC(toklev[j],lev); ! 234: SETPLEV(toklev[j],i); ! 235: } ! 236: if( ty ){ ! 237: if( TYPE(toklev[j]) ) error( "redeclaration of type of %s", tokname ); ! 238: SETTYPE(toklev[j],ty); ! 239: } ! 240: if( (t=gettok()) == NUMBER ){ ! 241: tokset[j].value = numbval; ! 242: if( j < ndefout && j>2 ){ ! 243: error( "please define type number of %s earlier", ! 244: tokset[j].name ); ! 245: } ! 246: t=gettok(); ! 247: } ! 248: continue; ! 249: ! 250: } ! 251: ! 252: break; ! 253: } ! 254: ! 255: continue; ! 256: ! 257: case LCURLY: ! 258: defout(0); ! 259: cpycode(); ! 260: t = gettok(); ! 261: continue; ! 262: ! 263: default: ! 264: error( "syntax error" ); ! 265: ! 266: } ! 267: ! 268: } ! 269: ! 270: if( t == ENDFILE ){ ! 271: error( "unexpected EOF before %%" ); ! 272: } ! 273: ! 274: /* t is MARK */ ! 275: ! 276: defout(1); ! 277: ! 278: fprintf( ftable, "#define yyclearin yychar = -1\n" ); ! 279: fprintf( ftable, "#define yyerrok yyerrflag = 0\n" ); ! 280: fprintf( ftable, "extern int yychar;\nextern short yyerrflag;\n" ); ! 281: fprintf( ftable, "#ifndef YYMAXDEPTH\n#define YYMAXDEPTH 150\n#endif\n" ); ! 282: if( !ntypes ) fprintf( ftable, "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n" ); ! 283: fprintf( ftable, "YYSTYPE yylval, yyval;\n" ); ! 284: ! 285: prdptr[0]=mem; ! 286: /* added production */ ! 287: *mem++ = NTBASE; ! 288: *mem++ = start; /* if start is 0, we will overwrite with the lhs of the first rule */ ! 289: *mem++ = 1; ! 290: *mem++ = 0; ! 291: prdptr[1]=mem; ! 292: ! 293: while( (t=gettok()) == LCURLY ) cpycode(); ! 294: ! 295: if( t != C_IDENTIFIER ) error( "bad syntax on first rule" ); ! 296: ! 297: if( !start ) prdptr[0][1] = chfind(1,tokname); ! 298: ! 299: /* read rules */ ! 300: ! 301: while( t!=MARK && t!=ENDFILE ){ ! 302: ! 303: /* process a rule */ ! 304: ! 305: rlines[nprod] = lineno; ! 306: if( t == '|' ){ ! 307: *mem++ = *prdptr[nprod-1]; ! 308: } ! 309: else if( t == C_IDENTIFIER ){ ! 310: *mem = chfind(1,tokname); ! 311: if( *mem < NTBASE ) error( "token illegal on LHS of grammar rule" ); ! 312: ++mem; ! 313: } ! 314: else error( "illegal rule: missing semicolon or | ?" ); ! 315: ! 316: /* read rule body */ ! 317: ! 318: ! 319: t = gettok(); ! 320: more_rule: ! 321: while( t == IDENTIFIER ) { ! 322: *mem = chfind(1,tokname); ! 323: if( *mem<NTBASE ) levprd[nprod] = toklev[*mem]; ! 324: ++mem; ! 325: t = gettok(); ! 326: } ! 327: ! 328: ! 329: if( t == PREC ){ ! 330: if( gettok()!=IDENTIFIER) error( "illegal %%prec syntax" ); ! 331: j = chfind(2,tokname); ! 332: if( j>=NTBASE)error("nonterminal %s illegal after %%prec", nontrst[j-NTBASE].name); ! 333: levprd[nprod]=toklev[j]; ! 334: t = gettok(); ! 335: } ! 336: ! 337: if( t == '=' ){ ! 338: levprd[nprod] |= ACTFLAG; ! 339: fprintf( faction, "\ncase %d:", nprod ); ! 340: cpyact( mem-prdptr[nprod]-1 ); ! 341: fprintf( faction, " break;" ); ! 342: if( (t=gettok()) == IDENTIFIER ){ ! 343: /* action within rule... */ ! 344: ! 345: sprintf( actnm, "$$%d", nprod ); ! 346: j = chfind(1,actnm); /* make it a nonterminal */ ! 347: ! 348: /* the current rule will become rule number nprod+1 */ ! 349: /* move the contents down, and make room for the null */ ! 350: ! 351: for( p=mem; p>=prdptr[nprod]; --p ) p[2] = *p; ! 352: mem += 2; ! 353: ! 354: /* enter null production for action */ ! 355: ! 356: p = prdptr[nprod]; ! 357: ! 358: *p++ = j; ! 359: *p++ = -nprod; ! 360: ! 361: /* update the production information */ ! 362: ! 363: levprd[nprod+1] = levprd[nprod] & ~ACTFLAG; ! 364: levprd[nprod] = ACTFLAG; ! 365: ! 366: if( ++nprod >= NPROD ) error( "more than %d rules", NPROD ); ! 367: prdptr[nprod] = p; ! 368: ! 369: /* make the action appear in the original rule */ ! 370: *mem++ = j; ! 371: ! 372: /* get some more of the rule */ ! 373: ! 374: goto more_rule; ! 375: } ! 376: ! 377: } ! 378: ! 379: while( t == ';' ) t = gettok(); ! 380: ! 381: *mem++ = -nprod; ! 382: ! 383: /* check that default action is reasonable */ ! 384: ! 385: if( ntypes && !(levprd[nprod]&ACTFLAG) && nontrst[*prdptr[nprod]-NTBASE].tvalue ){ ! 386: /* no explicit action, LHS has value */ ! 387: register tempty; ! 388: tempty = prdptr[nprod][1]; ! 389: if( tempty < 0 ) error( "must return a value, since LHS has a type" ); ! 390: else if( tempty >= NTBASE ) tempty = nontrst[tempty-NTBASE].tvalue; ! 391: else tempty = TYPE( toklev[tempty] ); ! 392: if( tempty != nontrst[*prdptr[nprod]-NTBASE].tvalue ){ ! 393: error( "default action causes potential type clash" ); ! 394: } ! 395: } ! 396: ! 397: if( ++nprod >= NPROD ) error( "more than %d rules", NPROD ); ! 398: prdptr[nprod] = mem; ! 399: levprd[nprod]=0; ! 400: ! 401: } ! 402: ! 403: /* end of all rules */ ! 404: ! 405: finact(); ! 406: if( t == MARK ){ ! 407: fprintf( ftable, "\n# line %d \"%s\"\n", lineno, infile ); ! 408: while( (c=getc(finput)) != EOF ) putc( c, ftable ); ! 409: } ! 410: fclose( finput ); ! 411: } ! 412: ! 413: finact(){ ! 414: /* finish action routine */ ! 415: ! 416: fclose(faction); ! 417: ! 418: fprintf( ftable, "# define YYERRCODE %d\n", tokset[2].value ); ! 419: ! 420: } ! 421: ! 422: defin( t, s ) register char *s; { ! 423: /* define s to be a terminal if t=0 ! 424: or a nonterminal if t=1 */ ! 425: ! 426: register val; ! 427: ! 428: if (t) { ! 429: if( ++nnonter >= NNONTERM ) error("too many nonterminals, limit %d",NNONTERM); ! 430: nontrst[nnonter].name = cstash(s); ! 431: return( NTBASE + nnonter ); ! 432: } ! 433: /* must be a token */ ! 434: if( ++ntokens >= NTERMS ) error("too many terminals, limit %d",NTERMS ); ! 435: tokset[ntokens].name = cstash(s); ! 436: ! 437: /* establish value for token */ ! 438: ! 439: if( s[0]==' ' && s[2]=='\0' ) /* single character literal */ ! 440: val = s[1]; ! 441: else if ( s[0]==' ' && s[1]=='\\' ) { /* escape sequence */ ! 442: if( s[3] == '\0' ){ /* single character escape sequence */ ! 443: switch ( s[2] ){ ! 444: /* character which is escaped */ ! 445: case 'n': val = '\n'; break; ! 446: case 'r': val = '\r'; break; ! 447: case 'b': val = '\b'; break; ! 448: case 't': val = '\t'; break; ! 449: case 'f': val = '\f'; break; ! 450: case '\'': val = '\''; break; ! 451: case '"': val = '"'; break; ! 452: case '\\': val = '\\'; break; ! 453: default: error( "invalid escape" ); ! 454: } ! 455: } ! 456: else if( s[2] <= '7' && s[2]>='0' ){ /* \nnn sequence */ ! 457: if( s[3]<'0' || s[3] > '7' || s[4]<'0' || ! 458: s[4]>'7' || s[5] != '\0' ) error("illegal \\nnn construction" ); ! 459: val = 64*s[2] + 8*s[3] + s[4] - 73*'0'; ! 460: if( val == 0 ) error( "'\\000' is illegal" ); ! 461: } ! 462: } ! 463: else { ! 464: val = extval++; ! 465: } ! 466: tokset[ntokens].value = val; ! 467: toklev[ntokens] = 0; ! 468: return( ntokens ); ! 469: } ! 470: ! 471: int tmpx[NTERMS + 0400]; /* extval = 0400 in setup is junky */ ! 472: defout(last) /* write out the defines (at the end of the declaration section) */ ! 473: { register int i, c; ! 474: register char *cp; ! 475: static int beenhere = 0; ! 476: ! 477: if(!beenhere++ && fdebug != NULL) ! 478: for(i = 0; i < sizeof(tmpx)/sizeof(tmpx[0]); tmpx[i++] = -1) ! 479: ; ! 480: for( i=ndefout; i<=ntokens; ++i ){ ! 481: ! 482: cp = tokset[i].name; ! 483: if( *cp == ' ' ) { /* literals */ ! 484: tmpx[tokset[i].value] = i; ! 485: } ! 486: else { ! 487: fprintf( ftable, "# define %s %d\n", ! 488: tokset[i].name, tokset[i].value ); ! 489: if(fdefine != NULL) ! 490: fprintf( fdefine, "# define %s %d\n", ! 491: tokset[i].name, tokset[i].value ); ! 492: tmpx[tokset[i].value] = i; ! 493: } ! 494: } ! 495: ! 496: ndefout = ntokens+1; ! 497: if(last && fdebug != NULL) { ! 498: fprintf(fdebug, "char *yytoknames[] = {\n"); ! 499: for(i = 0; i < sizeof(tmpx)/sizeof(tmpx[0]); i++) ! 500: if(tmpx[i] == -1) ! 501: fprintf(fdebug, "0,"); ! 502: else ! 503: fprintf(fdebug, "\"%s\",\n", tokset[tmpx[i]].name); ! 504: fprintf(fdebug, "};\n"); ! 505: } ! 506: } ! 507: ! 508: char * ! 509: cstash( s ) register char *s; { ! 510: char *temp; ! 511: ! 512: temp = cnamp; ! 513: do { ! 514: if( cnamp >= &cnames[cnamsz] ) error("too many characters in id's and literals" ); ! 515: else *cnamp++ = *s; ! 516: } while ( *s++ ); ! 517: return( temp ); ! 518: } ! 519: ! 520: gettok() { ! 521: register i, base; ! 522: static int peekline; /* number of '\n' seen in lookahead */ ! 523: register c, match, reserve; ! 524: ! 525: begin: ! 526: reserve = 0; ! 527: lineno += peekline; ! 528: peekline = 0; ! 529: c = getc(finput); ! 530: while( c==' ' || c=='\n' || c=='\t' || c=='\f' ){ ! 531: if( c == '\n' ) ++lineno; ! 532: c=getc(finput); ! 533: } ! 534: if( c == '/' ){ /* skip comment */ ! 535: lineno += skipcom(); ! 536: goto begin; ! 537: } ! 538: ! 539: switch(c){ ! 540: ! 541: case EOF: ! 542: return(ENDFILE); ! 543: case '{': ! 544: ungetc( c, finput ); ! 545: return( '=' ); /* action ... */ ! 546: case '<': /* get, and look up, a type name (union member name) */ ! 547: i = 0; ! 548: while( (c=getc(finput)) != '>' && c>=0 && c!= '\n' ){ ! 549: tokname[i] = c; ! 550: if( ++i >= NAMESIZE ) --i; ! 551: } ! 552: if( c != '>' ) error( "unterminated < ... > clause" ); ! 553: tokname[i] = '\0'; ! 554: for( i=1; i<=ntypes; ++i ){ ! 555: if( !strcmp( typeset[i], tokname ) ){ ! 556: numbval = i; ! 557: return( TYPENAME ); ! 558: } ! 559: } ! 560: typeset[numbval = ++ntypes] = cstash( tokname ); ! 561: return( TYPENAME ); ! 562: ! 563: case '"': ! 564: case '\'': ! 565: match = c; ! 566: tokname[0] = ' '; ! 567: i = 1; ! 568: for(;;){ ! 569: c = getc(finput); ! 570: if( c == '\n' || c == EOF ) ! 571: error("illegal or missing ' or \"" ); ! 572: if( c == '\\' ){ ! 573: c = getc(finput); ! 574: tokname[i] = '\\'; ! 575: if( ++i >= NAMESIZE ) --i; ! 576: } ! 577: else if( c == match ) break; ! 578: tokname[i] = c; ! 579: if( ++i >= NAMESIZE ) --i; ! 580: } ! 581: break; ! 582: ! 583: case '%': ! 584: case '\\': ! 585: ! 586: switch(c=getc(finput)) { ! 587: ! 588: case '0': return(TERM); ! 589: case '<': return(LEFT); ! 590: case '2': return(BINARY); ! 591: case '>': return(RIGHT); ! 592: case '%': ! 593: case '\\': return(MARK); ! 594: case '=': return(PREC); ! 595: case '{': return(LCURLY); ! 596: default: reserve = 1; ! 597: } ! 598: ! 599: default: ! 600: ! 601: if( isdigit(c) ){ /* number */ ! 602: numbval = c-'0' ; ! 603: base = (c=='0') ? 8 : 10 ; ! 604: for( c=getc(finput); isdigit(c) ; c=getc(finput) ){ ! 605: numbval = numbval*base + c - '0'; ! 606: } ! 607: ungetc( c, finput ); ! 608: return(NUMBER); ! 609: } ! 610: else if( islower(c) || isupper(c) || c=='_' || c=='.' || c=='$' ){ ! 611: i = 0; ! 612: while( islower(c) || isupper(c) || isdigit(c) || c == '-' || c=='_' || c=='.' || c=='$' ){ ! 613: tokname[i] = c; ! 614: if( reserve && isupper(c) ) tokname[i] += 'a'-'A'; ! 615: if( ++i >= NAMESIZE ) --i; ! 616: c = getc(finput); ! 617: } ! 618: } ! 619: else return(c); ! 620: ! 621: ungetc( c, finput ); ! 622: } ! 623: ! 624: tokname[i] = '\0'; ! 625: ! 626: if( reserve ){ /* find a reserved word */ ! 627: if( !strcmp(tokname,"term")) return( TERM ); ! 628: if( !strcmp(tokname,"token")) return( TERM ); ! 629: if( !strcmp(tokname,"left")) return( LEFT ); ! 630: if( !strcmp(tokname,"nonassoc")) return( BINARY ); ! 631: if( !strcmp(tokname,"binary")) return( BINARY ); ! 632: if( !strcmp(tokname,"right")) return( RIGHT ); ! 633: if( !strcmp(tokname,"prec")) return( PREC ); ! 634: if( !strcmp(tokname,"start")) return( START ); ! 635: if( !strcmp(tokname,"type")) return( TYPEDEF ); ! 636: if( !strcmp(tokname,"union")) return( UNION ); ! 637: error("invalid escape, or illegal reserved word: %s", tokname ); ! 638: } ! 639: ! 640: /* look ahead to distinguish IDENTIFIER from C_IDENTIFIER */ ! 641: ! 642: c = getc(finput); ! 643: while( c==' ' || c=='\t'|| c=='\n' || c=='\f' || c== '/' ) { ! 644: if( c == '\n' ) ++peekline; ! 645: else if( c == '/' ){ /* look for comments */ ! 646: peekline += skipcom(); ! 647: } ! 648: c = getc(finput); ! 649: } ! 650: if( c == ':' ) return( C_IDENTIFIER ); ! 651: ungetc( c, finput ); ! 652: return( IDENTIFIER ); ! 653: } ! 654: ! 655: fdtype( t ){ /* determine the type of a symbol */ ! 656: register v; ! 657: if( t >= NTBASE ) v = nontrst[t-NTBASE].tvalue; ! 658: else v = TYPE( toklev[t] ); ! 659: if( v <= 0 ) error( "must specify type for %s", (t>=NTBASE)?nontrst[t-NTBASE].name: ! 660: tokset[t].name ); ! 661: return( v ); ! 662: } ! 663: ! 664: chfind( t, s ) register char *s; { ! 665: int i; ! 666: ! 667: if (s[0]==' ')t=0; ! 668: TLOOP(i){ ! 669: if(!strcmp(s,tokset[i].name)){ ! 670: return( i ); ! 671: } ! 672: } ! 673: NTLOOP(i){ ! 674: if(!strcmp(s,nontrst[i].name)) { ! 675: return( i+NTBASE ); ! 676: } ! 677: } ! 678: /* cannot find name */ ! 679: if( t>1 ) ! 680: error( "%s should have been defined earlier", s ); ! 681: return( defin( t, s ) ); ! 682: } ! 683: ! 684: cpyunion(){ ! 685: /* copy the union declaration to the output, and the define file if present */ ! 686: ! 687: int level, c; ! 688: fprintf( ftable, "\n# line %d \"%s\"\n", lineno, infile ); ! 689: fprintf( ftable, "typedef union " ); ! 690: if( fdefine ) fprintf( fdefine, "\ntypedef union " ); ! 691: ! 692: level = 0; ! 693: for(;;){ ! 694: if( (c=getc(finput)) < 0 ) error( "EOF encountered while processing %%union" ); ! 695: putc( c, ftable ); ! 696: if( fdefine ) putc( c, fdefine ); ! 697: ! 698: switch( c ){ ! 699: ! 700: case '\n': ! 701: ++lineno; ! 702: break; ! 703: ! 704: case '{': ! 705: ++level; ! 706: break; ! 707: ! 708: case '}': ! 709: --level; ! 710: if( level == 0 ) { /* we are finished copying */ ! 711: fprintf( ftable, " YYSTYPE;\n" ); ! 712: if( fdefine ) fprintf( fdefine, " YYSTYPE;\nextern YYSTYPE yylval;\n" ); ! 713: return; ! 714: } ! 715: } ! 716: } ! 717: } ! 718: ! 719: cpycode(){ /* copies code between \{ and \} */ ! 720: ! 721: int c; ! 722: c = getc(finput); ! 723: if( c == '\n' ) { ! 724: c = getc(finput); ! 725: lineno++; ! 726: } ! 727: fprintf( ftable, "\n# line %d \"%s\"\n", lineno, infile ); ! 728: while( c>=0 ){ ! 729: if( c=='\\' ) ! 730: if( (c=getc(finput)) == '}' ) return; ! 731: else putc('\\', ftable ); ! 732: if( c=='%' ) ! 733: if( (c=getc(finput)) == '}' ) return; ! 734: else putc('%', ftable ); ! 735: putc( c , ftable ); ! 736: if( c == '\n' ) ++lineno; ! 737: c = getc(finput); ! 738: } ! 739: error("eof before %%}" ); ! 740: } ! 741: ! 742: skipcom(){ /* skip over comments */ ! 743: register c, i=0; /* i is the number of lines skipped */ ! 744: ! 745: /* skipcom is called after reading a / */ ! 746: ! 747: if( getc(finput) != '*' ) error( "illegal comment" ); ! 748: c = getc(finput); ! 749: while( c != EOF ){ ! 750: while( c == '*' ){ ! 751: if( (c=getc(finput)) == '/' ) return( i ); ! 752: } ! 753: if( c == '\n' ) ++i; ! 754: c = getc(finput); ! 755: } ! 756: error( "EOF inside comment" ); ! 757: /* NOTREACHED */ ! 758: } ! 759: ! 760: cpyact(offset){ /* copy C action to the next ; or closing } */ ! 761: int brac, c, match, j, s, tok, fnd; ! 762: ! 763: fprintf( faction, "\n# line %d \"%s\"\n", lineno, infile ); ! 764: ! 765: brac = 0; ! 766: ! 767: loop: ! 768: c = getc(finput); ! 769: swt: ! 770: switch( c ){ ! 771: ! 772: case ';': ! 773: if( brac == 0 ){ ! 774: putc( c , faction ); ! 775: return; ! 776: } ! 777: goto lcopy; ! 778: ! 779: case '{': ! 780: brac++; ! 781: goto lcopy; ! 782: ! 783: case '$': ! 784: s = 1; ! 785: tok = -1; ! 786: c = getc(finput); ! 787: if( c == '<' ){ /* type description */ ! 788: ungetc( c, finput ); ! 789: if( gettok() != TYPENAME ) error( "bad syntax on $<ident> clause" ); ! 790: tok = numbval; ! 791: c = getc(finput); ! 792: } ! 793: if( c == '$' ){ ! 794: fprintf( faction, "yyval"); ! 795: if( ntypes ){ /* put out the proper tag... */ ! 796: if( tok < 0 ) tok = fdtype( *prdptr[nprod] ); ! 797: fprintf( faction, ".%s", typeset[tok] ); ! 798: } ! 799: goto loop; ! 800: } ! 801: if( c == '-' ){ ! 802: s = -s; ! 803: c = getc(finput); ! 804: } ! 805: if( isdigit(c) ){ ! 806: j=0; ! 807: while( isdigit(c) ){ ! 808: j= j*10+c-'0'; ! 809: c = getc(finput); ! 810: } ! 811: ungetc(c, finput); ! 812: j = j*s - offset; ! 813: if( j > 0 ){ ! 814: error( "Illegal use of $%d", j+offset ); ! 815: } ! 816: dollar: ! 817: fprintf( faction, "yypvt[-%d]", -j ); ! 818: if( ntypes ){ /* put out the proper tag */ ! 819: if( j+offset <= 0 && tok < 0 ) error( "must specify type of $%d", j+offset ); ! 820: if( tok < 0 ) tok = fdtype( prdptr[nprod][j+offset] ); ! 821: fprintf( faction, ".%s", typeset[tok] ); ! 822: } ! 823: goto loop; ! 824: } ! 825: if( isupper(c) || islower(c) || c == '_' || c == '.' ) ! 826: { ! 827: /* look for $name */ ! 828: int tok; /* tok used oustide for type info */ ! 829: ungetc( c, finput ); ! 830: if( gettok() != IDENTIFIER ) ! 831: error( "$ must be followed by an identifier" ); ! 832: tok = chfind( 2, tokname ); ! 833: if( (c = getc( finput ) ) != '#' ) ! 834: { ! 835: ungetc( c, finput ); ! 836: fnd = -1; ! 837: } ! 838: else ! 839: { ! 840: if( gettok() != NUMBER ) ! 841: { ! 842: error( "# must be followed by number" ); ! 843: fnd = -1; ! 844: } ! 845: else ! 846: { ! 847: fnd = numbval; ! 848: } ! 849: } ! 850: ! 851: for( j=1; j<=offset; ++j ) ! 852: { ! 853: if( tok == prdptr[nprod][j] ) ! 854: { ! 855: if( --fnd <= 0 ) ! 856: { ! 857: j -= offset; ! 858: goto dollar; /* found it */ ! 859: } ! 860: } ! 861: } ! 862: error( "$name or $name#number not found" ); ! 863: } ! 864: ! 865: putc( '$' , faction ); ! 866: if( s<0 ) putc('-', faction ); ! 867: goto swt; ! 868: ! 869: case '}': ! 870: if( --brac ) goto lcopy; ! 871: putc( c, faction ); ! 872: return; ! 873: ! 874: ! 875: case '/': /* look for comments */ ! 876: putc( c , faction ); ! 877: c = getc(finput); ! 878: if( c != '*' ) goto swt; ! 879: ! 880: /* it really is a comment */ ! 881: ! 882: putc( c , faction ); ! 883: c = getc(finput); ! 884: while( c != EOF ){ ! 885: while( c=='*' ){ ! 886: putc( c , faction ); ! 887: if( (c=getc(finput)) == '/' ) goto lcopy; ! 888: } ! 889: putc( c , faction ); ! 890: if( c == '\n' )++lineno; ! 891: c = getc(finput); ! 892: } ! 893: error( "EOF inside comment" ); ! 894: ! 895: case '\'': /* character constant */ ! 896: match = '\''; ! 897: goto string; ! 898: ! 899: case '"': /* character string */ ! 900: match = '"'; ! 901: ! 902: string: ! 903: ! 904: putc( c , faction ); ! 905: while( c=getc(finput) ){ ! 906: ! 907: if( c=='\\' ){ ! 908: putc( c , faction ); ! 909: c=getc(finput); ! 910: if( c == '\n' ) ++lineno; ! 911: } ! 912: else if( c==match ) goto lcopy; ! 913: else if( c=='\n' ) error( "newline in string or char. const." ); ! 914: putc( c , faction ); ! 915: } ! 916: error( "EOF in string or character constant" ); ! 917: ! 918: case EOF: ! 919: error("action does not terminate" ); ! 920: ! 921: case '\n': ++lineno; ! 922: goto lcopy; ! 923: ! 924: } ! 925: ! 926: lcopy: ! 927: putc( c , faction ); ! 928: goto loop; ! 929: } ! 930: ! 931: ! 932: openup(stem, Dflag, dflag, vflag, ytab, ytabc) ! 933: char *stem, *ytabc; ! 934: { ! 935: char buf[256]; ! 936: ! 937: if(vflag) ! 938: { ! 939: sprintf(buf, "%s.%s", stem, FILEU); ! 940: foutput = fopen(buf, "w" ); ! 941: if( foutput == NULL ) ! 942: error( "cannot open %s", buf ); ! 943: } ! 944: if(Dflag) ! 945: { ! 946: sprintf(buf, "%s.%s", stem, FILEDEBUG); ! 947: if((fdebug = fopen(buf, "w")) == NULL) ! 948: error("can't open %s", buf); ! 949: fprintf(fdebug, "#ifdef YYDEBUG\n"); ! 950: } ! 951: if(dflag) ! 952: { ! 953: sprintf(buf, "%s.%s", stem, FILED); ! 954: fdefine = fopen( buf, "w" ); ! 955: if(fdefine == NULL) ! 956: error("can't create %s", buf); ! 957: } ! 958: if(ytab == 0) ! 959: sprintf(buf, "%s.%s", stem, OFILE); ! 960: else ! 961: strcpy(buf, ytabc); ! 962: ftable = fopen( buf, "w" ); ! 963: if( ftable == NULL ) error( "cannot open table file %s", buf); ! 964: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.