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

1.1       root        1: static char *sccsid = "@(#)ey2.c       4.2 (Berkeley) 4/1/81";
                      2: /* (c) 1979 Regents of the University of California */
                      3: # include "ey.h"
                      4: # define IDENTIFIER 257
                      5: # define MARK 258
                      6: # define TERM 259
                      7: # define LEFT 260
                      8: # define BINARY 261
                      9: # define RIGHT 262
                     10: # define PREC 263
                     11: # define LCURLY 264
                     12: # define C_IDENTIFIER 265  /* name followed by colon */
                     13: # define NUMBER 266
                     14: 
                     15: setup(argc,argv) int argc; char *argv[];
                     16: {      int i,j,lev,t;
                     17:        int c;
                     18: 
                     19:        foutput = stdout;
                     20:        i = 1;
                     21:        while( argc >= 2  && argv[1][0] == '-' ) {
                     22:                while( *++(argv[1]) ){
                     23:                        switch( *argv[1] ){
                     24:                        case 'v':
                     25:                        case 'V':
                     26:                                foutput = copen("y.output", 'w' );
                     27:                                if( foutput == 0 ) error( "cannot open y.output");
                     28:                                continue;
                     29:                        case 'o':
                     30:                        case 'O':
                     31:                                oflag = 1;
                     32:                                continue;
                     33:                        case 'r':
                     34:                        case 'R':
                     35:                                oflag = 1;
                     36:                                rflag = 1;
                     37:                                continue;
                     38:                        default:  error( "illegal option: %c", *argv[1]);
                     39:                                }
                     40:                        }
                     41:                argv++;
                     42:                argc--;
                     43:                }
                     44: 
                     45:        ftable = copen( oflag ? "yacc.tmp" : "y.tab.c" , 'w' );
                     46:        if( ftable==0 ) error( "cannot open table file" );
                     47:        if( argc > 1 ) { cin = copen( argv[1], 'r' );
                     48:        if( cin == 0 ) error( "cannot open input" );
                     49:        }
                     50:        settab();
                     51:        fprintf( cout , "#\n");
                     52:        ctokn = "$end";
                     53:        defin(0);  /* eof */
                     54:        extval = 0400;  /* beginning of assigned values */
                     55:        ctokn = "error";
                     56:        defin(0);
                     57:        ctokn = "$accept";
                     58:        defin(1);
                     59:        mem=mem0;
                     60:        cnamp = cnames;
                     61:        lev=0;
                     62:        i=0;
                     63: 
                     64:        while( ( t = gettok() ) != EOF ) {
                     65:                switch( t ){
                     66:                        case IDENTIFIER:        j = chfind(0);
                     67:                                        trmlev[j] = lev;
                     68:                                        continue;
                     69:                        case ',':
                     70:                        case ';':               continue;
                     71:                        case TERM:              lev=0; continue;
                     72:                        case LEFT:              lev=(++i<<3)|01; continue;
                     73:                        case BINARY:    lev=(++i<<3)|02; continue;
                     74:                        case RIGHT:     lev=(++i<<3)|03; continue;
                     75:                        case MARK:
                     76:                                        defout();
                     77:                                        if( rflag ){ /* RATFOR */
                     78:                                                fprintf( cout ,  "define yyerrok yyerrf = 0\n" );
                     79:                                                fprintf( cout ,  "define yyclearin yychar = -1\n" );
                     80:                                                fprintf( cout ,  "subroutine yyactr(yyprdn)\n");
                     81:                                                fprintf( cout ,  "common/yycomn/yylval,yyval,yypv,yyvalv(150)\n" );
                     82:                                                fprintf( cout ,  "common/yylcom/yychar,yyerrf,yydebu\n" );
                     83:                                                fprintf( cout ,  "integer yychar, yyerrf, yydebu\n" );
                     84:                                                fprintf( cout ,  "integer yyprdn,yyval,yylval,yypv,yyvalv\n" );
                     85:                                                }
                     86:                                        else {
                     87:                                                fprintf( cout ,  "#define yyclearin yychar = -1\n" );
                     88:                                                fprintf( cout ,  "#define yyerrok yyerrflag = 0\n" );
                     89:                                                fprintf( cout ,  "extern int yychar, yyerrflag;\n" );
                     90:                                                fprintf( cout , "\nint yyval 0;\nint *yypv;\nint yylval 0;");
                     91:                                                fprintf( cout , "\nyyactr(__np__){\n");
                     92:                                                }
                     93:                                        break;
                     94:                        case LCURLY:    defout();
                     95:                                        cpycode();
                     96:                                        continue;
                     97:                        case NUMBER:
                     98:                                trmset[j].value = numbval;
                     99:                                if( j < ndefout && j>2 ) 
                    100:                                        error("please define type # of %s earlier", trmset[j].name );
                    101:                                continue;
                    102:                        default:        error("bad precedence syntax, input %d", t );
                    103:                        }
                    104:                break;
                    105:                }
                    106:        prdptr[0]=mem;
                    107:        /* added production */
                    108:        *mem++ = NTBASE;
                    109:        *mem++ = NTBASE+1;
                    110:        *mem++ = 1;
                    111:        *mem++ = 0;
                    112:        prdptr[1]=mem;
                    113:        i=0;
                    114: 
                    115:        /* i is 0 when a rule can begin, 1 otherwise */
                    116: 
                    117:        for(;;) switch( t=gettok() ) {
                    118:        case C_IDENTIFIER:              if( mem == prdptr[1] ) {  /* first time */
                    119:                                                if( rflag ){
                    120:                                                        fprintf( cout ,  "goto 1000\n" );
                    121:                                                        }
                    122:                                                else fprintf( cout , "\nswitch(__np__){\n");
                    123:                                                }
                    124:                                if( i != 0 ) error( "previous rule not terminated" );
                    125:                                *mem = chfind(1);
                    126:                                if( *mem < NTBASE )error( "token illegal on lhs of grammar rule" );
                    127:                                i=1;
                    128:                                ++mem;
                    129:                                continue;
                    130:        case IDENTIFIER:
                    131:                        *mem=chfind(1);
                    132:                        if(*mem < NTBASE)levprd[nprod]=trmlev[*mem];
                    133:                        mem++;
                    134:                        if(i==0) error("missing :");
                    135:                        continue;
                    136:        case '=':               levprd[nprod] |= 04;
                    137:                                if( i==0 ) error("semicolon preceeds action");
                    138:                        fprintf( cout ,  rflag?"\n%d ":"\ncase %d:", nprod );
                    139:                        cpyact();
                    140:                        fprintf( cout ,  rflag ? " return" : " break;" );
                    141:        case '|':
                    142:        case ';':               if(i){
                    143:                                *mem++ = -nprod;
                    144:                                prdptr[++nprod] = mem;
                    145:                                levprd[nprod]=0;
                    146:                                i=0;}
                    147:                        if (t=='|'){i=1;*mem++ = *prdptr[nprod-1];}
                    148:                        continue;
                    149:        case 0:         /* End Of File */
                    150:        case EOF:
                    151:        case MARK:      if( i != 0 ) error( "rule not terminated before %%%% or EOF" );
                    152:                        settab();
                    153:                        finact();
                    154:                        /* copy the programs which follow the rules */
                    155:                        if( t == MARK ){
                    156:                                while (( c=fgetc( cin)) != EOF ) fputc(c,cout);
                    157:                                }
                    158:                        return;
                    159:        case PREC:      
                    160:                if( i==0 ) error( "%%prec must appear inside rule" );
                    161:                if( gettok()!=IDENTIFIER)error("illegal %%prec syntax" );
                    162:                j=chfind(2);
                    163:                if(j>=NTBASE)error("nonterminal %s illegal after %%prec", nontrst[j-NTBASE].name);
                    164:                levprd[nprod]=trmlev[j];
                    165:                continue;
                    166:        case LCURLY:    
                    167:                if( i!=0 ) error( "%%{ appears within a rule" );
                    168:                cpycode();
                    169:                continue;
                    170:        default: error( "syntax error, input %d", t  );
                    171:        }
                    172: }
                    173: 
                    174: finact(){
                    175:        /* finish action routine */
                    176:        register i;
                    177: 
                    178:        if( rflag ){
                    179: 
                    180:                fprintf( cout ,  "\n1000 goto(" );
                    181:                for( i=1; i<nprod; ++i ){
                    182:                        fprintf( cout ,  "%d,", (levprd[i]&04)==0?999:i );
                    183:                        }
                    184:                fprintf( cout ,  "999),yyprdn\n" );
                    185:                fprintf( cout ,  "999 return\nend\n" );
                    186:                fprintf( cout ,  "define YYERRCODE %d\n", trmset[2].value );
                    187:                }
                    188:        else {
                    189:                fprintf( cout ,  "\n}\n}\n" );
                    190:                fprintf( cout ,  "int yyerrval %d;\n", trmset[2].value );
                    191:                }
                    192:        }
                    193: defin(t) {
                    194: /*     define ctokn to be a terminal if t=0
                    195:        or a nonterminal if t=1         */
                    196:        char *cp,*p;
                    197:        int c;
                    198: 
                    199: 
                    200:         if (t) {
                    201:           if( ++nnonter >= ntlim ) error("too many nonterminals, limit %d",ntlim);
                    202:          nontrst[nnonter].name = ctokn;
                    203:          return( NTBASE + nnonter );
                    204:           }
                    205:         else {
                    206:           if( ++nterms >= tlim ) error("too many terminals, limit %d",tlim );
                    207:           trmset[nterms].name = ctokn;
                    208:        if( ctokn[0]==' ' && ctokn[2]=='\0' ) /* single character literal */
                    209:                trmset[nterms].value = ctokn[1];
                    210:        else if ( ctokn[0]==' ' && ctokn[1]=='\\' ) { /* escape sequence */
                    211:                if( ctokn[3] == '\0' ){ /* single character escape sequence */
                    212:                        switch ( ctokn[2] ){
                    213:                                 /* character which is escaped */
                    214:                        case 'n': trmset[nterms].value = '\n'; break;
                    215:                        case 'r': trmset[nterms].value = '\r'; break;
                    216:                        case 'b': trmset[nterms].value = '\b'; break;
                    217:                        case 't': trmset[nterms].value = '\t'; break;
                    218:                        case '\'': trmset[nterms].value = '\''; break;
                    219:                        case '"': trmset[nterms].value = '"'; break;
                    220:                        case '\\': trmset[nterms].value = '\\'; break;
                    221:                        default: error( "invalid escape" );
                    222:                                }
                    223:                        }
                    224:                else if( ctokn[2] <= '7' && ctokn[2]>='0' ){ /* \nnn sequence */
                    225:                        if( ctokn[3]<'0' || ctokn[3] > '7' || ctokn[4]<'0' ||
                    226:                                ctokn[4]>'7' || ctokn[5] != '\0' ) error("illegal \\nnn construction" );
                    227:                        trmset[nterms].value = 64*(ctokn[2]-'0')+8*(ctokn[3]-'0')+ctokn[4]-'0';
                    228:                        if( trmset[nterms].value == 0 ) error( "'\\000' is illegal" );
                    229:                        }
                    230:                }
                    231:        else {
                    232:                trmset[nterms].value = extval++;
                    233: 
                    234:                }
                    235:        trmlev[nterms] = 0;
                    236:        return( nterms );
                    237:           }
                    238: }
                    239: 
                    240: defout(){ /* write out the defines (at the end of the declaration section) */
                    241: 
                    242:        _REGISTER int i, c;
                    243:        _REGISTER char *cp;
                    244: 
                    245:        for( i=ndefout; i<=nterms; ++i ){
                    246: 
                    247:                cp = trmset[i].name;
                    248:                if( *cp == ' ' ) ++cp;  /* literals */
                    249: 
                    250:                for( ; (c= *cp)!='\0'; ++cp ){
                    251: 
                    252:                        if( c>='a' && c<='z' ||
                    253:                            c>='A' && c<='Z' ||
                    254:                            c>='0' && c<='9' ||
                    255:                            c=='_' )  ; /* VOID */
                    256:                        else goto nodef;
                    257:                        }
                    258: 
                    259:                /* define it */
                    260: 
                    261:                fprintf( cout ,  "%c define %s %d\n", rflag?' ':'#', trmset[i].name, trmset[i].value );
                    262: 
                    263:        nodef:  ;
                    264:                }
                    265: 
                    266:        ndefout = nterms+1;
                    267: 
                    268:        }
                    269: 
                    270: chstash( c ){
                    271:   /* put character away into cnames */
                    272:   if( cnamp >= &cnames[cnamsz] ) error("too many characters in id's and literals" );
                    273:   else *cnamp++ = c;
                    274:   }
                    275: 
                    276: int gettok() {
                    277:        int j, base;
                    278:        static int peekline; /* number of '\n' seen in lookahead */
                    279:        auto int c, match, reserve;
                    280: 
                    281: begin:
                    282:        reserve = 0;
                    283:         if( peekc>=0 ) {
                    284:                c = peekc;
                    285:                lineno += peekline;
                    286:                peekc = -1;
                    287:                peekline = 0;
                    288:                }
                    289:         else c = fgetc( cin);
                    290:         while( c==' ' || c=='\n' || c=='\t' || c == '\014'){
                    291:           if( c == '\n' ) ++lineno;
                    292:           c=fgetc( cin);
                    293:           }
                    294:        if (c=='/')
                    295:                {if (fgetc( cin)!='*')error("illegal /");
                    296:                c=fgetc( cin);
                    297:                while(c != EOF) {
                    298:                        if( c == '\n' ) ++lineno;
                    299:                        if (c=='*')
                    300:                                {if((c=fgetc( cin))=='/')break;}
                    301:                        else c=fgetc( cin);}
                    302:                if (!c) return(0);
                    303:                goto begin;}
                    304:        j=0;
                    305:        switch(c){
                    306:        case '"':       
                    307:        case '\'':      match = c;
                    308:                        ctokn = cnamp;
                    309:                        chstash( ' ' );
                    310:                        while(1){
                    311:                                c = fgetc( cin);
                    312:                                if( c == '\n' || c == '\0' )
                    313:                                        error("illegal or missing ' or \"");
                    314:                                if( c == '\\' ){
                    315:                                        c = fgetc( cin);
                    316:                                        chstash( '\\' );
                    317:                                        }
                    318:                                else if( c == match ) break;
                    319:                                chstash( c );
                    320:                                }
                    321:                        break;
                    322:        case '%':
                    323:        case '\\':      switch(c=fgetc( cin))
                    324:                {case '0':      return(TERM);
                    325:                case '<':       return(LEFT);
                    326:                case '2':       return(BINARY);
                    327:                case '>':       return(RIGHT);
                    328:                case '%':
                    329:                case '\\':      return(MARK);
                    330:                case '=':       return(PREC);
                    331:                case '{':       return(LCURLY);
                    332:                default:        reserve = 1;
                    333:                }
                    334:        default:        if( c >= '0' && c <= '9' ){ /* number */
                    335:                                numbval = c-'0' ;
                    336:                                base = (c=='0') ? 8 : 10 ;
                    337:                                for( c=fgetc( cin); c>='0' && c<='9'; c=fgetc( cin) ){
                    338:                                        numbval = numbval*base + c - '0';
                    339:                                        }
                    340:                                peekc = c;
                    341:                                return(NUMBER);
                    342:                                }
                    343:                        else if( (c>='a'&&c<='z')||(c>='A'&&c<='Z')||c=='_'||c=='.'||c=='$'){
                    344:                                ctokn = cnamp;
                    345:                                while(  (c>='a'&&c<='z') ||
                    346:                                        (c>='A'&&c<='Z') ||
                    347:                                        (c>='0'&&c<='9') ||
                    348:                                        c=='_' || c=='.' || c=='$' ) {
                    349:                                        chstash( c );
                    350:                                        if( peekc>=0 ) { c = peekc; peekc = -1; }
                    351:                                        else c = fgetc( cin);
                    352:                                        }
                    353:                                }
                    354:                        else return(c);
                    355: 
                    356:                        peekc=c;
                    357:                        }
                    358:        chstash( '\0' );
                    359: 
                    360:        if( reserve ){ /* find a reserved word */
                    361:                if( compare("term")) return( TERM );
                    362:                if( compare("TERM")) return( TERM );
                    363:                if( compare("token")) return( TERM );
                    364:                if( compare("TOKEN")) return( TERM );
                    365:                if( compare("left")) return( LEFT );
                    366:                if( compare("LEFT")) return( LEFT );
                    367:                if( compare("nonassoc")) return( BINARY );
                    368:                if( compare("NONASSOC")) return( BINARY );
                    369:                if( compare("binary")) return( BINARY );
                    370:                if( compare("BINARY")) return( BINARY );
                    371:                if( compare("right")) return( RIGHT );
                    372:                if( compare("RIGHT")) return( RIGHT );
                    373:                if( compare("prec")) return( PREC );
                    374:                if( compare("PREC")) return( PREC );
                    375:                error("invalid escape, or illegal reserved word: %s", ctokn );
                    376:                }
                    377: 
                    378:        /* look ahead to distinguish IDENTIFIER from C_IDENTIFIER */
                    379: 
                    380:   look:
                    381:        while( peekc==' ' || peekc=='\t' || peekc == '\n' || peekc == '\014' )
                    382:        {
                    383:                if( peekc == '\n' ) ++peekline;
                    384:                peekc = fgetc( cin);
                    385:        }
                    386: 
                    387:        if( peekc != ':' ) return( IDENTIFIER );
                    388:        peekc = -1;
                    389:        lineno += peekline;
                    390:        peekline = 0;
                    391:        return( C_IDENTIFIER );
                    392: }
                    393: chfind(t)
                    394: 
                    395: {      int i,j;
                    396: 
                    397:        if (ctokn[0]==' ')t=0;
                    398:        for(i=1;i<=nterms;i++)
                    399:                if(compare(trmset[i].name)){
                    400:                        cnamp = ctokn;
                    401:                        return( i );
                    402:                        }
                    403:        for(i=1;i<=nnonter;i++)
                    404:                if(compare(nontrst[i].name)) {
                    405:                        cnamp = ctokn;
                    406:                        return( i+NTBASE );
                    407:                        }
                    408:        /* cannot find name */
                    409:        if( t>1 && ctokn[0] != ' ' )
                    410:                error( "%s should have been defined earlier", ctokn );
                    411:        return( defin( t ) );
                    412:        }
                    413: 
                    414: cpycode(){ /* copies code between \{ and \} */
                    415: 
                    416:        int c;
                    417:        c = fgetc( cin);
                    418:        if( c == '\n' ) {
                    419:                c = fgetc( cin);
                    420:                lineno++;
                    421:                }
                    422:        while( c != EOF ){
                    423:                if( c=='\\' )
                    424:                        if( (c=fgetc( cin)) == '}' ) return;
                    425:                        else fputc('\\',cout);
                    426:                if( c=='%' )
                    427:                        if( (c=fgetc( cin)) == '}' ) return;
                    428:                        else fputc('%',cout);
                    429:                fputc( c, cout );
                    430:                if( c == '\n' ) ++lineno;
                    431:                c = fgetc( cin);
                    432:                }
                    433:        error("eof before %%}");
                    434:        }
                    435: 
                    436: cpyact(){ /* copy C action to the next ; or closing } */
                    437:        int brac, c, match, *i, j, s;
                    438: 
                    439:        brac = 0;
                    440: 
                    441: loop:
                    442:        c = fgetc( cin);
                    443: swt:
                    444:        switch( c ){
                    445: 
                    446: case ';':
                    447:                if( brac == 0 ){
                    448:                        fputc( c, cout );
                    449:                        return;
                    450:                        }
                    451:                goto lcopy;
                    452: 
                    453: case '{':
                    454:                brac++;
                    455:                goto lcopy;
                    456: 
                    457: case '$':
                    458:                s = 1;
                    459:                c = fgetc( cin);
                    460:                if( c == '$' ){
                    461:                        fprintf( cout , "yyval");
                    462:                        goto loop;
                    463:                        }
                    464:                if( c == '-' ){
                    465:                        s = -s;
                    466:                        c = fgetc( cin);
                    467:                        }
                    468:                if( c>='0' && c <= '9' ){
                    469:                        j=0;
                    470:                        while( c>='0' && c<= '9' ){
                    471:                                j= j*10+c-'0';
                    472:                                c = fgetc( cin);
                    473:                                }
                    474:                        if( rflag ) fprintf( cout ,  "yyvalv(yypv%c%d)", s==1?'+':'-', j );
                    475:                        else fprintf( cout , "yypv[%d]", s*j );
                    476:                        goto swt;
                    477:                        }
                    478:                fputc( '$' , cout);
                    479:                if( s<0 ) fputc('-', cout);
                    480:                goto swt;
                    481: 
                    482: case '}':
                    483:                brac--;
                    484:                if( brac == 0 ){
                    485:                        fputc( c , cout);
                    486:                        return;
                    487:                        }
                    488:                goto lcopy;
                    489: 
                    490: case '/':      /* look for comments */
                    491:                fputc( c ,cout);
                    492:                c = fgetc( cin);
                    493:                if( c != '*' ) goto swt;
                    494: 
                    495:                /* it really is a comment */
                    496: 
                    497:                fputc( c , cout);
                    498:                while( (c=fgetc( cin)) != EOF ){
                    499:                        if( c=='*' ){
                    500:                                fputc( c , cout);
                    501:                                if( (c=fgetc( cin)) == '/' ) goto lcopy;
                    502:                                }
                    503:                        fputc( c , cout);
                    504:                        }
                    505:                error( "EOF inside comment" );
                    506: 
                    507: case '\'':     /* character constant */
                    508:                match = '\'';
                    509:                goto string;
                    510: 
                    511: case '"':      /* character string */
                    512:                match = '"';
                    513: 
                    514:        string:
                    515: 
                    516:                fputc( c , cout);
                    517:                while( (c=fgetc( cin)) != EOF ){
                    518: 
                    519:                        if( c=='\\' ){
                    520:                                fputc( c , cout);
                    521:                                c=fgetc( cin);
                    522:                                }
                    523:                        else if( c==match ) goto lcopy;
                    524:                        fputc( c , cout);
                    525:                        }
                    526:                error( "EOF in string or character constant" );
                    527: 
                    528: case '\0':
                    529:                error("action does not terminate");
                    530: case '\n':     ++lineno;
                    531:                goto lcopy;
                    532: 
                    533:                }
                    534: 
                    535: lcopy:
                    536:        fputc( c , cout);
                    537:        goto loop;
                    538:        }

unix.superglobalmegacorp.com

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