|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 7681 (0x1e01) Types: TextFile Notes: UNIX file Names: »y5.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦f4b8d8c84⟧ UNIX Filesystem └─⟦this⟧ »cmd/yacc/y5.c«
/* * write goto table and parsing table out to temp file * to be picked up later by the optimizer * at this point, the tables are fit to be processed by the C parser */ #include "yacc.h" #include "assert.h" #include "action.h" char *actns[] = { "SHIFT", "REDUCE", "ACCEPT", "ERROR" }; static int *uv; go2out() { register i; if( verbose ) fprintf(listout, "\n\nGoto table:\n\n"); uv = (int *)yalloc(nstates, sizeof *uv); rewopt(); for(i=1; i<nnonterm; i++) outgo2(i); free(uv); } outgo2(n) { extern yyredns, yygodef; int max, sno, j; struct sym *sp; struct go2n g2; sp = ntrmptr[n]; for(j=0; j<sp->s_nstates; j++) uv[j] = 0; max = 0; for(j=0; j<sp->s_nstates; j++) { sno = findnt( &states[sp->s_states[j]], n+NTBASE)->ng_st; if( ++uv[sno] > uv[max] ) max = sno; } yygodef += uv[max]; g2.from = (YYGOTO<<YYACTSH) | n; g2.to = sp->s_nstates - uv[max] + 1; yyredns += g2.to; fwrite(&g2, sizeof g2, 1, optout); if( verbose ) fprintf(listout, "%s:\n\n", ntrmptr[n]->s_name); for(j=0; j<sp->s_nstates; j++) { sno = sp->s_states[j]; if( (g2.to=findnt(&states[sno], n+NTBASE)->ng_st) == max ) continue; g2.from = sno; if( verbose ) fprintf(listout, "\t%d\t%d\n", g2.from, g2.to); fwrite(&g2, sizeof g2, 1, optout); } g2.from = YYOTHERS; g2.to = max; fwrite(&g2, sizeof g2, 1, optout); if( verbose ) fprintf(listout, "\t.\t%d\n\n", max); } paout() { register i; if( verbose ) fprintf(listout, "\n\nParsing action table:\n\n"); for(i=0; i<nstates; i++) outstate(i); } outstate(n) { extern yydefact, yypact; register i, k; register struct state *stp; int size, max, errshift, pno, maxp, j, l; struct lset shls, rdls; struct actn rdact[MAXREDS], act; stp = &states[n]; zerolset(&shls); for(i=0; i<stp->s_tgo; i++) setbit(&shls, stp->s_tgos[i].tg_trm); max = 0; maxp = -1; for(i=k=0; i<stp->s_nred; i++) { pno = stp->s_reds[i].rd_prod->p_prodno; copylset(&rdls, stp->s_reds[i].rd_lset); resolve(n, i, &shls, &rdls); size = 0; for(j=first(&rdls); j>=0; j=next(&rdls, j)) { for(l=0; l<k; l++) if( rdact[l].a_chr==j ) { redred(n, pno, rdact[l].a_no&YYAMASK, j); goto nextj; /* C needs next <var> */ } bounded(l, MAXREDS, "reductions"); rdact[k].a_chr = j; rdact[k++].a_no = (YYREDACT<<YYACTSH) | pno; size++; nextj: ; } if( size>max ) { max = size; maxp = pno; } } if( bit(&shls, ERRNO) || maxp==0 ) /* shift on error or accept */ maxp = -1; /* count total number of actions */ size = k + lcount(&shls) + !bit(&shls,ERRNO); /* shifts+reds+default */ if( maxp >= 0 ) { size -= max; yydefact += max; } yypact += size; act.a_chr = size; act.a_no = (YYPACTION<<YYACTSH) | n; if( verbose ) fprintf(listout, "State %d (size %d):\n\n", n, size); fwrite(&act, sizeof act, 1, optout); /* now have shifts in shls redns in rdact */ /* output shifts */ for(j=0; j<stp->s_tgo; j++) { if( !bit(&shls, i = stp->s_tgos[j].tg_trm) ) continue; if( i==ERRNO ) { /* will be made default */ errshift = stp->s_tgos[j].tg_st; continue; } act.a_chr = i; act.a_no = (YYSHIFTACT<<YYACTSH) | stp->s_tgos[j].tg_st; wract(&act); } /* output reductions */ for(i=0; i<k; i++) { if( (pno = rdact[i].a_no&YYAMASK) == maxp ) continue; if( pno==0 ) /* $accept -> start $end . */ rdact[i].a_no = YYACCEPTACT<<YYACTSH; wract(&rdact[i]); } /* default action */ act.a_chr = YYOTHERS; if( bit(&shls, ERRNO) ) { act.a_no = (YYSHIFTACT<<YYACTSH) | errshift; } else if( maxp>=0 ) act.a_no = YYREDACT<<YYACTSH | maxp; else act.a_no = (YYERRACT<<YYACTSH); wract(&act); } wract(actp) register struct actn *actp; { register unsigned actn; actn = actp->a_no>>YYACTSH; if( verbose ) { fprintf(listout, "\t%s\t%s", actp->a_chr==YYOTHERS?".": trmptr[actp->a_chr]->s_name, actns[actn]); if( actn<=YYREDACT ) fprintf(listout, "\t%d", actp->a_no&YYAMASK); fprintf(listout, "\n"); } fwrite(actp, sizeof *actp, 1, optout); } lcount(lp) struct lset *lp; { register n, count; register unsigned char *ucp; extern unsigned char bcount[]; count = 0; ucp = lp->l_bits; n = LSETSIZE; do { count += bcount[*ucp++]; } while (--n); return(count); } setdiff(ld, ls) struct lset *ld, *ls; { register n; register unsigned char *udcp, *uscp; n = LSETSIZE; udcp = ld->l_bits; uscp = ls->l_bits; do { *udcp++ &= ~ *uscp++; } while (--n); } setunion(ld, ls) struct lset *ld, *ls; { register n; register unsigned char *udcp, *uscp; n = LSETSIZE; udcp = ld->l_bits; uscp = ls->l_bits; do { *udcp++ |= *uscp++; } while (--n); } setint(ld, ls) struct lset *ld, *ls; { register n; register unsigned char *udcp, *uscp; n = LSETSIZE; udcp = ld->l_bits; uscp = ls->l_bits; do { *udcp++ &= *uscp++; } while (--n); } copylset(ld, ls) struct lset *ld, *ls; { register n; register unsigned char *udcp, *uscp; n = LSETSIZE; udcp = ld->l_bits; uscp = ls->l_bits; do { *udcp++ = *uscp++; } while (--n); } zerolset(ld) struct lset *ld; { register n; register unsigned char *udcp; n = LSETSIZE; udcp = ld->l_bits; do { *udcp++ = 0; } while (--n); } resolve(sno, p, sls, rls) int p; struct lset *sls, *rls; { register i; struct lset cls; int todo; struct prod *pp; struct sym *tsp; copylset(&cls, sls); setint(&cls, rls); pp = states[sno].s_reds[p].rd_prod; for(i=first(&cls); i>=0; i=next(&cls,i) ) { /* conflict on term i */ tsp = trmptr[i]; if( tsp->s_ass<=UNASSOC || pp->p_ass<=UNASSOC ) { shiftred(sno, pp->p_prodno, i); clrbit(rls, i); continue; /* conflict resolved in favour of shift */ } if( pp->p_prc > tsp->s_prc ) todo = LASSOC; else if( pp->p_prc < tsp->s_prc ) todo = RASSOC; else todo = tsp->s_ass; switch( todo ) { case LASSOC: /* reduce */ clrbit(sls, i); break; case RASSOC: clrbit(rls, i); break; case UNASSOC: /* non-self associating op */ clrbit(rls, i); clrbit(sls, i); break; } } } shiftred(sno, pn, tok) { register i; struct state *stp; stp = &states[sno]; ++nsrconf; if( !verbose ) return; for(i=0; i<stp->s_tgo; i++) if( stp->s_tgos[i].tg_trm==tok ) break; fprintf(listout, "State %d: Shift/Reduce conflict ", sno); fprintf(listout, "(shift %d, red'n %d) on %s\n", stp->s_tgos[i].tg_st, pn, trmptr[tok]->s_name); } redred(sno, pn1, pn2, tok) { struct state *stp; stp = &states[sno]; ++nrrconf; if( !verbose ) return; fprintf(listout, "State %d: Reduce/Reduce conflict ", sno); fprintf(listout, "(red'n %d, red'n %d) on %s\n", pn1, pn2, trmptr[tok]->s_name); } clrbit(lp, n) struct lset *lp; register n; { register unsigned char *ucp; ucp = lp->l_bits; ucp[n>>LOGCHAR] &= ~( 01 << (n & (NBCHAR-1)) ); } setbit(lp, n) struct lset *lp; register n; { register unsigned char *ucp; ucp = lp->l_bits; ucp[n>>LOGCHAR] |= 01 << (n & (NBCHAR-1)); } bit(lp, n) struct lset *lp; register n; { register unsigned char *ucp; ucp = lp->l_bits; return( (ucp[n>>LOGCHAR] >> (n&(NBCHAR-1))) & 01 ); } first(lp) struct lset *lp; { return(next(lp,-1)); } next(lp, n) struct lset *lp; register n; { register w; register unsigned char *ucp; extern char ltab[]; if( ++n >= LSETSIZE*NBCHAR ) return(-1); ucp = lp->l_bits; w = ucp[n >> LOGCHAR]; w &= ~ ( (01 << (n&(NBCHAR-1))) - 1); n >>= LOGCHAR; while (w == 0) { if ( ++n >= LSETSIZE ) return(-1); w = ucp[n]; } return( (n<<LOGCHAR) + ltab[w] ); } struct ntgo * findnt(stp, nt) register struct state *stp; { register i; for(i=0; i<stp->s_ntgo; i++ ) if( stp->s_ntgos[i].ng_nt==nt ) return( &stp->s_ntgos[i] ); yyerror(NLNO|FATAL, "oops in findnt"); }