Annotation of researchv10no/cmd/picasso/y2.c, revision 1.1.1.1

1.1       root        1: #ident "@(#)/usr/src/cmd/yacc/y2.c     1.3 6/6/85 02:44:35 - Amdahl/UTS"
                      2: /*     @(#)y2.c        1.8     */
                      3: # include "dextern"
                      4: # define IDENTIFIER 257
                      5: # define MARK 258
                      6: # define TERM 259
                      7: # define LEFT 260
                      8: # define RIGHT 261
                      9: # define BINARY 262
                     10: # define PREC 263
                     11: # define LCURLY 264
                     12: # define C_IDENTIFIER 265  /* name followed by colon */
                     13: # define NUMBER 266
                     14: # define START 267
                     15: # define TYPEDEF 268
                     16: # define TYPENAME 269
                     17: # define UNION 270
                     18: # define ENDFILE 0
                     19: 
                     20:        /* communication variables between various I/O routines */
                     21: 
                     22: char *infile;  /* input file name */
                     23: int numbval;   /* value of an input number */
                     24: char tokname[NAMESIZE];        /* input token name */
                     25: 
                     26:        /* storage of names */
                     27: 
                     28: char cnames[CNAMSZ];   /* place where token and nonterminal names are stored */
                     29: int cnamsz = CNAMSZ;   /* size of cnames */
                     30: char * cnamp = cnames; /* place where next name is to be put in */
                     31: int ndefout = 3;  /* number of defined symbols output */
                     32: 
                     33:        /* storage of types */
                     34: int ntypes;    /* number of types defined */
                     35: char * typeset[NTYPES];        /* pointers to type tags */
                     36: 
                     37:        /* symbol tables for tokens and nonterminals */
                     38: 
                     39: int ntokens = 0;
                     40: struct toksymb tokset[NTERMS];
                     41: int toklev[NTERMS];
                     42: int nnonter = -1;
                     43: struct ntsymb nontrst[NNONTERM];
                     44: int start;     /* start symbol */
                     45: 
                     46:        /* assigned token type values */
                     47: int extval = 0;
                     48: 
                     49:        /* input and output file descriptors */
                     50: 
                     51: FILE * finput;         /* yacc input file */
                     52: FILE * faction;                /* file for saving actions */
                     53: FILE * fdefine;                /* file for # defines */
                     54: FILE * ftable;         /* y.tab.c file */
                     55: FILE * ftemp;          /* tempfile to pass 2 */
                     56: FILE * fdebug;         /* where the strings for debugging are stored */
                     57: FILE * foutput;                /* y.output file */
                     58: 
                     59:        /* storage for grammar rules */
                     60: 
                     61: int mem0[MEMSIZE] ; /* production storage */
                     62: int *mem = mem0;
                     63: int nprod= 1;  /* number of productions */
                     64: int *prdptr[NPROD];    /* pointers to descriptions of productions */
                     65: int levprd[NPROD] ;    /* precedence levels for the productions */
                     66: char had_act[NPROD];   /* set to 1 if the reduction has action code to do */
                     67: 
                     68: int gen_lines = 1;     /* flag for generating the # line's default is yes */
                     69: int gen_testing = 0;   /* flag for whether to include runtime debugging */
                     70: 
                     71: setup(argc,argv) int argc; char *argv[];
                     72: {      int i,j,lev,t, ty;
                     73:        int c;
                     74:        int *p;
                     75:        char actname[8];
                     76: 
                     77:        foutput = NULL;
                     78:        fdefine = NULL;
                     79:        i = 1;
                     80:        while( argc >= 2  && argv[1][0] == '-' ) {
                     81:                while( *++(argv[1]) ){
                     82:                        switch( *argv[1] ){
                     83:                        case 'v':
                     84:                        case 'V':
                     85:                                foutput = fopen(FILEU, "w" );
                     86:                                if( foutput == NULL ) error( "cannot open y.output" );
                     87:                                continue;
                     88:                        case 'D':
                     89:                        case 'd':
                     90:                                fdefine = fopen( FILED, "w" );
                     91:                                if ( fdefine == NULL ) error( "cannot open y.tab.h" );
                     92:                                continue;
                     93:                        case 'l':
                     94:                        case 'L':
                     95:                                gen_lines = !gen_lines;
                     96:                        case 't':
                     97:                        case 'T':
                     98:                                gen_testing = !gen_testing;
                     99:                                continue;
                    100:                        case 'o':
                    101:                        case 'O':
                    102:                                fprintf( stderr, "`o' flag now default in yacc\n" );
                    103:                                continue;
                    104: 
                    105:                        case 'r':
                    106:                        case 'R':
                    107:                                error( "Ratfor Yacc is dead: sorry...\n" );
                    108: 
                    109:                        default:
                    110:                                error( "illegal option: %c", *argv[1]);
                    111:                                }
                    112:                        }
                    113:                argv++;
                    114:                argc--;
                    115:                }
                    116: 
                    117:        fdebug = fopen( DEBUGNAME, "w" );
                    118:        if ( fdebug == NULL ) error( "cannot open yacc.debug" );
                    119:        ftable = fopen( OFILE, "w" );
                    120:        if( ftable == NULL ) error( "cannot open y.tab.c" );
                    121: 
                    122:        ftemp = fopen( TEMPNAME, "w" );
                    123:        faction = fopen( ACTNAME, "w" );
                    124:        if( ftemp==NULL || faction==NULL ) error( "cannot open temp file" );
                    125: 
                    126:        if( argc < 2 || ((finput=fopen( infile=argv[1], "r" )) == NULL ) ){
                    127:                error( "cannot open input file" );
                    128:                }
                    129: 
                    130:        cnamp = cnames;
                    131:        defin(0,"$end");
                    132:        extval = 0400;
                    133:        defin(0,"error");
                    134:        defin(1,"$accept");
                    135:        mem=mem0;
                    136:        lev = 0;
                    137:        ty = 0;
                    138:        i=0;
                    139:        beg_debug();    /* initialize fdebug file */
                    140: 
                    141:        /* sorry -- no yacc parser here.....
                    142:                we must bootstrap somehow... */
                    143: 
                    144:        for( t=gettok();  t!=MARK && t!= ENDFILE; ){
                    145:                switch( t ){
                    146: 
                    147:                case ';':
                    148:                        t = gettok();
                    149:                        break;
                    150: 
                    151:                case START:
                    152:                        if( (t=gettok()) != IDENTIFIER ){
                    153:                                error( "bad %%start construction" );
                    154:                                }
                    155:                        start = chfind(1,tokname);
                    156:                        t = gettok();
                    157:                        continue;
                    158: 
                    159:                case TYPEDEF:
                    160:                        if( (t=gettok()) != TYPENAME ) error( "bad syntax in %%type" );
                    161:                        ty = numbval;
                    162:                        for(;;){
                    163:                                t = gettok();
                    164:                                switch( t ){
                    165: 
                    166:                                case IDENTIFIER:
                    167:                                        if( (t=chfind( 1, tokname ) ) < NTBASE ) {
                    168:                                                j = TYPE( toklev[t] );
                    169:                                                if( j!= 0 && j != ty ){
                    170:                                                        error( "type redeclaration of token %s",
                    171:                                                                tokset[t].name );
                    172:                                                        }
                    173:                                                else SETTYPE( toklev[t],ty);
                    174:                                                }
                    175:                                        else {
                    176:                                                j = nontrst[t-NTBASE].tvalue;
                    177:                                                if( j != 0 && j != ty ){
                    178:                                                        error( "type redeclaration of nonterminal %s",
                    179:                                                                nontrst[t-NTBASE].name );
                    180:                                                        }
                    181:                                                else nontrst[t-NTBASE].tvalue = ty;
                    182:                                                }
                    183:                                case ',':
                    184:                                        continue;
                    185: 
                    186:                                case ';':
                    187:                                        t = gettok();
                    188:                                        break;
                    189:                                default:
                    190:                                        break;
                    191:                                        }
                    192:                                break;
                    193:                                }
                    194:                        continue;
                    195: 
                    196:                case UNION:
                    197:                        /* copy the union declaration to the output */
                    198:                        cpyunion();
                    199:                        t = gettok();
                    200:                        continue;
                    201: 
                    202:                case LEFT:
                    203:                case BINARY:
                    204:                case RIGHT:
                    205:                        ++i;
                    206:                case TERM:
                    207:                        lev = t-TERM;  /* nonzero means new prec. and assoc. */
                    208:                        ty = 0;
                    209: 
                    210:                        /* get identifiers so defined */
                    211: 
                    212:                        t = gettok();
                    213:                        if( t == TYPENAME ){ /* there is a type defined */
                    214:                                ty = numbval;
                    215:                                t = gettok();
                    216:                                }
                    217: 
                    218:                        for(;;) {
                    219:                                switch( t ){
                    220: 
                    221:                                case ',':
                    222:                                        t = gettok();
                    223:                                        continue;
                    224: 
                    225:                                case ';':
                    226:                                        break;
                    227: 
                    228:                                case IDENTIFIER:
                    229:                                        j = chfind(0,tokname);
                    230:                                        if( lev ){
                    231:                                                if( ASSOC(toklev[j]) ) error( "redeclaration of precedence of %s", tokname );
                    232:                                                SETASC(toklev[j],lev);
                    233:                                                SETPLEV(toklev[j],i);
                    234:                                                }
                    235:                                        if( ty ){
                    236:                                                if( TYPE(toklev[j]) ) error( "redeclaration of type of %s", tokname );
                    237:                                                SETTYPE(toklev[j],ty);
                    238:                                                }
                    239:                                        if( (t=gettok()) == NUMBER ){
                    240:                                                tokset[j].value = numbval;
                    241:                                                if( j < ndefout && j>2 ){
                    242:                                                        error( "please define type number of %s earlier",
                    243:                                                                tokset[j].name );
                    244:                                                        }
                    245:                                                t=gettok();
                    246:                                                }
                    247:                                        continue;
                    248: 
                    249:                                        }
                    250: 
                    251:                                break;
                    252:                                }
                    253: 
                    254:                        continue;
                    255: 
                    256:                case LCURLY:
                    257:                        defout();
                    258:                        cpycode();
                    259:                        t = gettok();
                    260:                        continue;
                    261: 
                    262:                default:
                    263:                        error( "syntax error" );
                    264: 
                    265:                        }
                    266: 
                    267:                }
                    268: 
                    269:        if( t == ENDFILE ){
                    270:                error( "unexpected EOF before %%" );
                    271:                }
                    272: 
                    273:        /* t is MARK */
                    274: 
                    275:        defout();
                    276:        end_toks();     /* all tokens dumped - get ready for reductions */
                    277: 
                    278:        fprintf( ftable,  "#define yyclearin yychar = -1\n" );
                    279:        fprintf( ftable,  "#define yyerrok yyerrflag = 0\n" );
                    280:        fprintf( ftable,  "extern int yychar;\nextern int yyerrflag;\n" );
                    281:        fprintf( ftable,  "#ifndef YYMAXDEPTH\n#define YYMAXDEPTH 150\n#endif\n" );
                    282:        if( !ntypes ) fprintf( ftable,  "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n" );
                    283:        fprintf( ftable,  "YYSTYPE yylval, yyval;\n" );
                    284:        fprintf( ftable,  "typedef int yytabelem;\n" );
                    285: 
                    286:        prdptr[0]=mem;
                    287:        /* added production */
                    288:        *mem++ = NTBASE;
                    289:        *mem++ = start;  /* if start is 0, we will overwrite with the lhs of the first rule */
                    290:        *mem++ = 1;
                    291:        *mem++ = 0;
                    292:        prdptr[1]=mem;
                    293: 
                    294:        while( (t=gettok()) == LCURLY ) cpycode();
                    295: 
                    296:        if( t != C_IDENTIFIER ) error( "bad syntax on first rule" );
                    297: 
                    298:        if( !start ) prdptr[0][1] = chfind(1,tokname);
                    299: 
                    300:        /* read rules */
                    301: 
                    302:        while( t!=MARK && t!=ENDFILE ){
                    303: 
                    304:                /* process a rule */
                    305: 
                    306:                if( t == '|' ){
                    307:                        rhsfill( (char *) 0 );  /* restart fill of rhs */
                    308:                        *mem++ = *prdptr[nprod-1];
                    309:                        }
                    310:                else if( t == C_IDENTIFIER ){
                    311:                        *mem = chfind(1,tokname);
                    312:                        if( *mem < NTBASE ) error( "token illegal on LHS of grammar rule" );
                    313:                        ++mem;
                    314:                        lhsfill( tokname );     /* new rule: restart strings */
                    315:                        }
                    316:                else error( "illegal rule: missing semicolon or | ?" );
                    317: 
                    318:                /* read rule body */
                    319: 
                    320: 
                    321:                t = gettok();
                    322:        more_rule:
                    323:                while( t == IDENTIFIER ) {
                    324:                        *mem = chfind(1,tokname);
                    325:                        if( *mem<NTBASE ) levprd[nprod] = toklev[*mem];
                    326:                        ++mem;
                    327:                        rhsfill( tokname );     /* add to rhs string */
                    328:                        t = gettok();
                    329:                        }
                    330: 
                    331: 
                    332:                if( t == PREC ){
                    333:                        if( gettok()!=IDENTIFIER) error( "illegal %%prec syntax" );
                    334:                        j = chfind(2,tokname);
                    335:                        if( j>=NTBASE)error("nonterminal %s illegal after %%prec", nontrst[j-NTBASE].name);
                    336:                        levprd[nprod]=toklev[j];
                    337:                        t = gettok();
                    338:                        }
                    339: 
                    340:                if( t == '=' ){
                    341:                        had_act[nprod] = 1;
                    342:                        levprd[nprod] |= ACTFLAG;
                    343:                        fprintf( faction, "\ncase %d:", nprod );
                    344:                        cpyact( mem-prdptr[nprod]-1 );
                    345:                        fprintf( faction, " break;" );
                    346:                        if( (t=gettok()) == IDENTIFIER ){
                    347:                                /* action within rule... */
                    348: 
                    349:                                lrprnt();               /* dump lhs, rhs */
                    350:                                sprintf( actname, "$$%d", nprod );
                    351:                                j = chfind(1,actname);  /* make it a nonterminal */
                    352: 
                    353:                                /* the current rule will become rule number nprod+1 */
                    354:                                /* move the contents down, and make room for the null */
                    355: 
                    356:                                for( p=mem; p>=prdptr[nprod]; --p ) p[2] = *p;
                    357:                                mem += 2;
                    358: 
                    359:                                /* enter null production for action */
                    360: 
                    361:                                p = prdptr[nprod];
                    362: 
                    363:                                *p++ = j;
                    364:                                *p++ = -nprod;
                    365: 
                    366:                                /* update the production information */
                    367: 
                    368:                                levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
                    369:                                levprd[nprod] = ACTFLAG;
                    370: 
                    371:                                if( ++nprod >= NPROD ) error( "more than %d rules", NPROD );
                    372:                                prdptr[nprod] = p;
                    373: 
                    374:                                /* make the action appear in the original rule */
                    375:                                *mem++ = j;
                    376: 
                    377:                                /* get some more of the rule */
                    378: 
                    379:                                goto more_rule;
                    380:                                }
                    381: 
                    382:                        }
                    383: 
                    384:                while( t == ';' ) t = gettok();
                    385: 
                    386:                *mem++ = -nprod;
                    387: 
                    388:                /* check that default action is reasonable */
                    389: 
                    390:                if( ntypes && !(levprd[nprod]&ACTFLAG) && nontrst[*prdptr[nprod]-NTBASE].tvalue ){
                    391:                        /* no explicit action, LHS has value */
                    392:                        register tempty;
                    393:                        tempty = prdptr[nprod][1];
                    394:                        if( tempty < 0 ) error( "must return a value, since LHS has a type" );
                    395:                        else if( tempty >= NTBASE ) tempty = nontrst[tempty-NTBASE].tvalue;
                    396:                        else tempty = TYPE( toklev[tempty] );
                    397:                        if( tempty != nontrst[*prdptr[nprod]-NTBASE].tvalue ){
                    398:                                error( "default action causes potential type clash" );
                    399:                                }
                    400:                        }
                    401: 
                    402:                if( ++nprod >= NPROD ) error( "more than %d rules", NPROD );
                    403:                prdptr[nprod] = mem;
                    404:                levprd[nprod]=0;
                    405: 
                    406:                }
                    407: 
                    408:        /* end of all rules */
                    409: 
                    410:        end_debug();            /* finish fdebug file's input */
                    411:        finact();
                    412:        if( t == MARK ){
                    413:                if ( gen_lines )
                    414:                        fprintf( ftable, "\n# line %d \"%s\"\n",
                    415:                                lineno, infile );
                    416:                while( (c=getc(finput)) != EOF ) putc( c, ftable );
                    417:                }
                    418:        fclose( finput );
                    419:        }
                    420: 
                    421: finact(){
                    422:        /* finish action routine */
                    423: 
                    424:        fclose(faction);
                    425: 
                    426:        fprintf( ftable, "# define YYERRCODE %d\n", tokset[2].value );
                    427: 
                    428:        }
                    429: 
                    430: defin( t, s ) register char  *s; {
                    431: /*     define s to be a terminal if t=0
                    432:        or a nonterminal if t=1         */
                    433: 
                    434:        register val;
                    435: 
                    436:        if (t) {
                    437:                if( ++nnonter >= NNONTERM ) error("too many nonterminals, limit %d",NNONTERM);
                    438:                nontrst[nnonter].name = cstash(s);
                    439:                return( NTBASE + nnonter );
                    440:                }
                    441:        /* must be a token */
                    442:        if( ++ntokens >= NTERMS ) error("too many terminals, limit %d",NTERMS );
                    443:        tokset[ntokens].name = cstash(s);
                    444: 
                    445:        /* establish value for token */
                    446: 
                    447:        if( s[0]==' ' && s[2]=='\0' ) /* single character literal */
                    448:                val = s[1];
                    449:        else if ( s[0]==' ' && s[1]=='\\' ) { /* escape sequence */
                    450:                if( s[3] == '\0' ){ /* single character escape sequence */
                    451:                        switch ( s[2] ){
                    452:                                         /* character which is escaped */
                    453:                        case 'n': val = '\n'; break;
                    454:                        case 'r': val = '\r'; break;
                    455:                        case 'b': val = '\b'; break;
                    456:                        case 't': val = '\t'; break;
                    457:                        case 'f': val = '\f'; break;
                    458:                        case '\'': val = '\''; break;
                    459:                        case '"': val = '"'; break;
                    460:                        case '\\': val = '\\'; break;
                    461:                        default: error( "invalid escape" );
                    462:                                }
                    463:                        }
                    464:                else if( s[2] <= '7' && s[2]>='0' ){ /* \nnn sequence */
                    465:                        if( s[3]<'0' || s[3] > '7' || s[4]<'0' ||
                    466:                                s[4]>'7' || s[5] != '\0' ) error("illegal \\nnn construction" );
                    467:                        val = 64*s[2] + 8*s[3] + s[4] - 73*'0';
                    468:                        if( val == 0 ) error( "'\\000' is illegal" );
                    469:                        }
                    470:                }
                    471:        else {
                    472:                val = extval++;
                    473:                }
                    474:        tokset[ntokens].value = val;
                    475:        toklev[ntokens] = 0;
                    476:        return( ntokens );
                    477:        }
                    478: 
                    479: defout(){ /* write out the defines (at the end of the declaration section) */
                    480: 
                    481:        register int i, c;
                    482:        register char *cp;
                    483: 
                    484:        for( i=ndefout; i<=ntokens; ++i ){
                    485: 
                    486:                cp = tokset[i].name;
                    487:                if( *cp == ' ' )        /* literals */
                    488:                {
                    489:                        fprintf( fdebug, "\t\"%s\",\t%d,\n",
                    490:                                tokset[i].name + 1, tokset[i].value );
                    491:                        cp++; /* in my opinion, this should be continue */
                    492:                }
                    493: 
                    494:                for( ; (c= *cp)!='\0'; ++cp ){
                    495: 
                    496:                        if( islower(c) || isupper(c) || isdigit(c) || c=='_' );  /* VOID */
                    497:                        else goto nodef;
                    498:                        }
                    499: 
                    500:                if ( tokset[i].name[0] != ' ' )
                    501:                        fprintf( fdebug, "\t\"%s\",\t%d,\n",
                    502:                                tokset[i].name, tokset[i].value );
                    503:                fprintf( ftable, "# define %s %d\n", tokset[i].name, tokset[i].value );
                    504:                if( fdefine != NULL ) fprintf( fdefine, "# define %s %d\n", tokset[i].name, tokset[i].value );
                    505: 
                    506:        nodef:  ;
                    507:                }
                    508: 
                    509:        ndefout = ntokens+1;
                    510: 
                    511:        }
                    512: 
                    513: char *
                    514: cstash( s ) register char *s; {
                    515:        char *temp;
                    516: 
                    517:        temp = cnamp;
                    518:        do {
                    519:                if( cnamp >= &cnames[cnamsz] ) error("too many characters in id's and literals" );
                    520:                else *cnamp++ = *s;
                    521:                }  while ( *s++ );
                    522:        return( temp );
                    523:        }
                    524: 
                    525: gettok() {
                    526:        register i, base;
                    527:        static int peekline; /* number of '\n' seen in lookahead */
                    528:        register c, match, reserve;
                    529: 
                    530: begin:
                    531:        reserve = 0;
                    532:        lineno += peekline;
                    533:        peekline = 0;
                    534:        c = getc(finput);
                    535:        while( c==' ' || c=='\n' || c=='\t' || c=='\f' ){
                    536:                if( c == '\n' ) ++lineno;
                    537:                c=getc(finput);
                    538:                }
                    539:        if( c == '/' ){ /* skip comment */
                    540:                lineno += skipcom();
                    541:                goto begin;
                    542:                }
                    543: 
                    544:        switch(c){
                    545: 
                    546:        case EOF:
                    547:                return(ENDFILE);
                    548:        case '{':
                    549:                ungetc( c, finput );
                    550:                return( '=' );  /* action ... */
                    551:        case '<':  /* get, and look up, a type name (union member name) */
                    552:                i = 0;
                    553:                while( (c=getc(finput)) != '>' && c>=0 && c!= '\n' ){
                    554:                        tokname[i] = c;
                    555:                        if( ++i >= NAMESIZE ) --i;
                    556:                        }
                    557:                if( c != '>' ) error( "unterminated < ... > clause" );
                    558:                tokname[i] = '\0';
                    559:                for( i=1; i<=ntypes; ++i ){
                    560:                        if( !strcmp( typeset[i], tokname ) ){
                    561:                                numbval = i;
                    562:                                return( TYPENAME );
                    563:                                }
                    564:                        }
                    565:                typeset[numbval = ++ntypes] = cstash( tokname );
                    566:                return( TYPENAME );
                    567: 
                    568:        case '"':       
                    569:        case '\'':
                    570:                match = c;
                    571:                tokname[0] = ' ';
                    572:                i = 1;
                    573:                for(;;){
                    574:                        c = getc(finput);
                    575:                        if( c == '\n' || c == EOF )
                    576:                                error("illegal or missing ' or \"" );
                    577:                        if( c == '\\' ){
                    578:                                c = getc(finput);
                    579:                                tokname[i] = '\\';
                    580:                                if( ++i >= NAMESIZE ) --i;
                    581:                                }
                    582:                        else if( c == match ) break;
                    583:                        tokname[i] = c;
                    584:                        if( ++i >= NAMESIZE ) --i;
                    585:                        }
                    586:                break;
                    587: 
                    588:        case '%':
                    589:        case '\\':
                    590: 
                    591:                switch(c=getc(finput)) {
                    592: 
                    593:                case '0':       return(TERM);
                    594:                case '<':       return(LEFT);
                    595:                case '2':       return(BINARY);
                    596:                case '>':       return(RIGHT);
                    597:                case '%':
                    598:                case '\\':      return(MARK);
                    599:                case '=':       return(PREC);
                    600:                case '{':       return(LCURLY);
                    601:                default:        reserve = 1;
                    602:                        }
                    603: 
                    604:        default:
                    605: 
                    606:                if( isdigit(c) ){ /* number */
                    607:                        numbval = c-'0' ;
                    608:                        base = (c=='0') ? 8 : 10 ;
                    609:                        for( c=getc(finput); isdigit(c) ; c=getc(finput) ){
                    610:                                numbval = numbval*base + c - '0';
                    611:                                }
                    612:                        ungetc( c, finput );
                    613:                        return(NUMBER);
                    614:                        }
                    615:                else if( islower(c) || isupper(c) || c=='_' || c=='.' || c=='$' ){
                    616:                        i = 0;
                    617:                        while( islower(c) || isupper(c) || isdigit(c) || c=='_' || c=='.' || c=='$' ){
                    618:                                tokname[i] = c;
                    619:                                if( reserve && isupper(c) ) tokname[i] += 'a'-'A';
                    620:                                if( ++i >= NAMESIZE ) --i;
                    621:                                c = getc(finput);
                    622:                                }
                    623:                        }
                    624:                else return(c);
                    625: 
                    626:                ungetc( c, finput );
                    627:                }
                    628: 
                    629:        tokname[i] = '\0';
                    630: 
                    631:        if( reserve ){ /* find a reserved word */
                    632:                if( !strcmp(tokname,"term")) return( TERM );
                    633:                if( !strcmp(tokname,"token")) return( TERM );
                    634:                if( !strcmp(tokname,"left")) return( LEFT );
                    635:                if( !strcmp(tokname,"nonassoc")) return( BINARY );
                    636:                if( !strcmp(tokname,"binary")) return( BINARY );
                    637:                if( !strcmp(tokname,"right")) return( RIGHT );
                    638:                if( !strcmp(tokname,"prec")) return( PREC );
                    639:                if( !strcmp(tokname,"start")) return( START );
                    640:                if( !strcmp(tokname,"type")) return( TYPEDEF );
                    641:                if( !strcmp(tokname,"union")) return( UNION );
                    642:                error("invalid escape, or illegal reserved word: %s", tokname );
                    643:                }
                    644: 
                    645:        /* look ahead to distinguish IDENTIFIER from C_IDENTIFIER */
                    646: 
                    647:        c = getc(finput);
                    648:        while( c==' ' || c=='\t'|| c=='\n' || c=='\f' || c== '/' ) {
                    649:                if( c == '\n' ) ++peekline;
                    650:                else if( c == '/' ){ /* look for comments */
                    651:                        peekline += skipcom();
                    652:                        }
                    653:                c = getc(finput);
                    654:                }
                    655:        if( c == ':' ) return( C_IDENTIFIER );
                    656:        ungetc( c, finput );
                    657:        return( IDENTIFIER );
                    658: }
                    659: 
                    660: fdtype( t ){ /* determine the type of a symbol */
                    661:        register v;
                    662:        if( t >= NTBASE ) v = nontrst[t-NTBASE].tvalue;
                    663:        else v = TYPE( toklev[t] );
                    664:        if( v <= 0 ) error( "must specify type for %s", (t>=NTBASE)?nontrst[t-NTBASE].name:
                    665:                        tokset[t].name );
                    666:        return( v );
                    667:        }
                    668: 
                    669: chfind( t, s ) register char *s; {
                    670:        int i;
                    671: 
                    672:        if (s[0]==' ')t=0;
                    673:        TLOOP(i){
                    674:                if(!strcmp(s,tokset[i].name)){
                    675:                        return( i );
                    676:                        }
                    677:                }
                    678:        NTLOOP(i){
                    679:                if(!strcmp(s,nontrst[i].name)) {
                    680:                        return( i+NTBASE );
                    681:                        }
                    682:                }
                    683:        /* cannot find name */
                    684:        if( t>1 )
                    685:                error( "%s should have been defined earlier", s );
                    686:        return( defin( t, s ) );
                    687:        }
                    688: 
                    689: cpyunion(){
                    690:        /* copy the union declaration to the output, and the define file if present */
                    691: 
                    692:        int level, c;
                    693:        if ( gen_lines )
                    694:                fprintf( ftable, "\n# line %d \"%s\"\n", lineno, infile );
                    695:        fprintf( ftable, "typedef union " );
                    696:        if( fdefine ) fprintf( fdefine, "\ntypedef union " );
                    697: 
                    698:        level = 0;
                    699:        for(;;){
                    700:                if( (c=getc(finput)) < 0 ) error( "EOF encountered while processing %%union" );
                    701:                putc( c, ftable );
                    702:                if( fdefine ) putc( c, fdefine );
                    703: 
                    704:                switch( c ){
                    705: 
                    706:                case '\n':
                    707:                        ++lineno;
                    708:                        break;
                    709: 
                    710:                case '{':
                    711:                        ++level;
                    712:                        break;
                    713: 
                    714:                case '}':
                    715:                        --level;
                    716:                        if( level == 0 ) { /* we are finished copying */
                    717:                                fprintf( ftable, " YYSTYPE;\n" );
                    718:                                if( fdefine ) fprintf( fdefine, " YYSTYPE;\nextern YYSTYPE yylval;\n" );
                    719:                                return;
                    720:                                }
                    721:                        }
                    722:                }
                    723:        }
                    724: 
                    725: cpycode(){ /* copies code between \{ and \} */
                    726: 
                    727:        int c;
                    728:        c = getc(finput);
                    729:        if( c == '\n' ) {
                    730:                c = getc(finput);
                    731:                lineno++;
                    732:                }
                    733:        if ( gen_lines )
                    734:                fprintf( ftable, "\n# line %d \"%s\"\n", lineno, infile );
                    735:        while( c>=0 ){
                    736:                if( c=='\\' )
                    737:                        if( (c=getc(finput)) == '}' ) return;
                    738:                        else putc('\\', ftable );
                    739:                if( c=='%' )
                    740:                        if( (c=getc(finput)) == '}' ) return;
                    741:                        else putc('%', ftable );
                    742:                putc( c , ftable );
                    743:                if( c == '\n' ) ++lineno;
                    744:                c = getc(finput);
                    745:                }
                    746:        error("eof before %%}" );
                    747:        }
                    748: 
                    749: skipcom(){ /* skip over comments */
                    750:        register c, i=0;  /* i is the number of lines skipped */
                    751: 
                    752:        /* skipcom is called after reading a / */
                    753: 
                    754:        if( getc(finput) != '*' ) error( "illegal comment" );
                    755:        c = getc(finput);
                    756:        while( c != EOF ){
                    757:                while( c == '*' ){
                    758:                        if( (c=getc(finput)) == '/' ) return( i );
                    759:                        }
                    760:                if( c == '\n' ) ++i;
                    761:                c = getc(finput);
                    762:                }
                    763:        error( "EOF inside comment" );
                    764:        /* NOTREACHED */
                    765:        }
                    766: 
                    767: cpyact(offset){ /* copy C action to the next ; or closing } */
                    768:        int brac, c, match, j, s, tok;
                    769: 
                    770:        if ( gen_lines )
                    771:                fprintf( faction, "\n# line %d \"%s\"\n", lineno, infile );
                    772: 
                    773:        brac = 0;
                    774: 
                    775: loop:
                    776:        c = getc(finput);
                    777: swt:
                    778:        switch( c ){
                    779: 
                    780: case ';':
                    781:                if( brac == 0 ){
                    782:                        putc( c , faction );
                    783:                        return;
                    784:                        }
                    785:                goto lcopy;
                    786: 
                    787: case '{':
                    788:                brac++;
                    789:                goto lcopy;
                    790: 
                    791: case '$':
                    792:                s = 1;
                    793:                tok = -1;
                    794:                c = getc(finput);
                    795:                if( c == '<' ){ /* type description */
                    796:                        ungetc( c, finput );
                    797:                        if( gettok() != TYPENAME ) error( "bad syntax on $<ident> clause" );
                    798:                        tok = numbval;
                    799:                        c = getc(finput);
                    800:                        }
                    801:                if( c == '$' ){
                    802:                        fprintf( faction, "yyval");
                    803:                        if( ntypes ){ /* put out the proper tag... */
                    804:                                if( tok < 0 ) tok = fdtype( *prdptr[nprod] );
                    805:                                fprintf( faction, ".%s", typeset[tok] );
                    806:                                }
                    807:                        goto loop;
                    808:                        }
                    809:                if( c == '-' ){
                    810:                        s = -s;
                    811:                        c = getc(finput);
                    812:                        }
                    813:                if( isdigit(c) ){
                    814:                        j=0;
                    815:                        while( isdigit(c) ){
                    816:                                j= j*10+c-'0';
                    817:                                c = getc(finput);
                    818:                                }
                    819: 
                    820:                        j = j*s - offset;
                    821:                        if( j > 0 ){
                    822:                                error( "Illegal use of $%d", j+offset );
                    823:                                }
                    824: 
                    825:                        fprintf( faction, "yypvt[-%d]", -j );
                    826:                        if( ntypes ){ /* put out the proper tag */
                    827:                                if( j+offset <= 0 && tok < 0 ) error( "must specify type of $%d", j+offset );
                    828:                                if( tok < 0 ) tok = fdtype( prdptr[nprod][j+offset] );
                    829:                                fprintf( faction, ".%s", typeset[tok] );
                    830:                                }
                    831:                        goto swt;
                    832:                        }
                    833:                putc( '$' , faction );
                    834:                if( s<0 ) putc('-', faction );
                    835:                goto swt;
                    836: 
                    837: case '}':
                    838:                if( --brac ) goto lcopy;
                    839:                putc( c, faction );
                    840:                return;
                    841: 
                    842: 
                    843: case '/':      /* look for comments */
                    844:                putc( c , faction );
                    845:                c = getc(finput);
                    846:                if( c != '*' ) goto swt;
                    847: 
                    848:                /* it really is a comment */
                    849: 
                    850:                putc( c , faction );
                    851:                c = getc(finput);
                    852:                while( c != EOF ){
                    853:                        while( c=='*' ){
                    854:                                putc( c , faction );
                    855:                                if( (c=getc(finput)) == '/' ) goto lcopy;
                    856:                                }
                    857:                        putc( c , faction );
                    858:                        if( c == '\n' )++lineno;
                    859:                        c = getc(finput);
                    860:                        }
                    861:                error( "EOF inside comment" );
                    862: 
                    863: case '\'':     /* character constant */
                    864:                match = '\'';
                    865:                goto string;
                    866: 
                    867: case '"':      /* character string */
                    868:                match = '"';
                    869: 
                    870:        string:
                    871: 
                    872:                putc( c , faction );
                    873:                while( c=getc(finput) ){
                    874: 
                    875:                        if( c=='\\' ){
                    876:                                putc( c , faction );
                    877:                                c=getc(finput);
                    878:                                if( c == '\n' ) ++lineno;
                    879:                                }
                    880:                        else if( c==match ) goto lcopy;
                    881:                        else if( c=='\n' ) error( "newline in string or char. const." );
                    882:                        putc( c , faction );
                    883:                        }
                    884:                error( "EOF in string or character constant" );
                    885: 
                    886: case EOF:
                    887:                error("action does not terminate" );
                    888: 
                    889: case '\n':     ++lineno;
                    890:                goto lcopy;
                    891: 
                    892:                }
                    893: 
                    894: lcopy:
                    895:        putc( c , faction );
                    896:        goto loop;
                    897:        }
                    898: 
                    899: 
                    900: #define RHS_TEXT_LEN           ( BUFSIZ * 4 )  /* length of rhstext */
                    901: 
                    902: char lhstext[ BUFSIZ ];                /* store current lhs (non-terminal) name */
                    903: char rhstext[ RHS_TEXT_LEN ];  /* store current rhs list */
                    904: 
                    905: lhsfill( s )   /* new rule, dump old (if exists), restart strings */
                    906:        char *s;
                    907: {
                    908:        rhsfill( (char *) 0 );
                    909:        strcpy( lhstext, s );   /* don't worry about too long of a name */
                    910: }
                    911: 
                    912: 
                    913: rhsfill( s )
                    914:        char *s;        /* either name or 0 */
                    915: {
                    916:        static char *loc = rhstext;     /* next free location in rhstext */
                    917:        register char *p;
                    918: 
                    919:        if ( !s )       /* print out and erase old text */
                    920:        {
                    921:                if ( *lhstext )         /* there was an old rule - dump it */
                    922:                        lrprnt();
                    923:                ( loc = rhstext )[0] = '\0';
                    924:                return;
                    925:        }
                    926:        /* add to stuff in rhstext */
                    927:        p = s;
                    928:        *loc++ = ' ';
                    929:        if ( *s == ' ' )        /* special quoted symbol */
                    930:        {
                    931:                *loc++ = '\'';  /* add first quote */
                    932:                p++;
                    933:        }
                    934:        while ( *loc = *p++ )
                    935:                if ( loc++ > &rhstext[ RHS_TEXT_LEN ] - 2 )
                    936:                        break;
                    937:        if ( *s == ' ' )
                    938:                *loc++ = '\'';
                    939:        *loc = '\0';            /* terminate the string */
                    940: }
                    941: 
                    942: 
                    943: lrprnt()       /* print out the left and right hand sides */
                    944: {
                    945:        char *rhs;
                    946: 
                    947:        if ( !*rhstext )                /* empty rhs - print usual comment */
                    948:                rhs = " /* empty */";
                    949:        else
                    950:                rhs = rhstext;
                    951:        fprintf( fdebug, "      \"%s :%s\",\n", lhstext, rhs );
                    952: }
                    953: 
                    954: 
                    955: beg_debug()    /* dump initial sequence for fdebug file */
                    956: {
                    957:        fprintf( fdebug,
                    958:                "typedef struct { char *t_name; int t_val; } yytoktype;\n" );
                    959:        fprintf( fdebug,
                    960:                "#ifndef YYDEBUG\n#\tdefine YYDEBUG\t%d", gen_testing );
                    961:        fprintf( fdebug, "\t/*%sallow debugging */\n#endif\n\n",
                    962:                gen_testing ? " " : " don't " );
                    963:        fprintf( fdebug, "#if YYDEBUG\n\nyytoktype yytoks[] =\n{\n" );
                    964: }
                    965: 
                    966: 
                    967: end_toks()     /* finish yytoks array, get ready for yyred's strings */
                    968: {
                    969:        fprintf( fdebug, "\t\"-unknown-\",\t-1\t/* ends search */\n" );
                    970:        fprintf( fdebug, "};\n\nchar * yyreds[] =\n{\n" );
                    971:        fprintf( fdebug, "\t\"-no such reduction-\",\n" );
                    972: }
                    973: 
                    974: 
                    975: end_debug()    /* finish yyred array, close file */
                    976: {
                    977:        lrprnt();               /* dump last lhs, rhs */
                    978:        fprintf( fdebug, "};\n#endif /* YYDEBUG */\n" );
                    979:        fclose( fdebug );
                    980: }

unix.superglobalmegacorp.com

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