Annotation of 43BSD/ucb/pascal/eyacc/ey1.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1979 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: static char sccsid[] = "@(#)ey1.c      5.1 (Berkeley) 4/29/85";
                      9: #endif not lint
                     10: 
                     11: # include "ey.h"
                     12:   /*     * * * *    e y a c c     * * * *     */
                     13: 
                     14:   /**** NB -----
                     15:    *
                     16:    * This version of yacc, known as "eyacc" has been slightly but
                     17:    * importantly modified to allow error recovery in the UNIX Pascal
                     18:    * translator "pi" and also in "pix".
                     19:    *
                     20:    * Changes here include:
                     21:    *
                     22:    * 1) Enumeration of test actions when "error" is an input token.
                     23:    *
                     24:    * 2) Change to the encoding of the action entries.  Test entries
                     25:    *    are encoded as the arithmetic inverse of the symbol being tested
                     26:    *   for.  This is an optimization that makes the parser run at the
                     27:    *   same speed even though, with error productions and enumerated
                     28:    *   lookaheads, it would normally be much slower.  Of course the
                     29:    *   same thing could be done to the regular yacc...
                     30:    *
                     31:    * 3) Different table sizes
                     32:    *
                     33:    * 4) Recognizes form feeds
                     34:    *
                     35:    * 5) Also most of the numbers for the sizes of the tables have been
                     36:    *   increased, to an extent to allow for "eyacc"ing of the Pascal grammar
                     37:    *   and of a grammar which I have for "EUCLID".
                     38:    *
                     39:    *   There seem to be subtle dependencies between the various magic
                     40:    *   numbers... I found some of them but to be safe most of the limits
                     41:    *   are very generous... for this reason "eyacc" will most likely
                     42:    *   have to run separate i/d... no matter.
                     43:    *
                     44:    *                                   Bill Joy
                     45:    *                                   Computer Science Division
                     46:    *                                   EECS Department
                     47:    *                                   University of California, Berkeley
                     48:    *                                   Berkeley, California  94704
                     49:    *   
                     50:    *                                   Office: (415) 642-4948
                     51:    *                                   Home:   (415) 524-4510
                     52:    ****/
                     53: 
                     54:   /*      features to be fixed up ...
                     55: 
                     56:   ***  Print estimate of total space needed for parser
                     57:   ***  Either list inputs on y.output, or list empty prdn's in states
                     58:   ***  Mention nonterms not used (or, rules. not reduced) as nonfatal error
                     59:   ***  Output states where conflicts were found by default on y.output
                     60:   ***  Engage in newspeak: production=>grammar rules, term=>token, etc.
                     61:   ***  handle # define, #ifdef, etc., in yacc actions, %{ %}
                     62:   */
                     63: 
                     64:   /*      new features to be added
                     65: 
                     66:   ***  reductions by single productions ( by request )
                     67:   ***  follow sets for start symbol
                     68:   ***  option to only do slr(1)
                     69:   ***  easily changed array names on output
                     70:   ***  allocate core, rather than predefined
                     71:   ***  input controlled by a grammar
                     72:   ***  support multiple choices for  conflicts
                     73:   ***  better conflict diagnostics
                     74:   */
                     75: 
                     76: extern char *symnam();
                     77: 
                     78: main(argc,argv) int argc; char *argv[]; {
                     79:   auto int n;
                     80: 
                     81:   whereami();
                     82:   setup(argc,argv); /* initialize and read productions */
                     83:   tbitset = (nterms+16)/16;
                     84:   cpres(); /* make table of which productions yield a given nonterminal */
                     85:   cempty(); /* make a table of which nonterminals can match the empty string */
                     86:   cpfir(); /* make a table of e free first lists */
                     87:   stagen(); /* generate the states */
                     88:   output();  /* write the states and the tables */
                     89:   go2out();
                     90:   summary();
                     91:   windup();
                     92:   }
                     93: 
                     94: whereami(){ /* sets the variable machine to UNIX, GCOS, or IBM */
                     95: 
                     96:   int i;
                     97: 
                     98:   i = 1;
                     99:   i = i << 30;
                    100:   if( i == 0 ) {
                    101:     machine = UNIX;
                    102:     return;
                    103:     }
                    104:   i = i << 4;
                    105:   if( i == 0 ){
                    106:     machine = IBM;
                    107:     return;
                    108:     }
                    109:   machine = GCOS;
                    110:   }
                    111: 
                    112: windup(){
                    113:   /* no errors, do the optimization if appropriate */
                    114:   char *cp;
                    115:   int i;
                    116: 
                    117:   if( !oflag ) cexit(0);
                    118: 
                    119:   switch( machine ){
                    120: 
                    121:   case GCOS:
                    122:     if( rflag ){
                    123:       if( foutput<0 ) system( "./yopt -r" );
                    124:       else system( "./yopt -rv" );
                    125:       }
                    126:     else {
                    127:       if( foutput<0 ) system( "./yopt" );
                    128:       else system( "./yopt -v" );
                    129:       }
                    130:     cexit(0);  /* terminate */
                    131: 
                    132:   case UNIX:
                    133:     cp = "/usr/nlib/yaccopt";
                    134:     if( rflag ) execl( cp, cp, (foutput<0)?"-r":"-rv", 0 );
                    135:     else if( foutput<0 ) execl( cp, cp, 0 );
                    136:     else execl( cp, cp, "-v", 0 );
                    137:     error( "optimization execl call fails" );
                    138: 
                    139:   case IBM:
                    140:     if( rflag ){
                    141:       if( foutput<0 ) system( "MH2019.yaccopt -r" );
                    142:       else system( "MH2019.yaccopt -rv" );
                    143:       }
                    144:     else {
                    145:       if( foutput<0 ) system( "MH2019.yaccopt" );
                    146:       else system( "MH2019.yaccopt -v" );
                    147:       }
                    148:     cexit(0);
                    149: 
                    150:     }
                    151: 
                    152:   }
                    153: 
                    154: settty()
                    155: /*     sets the output file to y.output */
                    156: {      
                    157:        cflush( foutput );  /* a bit of a cheat */
                    158:        cout = foutput;
                    159:        }
                    160: 
                    161: settab(){ /* sets the output file to y.tab.c */
                    162:        
                    163:        cflush( ftable );
                    164:        cout = ftable;
                    165:        }
                    166: 
                    167: char *chcopy( p, q )  char *p, *q; {
                    168:        /* copies string q into p, returning next free char ptr */
                    169:        while( *p = *q++ ) ++p;
                    170:        return( p );
                    171:        }
                    172: 
                    173: char *writem(pp) struct item *pp; { /* creates output string for item pointed to by pp */
                    174:        int i,*p;
                    175:        static char sarr[100];
                    176:        char *q;
                    177: 
                    178:        for( p=pp->pitem; *p>0 ; ++p ) ;
                    179:        p = prdptr[-*p];
                    180:        q = chcopy( sarr, nontrst[*p-NTBASE].name );
                    181:        q = chcopy( q, " : " );
                    182: 
                    183:        for(;;){
                    184:                *q++ = ++p==(pp->pitem) ? '_' : ' ';
                    185:                if((i = *p) <= 0) break;
                    186:                q = chcopy( q, symnam(i) );
                    187:                }
                    188: 
                    189:        *q = '\0' ;
                    190:        return( sarr );
                    191:        }
                    192: 
                    193: char *symnam(i){ /* return a pointer to the name of symbol i */
                    194:        char *cp;
                    195: 
                    196:        cp = (i>=NTBASE) ? nontrst[i-NTBASE].name : trmset[i].name ;
                    197:        if( *cp == ' ' ) ++cp;
                    198:        return( cp );
                    199:        }
                    200: 
                    201: summary(){ /* output the summary on the tty */
                    202: 
                    203:   int i, s, *pn;
                    204:   
                    205: 
                    206:        if( !rflag ){
                    207:                settab();
                    208:                fprintf( cout , "\nint nterms %d;",nterms);
                    209:                fprintf( cout , "\nint nnonter %d;", nnonter);
                    210:                fprintf( cout , "\nint nstate %d;", nstate);
                    211:                fprintf( cout , "\nchar *yysterm[] {");
                    212:                for (i=1;i<=nterms;i++) if( trmset[i].value >= 0400 ) fprintf( cout , "\n\"%s\",",symnam(i));
                    213:                fprintf( cout ,  "\n0 };\n" );
                    214:                fprintf( cout , "\nchar *yysnter[] {");
                    215:                for (i=0;i<nnonter;i++) fprintf( cout , "\n\"%s\",",nontrst[i].name);
                    216:                fprintf( cout , "\n\"%s\" };\n",nontrst[nnonter].name);
                    217:                }
                    218: 
                    219:   settty();
                    220:   fprintf( cout , "\n%d/%d terminals, %d/%d nonterminals\n", nterms, tlim,
                    221:       nnonter, ntlim );
                    222:   fprintf( cout , "%d/%d grammar rules, %d/%d states\n", nprod, prdlim, nstate, stsize );
                    223:   fprintf( cout , "%d shift/reduce, %d reduce/reduce conflicts reported\n", zzsrconf, zzrrconf );
                    224:   pn = (int *)pstate[nstate+1];
                    225:   fprintf( cout , "%d/%d working sets used\n", zzcwset,  wssize );
                    226:   fprintf( cout , "memory: states,etc. %d/%d, parser %d/%d\n", pn-mem0, memsiz,
                    227:       memact, actsiz );
                    228:   fprintf( cout , "%d/%d distinct lookahead sets\n", nlset, lsetsz );
                    229:   fprintf( cout , "%d extra closures\n", zzclose - 2*nstate );
                    230:   fprintf( cout , "%d action entries\n", zzacent );
                    231:   fprintf( cout , "%d action entries saved through merging %d states\n",zzacsave,zznsave);
                    232:   fprintf( cout , "%d goto entries\n", zzgoent );
                    233:   fprintf( cout , "%d entries saved by goto default\n", zzgobest );
                    234:   fprintf( cout , "%d lookahead sets saved\n", savedlook);
                    235:   if( zzsrconf!=0 || zzrrconf!=0 ){
                    236:     cflush( errfileno );
                    237:     cout = errfileno;
                    238:     fprintf( cout , "\nconflicts: ");
                    239:     if( zzsrconf )fprintf( cout ,  "%d shift/reduce" , zzsrconf );
                    240:     if( zzsrconf && zzrrconf )fprintf( cout ,  ", " );
                    241:     if( zzrrconf )fprintf( cout ,  "%d reduce/reduce" , zzrrconf );
                    242:     fprintf( cout ,  "\n" );
                    243:     }
                    244:   }
                    245: 
                    246: error(s,a1){ /* write out error comment */
                    247:        
                    248:        int c;
                    249:        ++nerrors;
                    250:        cflush( errfileno );
                    251:        cout = errfileno;   /* set output to tty */
                    252:        fprintf( cout , "\n fatal error: ");
                    253:        fprintf( cout , s,a1);
                    254:         fprintf( cout , ", line %d\n", lineno );
                    255:        if( !fatfl ) return;
                    256:        summary();
                    257:        cexit(1);
                    258:        }
                    259: 
                    260: arrset(s) char s[]; {
                    261:        fprintf( cout , "\nint %s[] {0", s );
                    262:        arrndx = 1;
                    263:        }
                    264: 
                    265: arrval(n){
                    266:        fprintf( cout , ",%d",n);
                    267:        if( (++arrndx%10) == 0 ) fprintf( cout , "\n");
                    268:        }
                    269: 
                    270: arrdone(){
                    271:        fprintf( cout , ",-1};\n");
                    272:        }
                    273: 
                    274: copy(v) char *v; {     /* copy ctokn to v */
                    275:        char *p;
                    276: 
                    277:        p=ctokn;
                    278:        while( *v++ = *p++ );
                    279:        }
                    280: 
                    281: compare(v) char *v; {  /* compare ctokn with v */
                    282:        char *p;
                    283: 
                    284:        for( p=ctokn; ; ++p ){
                    285:                if( *p != *v++ ) return( 0 );
                    286:                if( *p == 0 ) return(1);
                    287:                }
                    288:        }
                    289: 
                    290: int *yalloc(n){ /* allocate n+1 words from vector mem */
                    291:        int *omem;
                    292:        omem = mem;
                    293:        mem += n+1;
                    294:        if(mem-mem0 >= memsiz) error("memory overflow");
                    295:        return(omem);
                    296:        }
                    297: 
                    298: aryfil( v, n, c ) int *v,n,c; { /* set elements 0 through n-1 to c */
                    299:   int i;
                    300:   for( i=0; i<n; ++i ) v[i] = c;
                    301:   }
                    302: 
                    303: UNION( a, b, c ) int *a, *b, *c; {
                    304:   /* set a to the UNION of b and c */
                    305:   /* a may equal b */
                    306:   /* return 1 if c is not a subset of b, 0 otherwise */
                    307: 
                    308:   _REGISTER int i, x, sub;
                    309: 
                    310:   sub = 0;
                    311:   for( i=0; i<tbitset; ++i ){
                    312:     x = b[i] | c[i];
                    313:     if( x != b[i] ) sub=1;
                    314:     a[i] = x;
                    315:     }
                    316:   return( sub );
                    317:   }
                    318: 
                    319: prlook( p ) struct looksets *p;{
                    320:        int j, *pp;
                    321:        pp = p->lset;
                    322:        if( pp == 0 ) fprintf( cout , "\tNULL");
                    323:        else {
                    324:                fprintf( cout , " { " );
                    325:                for( j=1; j<=nterms; ++j ){
                    326:                        if( (pp[j>>4]>>(j&017) )&01 != 0 ) fprintf( cout ,  "%s ", symnam(j) );
                    327:                        }
                    328:                fprintf( cout ,  "}" );
                    329:                }
                    330:        }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.