glenn@extro.ucc.su.oz (G. Geers [ext 3241]) (06/28/89)
The next four articles contain a public domain version of yacc. This has only been tested on PC-MINIX (1.3c with 1.1 compiler) but should work on ST-MINIX with no modifications (see README.MINIX). Share and Enjoy, Glenn Glenn Geers Dept. Theoretical Physics University of Sydney Sydney, N.S.W. 2006 Phone: +61 2 692-3241 Perfection was a word invented by someone who couldn't do any better Usual disclaimer applies --- cut here --- cut here --- cut here --- cut here --- cut here --- #!/bin/sh # This is a shell archive. Remove anything before the /bin/sh line # then unpack it by saving it in a file and typing "sh file" # (Files unpacked will be owned by you and have default permissions). # Don't worry about trailing garbage - the archive ends with exit # This archive contains the following files: # ./yprcft.c # ./yprlok.c # ./yptitm.c # ./ysetup.c # ./yskpcm.c # ./ysmnam.c # ./ystagn.c # ./ystate.c # ./ystin.c # ./ystuni.c # ./ysumry.c # ./ywarry.c # ./ywract.c # ./ywritm.c # ./ywstat.c # ./yypars # if `test ! -s ./yprcft.c` then echo "writing ./yprcft.c" cat > ./yprcft.c << '\EOF\' #include "y3.h" precftn(r, t, s) { /* decide a shift/reduce conflict by precedence.*/ /* r is a rule number, t a token number */ /* the conflict is in state s */ /* temp1[t] is changed to reflect the action */ int lp, lt, action; lp = levprd[r]; lt = toklev[t]; if ( PLEVEL(lt) == 0 || PLEVEL(lp) == 0 ) { /* conflict */ if ( foutput != NULL ) fprintf( foutput, "\n%d: shift/reduce conflict (shift %d, red'n %d) on %s", s, temp1[t], r, symnam(t) ); ++zzsrconf; return; } if ( PLEVEL(lt) == PLEVEL(lp) ) action = ASSOC(lt); else if ( PLEVEL(lt) > PLEVEL(lp) ) action = RASC; /* shift */ else action = LASC; /* reduce */ switch ( action ) { case BASC: /* error action */ temp1[t] = ERRCODE; return; case LASC: /* reduce */ temp1[t] = -r; return; } } \EOF\ else echo "will not over write ./yprcft.c" fi if `test ! -s ./yprlok.c` then echo "writing ./yprlok.c" cat > ./yprlok.c << '\EOF\' #include "y1.h" prlook( p ) struct looksets *p; { register j, *pp; pp = p->lset; if ( pp == 0 ) fprintf( foutput, "\tNULL"); else { fprintf( foutput, " { " ); TLOOP(j) { if ( BIT(pp, j) ) fprintf( foutput, "%s ", symnam(j) ); } fprintf( foutput, "}" ); } } \EOF\ else echo "will not over write ./yprlok.c" fi if `test ! -s ./yptitm.c` then echo "writing ./yptitm.c" cat > ./yptitm.c << '\EOF\' #include "y1.h" /* * yptitm.1c * * Modified to make debug code conditionally compile. * 28-Aug-81 * Bob Denny */ putitem( ptr, lptr ) int *ptr; struct looksets *lptr; { register struct item *j; #ifdef debug if ( foutput != NULL ) { fprintf( foutput, "putitem(%s), state %d\n", writem(ptr), nstate ); } #endif j = pstate[nstate+1]; j->pitem = ptr; if ( !nolook ) j->look = flset( lptr ); pstate[nstate+1] = ++j; if ( (int *)j > zzmemsz ) { zzmemsz = (int *)j; if ( zzmemsz >= &mem0[MEMSIZE] ) error( "out of state space" ); } } \EOF\ else echo "will not over write ./yptitm.c" fi if `test ! -s ./ysetup.c` then echo "writing ./ysetup.c" cat > ./ysetup.c << '\EOF\' /* * YSETUP.C -- Modified for use with DECUS LEX * Variable "yylval" resides in yylex(), not in yypars(); * Therefore, is defined "extern" here. * * Also, the command line processing for the Decus version * has been changed. A new switch has been added to allow * specification of the "table" file name(s), and unused * switch processing removed. * * NOTE * This probably won't run on UNIX any more. * * Bob Denny 27-Aug-81 * Bob Denny 22-Mar-82 (01) Added header line, changes for 'new' DECUS library * Bob Denny 12-Apr-83 (02) Make filename[] size per #define'd FNAMESIZE so * VAX filenames won't blow out. Conditionalize * time handling for banner. Make filespec buffer * static for safety, since global "infile" is * pointed to it. * Scott Guthery 15-May-83 (03) Fixed up option flag handling for RT-11 * 23-Dec-83 Adapted for IBM PC/XT & DeSmet C compiler */ #include "y2.h" static char filename[FNAMESIZE]; int i, j, lev, t, ty; int c; int tempty; int *p; int defsw, infsw; char actname[8]; char *cp; setup(argc, argv) int argc; char *argv[]; { char finsave[FNAMESIZE]; defsw = infsw = 0; foutput = NULL; fdefine = NULL; i = 1; /*(03)*/ while ( argc > 1 && argv[i][0] == '-' ) /*(03)*/ { while ( *++(argv[i]) ) { switch ( *argv[i] ) { case 'i': case 'I': infsw++; continue; case 'h': case 'H': defsw++; continue; default: fprintf(stderr, "Illegal option: %c\n", *argv[i]); usage(); } } i++; /*(03)*/ argc--; } if (argc < 2) usage(); /* Catch no filename given */ /* * Now open the input file with a default extension of ".Y", * then replace the period in argv[1] with a null, so argv[1] * can be used to form the table, defs and info filenames. */ cp = argv[i]; while (*cp++ != '.' && *cp != '\0') ; /* Scan past '.' or to null */ if (*cp == '\0') { strcpy(filename, argv[i]); strcat(filename, ".Y"); } else { strcpy(filename, argv[i]); *(argv[i] - 1) = '\0'; /* Null the period */ } strcpy(finsave, filename); if ((finput = fopen( filename, "r" )) == NULL ) error( "cannot open input file \"%s\"", filename ); /* * Now open the .H and .I files if requested. */ if (defsw) { strcpy(filename, argv[i]); strcat(filename, ".h"); fdefine = fopen(filename, "w"); if (fdefine == NULL) error("cannot open defs file\"%s\"", filename); } if (infsw) { strcpy(filename, argv[i]); strcat(filename, ".i"); foutput = fopen(filename, "w"); if (foutput == NULL) error("cannot open info file\"%s\"", filename); } /* * Now the "table" output C file. */ strcpy(filename, argv[i]); strcat(filename, ".c"); ftable = fopen(filename, "w"); if ( ftable == NULL ) error( "cannot open table file\"%s\"", filename); /* * Finally, the temp files. */ ftemp = fopen( TEMPNAME, "w" ); if ( ftemp == NULL ) error( "cannot open temp file" ); faction = fopen( ACTNAME, "w" ); if ( faction == NULL ) error( "cannot open action file" ); /* * Now put the full filename of the input file into * the "filename" buffer for cpyact(), and point the * global cell "infile" at it. */ strcpy(filename, finsave); infile = filename; /* * Put out a header line at the beginning of the 'table' file. */ fprintf(ftable, "/*\n * Created by CSD YACC from \"%s\"\n */\n", infile); /* * Complete initialization. */ cnamp = cnames; defin(0, "$end"); extval = 0400; defin(0, "error"); defin(1, "$accept"); mem = mem0; lev = 0; ty = 0; i = 0; yyparse(); } yyparse() { /* sorry -- no yacc parser here..... we must bootstrap somehow... */ for ( t = gettok(); t != MARK && t != ENDFILE; ) { switch ( t ) { case ';': t = gettok(); break; case START: if ( (t = gettok()) != IDENTIFIER ) { error( "bad %%start construction" ); } start = chfind(1, tokname); t = gettok(); continue; case TYPEDEF: if ( (t = gettok()) != TYPENAME ) error( "bad syntax in %%type" ); ty = numbval; for (; ; ) { t = gettok(); switch ( t ) { case IDENTIFIER: if ( (t = chfind( 1, tokname ) ) < NTBASE ) { j = TYPE( toklev[t] ); if ( j != 0 && j != ty ) { error( "type redeclaration of token %s", tokset[t].name ); } else SETTYPE( toklev[t], ty); } else { j = nontrst[t-NTBASE].tvalue; if ( j != 0 && j != ty ) { error( "type redeclaration of nonterminal %s", nontrst[t-NTBASE].name ); } else nontrst[t-NTBASE].tvalue = ty; } case ',': continue; case ';': t = gettok(); break; default: break; } break; } continue; case UNION: /* copy the union declaration to the output */ cpyunion(); t = gettok(); continue; case LEFT: case BINARY: case RIGHT: ++i; case TERM: lev = t - TERM; /* nonzero means new prec. and assoc. */ ty = 0; /* get identifiers so defined */ t = gettok(); if ( t == TYPENAME ) { /* there is a type defined */ ty = numbval; t = gettok(); } for (; ; ) { switch ( t ) { case ',': t = gettok(); continue; case ';': break; case IDENTIFIER: j = chfind(0, tokname); if ( lev ) { if ( ASSOC(toklev[j]) ) error( "redeclaration of precedence of%s", tokname ); SETASC(toklev[j], lev); SETPLEV(toklev[j], i); } if ( ty ) { if ( TYPE(toklev[j]) ) error( "redeclaration of type of %s", tokname ); SETTYPE(toklev[j], ty); } if ( (t = gettok()) == NUMBER ) { tokset[j].value = numbval; if ( j < ndefout && j > 2 ) { error( "please define type number of %s earlier", tokset[j].name ); } t = gettok(); } continue; } break; } continue; case LCURLY: defout(); cpycode(); t = gettok(); continue; default: printf("Unrecognized character: %o\n", t); error( "syntax error" ); } } if ( t == ENDFILE ) { error( "unexpected EOF before %%" ); } /* t is MARK */ defout(); fprintf( ftable, "#define yyclearin yychar = -1\n" ); fprintf( ftable, "#define yyerrok yyerrflag = 0\n" ); /* fprintf( ftable,"extern int yychar;\nextern short yyerrflag;\n" ); */ fprintf( ftable, "#ifndef YYMAXDEPTH\n#define YYMAXDEPTH 150\n#endif\n" ); if (!ntypes) fprintf( ftable, "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n" ); #ifdef unix fprintf( ftable, "YYSTYPE yylval, yyval;\n" ); #else fprintf( ftable, "extern YYSTYPE yylval; /*CSD & DECUS LEX */\n"); fprintf( ftable, "YYSTYPE yyval; /*CSD & DECUS LEX */\n"); #endif prdptr[0] = mem; /* added production */ *mem++ = NTBASE; *mem++ = start; /* if start is 0, we will overwrite with the lhs of the firstrule */ *mem++ = 1; *mem++ = 0; prdptr[1] = mem; while ( (t = gettok()) == LCURLY ) cpycode(); if ( t != C_IDENTIFIER ) error( "bad syntax on first rule" ); if ( !start ) prdptr[0][1] = chfind(1, tokname); /* read rules */ while ( t != MARK && t != ENDFILE ) { /* process a rule */ if ( t == '|' ) { *mem++ = *prdptr[nprod-1]; } else if ( t == C_IDENTIFIER ) { *mem = chfind(1, tokname); if ( *mem < NTBASE ) error( "token illegal on LHS of grammar rule" ); ++mem; } else error( "illegal rule: missing semicolon or | ?" ); /* read rule body */ t = gettok(); more_rule: while ( t == IDENTIFIER ) { *mem = chfind(1, tokname); if ( *mem < NTBASE ) levprd[nprod] = toklev[*mem]; ++mem; t = gettok(); } if ( t == PREC ) { if ( gettok() != IDENTIFIER) error( "illegal %%prec syntax" ); j = chfind(2, tokname); if ( j >= NTBASE) error("nonterminal %s illegal after %%prec", nontrst[j-NTBASE].name); levprd[nprod] = toklev[j]; t = gettok(); } if ( t == '=' ) { levprd[nprod] |= ACTFLAG; fprintf( faction, "\ncase %d:", nprod ); cpyact( mem - prdptr[nprod] - 1 ); fprintf( faction, " break;" ); if ( (t = gettok()) == IDENTIFIER ) { /* action within rule... */ sprintf( actname, "$$%d", nprod ); j = chfind(1, actname); /* make it a nonterminal */ /* the current rule will become rule number nprod+1 */ /* move the contents down, and make room for the null */ for ( p = mem; p >= prdptr[nprod]; --p ) p[2] = *p; mem += 2; /* enter null production for action */ p = prdptr[nprod]; *p++ = j; *p++ = -nprod; /* update the production information */ levprd[nprod+1] = levprd[nprod] & ~ACTFLAG; levprd[nprod] = ACTFLAG; if ( ++nprod >= NPROD ) error( "more than %d rules", NPROD ); prdptr[nprod] = p; /* make the action appear in the original rule */ *mem++ = j; /* get some more of the rule */ goto more_rule; } } while ( t == ';' ) t = gettok(); *mem++ = -nprod; /* check that default action is reasonable */ if ( ntypes && !(levprd[nprod] & ACTFLAG) && nontrst[*prdptr[nprod]-NTBASE].tvalue ) { /* no explicit action, LHS has value */ /*01*/ tempty = prdptr[nprod][1]; if ( tempty < 0 ) error( "must return a value, since LHS has a type" ); else if ( tempty >= NTBASE ) tempty = nontrst[tempty-NTBASE].tvalue; else tempty = TYPE( toklev[tempty] ); if ( tempty != nontrst[*prdptr[nprod]-NTBASE].tvalue ) { error( "default action causes potential type clash" ); } } if ( ++nprod >= NPROD ) error( "more than %d rules", NPROD ); prdptr[nprod] = mem; levprd[nprod] = 0; } /* end of all rules */ fprintf(faction, "/* End of actions */"); /* Properly terminate the last line */ finact(); if ( t == MARK ) { fprintf( ftable, "\n#line %d\n", lineno ); while ( (c = unix_getc(finput)) != EOF ) putc( c, ftable ); } fclose( finput ); } usage() { fprintf(stderr, "UNIX YACC (CSD Variant):\n"); fprintf(stderr, " yacc -hi infile\n\n"); fprintf(stderr, "Switches:\n"); fprintf(stderr, " -h Create definitions header file\n"); fprintf(stderr, " -i Create parser description file\n\n"); fprintf(stderr, "Default input file extension is \".y\"\n"); fprintf(stderr, "Defs file same name, \".h\" extension.\n"); fprintf(stderr, "Info file same name, \".i\" extension.\n"); exit(EX_ERR); } \EOF\ else echo "will not over write ./ysetup.c" fi if `test ! -s ./yskpcm.c` then echo "writing ./yskpcm.c" cat > ./yskpcm.c << '\EOF\' #include "y2.h" skipcom() { /* skip over comments */ register c, i; /* i is the number of lines skipped */ i = 0; /*01*/ /* skipcom is called after reading a / */ if ( unix_getc(finput) != '*' ) error( "illegal comment" ); c = unix_getc(finput); while ( c != EOF ) { while ( c == '*' ) { if ( (c = unix_getc(finput)) == '/' ) return( i ); } if ( c == '\n' ) ++i; c = unix_getc(finput); } error( "EOF inside comment" ); /* NOTREACHED */ } \EOF\ else echo "will not over write ./yskpcm.c" fi if `test ! -s ./ysmnam.c` then echo "writing ./ysmnam.c" cat > ./ysmnam.c << '\EOF\' #include "y1.h" char *symnam(i) { /* return a pointer to the name of symbol i */ char *cp; cp = (i >= NTBASE) ? nontrst[i-NTBASE].name : tokset[i].name ; if ( *cp == ' ' ) ++cp; return( cp ); } \EOF\ else echo "will not over write ./ysmnam.c" fi if `test ! -s ./ystagn.c` then echo "writing ./ystagn.c" cat > ./ystagn.c << '\EOF\' #include "y1.h" /* * ystagn.1c * * Modified to make debug code conditionally compile. * 28-Aug-81 * Bob Denny */ stagen() { /* generate the states */ int i, j; register c; register struct wset *p, *q; /* initialize */ nstate = 0; /* THIS IS FUNNY from the standpoint of portability */ /* it represents the magic moment when the mem0 array, which has /* been holding the productions, starts to hold item pointers, of a /* different type... */ /* someday, alloc should be used to allocate all this stuff... for now, we /* accept that if pointers don't fit in integers, there is a problem... */ pstate[0] = pstate[1] = (struct item *)mem; aryfil( clset.lset, tbitset, 0 ); putitem( prdptr[0] + 1, &clset ); tystate[0] = MUSTDO; nstate = 1; pstate[2] = pstate[1]; aryfil( amem, ACTSIZE, 0 ); /* now, the main state generation loop */ more: SLOOP(i) { if ( tystate[i] != MUSTDO ) continue; tystate[i] = DONE; aryfil( temp1, nnonter + 1, 0 ); /* take state i, close it, and do gotos */ closure(i); WSLOOP(wsets, p) { /* generate goto's */ if ( p->flag ) continue; p->flag = 1; c = *(p->pitem); if ( c <= 1 ) { if ( pstate[i+1] - pstate[i] <= p - wsets ) tystate[i] = MUSTLOOKAHEAD; continue; } /* do a goto on c */ WSLOOP(p, q) { if ( c == *(q->pitem) ) { /* this item contributes to the goto */ putitem( q->pitem + 1, &q->ws ); q->flag = 1; } } if ( c < NTBASE ) { state(c); /* register new state */ } else { temp1[c-NTBASE] = state(c); } } #ifdef debug if ( foutput != NULL ) { fprintf( foutput, "%d: ", i ); NTLOOP(j) { if ( temp1[j] ) fprintf( foutput, "%s %d, ", nontrst[j].name, temp1[j] ); } fprintf( foutput, "\n"); } #endif indgo[i] = apack( &temp1[1], nnonter - 1 ) - 1; goto more; /* we have done one goto; do some more */ } /* no more to do... stop */ } \EOF\ else echo "will not over write ./ystagn.c" fi if `test ! -s ./ystate.c` then echo "writing ./ystate.c" cat > ./ystate.c << '\EOF\' #include "y1.h" state(c) { /* sorts last state,and sees if it equals earlier ones. returns state number */ int size1, size2; register i; int *s; /*01*/ struct looksets *ss; /*01*/ int s__; /*01*/ struct item *p1, *p2, *k, *l, *q1, *q2; p1 = pstate[nstate]; p2 = pstate[nstate+1]; if (p1 == p2) return(0); /* null state */ /* sort the items */ for (k = p2 - 1; k > p1; k--) { /* make k the biggest */ for (l = k - 1; l >= p1; --l) if ( l->pitem > k->pitem ) { s = k->pitem; k->pitem = l->pitem; l->pitem = s; ss = k->look; k->look = l->look; l->look = ss; } } size1 = p2 - p1; /* size of state */ for ( i = (c >= NTBASE) ? ntstates[c-NTBASE] : tstates[c]; i != 0; i = mstates[i] ) { /* get ith state */ q1 = pstate[i]; q2 = pstate[i+1]; size2 = q2 - q1; if (size1 != size2) continue; k = p1; for (l = q1; l < q2; l++) { if ( l->pitem != k->pitem ) break; ++k; } if (l != q2) continue; /* found it */ pstate[nstate+1] = pstate[nstate]; /* delete last state */ /* fix up lookaheads */ if ( nolook ) return(i); for ( l = q1, k = p1; l < q2; ++l, ++k ) { SETLOOP(s__) clset.lset[s__] = l->look->lset[s__]; if ( setunion( clset.lset, k->look->lset ) ) { tystate[i] = MUSTDO; /* register the new set */ l->look = flset( &clset ); } } return (i); } /* state is new */ if ( nolook ) error( "yacc state/nolook error" ); pstate[nstate+2] = p2; if (nstate + 1 >= NSTATES) error("too many states" ); if ( c >= NTBASE ) { mstates[ nstate ] = ntstates[ c-NTBASE ]; ntstates[ c-NTBASE ] = nstate; } else { mstates[ nstate ] = tstates[ c ]; tstates[ c ] = nstate; } tystate[nstate] = MUSTDO; return(nstate++); } \EOF\ else echo "will not over write ./ystate.c" fi if `test ! -s ./ystin.c` then echo "writing ./ystin.c" cat > ./ystin.c << '\EOF\' #include "y4.h" stin(i) { register *r, *s, n, flag, j, *q1, *q2; greed[i] = 0; /* enter state i into the a array */ q2 = mem0 + yypact[i+1]; q1 = mem0 + yypact[i]; /* find an acceptable place */ for ( n = -maxoff; n < ACTSIZE; ++n ) { flag = 0; for ( r = q1; r < q2; r += 2 ) { if ( (s = *r + n + a ) < a ) goto nextn; if ( *s == 0 ) ++flag; else if ( *s != r[1] ) goto nextn; } /* check that the position equals another only if the states are identical */ for ( j = 0; j < nstate; ++j ) { if ( pa[j] == n ) { if ( flag ) goto nextn; /* we have some disagreement */ if ( yypact[j+1] + yypact[i] == yypact[j] + yypact[i+1] ) { /* states are equal */ pa[i] = n; if ( adb > 1 ) fprintf( ftable, "State %d: entry at %d equals state %d\n", i, n, j ); return; } goto nextn; /* we have some disagreement */ } } for ( r = q1; r < q2; r += 2 ) { if ( (s = *r + n + a ) >= &a[ACTSIZE] ) error( "out of space in optimizer a array" ); if ( s > maxa ) maxa = s; if ( *s != 0 && *s != r[1] ) error( "clobber of a array, pos'n %d, by %d", s - a, r[1] ); *s = r[1]; } pa[i] = n; if ( adb > 1 ) fprintf( ftable, "State %d: entry at %d\n", i, pa[i] ); return; nextn: ; } error( "Error; failure to place state %d\n", i ); } \EOF\ else echo "will not over write ./ystin.c" fi if `test ! -s ./ystuni.c` then echo "writing ./ystuni.c" cat > ./ystuni.c << '\EOF\' #include "y1.h" setunion( a, b ) register *a, *b; { /* set a to the union of a and b */ /* return 1 if b is not a subset of a, 0 otherwise */ register i, x, sub; sub = 0; SETLOOP(i) { *a = (x = *a) | *b++; if ( *a++ != x ) sub = 1; } return( sub ); } \EOF\ else echo "will not over write ./ystuni.c" fi if `test ! -s ./ysumry.c` then echo "writing ./ysumry.c" cat > ./ysumry.c << '\EOF\' #include "y1.h" summary() { /* output the summary on the tty */ if ( foutput != NULL ) { fprintf( foutput, "\n%d/%d terminals, %d/%d nonterminals\n", ntokens, NTERMS, nnonter, NNONTERM ); fprintf( foutput, "%d/%d grammar rules, %d/%d states\n", nprod, NPROD, nstate, NSTATES ); fprintf( foutput, "%d shift/reduce, %d reduce/reduce conflicts reported\n", zzsrconf, zzrrconf ); fprintf( foutput, "%d/%d working sets used\n", zzcwp - wsets, WSETSIZE ); fprintf( foutput, "memory: states,etc. %d/%d, parser %d/%d\n", zzmemsz - mem0, MEMSIZE, memp - amem, ACTSIZE ); fprintf( foutput, "%d/%d distinct lookahead sets\n", nlset, LSETSIZE ); fprintf( foutput, "%d extra closures\n", zzclose - 2 * nstate ); fprintf( foutput, "%d shift entries, %d exceptions\n", zzacent, zzexcp ); fprintf( foutput, "%d goto entries\n", zzgoent ); fprintf( foutput, "%d entries saved by goto default\n", zzgobest ); } if ( zzsrconf != 0 || zzrrconf != 0 ) { fprintf( stdout, "\nconflicts: "); if ( zzsrconf ) fprintf( stdout, "%d shift/reduce" , zzsrconf ); if ( zzsrconf && zzrrconf ) fprintf( stdout, ", " ); if ( zzrrconf ) fprintf( stdout, "%d reduce/reduce" , zzrrconf ); fprintf( stdout, "\n" ); } fclose( ftemp ); if ( fdefine != NULL ) fclose( fdefine ); } \EOF\ else echo "will not over write ./ysumry.c" fi if `test ! -s ./ywarry.c` then echo "writing ./ywarry.c" cat > ./ywarry.c << '\EOF\' #include "y3.h" warray( s, v, n ) char *s; int *v, n; { register i; fprintf( ftable, "short %s[]={\n", s ); for ( i = 0; i < n; ) { if ( i % 10 == 0 ) fprintf( ftable, "\n" ); fprintf( ftable, "%4d", v[i] ); if ( ++i == n ) fprintf( ftable, " };\n" ); else fprintf( ftable, "," ); } } \EOF\ else echo "will not over write ./ywarry.c" fi if `test ! -s ./ywract.c` then echo "writing ./ywract.c" cat > ./ywract.c << '\EOF\' #include "y3.h" wract(i) { /* output state i */ /* temp1 has the actions, lastred the default */ int p, p0, p1; int ntimes, tred, count, j; int flag; /* find the best choice for lastred */ lastred = 0; ntimes = 0; TLOOP(j) { if ( temp1[j] >= 0 ) continue; if ( temp1[j] + lastred == 0 ) continue; /* count the number of appearances of temp1[j] */ count = 0; tred = -temp1[j]; levprd[tred] |= REDFLAG; TLOOP(p) { if ( temp1[p] + tred == 0 ) ++count; } if ( count > ntimes ) { lastred = tred; ntimes = count; } } /* for error recovery, arrange that, if there is a shift on the /* error recovery token, `error', that the default be the error action */ if ( temp1[1] > 0 ) lastred = 0; /* clear out entries in temp1 which equal lastred */ TLOOP(p) if ( temp1[p] + lastred == 0 ) temp1[p] = 0; wrstate(i); defact[i] = lastred; flag = 0; TLOOP(p0) { if ( (p1 = temp1[p0]) != 0 ) { if ( p1 < 0 ) { p1 = -p1; goto exc; } else if ( p1 == ACCEPTCODE ) { p1 = -1; goto exc; } else if ( p1 == ERRCODE ) { p1 = 0; goto exc; exc: if ( flag++ == 0 ) fprintf( ftable, "-1, %d,\n", i ); fprintf( ftable, "\t%d, %d,\n", tokset[p0].value, p1 ); ++zzexcp; } else { fprintf( ftemp, "%d,%d,", tokset[p0].value, p1 ); ++zzacent; } } } if ( flag ) { defact[i] = -2; fprintf( ftable, "\t-2, %d,\n", lastred ); } fprintf( ftemp, "\n" ); return; } \EOF\ else echo "will not over write ./ywract.c" fi if `test ! -s ./ywritm.c` then echo "writing ./ywritm.c" cat > ./ywritm.c << '\EOF\' /* * ywritm.c - * * HISTORY */ #include "y1.h" extern char sarr[ISIZE]; char *chcopy(); char *writem(pp) int *pp; { /* creates output string for item pointed to by pp */ int i, *p; char *q; for (p = pp; *p > 0; ++p) ; p = prdptr[-*p]; q = chcopy(sarr, nontrst[*p - NTBASE].name); q = chcopy(q, " : "); for (; ; ) { *q++ = ++p == pp ? '_' : ' '; *q = '\0'; if ((i = *p) <= 0) break; q = chcopy(q, symnam(i)); if (q > &sarr[ISIZE - 30]) error("item too big"); } if ((i = *pp) < 0) { /* an item calling for a reduction */ q = chcopy(q, " ("); sprintf(q, "%d)", -i); } return (sarr); } \EOF\ else echo "will not over write ./ywritm.c" fi if `test ! -s ./ywstat.c` then echo "writing ./ywstat.c" cat > ./ywstat.c << '\EOF\' #include "y3.h" wrstate(i) { /* writes state i */ register j0, j1; register struct item *pp, *qq; register struct wset *u; if ( foutput == NULL ) return; fprintf( foutput, "\nstate %d\n", i); ITMLOOP(i, pp, qq) fprintf( foutput, "\t%s\n", writem(pp->pitem)); if ( tystate[i] == MUSTLOOKAHEAD ) { /* print out empty productions in closure */ WSLOOP( wsets + (pstate[i+1] - pstate[i]), u ) { if ( *(u->pitem) < 0 ) fprintf( foutput, "\t%s\n", writem(u->pitem) ); } } /* check for state equal to another */ TLOOP(j0) if ( (j1 = temp1[j0]) != 0 ) { fprintf( foutput, "\n\t%s ", symnam(j0) ); if ( j1 > 0 ) { /* shift, error, or accept */ if ( j1 == ACCEPTCODE ) fprintf( foutput, "accept" ); else if ( j1 == ERRCODE ) fprintf( foutput, "error" ); else fprintf( foutput, "shift %d", j1 ); } else fprintf( foutput, "reduce %d", -j1 ); } /* output the final production */ if ( lastred ) fprintf( foutput, "\n\t. reduce %d\n\n", lastred ); else fprintf( foutput, "\n\t. error\n\n" ); /* now, output nonterminal actions */ j1 = ntokens; for ( j0 = 1; j0 <= nnonter; ++j0 ) { if ( temp1[++j1] ) fprintf( foutput, "\t%s goto %d\n", symnam( j0 + NTBASE), temp1[j1] ); } } wdef( s, n ) char *s; { /* output a definition of s to the value n */ fprintf( ftable, "# define %s %d\n", s, n ); } \EOF\ else echo "will not over write ./ywstat.c" fi if `test ! -s ./yypars` then echo "writing ./yypars" cat > ./yypars << '\EOF\' /* @(#)yaccpar 1.9 */ /* ** Skeleton parser driver for yacc output */ /* ** yacc user known macros and defines */ #define YYERROR goto yyerrlab #define YYACCEPT return(0) #define YYABORT return(1) #define YYBACKUP( newtoken, newvalue )\ {\ if ( yychar >= 0 || ( yyr2[ yytmp ] >> 1 ) != 1 )\ {\ yyerror( "syntax error - cannot backup" );\ goto yyerrlab;\ }\ yychar = newtoken;\ yystate = *yyps;\ yylval = newvalue;\ goto yynewstate;\ } #define YYRECOVERING() (!!yyerrflag) #ifndef YYDEBUG # define YYDEBUG 1 /* make debugging available */ #endif /* ** user known globals */ int yydebug; /* set to 1 to get debugging */ /* ** driver internal defines */ #define YYFLAG (-1000) /* ** global variables used by the parser */ YYSTYPE yyv[ YYMAXDEPTH ]; /* value stack */ int yys[ YYMAXDEPTH ]; /* state stack */ YYSTYPE *yypv; /* top of value stack */ int *yyps; /* top of state stack */ int yystate; /* current state */ int yytmp; /* extra var (lasts between blocks) */ int yynerrs; /* number of errors */ int yyerrflag; /* error recovery flag */ int yychar; /* current input token number */ /* ** yyparse - return 0 if worked, 1 if syntax error not recovered from */ int yyparse() { register YYSTYPE *yypvt; /* top of value stack for $vars */ /* ** Initialize externals - yyparse may be called more than once */ yypv = &yyv[-1]; yyps = &yys[-1]; yystate = 0; yytmp = 0; yynerrs = 0; yyerrflag = 0; yychar = -1; goto yystack; { register YYSTYPE *yy_pv; /* top of value stack */ register int *yy_ps; /* top of state stack */ register int yy_state; /* current state */ register int yy_n; /* internal state number info */ /* ** get globals into registers. ** branch to here only if YYBACKUP was called. */ yynewstate: yy_pv = yypv; yy_ps = yyps; yy_state = yystate; goto yy_newstate; /* ** get globals into registers. ** either we just started, or we just finished a reduction */ yystack: yy_pv = yypv; yy_ps = yyps; yy_state = yystate; /* ** top of for (;;) loop while no reductions done */ yy_stack: /* ** put a state and value onto the stacks */ #if YYDEBUG /* ** if debugging, look up token value in list of value vs. ** name pairs. 0 and negative (-1) are special values. ** Note: linear search is used since time is not a real ** consideration while debugging. */ if ( yydebug ) { register int yy_i; printf( "State %d, token ", yy_state ); if ( yychar == 0 ) printf( "end-of-file\n" ); else if ( yychar < 0 ) printf( "-none-\n" ); else { for ( yy_i = 0; yytoks[yy_i].t_val >= 0; yy_i++ ) { if ( yytoks[yy_i].t_val == yychar ) break; } printf( "%s\n", yytoks[yy_i].t_name ); } } #endif /* YYDEBUG */ if ( ++yy_ps >= &yys[ YYMAXDEPTH ] ) /* room on stack? */ { yyerror( "yacc stack overflow" ); YYABORT; } *yy_ps = yy_state; *++yy_pv = yyval; /* ** we have a new state - find out what to do */ yy_newstate: if ( ( yy_n = yypact[ yy_state ] ) <= YYFLAG ) goto yydefault; /* simple state */ #if YYDEBUG /* ** if debugging, need to mark whether new token grabbed */ yytmp = yychar < 0; #endif if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) ) yychar = 0; /* reached EOF */ #if YYDEBUG if ( yydebug && yytmp ) { register int yy_i; printf( "Received token " ); if ( yychar == 0 ) printf( "end-of-file\n" ); else if ( yychar < 0 ) printf( "-none-\n" ); else { for ( yy_i = 0; yytoks[yy_i].t_val >= 0; yy_i++ ) { if ( yytoks[yy_i].t_val == yychar ) break; } printf( "%s\n", yytoks[yy_i].t_name ); } } #endif /* YYDEBUG */ if ( ( ( yy_n += yychar ) < 0 ) || ( yy_n >= YYLAST ) ) goto yydefault; if ( yychk[ yy_n = yyact[ yy_n ] ] == yychar ) /*valid shift*/ { yychar = -1; yyval = yylval; yy_state = yy_n; if ( yyerrflag > 0 ) yyerrflag--; goto yy_stack; } yydefault: if ( ( yy_n = yydef[ yy_state ] ) == -2 ) { #if YYDEBUG yytmp = yychar < 0; #endif if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) ) yychar = 0; /* reached EOF */ #if YYDEBUG if ( yydebug && yytmp ) { register int yy_i; printf( "Received token " ); if ( yychar == 0 ) printf( "end-of-file\n" ); else if ( yychar < 0 ) printf( "-none-\n" ); else { for ( yy_i = 0; yytoks[yy_i].t_val >= 0; yy_i++ ) { if ( yytoks[yy_i].t_val == yychar ) { break; } } printf( "%s\n", yytoks[yy_i].t_name ); } } #endif /* YYDEBUG */ /* ** look through exception table */ { register int *yyxi = yyexca; while ( ( *yyxi != -1 ) || ( yyxi[1] != yy_state ) ) { yyxi += 2; } while ( ( *(yyxi += 2) >= 0 ) && ( *yyxi != yychar ) ) ; if ( ( yy_n = yyxi[1] ) < 0 ) YYACCEPT; } } /* ** check for syntax error */ if ( yy_n == 0 ) /* have an error */ { /* no worry about speed here! */ switch ( yyerrflag ) { case 0: /* new error */ yyerror( "syntax error" ); goto skip_init; yyerrlab: /* ** get globals into registers. ** we have a user generated syntax type error */ yy_pv = yypv; yy_ps = yyps; yy_state = yystate; yynerrs++; skip_init: case 1: case 2: /* incompletely recovered error */ /* try again... */ yyerrflag = 3; /* ** find state where "error" is a legal ** shift action */ while ( yy_ps >= yys ) { yy_n = yypact[ *yy_ps ] + YYERRCODE; if ( yy_n >= 0 && yy_n < YYLAST && yychk[yyact[yy_n]] == YYERRCODE) { /* ** simulate shift of "error" */ yy_state = yyact[ yy_n ]; goto yy_stack; } /* ** current state has no shift on ** "error", pop stack */ #if YYDEBUG # define _POP_ "Error recovery pops state %d, uncovers state %d\n" if ( yydebug ) printf( _POP_, *yy_ps, yy_ps[-1] ); # undef _POP_ #endif yy_ps--; yy_pv--; } /* ** there is no state on stack with "error" as ** a valid shift. give up. */ YYABORT; case 3: /* no shift yet; eat a token */ #if YYDEBUG /* ** if debugging, look up token in list of ** pairs. 0 and negative shouldn't occur, ** but since timing doesn't matter when ** debugging, it doesn't hurt to leave the ** tests here. */ if ( yydebug ) { register int yy_i; printf( "Error recovery discards " ); if ( yychar == 0 ) printf( "token end-of-file\n" ); else if ( yychar < 0 ) printf( "token -none-\n" ); else { for ( yy_i = 0; yytoks[yy_i].t_val >= 0; yy_i++ ) { if ( yytoks[yy_i].t_val == yychar ) { break; } } printf( "token %s\n", yytoks[yy_i].t_name ); } } #endif /* YYDEBUG */ if ( yychar == 0 ) /* reached EOF. quit */ YYABORT; yychar = -1; goto yy_newstate; } }/* end if ( yy_n == 0 ) */ /* ** reduction by production yy_n ** put stack tops, etc. so things right after switch */ #if YYDEBUG /* ** if debugging, print the string that is the user's ** specification of the reduction which is just about ** to be done. */ if ( yydebug ) printf( "Reduce by (%d) \"%s\"\n", yy_n, yyreds[ yy_n ] ); #endif yytmp = yy_n; /* value to switch over */ yypvt = yy_pv; /* $vars top of value stack */ /* ** Look in goto table for next state ** Sorry about using yy_state here as temporary ** register variable, but why not, if it works... ** If yyr2[ yy_n ] doesn't have the low order bit ** set, then there is no action to be done for ** this reduction. So, no saving & unsaving of ** registers done. The only difference between the ** code just after the if and the body of the if is ** the goto yy_stack in the body. This way the test ** can be made before the choice of what to do is needed. */ { /* length of production doubled with extra bit */ register int yy_len = yyr2[ yy_n ]; if ( !( yy_len & 01 ) ) { yy_len >>= 1; yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + *( yy_ps -= yy_len ) + 1; if ( yy_state >= YYLAST || yychk[ yy_state = yyact[ yy_state ] ] != -yy_n ) { yy_state = yyact[ yypgo[ yy_n ] ]; } goto yy_stack; } yy_len >>= 1; yyval = ( yy_pv -= yy_len )[1]; /* $$ = $1 */ yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] + *( yy_ps -= yy_len ) + 1; if ( yy_state >= YYLAST || yychk[ yy_state = yyact[ yy_state ] ] != -yy_n ) { yy_state = yyact[ yypgo[ yy_n ] ]; } } /* save until reenter driver code */ yystate = yy_state; yyps = yy_ps; yypv = yy_pv; } /* ** code supplied by user is placed in this switch */ switch( yytmp ) { $A } goto yystack; /* reset registers in driver code */ } \EOF\ else echo "will not over write ./yypars" fi echo "Finished archive 1 of 4" # if you want to concatenate archives, remove anything after this line exit 0
glenn@extro.ucc.su.oz (G. Geers [ext 3241]) (06/28/89)
--- cut here --- cut here --- cut here --- cut here --- cut here --- #!/bin/sh # This is a shell archive. Remove anything before the /bin/sh line # then unpack it by saving it in a file and typing "sh file" # (Files unpacked will be owned by you and have default permissions). # Don't worry about trailing garbage - the archive ends with exit # This archive contains the following files: # ./yarout.c # ./yaryfl.c # ./ycemty.c # ./ychcpy.c # ./ychfnd.c # ./yclopt.c # ./yclsur.c # ./ycpact.c # ./ycpfir.c # ./ycpres.c # ./ycpuni.c # ./ycpycd.c # ./ycstsh.c # ./ydefin.c # ./ydfout.c # ./yerror.c # ./yfdtyp.c # ./yflset.c # ./yfnact.c # ./yg2gen.c # ./yg2out.c # ./ygin.c # ./ygtnm.c # ./ygttok.c # ./yhdprd.c # ./ymain.c # ./ymkfil # ./ynxti.c # ./yosmry.c # ./yothrs.c # ./youtpt.c # if `test ! -s ./yarout.c` then echo "writing ./yarout.c" cat > ./yarout.c << '\EOF\' /* * yarout.c - * * HISTORY */ #include "y4.h" int arout(s, v, n) char *s; int *v, n; { register i; fprintf(ftable, "short %s[]={\n", s); for (i = 0; i < n; ) { if (i % 10 == 0) fprintf(ftable, "\n"); fprintf(ftable, "%4d", v[i]); if (++i == n) fprintf(ftable, " };\n"); else fprintf(ftable, ","); } } \EOF\ else echo "will not over write ./yarout.c" fi if `test ! -s ./yaryfl.c` then echo "writing ./yaryfl.c" cat > ./yaryfl.c << '\EOF\' /* * yaryfl.c - set elements 0 through n-1 to c * * HISTORY */ #include "y1.h" int aryfil(v, n, c) int *v, n, c; { register int i; for (i = 0; i < n; ++i) v[i] = c; } \EOF\ else echo "will not over write ./yaryfl.c" fi if `test ! -s ./ycemty.c` then echo "writing ./ycemty.c" cat > ./ycemty.c << '\EOF\' /* * ycemty.c - mark nonterminals which derive the empty string * * In addition to looking for empty nonterminals, look for nonterminals * which don't derive any token strings. Both of these should be optimized * away. * * HISTORY * {1} 12-Apr-83 Bob Denny * Add symbolic exit status. * */ #include "y1.h" #define EMPTY 1 #define WHOKNOWS 0 #define OK 1 int cempty() { register i, *p; /* * first, use the array pempty to detect productions that can * never be reduced */ /* set pempty to WHONOWS */ aryfil(pempty, nnonter + 1, WHOKNOWS); /* * now, look at productions, marking nonterminals which derive * something */ more: PLOOP(0, i) { if (pempty[*prdptr[i] - NTBASE]) continue; for (p = prdptr[i] + 1; *p >= 0; ++p) { if (*p >= NTBASE && pempty[*p - NTBASE] == WHOKNOWS) break; } if (*p < 0) { /* production can be derived */ pempty[*prdptr[i] - NTBASE] = OK; goto more; } } /* now, look at the nonterminals, to see if they are all OK */ NTLOOP(i) { /* * the added production rises or falls as the start symbol * ... */ if (i == 0) continue; if (pempty[i] != OK) { fatfl = 0; error("nonterminal %s never derives any token string", nontrst[i].name); } } if (nerrors) { summary(); exit(EX_ERR); } /* * now, compute the pempty array, to see which nonterminals derive * the empty string */ /* set pempty to WHOKNOWS */ aryfil(pempty, nnonter + 1, WHOKNOWS); /* loop as long as we keep finding empty nonterminals */ again: PLOOP(1, i) { if (pempty[*prdptr[i] - NTBASE] == WHOKNOWS) { /* not known to be empty */ for (p = prdptr[i] + 1; *p >= NTBASE && pempty[*p - NTBASE] == EMPTY; ++p) ; if (*p < 0) { /* * we have a nontrivially empty * nonterminal */ pempty[*prdptr[i] - NTBASE] = EMPTY; goto again; /* got one ... try for * another */ } } } } \EOF\ else echo "will not over write ./ycemty.c" fi if `test ! -s ./ychcpy.c` then echo "writing ./ychcpy.c" cat > ./ychcpy.c << '\EOF\' /* * ychcpy.c - copies string q into p, return next free char ptr * * HISTORY */ #include "y1.h" char *chcopy(p, q) char *p, *q; { while (*p = *q++) ++p; return (p); } \EOF\ else echo "will not over write ./ychcpy.c" fi if `test ! -s ./ychfnd.c` then echo "writing ./ychfnd.c" cat > ./ychfnd.c << '\EOF\' /* * ychfnd.c - * * HISTORY */ #include "y2.h" int chfind( t, s ) register char *s; { int i; if (s[0] == ' ') t = 0; TLOOP(i) { if (!strcmp(s, tokset[i].name)) { return (i); } } NTLOOP(i) { if (!strcmp(s, nontrst[i].name)) { return (i + NTBASE); } } /* cannot find name */ if (t > 1) error("%s should have been defined earlier", s); return (defin(t, s)); } \EOF\ else echo "will not over write ./ychfnd.c" fi if `test ! -s ./yclopt.c` then echo "writing ./yclopt.c" cat > ./yclopt.c << '\EOF\' /* * yclopt.c - * * HISTORY */ #include "y4.h" int callopt() { register i, *p, j, k, *q; /* read the arrays from tempfile and set parameters */ if ((finput = fopen(TEMPNAME, "r")) == NULL) error("optimizer cannot open tempfile"); pgo[0] = 0; yypact[0] = 0; nstate = 0; nnonter = 0; for (; ; ) { switch (gtnm()) { case '\n': yypact[++nstate] = (--pmem) - mem0; case ',': continue; case '$': break; default: error("bad tempfile"); } break; } yypact[nstate] = yypgo[0] = (--pmem) - mem0; for (; ; ) { switch (gtnm()) { case '\n': yypgo[++nnonter] = pmem - mem0; case '\r': case ',': continue; case -1: /* EOF */ break; default: error("bad tempfile"); } break; } yypgo[nnonter--] = (--pmem) - mem0; for (i = 0; i < nstate; ++i) { k = 32000; j = 0; q = mem0 + yypact[i + 1]; for (p = mem0 + yypact[i]; p < q; p += 2) { if (*p > j) j = *p; if (*p < k) k = *p; } if (k <= j) { /* nontrivial situation */ /* * temporarily, kill this for compatibility j -= * k; j is now the range */ if (k > maxoff) maxoff = k; } greed[i] = (yypact[i + 1] - yypact[i]) + 2 * j; if (j > maxspr) maxspr = j; } /* initialize ggreed table */ for (i = 1; i <= nnonter; ++i) { ggreed[i] = 1; j = 0; /* minimum entry index is always 0 */ q = mem0 + yypgo[i + 1] - 1; for (p = mem0 + yypgo[i]; p < q; p += 2) { ggreed[i] += 2; if (*p > j) j = *p; } ggreed[i] = ggreed[i] + 2 * j; if (j > maxoff) maxoff = j; } /* now, prepare to put the shift actions into the a array */ for (i = 0; i < ACTSIZE; ++i) a[i] = 0; maxa = a; for (i = 0; i < nstate; ++i) { if (greed[i] == 0 && adb > 1) fprintf(ftable, "State %d: null\n", i); pa[i] = YYFLAG1; } while ((i = nxti()) != NOMORE) { if (i >= 0) stin(i); else gin(-i); } if (adb > 2) { /* print a array */ for (p = a; p <= maxa; p += 10) { fprintf(ftable, "%4d ", p - a); for (i = 0; i < 10; ++i) fprintf(ftable, "%4d ", p[i]); fprintf(ftable, "\n"); } } /* write out the output appropriate to the language */ aoutput(); osummary(); fclose(finput); ZAPFILE(TEMPNAME); } \EOF\ else echo "will not over write ./yclopt.c" fi if `test ! -s ./yclsur.c` then echo "writing ./yclsur.c" cat > ./yclsur.c << '\EOF\' /* * yclsur.c - generate closure of state i * * HISTORY * {1} 28-Aug-81 Bob Denny * Modified to make debug code conditionally compile. * */ #include "y1.h" int closure(i) { int c, ch, work, k; register struct wset *u, *v; int *pi; int **s, **t; struct item *q; register struct item *p; ++zzclose; /* first, copy kernel of state i to wsets */ cwp = wsets; ITMLOOP(i, p, q) { cwp->pitem = p->pitem; cwp->flag = 1; /* this item must get closed */ SETLOOP(k) cwp->ws.lset[k] = p->look->lset[k]; WSBUMP(cwp); } /* now, go through the loop, closing each item */ work = 1; while (work) { work = 0; WSLOOP(wsets, u) { if (u->flag == 0) continue; c = *(u->pitem); /* dot is before c */ if (c < NTBASE) { u->flag = 0; continue; /* only interesting case * is where . is before * nonterminal */ } /* compute the lookahead */ aryfil(clset.lset, tbitset, 0); /* find items involving c */ WSLOOP(u, v) { if (v->flag == 1 && *(pi = v->pitem) == c) { v->flag = 0; if (nolook) continue; while ((ch = *++pi) > 0) { if (ch < NTBASE) { /* terminal symbol */ SETBIT(clset.lset, ch); break; } /* nonterminal symbol */ setunion(clset.lset, pfirst[ch - NTBASE]->lset); if (!pempty[ch - NTBASE]) break; } if (ch <= 0) setunion(clset.lset, v->ws.lset); } } /* now loop over productions derived from c */ c -= NTBASE; /* c is now nonterminal number */ t = pres[c + 1]; for (s = pres[c]; s < t; ++s) { /* put these items into the closure */ WSLOOP(wsets, v) { /* is the item there */ if (v->pitem == *s) { /* yes, it is there */ if (nolook) goto nexts; if (setunion(v->ws.lset, clset.lset)) v->flag = work = 1; goto nexts; } } /* not there; make a new entry */ if (cwp - wsets + 1 >= WSETSIZE) error("working set overflow"); cwp->pitem = *s; cwp->flag = 1; if (!nolook) { work = 1; SETLOOP(k) cwp->ws.lset[k] = clset.lset[k]; } WSBUMP(cwp); nexts: ; } } } /* have computed closure; flags are reset; return */ if (cwp > zzcwp) zzcwp = cwp; #ifdef debug if (foutput != NULL) { fprintf(foutput, "\nState %d, nolook = %d\n", i, nolook); WSLOOP(wsets, u) { if (u->flag) fprintf(foutput, "flag set!\n"); u->flag = 0; fprintf(foutput, "\t%s", writem(u->pitem)); prlook(&u->ws); fprintf(foutput, "\n"); } } #endif } \EOF\ else echo "will not over write ./yclsur.c" fi if `test ! -s ./ycpact.c` then echo "writing ./ycpact.c" cat > ./ycpact.c << '\EOF\' /* * ycpact.c - copy C action to next ; or closing curly brace * * HISTORY */ #include <stdio.h> #include <ctype.h> #include "y2.h" int cpyact(offset) int offset; { int brac, c, match, j, s, tok; fprintf(faction, "\n# line %d\n", lineno); brac = 0; loop: c = unix_getc(finput); swt: switch (c) { case ';': if (brac == 0) { putc(c, faction); return; } goto lcopy; case '{': brac++; goto lcopy; case '$': s = 1; tok = -1; c = unix_getc(finput); if (c == '<') { /* type description */ ungetc(c, finput); if (gettok() != TYPENAME) error("bad syntax on $<ident> clause"); tok = numbval; c = unix_getc(finput); } if (c == '$') { fprintf(faction, "yyval"); if (ntypes) { /* put out the proper tag... */ if (tok < 0) tok = fdtype(*prdptr[nprod]); fprintf(faction, ".%s", typeset[tok]); } goto loop; } if (c == '-') { s = -s; c = unix_getc(finput); } if (isdigit(c)) { j = 0; while (isdigit(c)) { j = j * 10 + c - '0'; c = unix_getc(finput); } j = j * s - offset; if (j > 0) { error("Illegal use of $%d", j + offset); } fprintf(faction, "yypvt[-%d]", -j); if (ntypes) { /* put out the proper tag */ if (j + offset <= 0 && tok < 0) error("must specify type of $%d", j + offset); if (tok < 0) tok = fdtype(prdptr[nprod][j + offset]); fprintf(faction, ".%s", typeset[tok]); } goto swt; } putc('$', faction); if (s < 0) putc('-', faction); goto swt; case '}': if (--brac) goto lcopy; putc(c, faction); return; case '/': /* look for comments */ putc(c, faction); c = unix_getc(finput); if (c != '*') goto swt; /* it really is a comment */ putc(c, faction); c = unix_getc(finput); while (c != EOF) { while (c == '*') { putc(c, faction); if ((c = unix_getc(finput)) == '/') goto lcopy; } putc(c, faction); if (c == '\n') ++lineno; c = unix_getc(finput); } error("EOF inside comment"); case '\'': /* character constant */ match = '\''; goto string; case '"': /* character string */ match = '"'; string: putc(c, faction); while (c = unix_getc(finput)) { if (c == '\\') { putc(c, faction); c = unix_getc(finput); if (c == '\n') ++lineno; } else if (c == match) goto lcopy; else if (c == '\n') error("newline in string or char. const."); putc(c, faction); } error("EOF in string or character constant"); case -1: /* EOF */ error("action does not terminate"); case '\n': ++lineno; goto lcopy; } lcopy: putc(c, faction); goto loop; } \EOF\ else echo "will not over write ./ycpact.c" fi if `test ! -s ./ycpfir.c` then echo "writing ./ycpfir.c" cat > ./ycpfir.c << '\EOF\' /* * ycpfir.c - compute an array with the first of nonterminals * * HISTORY * {1} 28-Aug-81 Bob Denny * Modified to make debug code conditionally compile. * */ #include "y1.h" int cpfir() { /* compute an array with the first of nonterminals */ register *p, **s, i, **t, ch, changes; int *tmp; tmp = &wsets[nnonter]; zzcwp = tmp; NTLOOP(i) { aryfil(wsets[i].ws.lset, tbitset, 0); t = pres[i + 1]; for (s = pres[i]; s < t; ++s) { /* initially fill the sets */ for (p = *s; (ch = *p) > 0; ++p) { if (ch < NTBASE) { SETBIT(wsets[i].ws.lset, ch); break; } else if (!pempty[ch - NTBASE]) break; } } } /* now, reflect transitivity */ changes = 1; while (changes) { changes = 0; NTLOOP(i) { t = pres[i + 1]; for (s = pres[i]; s < t; ++s) { for (p = *s; (ch = (*p - NTBASE)) >= 0; ++p) { changes |= setunion(wsets[i].ws.lset, wsets[ch].ws.lset); if (!pempty[ch]) break; } } } } NTLOOP(i) pfirst[i] = flset(&wsets[i].ws); #ifdef debug if ((foutput != NULL)) { NTLOOP(i) { fprintf(foutput, "\n%s: ", nontrst[i].name); prlook(pfirst[i]); fprintf(foutput, " %d\n", pempty[i]); } } #endif } \EOF\ else echo "will not over write ./ycpfir.c" fi if `test ! -s ./ycpres.c` then echo "writing ./ycpres.c" cat > ./ycpres.c << '\EOF\' /* * ycpres.c - compute an array with the beginnings of productions * * compute an array with the beginnings of productions yielding given * nonterminals The array pres points to these lists the array pyield has * the lists: the total size is only NPROD+1 * * HISTORY * {1} 12-Apr-83 Bob Denny * Add symbol exit status. * */ #include "y1.h" extern int *pyield[NPROD]; int cpres() { register **pmem; register c, j, i; pmem = pyield; NTLOOP(i) { c = i + NTBASE; pres[i] = pmem; fatfl = 0; /* make undefined symbols nonfatal */ PLOOP(0, j) { if (*prdptr[j] == c) *pmem++ = prdptr[j] + 1; } if (pres[i] == pmem) { error("nonterminal %s not defined!", nontrst[i].name); } } pres[i] = pmem; fatfl = 1; if (nerrors) { summary(); exit(EX_ERR); } if (pmem != &pyield[nprod]) error("internal Yacc error: pyield %d", pmem - &pyield[nprod]); } \EOF\ else echo "will not over write ./ycpres.c" fi if `test ! -s ./ycpuni.c` then echo "writing ./ycpuni.c" cat > ./ycpuni.c << '\EOF\' /* * ycpuni.c - copy the union declaration & define file (if present) to output * * HISTORY */ #include "y2.h" int cpyunion() { int level, c; fprintf(ftable, "\n# line %d\n", lineno); fprintf(ftable, "\n#define UNION 1\n"); fprintf(ftable, "typedef union "); if (fdefine) fprintf(fdefine, "\ntypedef union "); level = 0; for (; ; ) { if ((c = unix_getc(finput)) < 0) error("EOF encountered while processing %%union"); putc(c, ftable); if (fdefine) putc(c, fdefine); switch (c) { case '\n': ++lineno; break; case '{': ++level; break; case '}': --level; if (level == 0) { /* we are finished copying */ fprintf(ftable, " YYSTYPE;\n"); if (fdefine) fprintf(fdefine, " YYSTYPE;\nextern YYSTYPE yylval;\n"); return; } } } } \EOF\ else echo "will not over write ./ycpuni.c" fi if `test ! -s ./ycpycd.c` then echo "writing ./ycpycd.c" cat > ./ycpycd.c << '\EOF\' /* * ycpycd.c - copies code between \{ and \} * * HISTORY */ #include "y2.h" int cpycode() { int c; c = unix_getc(finput); if (c == '\n') { c = unix_getc(finput); lineno++; } fprintf(ftable, "\n# line %d\n", lineno); while (c >= 0) { if (c == '\\') if ((c = unix_getc(finput)) == '}') return; else putc('\\', ftable); if (c == '%') if ((c = unix_getc(finput)) == '}') return; else putc('%', ftable); putc(c, ftable); if (c == '\n') ++lineno; c = unix_getc(finput); } error("eof before %%}"); } \EOF\ else echo "will not over write ./ycpycd.c" fi if `test ! -s ./ycstsh.c` then echo "writing ./ycstsh.c" cat > ./ycstsh.c << '\EOF\' #include "y2.h" char * cstash( s ) register char *s; { char *temp; temp = cnamp; do { if ( cnamp >= &cnames[cnamsz] ) error("too many characters in id's and literals" ); else *cnamp++ = *s; } while ( *s++); return( temp ); } \EOF\ else echo "will not over write ./ycstsh.c" fi if `test ! -s ./ydefin.c` then echo "writing ./ydefin.c" cat > ./ydefin.c << '\EOF\' #include "y2.h" defin( t, s ) register char *s; { /* define s to be a terminal if t=0 or a nonterminal if t=1 */ register val; if (t) { if ( ++nnonter >= NNONTERM ) error("too many nonterminals, limit %d", NNONTERM); nontrst[nnonter].name = cstash(s); return( NTBASE + nnonter ); } /* must be a token */ if ( ++ntokens >= NTERMS ) error("too many terminals, limit %d", NTERMS ); tokset[ntokens].name = cstash(s); /* establish value for token */ if ( s[0] == ' ' && s[2] == '\0' ) /* single character literal */ val = s[1]; else if ( s[0] == ' ' && s[1] == '\\' ) { /* escape sequence */ if ( s[3] == '\0' ) { /* single character escape sequence */ switch ( s[2] ) { /* character which is escaped */ case 'n': val = '\n'; break; case 'r': val = '\r'; break; case 'b': val = '\b'; break; case 't': val = '\t'; break; case 'f': val = '\f'; break; case '\'': val = '\''; break; case '"': val = '"'; break; case '\\': val = '\\'; break; default: error( "invalid escape" ); } } else if ( s[2] <= '7' && s[2] >= '0' ) { /* \nnn sequence */ if ( s[3] < '0' || s[3] > '7' || s[4] < '0' || s[4] > '7' || s[5] != '\0' ) error("illegal \\nnn construction" ); val = 64 * s[2] + 8 * s[3] + s[4] - 73 * '0'; if ( val == 0 ) error( "'\\000' is illegal" ); } } else { val = extval++; } tokset[ntokens].value = val; toklev[ntokens] = 0; return( ntokens ); } \EOF\ else echo "will not over write ./ydefin.c" fi if `test ! -s ./ydfout.c` then echo "writing ./ydfout.c" cat > ./ydfout.c << '\EOF\' /* * ydfout.c - * * HISTORY */ #include <ctype.h> #include "y2.h" int defout() { /* write out the defines (at the end of the declaration section) */ register int i, c; register char *cp; for (i = ndefout; i <= ntokens; ++i) { cp = tokset[i].name; if (*cp == ' ') ++cp; /* literals */ for (; (c = *cp) != '\0'; ++cp) { if (islower(c) || isupper(c) || isdigit(c) || c == '_') ; /* VOID */ else goto nodef; } fprintf(ftable, "# define %s %d\n", tokset[i].name, tokset[i].value); if (fdefine != NULL) fprintf(fdefine, "# define %s %d\n", tokset[i].name, tokset[i].value); nodef: ; } ndefout = ntokens + 1; } \EOF\ else echo "will not over write ./ydfout.c" fi if `test ! -s ./yerror.c` then echo "writing ./yerror.c" cat > ./yerror.c << '\EOF\' #include "y1.h" /* * 12-Apr-83 (RBD) Add symbolic exit status */ /* VARARGS1 */ error(s, a1) char *s; { /* write out error comment */ ++nerrors; fprintf( stderr, "\n fatal error: "); fprintf( stderr, s, a1); fprintf( stderr, ", line %d\n", lineno ); if ( !fatfl ) return; summary(); exit(EX_ERR); } \EOF\ else echo "will not over write ./yerror.c" fi if `test ! -s ./yfdtyp.c` then echo "writing ./yfdtyp.c" cat > ./yfdtyp.c << '\EOF\' #include "y2.h" fdtype( t ) { /* determine the type of a symbol */ register v; if ( t >= NTBASE ) v = nontrst[t-NTBASE].tvalue; else v = TYPE( toklev[t] ); if ( v <= 0 ) error( "must specify type for %s", (t >= NTBASE) ? nontrst[t-NTBASE].name : tokset[t].name ); return( v ); } \EOF\ else echo "will not over write ./yfdtyp.c" fi if `test ! -s ./yflset.c` then echo "writing ./yflset.c" cat > ./yflset.c << '\EOF\' #include "y1.h" struct looksets *flset( p ) struct looksets *p; { /* decide if the lookahead set pointed to by p is known */ /* return pointer to a perminent location for the set */ register struct looksets *q; int j, *w; register *u, *v; for ( q = &lkst[nlset]; q-- > lkst; ) { u = p->lset; v = q->lset; w = &v[tbitset]; while ( v < w) if ( *u++ != *v++) goto more; /* we have matched */ return( q ); more: ; } /* add a new one */ q = &lkst[nlset++]; if ( nlset >= LSETSIZE ) error("too many lookahead sets" ); SETLOOP(j) { q->lset[j] = p->lset[j]; } return( q ); } \EOF\ else echo "will not over write ./yflset.c" fi if `test ! -s ./yfnact.c` then echo "writing ./yfnact.c" cat > ./yfnact.c << '\EOF\' #include "y2.h" finact() { /* finish action routine */ fclose(faction); fprintf( ftable, "# define YYERRCODE %d\n", tokset[2].value ); } \EOF\ else echo "will not over write ./yfnact.c" fi if `test ! -s ./yg2gen.c` then echo "writing ./yg2gen.c" cat > ./yg2gen.c << '\EOF\' #include "y3.h" /* * yg2gen.3c * * Modified to make debug code conditionally compile. * 28-Aug-81 * Bob Denny */ go2gen(c) { /* output the gotos for nonterminal c */ int i, work, cc; struct item *p, *q; /* first, find nonterminals with gotos on c */ aryfil( temp1, nnonter + 1, 0 ); temp1[c] = 1; work = 1; while ( work ) { work = 0; PLOOP(0, i) { if ( (cc = prdptr[i][1] - NTBASE) >= 0 ) { /* cc is a nonterminal */ if ( temp1[cc] != 0 ) { /* cc has a goto on c */ cc = *prdptr[i] - NTBASE; /* thus, the left side of production i does too */ if ( temp1[cc] == 0 ) { work = 1; temp1[cc] = 1; } } } } } /* now, we have temp1[c] = 1 if a goto on c in closure of cc */ #ifdef debug if ( foutput != NULL ) { fprintf( foutput, "%s: gotos on ", nontrst[c].name ); NTLOOP(i) if ( temp1[i] ) fprintf( foutput, "%s ", nontrst[i].name); fprintf( foutput, "\n"); } #endif /* now, go through and put gotos into tystate */ aryfil( tystate, nstate, 0 ); SLOOP(i) { ITMLOOP(i, p, q) { if ( (cc = *p->pitem) >= NTBASE ) { if ( temp1[cc -= NTBASE] ) { /* goto on c is possible */ tystate[i] = amem[indgo[i]+c]; break; } } } } } \EOF\ else echo "will not over write ./yg2gen.c" fi if `test ! -s ./yg2out.c` then echo "writing ./yg2out.c" cat > ./yg2out.c << '\EOF\' #include "y3.h" go2out() { /* output the gotos for the nontermninals */ int i, j, k, best, count, cbest, times; fprintf( ftemp, "$\n" ); /* mark begining of gotos */ for ( i = 1; i <= nnonter; ++i ) { go2gen(i); /* find the best one to make default */ best = -1; times = 0; for ( j = 0; j <= nstate; ++j ) { /* is j the most frequent */ if ( tystate[j] == 0 ) continue; if ( tystate[j] == best ) continue; /* is tystate[j] the most frequent */ count = 0; cbest = tystate[j]; for ( k = j; k <= nstate; ++k ) if ( tystate[k] == cbest ) ++count; if ( count > times ) { best = cbest; times = count; } } /* best is now the default entry */ zzgobest += (times - 1); for ( j = 0; j <= nstate; ++j ) { if ( tystate[j] != 0 && tystate[j] != best ) { fprintf( ftemp, "%d,%d,", j, tystate[j] ); zzgoent += 1; } } /* now, the default */ zzgoent += 1; fprintf( ftemp, "%d\n", best ); } } \EOF\ else echo "will not over write ./yg2out.c" fi if `test ! -s ./ygin.c` then echo "writing ./ygin.c" cat > ./ygin.c << '\EOF\' #include "y4.h" gin(i) { register *p, *r, *s, *q1, *q2; /* enter gotos on nonterminal i into array a */ ggreed[i] = 0; q2 = mem0 + yypgo[i+1] - 1; q1 = mem0 + yypgo[i]; /* now, find a place for it */ for ( p = a; p < &a[ACTSIZE]; ++p ) { if ( *p ) continue; for ( r = q1; r < q2; r += 2 ) { s = p + *r + 1; if ( *s ) goto nextgp; if ( s > maxa ) { if ( (maxa = s) > &a[ACTSIZE] ) error( "a array overflow" ); } } /* we have found a spot */ *p = *q2; if ( p > maxa ) { if ( (maxa = p) > &a[ACTSIZE] ) error( "a array overflow" ); } for ( r = q1; r < q2; r += 2 ) { s = p + *r + 1; *s = r[1]; } pgo[i] = p - a; if ( adb > 1 ) fprintf( ftable, "Nonterminal %d, entry at %d\n" , i, pgo[i] ); goto nextgi; nextgp: ; } error( "cannot place goto %d\n", i ); nextgi: ; } \EOF\ else echo "will not over write ./ygin.c" fi if `test ! -s ./ygtnm.c` then echo "writing ./ygtnm.c" cat > ./ygtnm.c << '\EOF\' /* * ygtnm.c - * * HISTORY */ #include <ctype.h> #include "y4.h" int gtnm() { register s, val, c; /* read and convert an integer from the standard input */ /* return the terminating character */ /* blanks, tabs, and newlines are ignored */ s = 1; val = 0; while ((c = unix_getc(finput)) != EOF) { if (isdigit(c)) { val = val * 10 + c - '0'; } else if (c == '-') s = -1; else if (c == '\r') continue; else break; } *pmem++ = s * val; if (pmem > &mem0[MEMSIZE]) error("out of space"); return (c); } \EOF\ else echo "will not over write ./ygtnm.c" fi if `test ! -s ./ygttok.c` then echo "writing ./ygttok.c" cat > ./ygttok.c << '\EOF\' /* * ygttok.c - * * HISTORY */ #include <ctype.h> #include "y2.h" extern int peekline; /* number of '\n' seen in lookahead */ int gettok() { register i, base; register c, match, reserve; begin: reserve = 0; lineno += peekline; peekline = 0; c = unix_getc(finput); while (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r') { if (c == '\n') ++lineno; c = unix_getc(finput); } if (c == '/') { /* skip comment */ lineno += skipcom(); goto begin; } switch (c) { case -1: /* EOF */ return (ENDFILE); case '{': ungetc(c, finput); return ('='); /* action ... */ case '<': /* get, and look up, a type name (union * member name) */ i = 0; while ((c = unix_getc(finput)) != '>' && c >= 0 && c != '\n') { tokname[i] = c; if (++i >= NAMESIZE) --i; } if (c != '>') error("unterminated < ... > clause"); tokname[i] = '\0'; for (i = 1; i <= ntypes; ++i) { if (!strcmp(typeset[i], tokname)) { numbval = i; return (TYPENAME); } } typeset[numbval = ++ntypes] = cstash(tokname); return (TYPENAME); case '"': case '\'': match = c; tokname[0] = ' '; i = 1; for (; ; ) { c = unix_getc(finput); if (c == '\n' || c == EOF) error("illegal or missing ' or \""); if (c == '\\') { c = unix_getc(finput); tokname[i] = '\\'; if (++i >= NAMESIZE) --i; } else if (c == match) break; tokname[i] = c; if (++i >= NAMESIZE) --i; } break; case '%': case '\\': switch (c = unix_getc(finput)) { case '0': return (TERM); case '<': return (LEFT); case '2': return (BINARY); case '>': return (RIGHT); case '%': case '\\': return (MARK); case '=': return (PREC); case '{': return (LCURLY); default: reserve = 1; } default: if (isdigit(c)) { /* number */ numbval = c - '0'; base = (c == '0') ? 8 : 10; for (c = unix_getc(finput); isdigit(c); c = getc(finput)) { numbval = numbval * base + c - '0'; } ungetc(c, finput); return (NUMBER); } else if (islower(c) || isupper(c) || c == '_' || c == '.' || c == '$') { i = 0; while (islower(c) || isupper(c) || isdigit(c) || c == '_' || c == '.' || c == '$') { tokname[i] = c; if (reserve && isupper(c)) tokname[i] += 'a' - 'A'; if (++i >= NAMESIZE) --i; c = unix_getc(finput); } } else return (c); ungetc(c, finput); } tokname[i] = '\0'; if (reserve) { /* find a reserved word */ if (!strcmp(tokname, "term")) return (TERM); if (!strcmp(tokname, "token")) return (TERM); if (!strcmp(tokname, "left")) return (LEFT); if (!strcmp(tokname, "nonassoc")) return (BINARY); if (!strcmp(tokname, "binary")) return (BINARY); if (!strcmp(tokname, "right")) return (RIGHT); if (!strcmp(tokname, "prec")) return (PREC); if (!strcmp(tokname, "start")) return (START); if (!strcmp(tokname, "type")) return (TYPEDEF); if (!strcmp(tokname, "union")) return (UNION); error("invalid escape, or illegal reserved word: %s", tokname); } /* look ahead to distinguish IDENTIFIER from C_IDENTIFIER */ c = unix_getc(finput); while (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '/') { if (c == '\n') ++peekline; else if (c == '/') { /* look for comments */ peekline += skipcom(); } c = unix_getc(finput); } if (c == ':') return (C_IDENTIFIER); ungetc(c, finput); return (IDENTIFIER); } \EOF\ else echo "will not over write ./ygttok.c" fi if `test ! -s ./yhdprd.c` then echo "writing ./yhdprd.c" cat > ./yhdprd.c << '\EOF\' #include "y3.h" hideprod() { /* in order to free up the mem and amem arrays for the optimizer, /* and still be able to output yyr1, etc., after the sizes of /* the action array is known, we hide the nonterminals /* derived by productions in levprd. */ register i, j; j = 0; levprd[0] = 0; PLOOP(1, i) { if ( !(levprd[i] & REDFLAG) ) { ++j; if ( foutput != NULL ) { fprintf( foutput, "Rule not reduced: %s\n", writem( prdptr[i] ) ); } } levprd[i] = *prdptr[i] - NTBASE; } if ( j ) fprintf( stdout, "%d rules never reduced\n", j ); } \EOF\ else echo "will not over write ./yhdprd.c" fi if `test ! -s ./ymain.c` then echo "writing ./ymain.c" cat > ./ymain.c << '\EOF\' #include "y1.h" /* * 12-Apr-83 (RBD) Add symbolic exit status */ main(argc, argv) int argc; char *argv[]; { puts("Setup..."); setup(argc, argv); /* initialize and read productions */ puts("cpres ..."); tbitset = NWORDS(ntokens); cpres(); /* make table of which productions yield a given nonterminal */ puts("cempty ..."); cempty(); /* make a table of which nonterminals can match the empty string */ puts("cpfir ..."); cpfir(); /* make a table of firsts of nonterminals */ puts("stagen ..."); stagen(); /* generate the states */ puts("output ..."); output(); /* write the states and the tables */ puts("go2out ..."); go2out(); puts("hideprod ..."); hideprod(); puts("summary ..."); summary(); puts("callopt ..."); callopt(); puts("others ..."); others(); puts("DONE !!!"); exit(EX_SUC); } \EOF\ else echo "will not over write ./ymain.c" fi if `test ! -s ./ymkfil` then echo "writing ./ymkfil" cat > ./ymkfil << '\EOF\' CFLAGS = -Ot -Ml LDFLAGS = -Ml -s OBJECTS = y1imp.o y2imp.o y3imp.o y4imp.o yaryfl.o ycemty.o ychcpy.o\ yclsur.o ycpfir.o ycpres.o yerror.o yflset.o ymain.o yothrs.o\ yprlok.o yptitm.o ysmnam.o ystagn.o ystate.o ystuni.o ysumry.o\ ywritm.o ychfnd.o ycpact.o ycpuni.o ycpycd.o ycstsh.o ydefin.o\ ydfout.o yfdtyp.o yfnact.o ygttok.o ysetup.o yskpcm.o yapack.o\ yg2gen.o yg2out.o yhdprd.o youtpt.o yprcft.o ywarry.o ywract.o\ ywstat.o yaoput.o yclopt.o ygin.o ygtnm.o ynxti.o yosmry.o\ ystin.o yarout.o PROGRAMS = yacc all: ${PROGRAMS} clean: rm -f ${PROGRAMS} rm -f ${OBJECTS} rm -f a.out core yacc: ${OBJECTS} cc ${LDFLAGS} ${OBJECTS} -o yacc dtxtrn.h: /usr/include/stdio.h system.h y1.h: dtxtrn.h y1imp.o: dtxtrn.h y2.h: dtxtrn.h y2imp.o: dtxtrn.h y3.h: dtxtrn.h y3imp.o: dtxtrn.h y4.h: dtxtrn.h y4imp.o: dtxtrn.h yaoput.o: y4.h yapack.o: y3.h yarout.o: y4.h yaryfl.o: y1.h ycemty.o: y1.h ychcpy.o: y1.h ychfnd.o: y2.h yclopt.o: y4.h yclsur.o: y1.h ycpact.o: /usr/include/stdio.h /usr/include/ctype.h y2.h ycpfir.o: y1.h ycpres.o: y1.h ycpuni.o: y2.h ycpycd.o: y2.h ycstsh.o: y2.h ydefin.o: y2.h ydfout.o: /usr/include/ctype.h y2.h yerror.o: y1.h yfdtyp.o: y2.h yflset.o: y1.h yfnact.o: y2.h yg2gen.o: y3.h yg2out.o: y3.h ygin.o: y4.h ygtnm.o: /usr/include/ctype.h y4.h ygttok.o: /usr/include/ctype.h y2.h yhdprd.o: y3.h ymain.o: y1.h ynxti.o: y4.h yosmry.o: y4.h yothrs.o: y1.h youtpt.o: y3.h yprcft.o: y3.h yprlok.o: y1.h yptitm.o: y1.h ysetup.o: y2.h yskpcm.o: y2.h ysmnam.o: y1.h ystagn.o: y1.h ystate.o: y1.h ystin.o: y4.h ystuni.o: y1.h ysumry.o: y1.h ywarry.o: y3.h ywract.o: y3.h ywritm.o: y1.h ywstat.o: y3.h \EOF\ else echo "will not over write ./ymkfil" fi if `test ! -s ./ynxti.c` then echo "writing ./ynxti.c" cat > ./ynxti.c << '\EOF\' #include "y4.h" nxti() { /* finds the next i */ register i, max, maxi; max = 0; for ( i = 1; i <= nnonter; ++i ) if ( ggreed[i] >= max ) { max = ggreed[i]; maxi = -i; } for ( i = 0; i < nstate; ++i ) if ( greed[i] >= max ) { max = greed[i]; maxi = i; } if ( nxdb ) fprintf( ftable, "nxti = %d, max = %d\n", maxi, max ); if ( max == 0 ) return( NOMORE ); else return( maxi ); } \EOF\ else echo "will not over write ./ynxti.c" fi if `test ! -s ./yosmry.c` then echo "writing ./yosmry.c" cat > ./yosmry.c << '\EOF\' #include "y4.h" /* * Write summary. */ osummary() { register int i, *p; if (foutput == NULL) return; i = 0; for (p = maxa; p >= a; --p) { if (*p == 0) ++i; } fprintf(foutput, "Optimizer space used: input %d/%d, output %d/%d\n", pmem - mem0 + 1, MEMSIZE, maxa - a + 1, ACTSIZE); fprintf(foutput, "%d table entries, %d zero\n", (maxa - a) + 1, i); fprintf(foutput, "maximum spread: %d, maximum offset: %d\n", maxspr, maxoff); fclose(foutput); } \EOF\ else echo "will not over write ./yosmry.c" fi if `test ! -s ./yothrs.c` then echo "writing ./yothrs.c" cat > ./yothrs.c << '\EOF\' /* Edits: * 06-Dec-80 Original code broken out of y1.c. * 18-Dec-80 Add conditional code for Decus for tempfile deletion. */ #include "y1.h" int others() { /* put out other arrays, copy the parsers */ register c, i, j; finput = (FILE * )fopen(PARSER, "r"); if (finput == (FILE * )NULL) error("cannot find parser %s", PARSER); warray("yyr1", levprd, nprod); aryfil(temp1, nprod, 0); PLOOP(1, i) temp1[i] = prdptr[i + 1] - prdptr[i] - 2; warray("yyr2", temp1, nprod); aryfil(temp1, nstate, -1000); TLOOP(i) { for (j = tstates[i]; j != 0; j = mstates[j]) { temp1[j] = tokset[i].value; } } NTLOOP(i) { for (j = ntstates[i]; j != 0; j = mstates[j]) { temp1[j] = -i; } } warray("yychk", temp1, nstate); warray("yydef", defact, nstate); /* copy parser text */ while ((c = unix_getc(finput)) != EOF) { if (c == '$') { if ((c = unix_getc(finput)) != 'A') putc('$', ftable); else { /* copy actions */ faction = fopen(ACTNAME, "r"); if (faction == NULL) error("cannot reopen action tempfile"); while ((c = unix_getc(faction)) != EOF) putc(c, ftable); fclose(faction); ZAPFILE(ACTNAME); c = unix_getc(finput); } } putc(c, ftable); } fclose(ftable); } int unix_getc(iop) FILE *iop; { int c; c = getc(iop); /* Stop on Control-Z */ if (c == '\032') return (EOF); else return (c); } \EOF\ else echo "will not over write ./yothrs.c" fi if `test ! -s ./youtpt.c` then echo "writing ./youtpt.c" cat > ./youtpt.c << '\EOF\' #include "y3.h" output() { /* print the output for the states */ int i, k, c; register struct wset *u, *v; fprintf( ftable, "short yyexca[] ={\n" ); SLOOP(i) { /* output the stuff for state i */ nolook = !(tystate[i] == MUSTLOOKAHEAD); closure(i); /* output actions */ nolook = 1; aryfil( temp1, ntokens + nnonter + 1, 0 ); WSLOOP(wsets, u) { c = *( u->pitem ); if ( c > 1 && c < NTBASE && temp1[c] == 0 ) { WSLOOP(u, v) { if ( c == *(v->pitem) ) putitem( v->pitem + 1, (struct looksets *)0 ); } temp1[c] = state(c); } else if ( c > NTBASE && temp1[ (c -= NTBASE) + ntokens ] == 0 ) { temp1[ c+ntokens ] = amem[indgo[i]+c]; } } if ( i == 1 ) temp1[1] = ACCEPTCODE; /* now, we have the shifts; look at the reductions */ lastred = 0; WSLOOP(wsets, u) { c = *( u->pitem ); if ( c <= 0 ) { /* reduction */ lastred = -c; TLOOP(k) { if ( BIT(u->ws.lset, k) ) { if ( temp1[k] == 0 ) temp1[k] = c; else if ( temp1[k] < 0 ) { /* reduce/reduce conflict */ if ( foutput != NULL ) fprintf( foutput, "\n%d: reduce/reduce conflict (red'ns %d and %d ) on %s", i, -temp1[k], lastred, symnam(k) ); if ( -temp1[k] > lastred ) temp1[k] = -lastred; ++zzrrconf; } else { /* potential shift/reduce conflict */ precftn( lastred, k, i ); } } } } } wract(i); } fprintf( ftable, "\t};\n" ); wdef( "YYNPROD", nprod ); } \EOF\ else echo "will not over write ./youtpt.c" fi echo "Finished archive 2 of 4" # if you want to concatenate archives, remove anything after this line exit 0
glenn@extro.ucc.su.oz (G. Geers [ext 3241]) (06/28/89)
--- cut here --- cut here --- cut here --- cut here --- cut here --- #!/bin/sh # This is a shell archive. Remove anything before the /bin/sh line # then unpack it by saving it in a file and typing "sh file" # (Files unpacked will be owned by you and have default permissions). # Don't worry about trailing garbage - the archive ends with exit # This archive contains the following files: # ./dtxtrn.h # ./parse.y # ./system.h # ./y1.h # ./y1imp.c # ./y2.h # ./y2imp.c # ./y3.h # ./y3imp.c # ./y4.h # ./y4imp.c # ./yaoput.c # ./yapack.c # if `test ! -s ./dtxtrn.h` then echo "writing ./dtxtrn.h" cat > ./dtxtrn.h << '\EOF\' /* * DTXTRN.H -- Original extern file for UNIX YACC. * * Modified to call in "decus" or "vax11c" .H files to set up * parameters as appropriate. */ #include <stdio.h> #include "system.h" /* MANIFEST CONSTANT DEFINITIONS */ /* base of nonterminal internal numbers */ #define NTBASE 010000 /* internal codes for error and accept actions */ #define ERRCODE 8190 #define ACCEPTCODE 8191 /* sizes and limits */ #ifdef HUGETAB #define ACTSIZE 12000 #define MEMSIZE 12000 #define NSTATES 750 #define NTERMS 127 #define NPROD 600 #define NNONTERM 300 #define TEMPSIZE 1200 #define CNAMSZ 5000 #define LSETSIZE 600 #define WSETSIZE 350 #endif #ifdef MEDTAB #define ACTSIZE 4000 #define MEMSIZE 5200 #define NSTATES 600 #define NTERMS 127 #define NPROD 400 #define NNONTERM 200 #define TEMPSIZE 800 #define CNAMSZ 5000 #define LSETSIZE 450 #define WSETSIZE 250 #endif #ifdef SMALLTAB #define ACTSIZE 1000 #define MEMSIZE 1500 #define NSTATES 450 #define NTERMS 127 #define NPROD 200 #define NNONTERM 100 #define TEMPSIZE 600 #define CNAMSZ 5000 #define LSETSIZE 200 #define WSETSIZE 125 #endif #define NAMESIZE 50 #define NTYPES 63 #ifdef WORD32 #define TBITSET ((32+NTERMS)/32) /* bit packing macros (may be machine dependent) */ #define BIT(a,i) ((a)[(i)>>5] & (1<<((i)&037))) #define SETBIT(a,i) ((a)[(i)>>5] |= (1<<((i)&037))) /* number of words needed to hold n+1 bits */ #define NWORDS(n) (((n)+32)/32) #else #define TBITSET ((16+NTERMS)/16) /* bit packing macros (may be machine dependent) */ #define BIT(a,i) ((a)[(i)>>4] & (1<<((i)&017))) #define SETBIT(a,i) ((a)[(i)>>4] |= (1<<((i)&017))) /* number of words needed to hold n+1 bits */ #define NWORDS(n) (((n)+16)/16) #endif /* relationships which must hold: TBITSET ints must hold NTERMS+1 bits... WSETSIZE >= NNONTERM LSETSIZE >= NNONTERM TEMPSIZE >= NTERMS + NNONTERMs + 1 TEMPSIZE >= NSTATES */ /* associativities */ #define NOASC 0 /* no assoc. */ #define LASC 1 /* left assoc. */ #define RASC 2 /* right assoc. */ #define BASC 3 /* binary assoc. */ /* flags for state generation */ #define DONE 0 #define MUSTDO 1 #define MUSTLOOKAHEAD 2 /* flags for a rule having an action, and being reduced */ #define ACTFLAG 04 #define REDFLAG 010 /* output parser flags */ #define YYFLAG1 (-1000) /* macros for getting associativity and precedence levels */ #define ASSOC(i) ((i)&03) #define PLEVEL(i) (((i)>>4)&077) #define TYPE(i) ((i>>10)&077) /* macros for setting associativity and precedence levels */ #define SETASC(i,j) i|=j #define SETPLEV(i,j) i |= (j<<4) #define SETTYPE(i,j) i |= (j<<10) /* looping macros */ #define TLOOP(i) for(i=1;i<=ntokens;++i) #define NTLOOP(i) for(i=0;i<=nnonter;++i) #define PLOOP(s,i) for(i=s;i<nprod;++i) #define SLOOP(i) for(i=0;i<nstate;++i) #define WSBUMP(x) ++x #define WSLOOP(s,j) for(j=s;j<cwp;++j) #define ITMLOOP(i,p,q) q=pstate[i+1];for(p=pstate[i];p<q;++p) #define SETLOOP(i) for(i=0;i<tbitset;++i) /* I/O descriptors */ #ifndef y2imp extern FILE *finput; /* input file */ extern FILE *faction; /* file for saving actions */ extern FILE *fdefine; /* file for #defines */ extern FILE *ftable; /* y.tab.c file */ extern FILE *ftemp; /* tempfile to pass 2 */ extern FILE *foutput; /* y.output file */ #endif /* structure declarations */ struct looksets { int lset[TBITSET]; }; struct item { int *pitem; struct looksets *look; }; struct toksymb { char *name; int value; }; struct ntsymb { char *name; int tvalue; }; struct wset { int *pitem; int flag; struct looksets ws; }; #ifndef y2imp /* token information */ extern int ntokens ; /* number of tokens */ extern struct toksymb tokset[]; extern int toklev[]; /* vector with the precedence of the terminals */ #endif /* nonterminal information */ #ifndef y2imp extern int nnonter ; /* the number of nonterminals */ extern struct ntsymb nontrst[]; #endif /* grammar rule information */ #ifndef y2imp extern int nprod ; /* number of productions */ extern int *prdptr[]; /* pointers to descriptions of productions */ extern int levprd[] ; /* contains production levels to break conflicts */ #endif /* state information */ #ifndef y1imp extern int nstate ; /* number of states */ extern struct item *pstate[]; /* pointers to the descriptions of the states */ extern int tystate[]; /* contains type information about the states */ #ifndef y3imp extern int defact[]; /* the default action of the state */ #endif extern int tstates[]; /* the states deriving each token */ extern int ntstates[]; /* the states deriving each nonterminal */ extern int mstates[]; /* the continuation of the chains begun in tstates and ntstates */ #endif /* lookahead set information */ #ifndef y1imp extern struct looksets lkst[]; extern int nolook; /* flag to turn off lookahead computations */ #endif /* working set information */ #ifndef y1imp extern struct wset wsets[]; extern struct wset *cwp; #endif /* storage for productions */ #ifndef y2imp extern int mem0[]; extern int *mem; #endif /* storage for action table */ #ifndef y1imp extern int amem[]; /* action table storage */ extern int *memp ; /* next free action table position */ extern int indgo[]; /* index to the stored goto table */ /* temporary vector, indexable by states, terms, or ntokens */ extern int temp1[]; extern int lineno; /* current line number */ /* statistics collection variables */ extern int zzgoent ; extern int zzgobest ; extern int zzacent ; extern int zzexcp ; extern int zzclose ; extern int zzrrconf ; extern int zzsrconf ; #endif /* define functions with strange types... */ extern char *cstash(); extern struct looksets *flset(); extern char *symnam(); extern char *writem(); /* default settings for a number of macros */ #define ISIZE 400 /* Specific for static in cpres() */ /* name of yacc tempfiles */ #ifndef TEMPNAME #define TEMPNAME "yacc.tmp" #endif #ifndef ACTNAME #define ACTNAME "yacc.act" #endif /* output file name */ #ifndef OFILE #define OFILE "ytab.c" #endif /* user output file name */ #ifndef FILEU #define FILEU "y.out" #endif /* output file for #defines */ #ifndef FILED #define FILED "ytab.h" #endif /* Size of complete filespec */ #ifndef FNAMESIZE #define FNAMESIZE 32 #endif /* command to clobber tempfiles after use */ #ifndef ZAPFILE #define ZAPFILE(x) unlink(x) #endif \EOF\ else echo "will not over write ./dtxtrn.h" fi if `test ! -s ./parse.y` then echo "writing ./parse.y" cat > ./parse.y << '\EOF\' /* parse.y - parser for flex input */ /* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Vern Paxson. * * The United States Government has rights in this work pursuant to * contract no. DE-AC03-76SF00098 between the United States Department of * Energy and the University of California. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ %token CHAR NUMBER SECTEND SCDECL XSCDECL WHITESPACE NAME PREVCCL EOF_OP %{ #include "flexdef.h" #ifndef lint static char copyright[] = "@(#) Copyright (c) 1989 The Regents of the University of California.\n"; static char CR_continuation[] = "@(#) All rights reserved.\n"; static char rcsid[] = "@(#) $Header: parse.y,v 2.1 89/06/20 17:23:54 vern Exp $ (LBL)"; #endif int pat, scnum, eps, headcnt, trailcnt, anyccl, lastchar, i, actvp, rulelen; int trlcontxt, xcluflg, cclsorted, varlength, variable_trail_rule; char clower(); static int madeany = false; /* whether we've made the '.' character class */ int previous_continued_action; /* whether the previous rule's action was '|' */ %} %% goal : initlex sect1 sect1end sect2 initforrule { /* add default rule */ int def_rule; pat = cclinit(); cclnegate( pat ); def_rule = mkstate( -pat ); finish_rule( def_rule, false, 0, 0 ); for ( i = 1; i <= lastsc; ++i ) scset[i] = mkbranch( scset[i], def_rule ); if ( spprdflt ) fputs( "YY_FATAL_ERROR( \"flex scanner jammed\" )", temp_action_file ); else fputs( "ECHO", temp_action_file ); fputs( ";\n\tYY_BREAK\n", temp_action_file ); } ; initlex : { /* initialize for processing rules */ /* create default DFA start condition */ scinstal( "INITIAL", false ); } ; sect1 : sect1 startconddecl WHITESPACE namelist1 '\n' | | error '\n' { synerr( "unknown error processing section 1" ); } ; sect1end : SECTEND ; startconddecl : SCDECL { /* these productions are separate from the s1object * rule because the semantics must be done before * we parse the remainder of an s1object */ xcluflg = false; } | XSCDECL { xcluflg = true; } ; namelist1 : namelist1 WHITESPACE NAME { scinstal( nmstr, xcluflg ); } | NAME { scinstal( nmstr, xcluflg ); } | error { synerr( "bad start condition list" ); } ; sect2 : sect2 initforrule flexrule '\n' | ; initforrule : { /* initialize for a parse of one rule */ trlcontxt = variable_trail_rule = varlength = false; trailcnt = headcnt = rulelen = 0; current_state_type = STATE_NORMAL; previous_continued_action = continued_action; new_rule(); } ; flexrule : scon '^' re eol { pat = link_machines( $3, $4 ); finish_rule( pat, variable_trail_rule, headcnt, trailcnt ); for ( i = 1; i <= actvp; ++i ) scbol[actvsc[i]] = mkbranch( scbol[actvsc[i]], pat ); if ( ! bol_needed ) { bol_needed = true; if ( performance_report ) fprintf( stderr, "'^' operator results in sub-optimal performance\n" ); } } | scon re eol { pat = link_machines( $2, $3 ); finish_rule( pat, variable_trail_rule, headcnt, trailcnt ); for ( i = 1; i <= actvp; ++i ) scset[actvsc[i]] = mkbranch( scset[actvsc[i]], pat ); } | '^' re eol { pat = link_machines( $2, $3 ); finish_rule( pat, variable_trail_rule, headcnt, trailcnt ); /* add to all non-exclusive start conditions, * including the default (0) start condition */ for ( i = 1; i <= lastsc; ++i ) if ( ! scxclu[i] ) scbol[i] = mkbranch( scbol[i], pat ); if ( ! bol_needed ) { bol_needed = true; if ( performance_report ) fprintf( stderr, "'^' operator results in sub-optimal performance\n" ); } } | re eol { pat = link_machines( $1, $2 ); finish_rule( pat, variable_trail_rule, headcnt, trailcnt ); for ( i = 1; i <= lastsc; ++i ) if ( ! scxclu[i] ) scset[i] = mkbranch( scset[i], pat ); } | scon EOF_OP { build_eof_action(); } | EOF_OP { /* this EOF applies only to the INITIAL start cond. */ actvsc[actvp = 1] = 1; build_eof_action(); } | error { synerr( "unrecognized rule" ); } ; scon : '<' namelist2 '>' ; namelist2 : namelist2 ',' NAME { if ( (scnum = sclookup( nmstr )) == 0 ) lerrsf( "undeclared start condition %s", nmstr ); else actvsc[++actvp] = scnum; } | NAME { if ( (scnum = sclookup( nmstr )) == 0 ) lerrsf( "undeclared start condition %s", nmstr ); else actvsc[actvp = 1] = scnum; } | error { synerr( "bad start condition list" ); } ; eol : '$' { if ( trlcontxt ) { synerr( "trailing context used twice" ); $$ = mkstate( SYM_EPSILON ); } else { trlcontxt = true; if ( ! varlength ) headcnt = rulelen; ++rulelen; trailcnt = 1; eps = mkstate( SYM_EPSILON ); $$ = link_machines( eps, mkstate( '\n' ) ); } } | { $$ = mkstate( SYM_EPSILON ); if ( trlcontxt ) { if ( varlength && headcnt == 0 ) /* both head and trail are variable-length */ variable_trail_rule = true; else trailcnt = rulelen; } } ; re : re '|' series { varlength = true; $$ = mkor( $1, $3 ); } | re2 series { if ( transchar[lastst[$2]] != SYM_EPSILON ) /* provide final transition \now/ so it * will be marked as a trailing context * state */ $2 = link_machines( $2, mkstate( SYM_EPSILON ) ); mark_beginning_as_normal( $2 ); current_state_type = STATE_NORMAL; if ( previous_continued_action ) { /* we need to treat this as variable trailing * context so that the backup does not happen * in the action but before the action switch * statement. If the backup happens in the * action, then the rules "falling into" this * one's action will *also* do the backup, * erroneously. */ if ( ! varlength || headcnt != 0 ) { fprintf( stderr, "flex: warning - trailing context rule at line %d made variable because\n", linenum ); fprintf( stderr, " of preceding '|' action\n" ); } /* mark as variable */ varlength = true; headcnt = 0; } if ( varlength && headcnt == 0 ) { /* variable trailing context rule */ /* mark the first part of the rule as the accepting * "head" part of a trailing context rule */ /* by the way, we didn't do this at the beginning * of this production because back then * current_state_type was set up for a trail * rule, and add_accept() can create a new * state ... */ add_accept( $1, num_rules | YY_TRAILING_HEAD_MASK ); } $$ = link_machines( $1, $2 ); } | series { $$ = $1; } ; re2 : re '/' { /* this rule is separate from the others for "re" so * that the reduction will occur before the trailing * series is parsed */ if ( trlcontxt ) synerr( "trailing context used twice" ); else trlcontxt = true; if ( varlength ) /* we hope the trailing context is fixed-length */ varlength = false; else headcnt = rulelen; rulelen = 0; current_state_type = STATE_TRAILING_CONTEXT; $$ = $1; } ; series : series singleton { /* this is where concatenation of adjacent patterns * gets done */ $$ = link_machines( $1, $2 ); } | singleton { $$ = $1; } ; singleton : singleton '*' { varlength = true; $$ = mkclos( $1 ); } | singleton '+' { varlength = true; $$ = mkposcl( $1 ); } | singleton '?' { varlength = true; $$ = mkopt( $1 ); } | singleton '{' NUMBER ',' NUMBER '}' { varlength = true; if ( $3 > $5 || $3 < 0 ) { synerr( "bad iteration values" ); $$ = $1; } else { if ( $3 == 0 ) $$ = mkopt( mkrep( $1, $3, $5 ) ); else $$ = mkrep( $1, $3, $5 ); } } | singleton '{' NUMBER ',' '}' { varlength = true; if ( $3 <= 0 ) { synerr( "iteration value must be positive" ); $$ = $1; } else $$ = mkrep( $1, $3, INFINITY ); } | singleton '{' NUMBER '}' { /* the singleton could be something like "(foo)", * in which case we have no idea what its length * is, so we punt here. */ varlength = true; if ( $3 <= 0 ) { synerr( "iteration value must be positive" ); $$ = $1; } else $$ = link_machines( $1, copysingl( $1, $3 - 1 ) ); } | '.' { if ( ! madeany ) { /* create the '.' character class */ anyccl = cclinit(); ccladd( anyccl, '\n' ); cclnegate( anyccl ); if ( useecs ) mkeccl( ccltbl + cclmap[anyccl], ccllen[anyccl], nextecm, ecgroup, CSIZE ); madeany = true; } ++rulelen; $$ = mkstate( -anyccl ); } | fullccl { if ( ! cclsorted ) /* sort characters for fast searching. We use a * shell sort since this list could be large. */ cshell( ccltbl + cclmap[$1], ccllen[$1] ); if ( useecs ) mkeccl( ccltbl + cclmap[$1], ccllen[$1], nextecm, ecgroup, CSIZE ); ++rulelen; $$ = mkstate( -$1 ); } | PREVCCL { ++rulelen; $$ = mkstate( -$1 ); } | '"' string '"' { $$ = $2; } | '(' re ')' { $$ = $2; } | CHAR { ++rulelen; if ( $1 == '\0' ) synerr( "null in rule" ); if ( caseins && $1 >= 'A' && $1 <= 'Z' ) $1 = clower( $1 ); $$ = mkstate( $1 ); } ; fullccl : '[' ccl ']' { $$ = $2; } | '[' '^' ccl ']' { /* *Sigh* - to be compatible Unix lex, negated ccls * match newlines */ #ifdef NOTDEF ccladd( $3, '\n' ); /* negated ccls don't match '\n' */ cclsorted = false; /* because we added the newline */ #endif cclnegate( $3 ); $$ = $3; } ; ccl : ccl CHAR '-' CHAR { if ( $2 > $4 ) synerr( "negative range in character class" ); else { if ( caseins ) { if ( $2 >= 'A' && $2 <= 'Z' ) $2 = clower( $2 ); if ( $4 >= 'A' && $4 <= 'Z' ) $4 = clower( $4 ); } for ( i = $2; i <= $4; ++i ) ccladd( $1, i ); /* keep track if this ccl is staying in alphabetical * order */ cclsorted = cclsorted && ($2 > lastchar); lastchar = $4; } $$ = $1; } | ccl CHAR { if ( caseins ) if ( $2 >= 'A' && $2 <= 'Z' ) $2 = clower( $2 ); ccladd( $1, $2 ); cclsorted = cclsorted && ($2 > lastchar); lastchar = $2; $$ = $1; } | { cclsorted = true; lastchar = 0; $$ = cclinit(); } ; string : string CHAR { if ( caseins ) if ( $2 >= 'A' && $2 <= 'Z' ) $2 = clower( $2 ); ++rulelen; $$ = link_machines( $1, mkstate( $2 ) ); } | { $$ = mkstate( SYM_EPSILON ); } ; %% /* build_eof_action - build the "<<EOF>>" action for the active start * conditions */ build_eof_action() { register int i; for ( i = 1; i <= actvp; ++i ) { if ( sceof[actvsc[i]] ) lerrsf( "multiple <<EOF>> rules for start condition %s", scname[actvsc[i]] ); else { sceof[actvsc[i]] = true; fprintf( temp_action_file, "case YY_STATE_EOF(%s):\n", scname[actvsc[i]] ); } } line_directive_out( temp_action_file ); } /* synerr - report a syntax error * * synopsis * char str[]; * synerr( str ); */ synerr( str ) char str[]; { syntaxerror = true; fprintf( stderr, "Syntax error at line %d: %s\n", linenum, str ); } /* yyerror - eat up an error message from the parser * * synopsis * char msg[]; * yyerror( msg ); */ yyerror( msg ) char msg[]; { } \EOF\ else echo "will not over write ./parse.y" fi if `test ! -s ./system.h` then echo "writing ./system.h" cat > ./system.h << '\EOF\' /* ********************* * * S Y S T E M . H * * ********************* * * This file replaces the original "files." header file. It defines, for * the IBM PC/XT version, the target parser function source file, overriding * file name string defines, and other system-specific definitions and * parameters. * * Bob Denny 06-Dec-80 * * Edits: * 18-Dec-80 ZAPFILE no longer used in Decus Yacc. * Parser file renamed yypars.c * * 28-Aug-81 Temp files for RSX have specific version * numbers of 1 to avoid multi-versions. Rename * parser info file ".i". * * 12-Apr-83 Add FNAMESIZE & EX_xxx parameters. * *Scott Guthery 23-Dec-83 Adapt for the IBM PC/XT & DeSmet C compiler. * */ /* Define WORD32 if target machine is a 32 bitter */ # undef WORD32 /* * Target parser source file */ #define PARSER "/usr/lib/yypars" /* * basic size of the Yacc implementation */ #define MEDIUM YES /* * Table size for this Yacc */ # define MEDTAB YES /* * Filespec definitions */ # define ACTNAME "yacc2.tmp" # define TEMPNAME "yacc1.tmp" # define FNAMESIZE 24 /* * Exit status values */ #define EX_SUC 1 #define EX_WAR 0 #define EX_ERR 2 #define EX_SEV 4 \EOF\ else echo "will not over write ./system.h" fi if `test ! -s ./y1.h` then echo "writing ./y1.h" cat > ./y1.h << '\EOF\' /*****************************************************************************/ /* ************* */ /* * Y 1 . H * */ /* ************* */ /* */ /* This file contains the external declarations needed to hook Yacc modules */ /* which were originally in Y1.C to their impure data in Y1IMP.1C. Also does */ /* the include of the original data/external file DTXTRN.H. */ /* */ /*****************************************************************************/ #include "dtxtrn.h" /* lookahead computations */ extern int tbitset; /* size of lookahead sets */ extern int nlset; /* next lookahead set index */ extern struct looksets clset; /* temporary storage for lookahead computations */ /* other storage areas */ extern int fatfl; /* if on, error is fatal */ extern int nerrors; /* number of errors */ /* storage for information about the nonterminals */ extern int **pres[ ]; /* vector of pointers to productions yielding each nonterminal */ extern struct looksets *pfirst[ ]; /* vector of pointers to first sets for each nonterminal */ extern int pempty[ ]; /* vector of nonterminals nontrivially deriving e */ /* accumulators for statistics information */ extern struct wset *zzcwp; extern int *zzmemsz; \EOF\ else echo "will not over write ./y1.h" fi if `test ! -s ./y1imp.c` then echo "writing ./y1imp.c" cat > ./y1imp.c << '\EOF\' /* * y1imp.c - impure data used by modules originally in y1.c. * * HISTORY */ #define y1imp yes #include "dtxtrn.h" /* lookahead computations */ int tbitset; /* size of lookahead sets */ struct looksets lkst[LSETSIZE]; int nlset = 0; /* next lookahead set index */ int nolook = 0; /* flag to suppress lookahead computations */ struct looksets clset; /* temporary storage for lookahead */ /* working set computations */ struct wset wsets[WSETSIZE]; struct wset *cwp; /* state information */ int nstate = 0; /* number of states */ struct item *pstate[NSTATES+2]; /* pointers to descriptions of states */ int tystate[NSTATES]; /* contains type information about states */ int indgo[NSTATES]; /* index to the stored goto table */ int tstates[NTERMS]; /* states generated by terminal gotos */ int ntstates[NNONTERM]; /* states generated by nonterminal gotos */ int mstates[NSTATES]; /* overflow of term/nonterm generation lists */ /* storage for the actions in the parser */ int amem[ACTSIZE]; /* action table storage */ int *memp = amem; /* next free action table position */ /* other storage areas */ int temp1[TEMPSIZE]; /* temporary storage, indexed by terms + ntokens or states */ int lineno = 1; /* current input line number */ int fatfl = 1; /* if on, error is fatal */ int nerrors = 0; /* number of errors */ /* storage for information about the nonterminals */ int **pres[NNONTERM+2]; /* vector of pointers to productions yielding each nonterminal */ struct looksets *pfirst[NNONTERM+2]; /* vector of pointers to first sets for each nonterminal */ int pempty[NNONTERM+1]; /* vector of nonterminals nontrivially deriving e */ /* accumulators for statistics information */ struct wset *zzcwp = wsets; int zzgoent = 0; int zzgobest = 0; int zzacent = 0; int zzexcp = 0; int zzclose = 0; int zzsrconf = 0; int *zzmemsz = mem0; int zzrrconf = 0; /* data pulled from internal static to here */ /* declared external only in user module */ int *pyield[NPROD]; /* from ycpres */ char sarr[ISIZE]; /* from ywritm */ \EOF\ else echo "will not over write ./y1imp.c" fi if `test ! -s ./y2.h` then echo "writing ./y2.h" cat > ./y2.h << '\EOF\' /*****************************************************************************/ /* ************* */ /* * Y 2 . H * */ /* ************* */ /* */ /* This file contains the external declarations needed to hook Yacc modules */ /* which were originally in Y2.C to their impure data in Y2IMP.2C. Also does */ /* the include of the original data/external file DTXTRN.H. */ /* */ /*****************************************************************************/ # include "dtxtrn.h" # define IDENTIFIER 257 # define MARK 258 # define TERM 259 # define LEFT 260 # define RIGHT 261 # define BINARY 262 # define PREC 263 # define LCURLY 264 # define C_IDENTIFIER 265 /* name followed by colon */ # define NUMBER 266 # define START 267 # define TYPEDEF 268 # define TYPENAME 269 # define UNION 270 # define ENDFILE 0 /* communication variables between various I/O routines */ extern char *infile; /* input file name */ extern int numbval; /* value of an input number */ extern char tokname[ ]; /* input token name */ /* storage of names */ extern char cnames[ ]; /* place where token and nonterminal names are stored */ extern int cnamsz; /* size of cnames */ extern char *cnamp; /* place where next name is to be put in */ extern int ndefout; /* number of defined symbols output */ /* storage of types */ extern int ntypes; /* number of types defined */ extern char *typeset[ ]; /* pointers to type tags */ /* symbol tables for tokens and nonterminals */ extern int start; /* start symbol */ /* assigned token type values */ extern int extval; \EOF\ else echo "will not over write ./y2.h" fi if `test ! -s ./y2imp.c` then echo "writing ./y2imp.c" cat > ./y2imp.c << '\EOF\' /* * y2imp.c - impure date needed by routines pulled from y2.c * * HISTORY */ #define y2imp YES #include "dtxtrn.h" /* communication variables between various I/O routines */ char *infile; /* input file name */ int numbval; /* value of an input number */ char tokname[NAMESIZE]; /* input token name */ /* storage of names */ char cnames[CNAMSZ]; /* token and nonterminal name storage */ int cnamsz = CNAMSZ; /* size of cnames */ char *cnamp = cnames; /* place where next name is to be put in */ int ndefout = 3; /* number of defined symbols output */ /* storage of types */ int ntypes; /* number of types defined */ char *typeset[NTYPES]; /* pointers to type tags */ /* symbol tables for tokens and nonterminals */ int ntokens = 0; struct toksymb tokset[NTERMS]; int toklev[NTERMS]; int nnonter = -1; struct ntsymb nontrst[NNONTERM]; int start; /* start symbol */ /* assigned token type values */ int extval = 0; /* input and output file descriptors */ FILE *finput; /* yacc input file */ FILE *faction; /* file for saving actions */ FILE *fdefine; /* file for # defines */ FILE *ftable; /* y.tab.c file */ FILE *ftemp; /* tempfile to pass 2 */ FILE *foutput; /* y.output file */ /* storage for grammar rules */ int mem0[MEMSIZE]; /* production storage */ int *mem = mem0; int nprod = 1; /* number of productions */ int *prdptr[NPROD]; /* pointers to descriptions of productions */ int levprd[NPROD]; /* precedence levels for the productions */ /* Statics pulled from modules */ int peekline; /* from gettok() */ \EOF\ else echo "will not over write ./y2imp.c" fi if `test ! -s ./y3.h` then echo "writing ./y3.h" cat > ./y3.h << '\EOF\' /*****************************************************************************/ /* ************* */ /* * Y 3 . H * */ /* ************* */ /* */ /* This file contains the external declarations needed to hook Yacc modules */ /* which were originally in Y3.C to their impure data in Y3IMP.3C. Also does */ /* the include of the original data/external file DTXTRN.H. */ /* */ /*****************************************************************************/ #include "dtxtrn.h" extern int lastred; /* the number of the last reduction of a state */ \EOF\ else echo "will not over write ./y3.h" fi if `test ! -s ./y3imp.c` then echo "writing ./y3imp.c" cat > ./y3imp.c << '\EOF\' /* * y3imp.c - impure data from modules split from y3.c * * HISTORY */ #define y3imp YES #include "dtxtrn.h" int lastred; /* the number of the last reduction of a state */ int defact[NSTATES]; /* the default actions of states */ \EOF\ else echo "will not over write ./y3imp.c" fi if `test ! -s ./y4.h` then echo "writing ./y4.h" cat > ./y4.h << '\EOF\' /*****************************************************************************/ /* ************* */ /* * Y 4 . H * */ /* ************* */ /* */ /* This file contains the external declarations needed to hook Yacc modules */ /* which were originally in Y4.C to their impure data in Y4IMP.4C. Also does */ /* the include of the original data/external file DTXTRN.H. */ /* */ /*****************************************************************************/ # include "dtxtrn.h" # define a amem # define pa indgo # define yypact temp1 # define greed tystate # define NOMORE -1000 extern int *ggreed; extern int *pgo; extern int *yypgo; extern int maxspr; /* maximum spread of any entry */ extern int maxoff; /* maximum offset into a array */ extern int *pmem; extern int *maxa; extern int nxdb; extern int adb; \EOF\ else echo "will not over write ./y4.h" fi if `test ! -s ./y4imp.c` then echo "writing ./y4imp.c" cat > ./y4imp.c << '\EOF\' /* * y4imp.c - impure data from y4.c modules * * HISTORY */ # include "dtxtrn.h" # define a amem # define pa indgo # define yypact temp1 # define greed tystate # define NOMORE -1000 int *ggreed = lkst[0].lset; int *pgo = wsets[0].ws.lset; int *yypgo = &nontrst[0].tvalue; int maxspr = 0; /* maximum spread of any entry */ int maxoff = 0; /* maximum offset into a array */ int *pmem = mem0; int *maxa; int nxdb = 0; int adb = 0; \EOF\ else echo "will not over write ./y4imp.c" fi if `test ! -s ./yaoput.c` then echo "writing ./yaoput.c" cat > ./yaoput.c << '\EOF\' /* * yaoput.c - write out the optimized parser * * HISTORY */ #include "y4.h" int aoutput() { fprintf(ftable, "# define YYLAST %d\n", maxa - a + 1); arout("yyact", a, (maxa - a) + 1); arout("yypact", pa, nstate); arout("yypgo", pgo, nnonter + 1); } \EOF\ else echo "will not over write ./yaoput.c" fi if `test ! -s ./yapack.c` then echo "writing ./yapack.c" cat > ./yapack.c << '\EOF\' /* * yapack.c - * * HISTORY * {1} 28-Aug-81 Bob Denny * Modified to make debug code conditionally compile. */ #include "y3.h" int apack(p, n ) int *p; { /* pack state i from temp1 into amem */ int off; register *pp, *qq, *rr; int *q, *r; /* * we don't need to worry about checking because we we will only * look entries known to be there... */ /* eliminate leading and trailing 0's */ q = p + n; for (pp = p, off = 0; *pp == 0 && pp <= q; ++pp, --off) /* VOID */; if (pp > q) return (0); /* no actions */ p = pp; /* now, find a place for the elements from p to q, inclusive */ r = &amem[ACTSIZE - 1]; for (rr = amem; rr <= r; ++rr, ++off) { /* try rr */ for (qq = rr, pp = p; pp <= q; ++pp, ++qq) { if (*pp != 0) { if (*pp != *qq && *qq != 0) goto nextk; } } /* we have found an acceptable k */ #ifdef debug if (foutput != NULL) fprintf(foutput, "off = %d, k = %d\n", off, rr - amem); #endif for (qq = rr, pp = p; pp <= q; ++pp, ++qq) { if (*pp) { if (qq > r) error("action table overflow"); if (qq > memp) memp = qq; *qq = *pp; } } #ifdef debug if (foutput != NULL) { for (pp = amem; pp <= memp; pp += 10) { fprintf(foutput, "\t"); for (qq = pp; qq <= pp + 9; ++qq) fprintf(foutput, "%d ", *qq); fprintf(foutput, "\n"); } } #endif return (off); nextk: ; } error("no space in action table"); /* NOTREACHED */ } \EOF\ else echo "will not over write ./yapack.c" fi echo "Finished archive 3 of 4" # if you want to concatenate archives, remove anything after this line exit 0
glenn@extro.ucc.su.oz (G. Geers [ext 3241]) (06/28/89)
--- cut here --- cut here --- cut here --- cut here --- cut here --- #!/bin/sh # This is a shell archive. Remove anything before the /bin/sh line # then unpack it by saving it in a file and typing "sh file" # (Files unpacked will be owned by you and have default permissions). # Don't worry about trailing garbage - the archive ends with exit # This archive contains the following files: # ./HEADER # ./Makefile # ./Makefile.msc # ./README # ./README.MINIX # ./cytab.h # if `test ! -s ./HEADER` then echo "writing ./HEADER" cat > ./HEADER << '\EOF\' @From mark@ems.UUCP@munnari.oz Sun Feb 1 18:27:23 1987 Path: ipso!metro!otc!munnari!seismo!rutgers!dayton!ems!mark @From: mark@ems.UUCP (Mark H. Colburn) Newsgroups: net.sources Subject: Public Domain YACC (part 1 of 2) Keywords: UNIX MS-DOS IBM-PC YACC Finally Message-ID: <135@ems.UUCP> Date: 1 Feb 87 07:27:23 GMT Sender: news@ems.UUCP Reply-To: mark@ems.UUCP (Mark H. Colburn) Distribution: world Organization: EMS/McGraw-Hill, Eden Prairie Lines: 2363 Here is a copy of the Public Domain YACC that I promised earlier. For those of you who sent me mail, if you still need me to email you a copy, please let me know, otherwise I will assume that you have pulled it off of the net. This version runs on System V and MS-DOS. I have not been able to get access to a BSD machine to test it there. Please send any bug reports, fixes, enhancements, comments or suggestions to me so that they can be included in any later releases or patches. Have fun. Mark H. Colburn mark@ems.uucp EMS/McGraw-Hill {rutgers|amdahl|ihnp4}!meccts!ems!mark 9855 West 78th Street Eden Prairie, MN 55344 (612) 829-8200 x235 # # The following files will be created: # ysetup.c # dtxtrn.h # yypars.c # ygttok.c # ycpact.c # yclsur.c # yclopt.c # y1imp.c # y2.h # ystagn.c # ycemty.c # ystate.c # Makefile # y1.h # yywrap.c # Lines: 2555 # The following files will be created: # youtpt.c # y2imp.c # ydefin.c # ywract.c # yapack.c # yothrs.c # ywstat.c # ystin.c # system.h # ysumry.c # README # yg2gen.c # y4.h # ycpfir.c # yg2out.c # ycpres.c # y3.h # ygin.c # ymain.c # yprcft.c # ycpuni.c # ydfout.c # ywritm.c # yflset.c # yhdprd.c # yptitm.c # ycpycd.c # ygtnm.c # yskpcm.c # yosmry.c # y4imp.c # ynxti.c # ychfnd.c # yyless.c # yarout.c # yerror.c # ywarry.c # yfdtyp.c # yprlok.c # ystuni.c # yaoput.c # y3imp.c # ycstsh.c # ysmnam.c # yaryfl.c # ychcpy.c # yfnact.c # \EOF\ else echo "will not over write ./HEADER" fi if `test ! -s ./Makefile` then echo "writing ./Makefile" cat > ./Makefile << '\EOF\' # Makefile for MINIX # BIN = /usr/bin LIB = /usr/lib CFLAGS = -O LDFLAGS = -i OBJECTS = y1imp.s y2imp.s y3imp.s y4imp.s yaryfl.s ycemty.s ychcpy.s\ yclsur.s ycpfir.s ycpres.s yerror.s yflset.s ymain.s yothrs.s\ yprlok.s yptitm.s ysmnam.s ystagn.s ystate.s ystuni.s ysumry.s\ ywritm.s ychfnd.s ycpact.s ycpuni.s ycpycd.s ycstsh.s ydefin.s\ ydfout.s yfdtyp.s yfnact.s ygttok.s ysetup.s yskpcm.s yapack.s\ yg2gen.s yg2out.s yhdprd.s youtpt.s yprcft.s ywarry.s ywract.s\ ywstat.s yaoput.s yclopt.s ygin.s ygtnm.s ynxti.s yosmry.s\ ystin.s yarout.s PROGRAMS = yacc all: ${PROGRAMS} clean: rm -f ${PROGRAMS} rm -f ${OBJECTS} rm -f a.out core yacc: ${OBJECTS} cc ${LDFLAGS} ${OBJECTS} -o yacc test: parse.y yacc ./yacc -hi parse.y install: yacc yypars cp yacc $(BIN)/yacc cp yypars $(LIB)/yypars dtxtrn.h: /usr/include/stdio.h system.h y1.h: dtxtrn.h y1imp.s: dtxtrn.h y2.h: dtxtrn.h y2imp.s: dtxtrn.h y3.h: dtxtrn.h y3imp.s: dtxtrn.h y4.h: dtxtrn.h y4imp.s: dtxtrn.h yaoput.s: y4.h yapack.s: y3.h yarout.s: y4.h yaryfl.s: y1.h ycemty.s: y1.h ychcpy.s: y1.h ychfnd.s: y2.h yclopt.s: y4.h yclsur.s: y1.h ycpact.s: /usr/include/stdio.h /usr/include/ctype.h y2.h ycpfir.s: y1.h ycpres.s: y1.h ycpuni.s: y2.h ycpycd.s: y2.h ycstsh.s: y2.h ydefin.s: y2.h ydfout.s: /usr/include/ctype.h y2.h yerror.s: y1.h yfdtyp.s: y2.h yflset.s: y1.h yfnact.s: y2.h yg2gen.s: y3.h yg2out.s: y3.h ygin.s: y4.h ygtnm.s: /usr/include/ctype.h y4.h ygttok.s: /usr/include/ctype.h y2.h yhdprd.s: y3.h ymain.s: y1.h ynxti.s: y4.h yosmry.s: y4.h yothrs.s: y1.h youtpt.s: y3.h yprcft.s: y3.h yprlok.s: y1.h yptitm.s: y1.h ysetup.s: y2.h yskpcm.s: y2.h ysmnam.s: y1.h ystagn.s: y1.h ystate.s: y1.h ystin.s: y4.h ystuni.s: y1.h ysumry.s: y1.h ywarry.s: y3.h ywract.s: y3.h ywritm.s: y1.h ywstat.s: y3.h \EOF\ else echo "will not over write ./Makefile" fi if `test ! -s ./Makefile.msc` then echo "writing ./Makefile.msc" cat > ./Makefile.msc << '\EOF\' CFLAGS = -OX -FPi LDFLAGS = OBJECTS = y1imp.o y2imp.o y3imp.o y4imp.o yaryfl.o ycemty.o ychcpy.o\ yclsur.o ycpfir.o ycpres.o yerror.o yflset.o ymain.o yothrs.o\ yprlok.o yptitm.o ysmnam.o ystagn.o ystate.o ystuni.o ysumry.o\ ywritm.o ychfnd.o ycpact.o ycpuni.o ycpycd.o ycstsh.o ydefin.o\ ydfout.o yfdtyp.o yfnact.o ygttok.o ysetup.o yskpcm.o yapack.o\ yg2gen.o yg2out.o yhdprd.o youtpt.o yprcft.o ywarry.o ywract.o\ ywstat.o yaoput.o yclopt.o ygin.o ygtnm.o ynxti.o yosmry.o\ ystin.o yarout.o PROGRAMS = yacc yacc: cl $LDFLAGS $OBJECTS -o yacc dtxtrn.h: stdio.h system.h y1.h: dtxtrn.h y1imp.o: dtxtrn.h y2.h: dtxtrn.h y2imp.o: dtxtrn.h y3.h: dtxtrn.h y3imp.o: dtxtrn.h y4.h: dtxtrn.h y4imp.o: dtxtrn.h yaoput.o: y4.h yapack.o: y3.h yarout.o: y4.h yaryfl.o: y1.h ycemty.o: y1.h ychcpy.o: y1.h ychfnd.o: y2.h yclopt.o: y4.h yclsur.o: y1.h ycpact.o: stdio.h ctype.h y2.h ycpfir.o: y1.h ycpres.o: y1.h ycpuni.o: y2.h ycpycd.o: y2.h ycstsh.o: y2.h ydefin.o: y2.h ydfout.o: ctype.h y2.h yerror.o: y1.h yfdtyp.o: y2.h yflset.o: y1.h yfnact.o: y2.h yg2gen.o: y3.h yg2out.o: y3.h ygin.o: y4.h ygtnm.o: ctype.h y4.h ygttok.o: ctype.h y2.h yhdprd.o: y3.h ymain.o: y1.h ynxti.o: y4.h yosmry.o: y4.h yothrs.o: y1.h youtpt.o: y3.h yprcft.o: y3.h yprlok.o: y1.h yptitm.o: y1.h ysetup.o: y2.h yskpcm.o: y2.h ysmnam.o: y1.h ystagn.o: y1.h ystate.o: y1.h ystin.o: y4.h ystuni.o: y1.h ysumry.o: y1.h ywarry.o: y3.h ywract.o: y3.h ywritm.o: y1.h ywstat.o: y3.h \EOF\ else echo "will not over write ./Makefile.msc" fi if `test ! -s ./README` then echo "writing ./README" cat > ./README << '\EOF\' UNIX/MS-DOS YACC Here is a copy of a public domain version of YACC. This version is a derivative of the DECUS yacc (at lease some where along the it come from there anyways). When I got it it had been modified to run under MS-DOS on IBM-PC's. I have modified it to, (once again) run under UNIX, as well as PC-DOS. It runs fine under System V.2 on an Arete 1200, as well as PC-DOS 3.1. I do not have access to a Berkley machine, so I have not been able to test it in that environment. I will post updates and patches to this version of YACC as I work with it more, and as I get comments from other people who use it. If you have any enhancements, portability problems or comments, please let me know and I will put them in. For those of you who have been wanting YACC on a PC, here it is. In order to install the package, look at the #defines in system.h and dtxtrn.h and modify them to match you machine configuration and needs/desires. Then type make. Mark H. Colburn mark@ems.uucp EMS/McGraw-Hill {rutgers|amdahl|ihnp4}!meccts!ems!mark 9855 West 78th Street Eden Prairie, MN 55344 (612) 829-8200 x235 \EOF\ else echo "will not over write ./README" fi if `test ! -s ./README.MINIX` then echo "writing ./README.MINIX" cat > ./README.MINIX << '\EOF\' The following program is a public domain implementation of yacc. There were no modifications required to any of the files (except the Makefile, of course). In the current state a MEDIUM sized version of yacc is made. This is the largest version possible under PC-MINIX. ST-MINIX users should edit the file system.h and #define HUGE, HUGETAB and probably WORD32 if they are using gcc. This will give a gigantic version of yacc capable of handling grammars of almost any size. The program will also compile on almost all versions of UNIX (I've tried Xenix/286, Ultrix, SysV.3 and UMIPS) and under DOS. Please read the files HEADER and README for the original info. The file parse.y used for testing yacc is taken from the flex distribution. I also noticed a nice irony here: the author works for Mc.Graw-Hill ! Share and Enjoy, Glenn Glenn Geers Department of Theoretical Physics, University of Sydney, Sydney, N.S.W., 2006 phone: +61 2 692-3241 email: glenn@extro.ucc.su.oz \EOF\ else echo "will not over write ./README.MINIX" fi if `test ! -s ./cytab.h` then echo "writing ./cytab.h" cat > ./cytab.h << '\EOF\' # define IDENTIFIER 257 # define CONSTANT 258 # define STRING_LITERAL 259 # define SIZEOF 260 # define PTR_OP 261 # define INC_OP 262 # define DEC_OP 263 # define LEFT_OP 264 # define RIGHT_OP 265 # define LE_OP 266 # define GE_OP 267 # define EQ_OP 268 # define NE_OP 269 # define AND_OP 270 # define OR_OP 271 # define MUL_ASSIGN 272 # define DIV_ASSIGN 273 # define MOD_ASSIGN 274 # define ADD_ASSIGN 275 # define SUB_ASSIGN 276 # define LEFT_ASSIGN 277 # define RIGHT_ASSIGN 278 # define AND_ASSIGN 279 # define XOR_ASSIGN 280 # define OR_ASSIGN 281 # define TYPE_NAME 282 # define TYPEDEF 283 # define EXTERN 284 # define STATIC 285 # define AUTO 286 # define REGISTER 287 # define CHAR 288 # define SHORT 289 # define INT 290 # define LONG 291 # define SIGNED 292 # define UNSIGNED 293 # define FLOAT 294 # define DOUBLE 295 # define CONST 296 # define VOLATILE 297 # define VOID 298 # define STRUCT 299 # define UNION 300 # define ENUM 301 # define ELIPSIS 302 # define RANGE 303 # define CASE 304 # define DEFAULT 305 # define IF 306 # define ELSE 307 # define SWITCH 308 # define WHILE 309 # define DO 310 # define FOR 311 # define GOTO 312 # define CONTINUE 313 # define BREAK 314 # define RETURN 315 \EOF\ else echo "will not over write ./cytab.h" fi echo "Finished archive 4 of 4" # if you want to concatenate archives, remove anything after this line exit 0
jds@mimsy.UUCP (James da Silva) (06/29/89)
In article <487@extro.ucc.su.oz> glenn@extro.ucc.su.oz (G. Geers [ext 3241]) writes: >The next four articles contain a public domain version of yacc. Bad News, Glenn. This is NOT a public domain yacc; this is THE yacc, as in AT&T's yacc. I strongly urge you to cancel your articles and everyone to delete their copies. Real Yacc got onto a DECUS tape by mistake, and has long since been withdrawn. Still, since then it has made the rounds and pops up on the net and on BBSes now and again. There is no `Public Domain Yacc' that I know of. Bison is a freely distri- butable Yacc clone, but it is never refered to as `PD-Yacc'. If you see such a thing on a BBS or somewhere, you can be 99.9% sure that it is a decendant of this rogue DECUS Yacc. Pass the word... Jaime ........................................................................... : domain: jds@mimsy.umd.edu James da Silva : path: uunet!mimsy!jds
maart@cs.vu.nl (Maarten Litmaath) (06/29/89)
glenn@extro.ucc.su.oz (G. Geers [ext 3241]) writes:
\...
\if `test ! -s ./yprcft.c`
^ ^
I would leave those backquotes out...
--
"I HATE arbitrary limits, especially when |Maarten Litmaath @ VU Amsterdam:
they're small." (Stephen Savitzky) |maart@cs.vu.nl, mcvax!botter!maart
john@minster.york.ac.uk (03/21/90)
Please would some kind Minix (PC?) user who has a working copy of David Clunie's yacc please post the sources to the net? (presumably having received David's permission first). I've tried porting both GNU yacc (bison) and Berkeley yacc (byacc) to my IBM-PC/XT (now, ST and 386 users, don't smirk :-) ) but, of course, they won't translate anything other than the most simple Yacc grammars, even compiled separate I+D. Berkeley yacc seems particularly heap-space hungry. The `DECUS' yacc and its derivatives posted to this newsgroup are apparently modified versions of a pirate copy of the original AT&T yacc, and so should not be used or supported by Minix owners. The archived sources of Clunie-yacc I retrieved from the archive server at Imperial College, London, seem to require some work doing to them before they will run under Minix. Since I imagine many Minix PC users would like a small (even slow) yacc, someone who has already done the work and who is willing to post it would surely be much appreciated. A full source posting is required for those who don't have Mr. Clunie's original. -------------------------------------------------------- John A. Murdie +44 904 432752 Dept. of Comp. Sci. ukc!minster!john University of York England
ghelmer@dsuvax.uucp (Guy Helmer) (03/21/90)
In article <637950680.761@minster.york.ac.uk>, john@minster.york.ac.uk writes: > Please would some kind Minix (PC?) user who has a > working copy of David Clunie's yacc please post the > sources to the net? (presumably having received David's > permission first). I ported David's yacc to Minix about six months ago. I hope I still have it somewhere on my Minix partition, and if I do, I could mail it out or post it if there's interest. Please respond by mail to my offer. > John A. Murdie +44 904 432752 > Dept. of Comp. Sci. ukc!minster!john -- Guy Helmer ...!cs.texas.edu!bigtex!uudell!loft386!dsuvax!ghelmer DSU Computing Services ghelmer@dsuvax.uucp, helmer@sdnet.bitnet "... the quickest way to kill any business is to let the government take it over." - Alan Abelson