Annotation of 40BSD/cmd/eyacc/ey1.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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