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