Annotation of 40BSD/cmd/eyacc/ey1.c, revision 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.