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

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