Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!cs.utexas.edu!uunet!murtoa.cs.mu.oz.au!munnari.oz.au!otc!metro!extro!glenn From: glenn@extro.ucc.su.oz (G. Geers [ext 3241]) Newsgroups: comp.os.minix Subject: yacc for minix (1 of 4) Message-ID: <487@extro.ucc.su.oz> Date: 28 Jun 89 10:39:33 GMT Reply-To: glenn@extro.ucc.su.oz (G. Geers [ext 3241]) Organization: University Computing Service, Uni. of Sydney, Australia. Lines: 1668 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