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

unix.superglobalmegacorp.com

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