Annotation of researchv9/cmd/make/gram.y, revision 1.1.1.1

1.1       root        1: %{#include "defs"
                      2: static char *sccsid = "@(#)gram.y      8th Edition (Bell Labs) 85/05/14";
                      3: %}
                      4: 
                      5: %term NAME SHELLINE START MACRODEF COLON DOUBLECOLON GREATER AMPER AMPERAMPER
                      6: %union
                      7:        {
                      8:        struct shblock *yshblock;
                      9:        depblkp ydepblock;
                     10:        nameblkp ynameblock;
                     11:        }
                     12: 
                     13: %type <yshblock> SHELLINE, shlist, shellist
                     14: %type <ynameblock> NAME, namelist
                     15: %type <ydepblock> deplist, dlist
                     16: 
                     17: 
                     18: %%
                     19: 
                     20: %{
                     21: struct depblock *pp;
                     22: FSTATIC struct shblock *prevshp;
                     23: 
                     24: FSTATIC struct nameblock *lefts[NLEFTS];
                     25: struct nameblock *leftp;
                     26: FSTATIC int nlefts;
                     27: 
                     28: struct lineblock *lp, *lpp;
                     29: FSTATIC struct depblock *prevdep;
                     30: FSTATIC int sepc;
                     31: FSTATIC int allnowait;
                     32: 
                     33: FSTATIC struct fstack
                     34:        {
                     35:        FILE *fin;
                     36:        char *fname;
                     37:        int lineno;
                     38:        } filestack[MAXINCLUDE];
                     39: FSTATIC int ninclude = 0;
                     40: %}
                     41: 
                     42: 
                     43: file:
                     44:        | file comline
                     45:        ;
                     46: 
                     47: comline:  START
                     48:        | MACRODEF
                     49:        | START namelist deplist shellist = {
                     50:            while( --nlefts >= 0)
                     51:                {
                     52:                wildp iswild(), wp;
                     53: 
                     54:                leftp = lefts[nlefts];
                     55:                if(wp = iswild(leftp->namep))
                     56:                        {
                     57:                        leftp->septype = SOMEDEPS;
                     58:                        if(lastwild)
                     59:                                lastwild->next = wp;
                     60:                        else
                     61:                                firstwild = wp;
                     62:                        lastwild = wp;
                     63:                        }
                     64: 
                     65:                if(leftp->septype == 0)
                     66:                        leftp->septype = sepc;
                     67:                else if(leftp->septype != sepc)
                     68:                        {
                     69:                        if(! wp)
                     70:                                fprintf(stderr,
                     71:                                        "Inconsistent rules lines for `%s'\n",
                     72:                                        leftp->namep);
                     73:                        }
                     74:                else if(sepc==ALLDEPS && leftp->namep[0]!='.' && $4!=0)
                     75:                        {
                     76:                        for(lp=leftp->linep; lp->nxtlineblock; lp=lp->nxtlineblock)
                     77:                        if(lp->shp)
                     78:                                fprintf(stderr,
                     79:                                        "Multiple rules lines for `%s'\n",
                     80:                                        leftp->namep);
                     81:                        }
                     82: 
                     83:                lp = ALLOC(lineblock);
                     84:                lp->nxtlineblock = NULL;
                     85:                lp->depp = $3;
                     86:                lp->shp = $4;
                     87:                if(wp)
                     88:                        wp->linep = lp;
                     89: 
                     90:                if(equal(leftp->namep, ".SUFFIXES") && $3==0)
                     91:                        leftp->linep = 0;
                     92:                else if(leftp->linep == 0)
                     93:                        leftp->linep = lp;
                     94:                else    {
                     95:                        for(lpp = leftp->linep; lpp->nxtlineblock;
                     96:                                lpp = lpp->nxtlineblock) ;
                     97:                                if(sepc==ALLDEPS && leftp->namep[0]=='.')
                     98:                                        lpp->shp = 0;
                     99:                        lpp->nxtlineblock = lp;
                    100:                        }
                    101:                }
                    102:        }
                    103:        | error
                    104:        ;
                    105: 
                    106: namelist: NAME = { lefts[0] = $1; nlefts = 1; }
                    107:        | namelist NAME = { lefts[nlefts++] = $2;
                    108:                if(nlefts>=NLEFTS) fatal("Too many lefts"); }
                    109:        ;
                    110: 
                    111: deplist:
                    112:                {
                    113:                char junk[10];
                    114:                sprintf(junk, "%d", yylineno);
                    115:                fatal1("Must be a separator on rules line %s", junk);
                    116:                }
                    117:        | dlist
                    118:        ;
                    119: 
                    120: dlist:  sepchar        = { prevdep = 0;  $$ = 0; allnowait = NO; }
                    121:        | sepchar AMPER = { prevdep = 0; $$ = 0; allnowait = YES; }
                    122:        | dlist NAME    = {
                    123:                          pp = ALLOC(depblock);
                    124:                          pp->nxtdepblock = NULL;
                    125:                          pp->depname = $2;
                    126:                          pp->nowait = allnowait;
                    127:                          if(prevdep == 0) $$ = pp;
                    128:                          else  prevdep->nxtdepblock = pp;
                    129:                          prevdep = pp;
                    130:                          }
                    131:        | dlist AMPER   = { if(prevdep) prevdep->nowait = YES; }
                    132:        | dlist AMPERAMPER
                    133:        ;
                    134: 
                    135: sepchar:  COLON        = { sepc = ALLDEPS; }
                    136:        | DOUBLECOLON   = { sepc = SOMEDEPS; }
                    137:        ;
                    138: 
                    139: shellist:      = {$$ = 0; }
                    140:        | shlist = { $$ = $1; }
                    141:        ;
                    142: 
                    143: shlist:        SHELLINE   = { $$ = $1;  prevshp = $1; }
                    144:        | shlist SHELLINE = { $$ = $1;
                    145:                        prevshp->nxtshblock = $2;
                    146:                        prevshp = $2;
                    147:                        }
                    148:        ;
                    149: 
                    150: %%
                    151: 
                    152: FSTATIC char *zznextc; /* null if need another line;
                    153:                           otherwise points to next char */
                    154: FSTATIC int yylineno;
                    155: FSTATIC FILE * fin;
                    156: 
                    157: parse(name)
                    158: char *name;
                    159: {
                    160: extern int yylineno;
                    161: FILE *stream;
                    162: extern char *zznextc;
                    163: 
                    164: if(name == CHNULL)
                    165:        {
                    166:        stream = NULL;
                    167:        name = "(builtin-rules)";
                    168:        }
                    169: else if(equal(name, "-"))
                    170:        {
                    171:        stream = stdin;
                    172:        name = "(stdin)";
                    173:        }
                    174: else if( (stream = fopen(name, "r")) == NULL)
                    175:        return NO;
                    176: filestack[0].fname = copys(name);
                    177: ninclude = 1;
                    178: fin = stream;
                    179: yylineno = 0;
                    180: zznextc = 0;
                    181: 
                    182: if( yyparse() )
                    183:        fatal("Description file error");
                    184: 
                    185: if(fin)
                    186:        fclose(fin);
                    187: return YES;
                    188: }
                    189: 
                    190: 
                    191: yylex()
                    192: {
                    193: register char *p;
                    194: register char *q;
                    195: char word[INMAX];
                    196: 
                    197: if(! zznextc )
                    198:        return nextlin() ;
                    199: 
                    200: while( isspace(*zznextc) )
                    201:        ++zznextc;
                    202: switch(*zznextc)
                    203:        {
                    204:        case '\0':
                    205:                return nextlin() ;
                    206: 
                    207:        case '|':
                    208:                if(zznextc[1]==':')
                    209:                        {
                    210:                        zznextc += 2;
                    211:                        return DOUBLECOLON;
                    212:                        }
                    213:                break;
                    214:        case ':':
                    215:                if(*++zznextc == ':')
                    216:                        {
                    217:                        ++zznextc;
                    218:                        return DOUBLECOLON;
                    219:                        }
                    220:                return COLON;
                    221:        case '>':
                    222:                ++zznextc;
                    223:                return GREATER;
                    224:        case '&':
                    225:                if(*++zznextc == '&')
                    226:                        {
                    227:                        ++zznextc;
                    228:                        return AMPERAMPER;
                    229:                        }
                    230:                return AMPER;
                    231:        case ';':
                    232:                return retsh(zznextc) ;
                    233:        }
                    234: 
                    235: p = zznextc;
                    236: q = word;
                    237: 
                    238: while( ! ( funny[*p] & TERMINAL) )
                    239:        *q++ = *p++;
                    240: 
                    241: if(p != zznextc)
                    242:        {
                    243:        *q = '\0';
                    244:        if((yylval.ynameblock=srchname(word))==0)
                    245:                yylval.ynameblock = makename(word);
                    246:        zznextc = p;
                    247:        return NAME;
                    248:        }
                    249: 
                    250: else   {
                    251:        char junk[100];
                    252:        sprintf(junk, "Bad character %c (octal %o), line %d of file %s",
                    253:                *zznextc, *zznextc, yylineno, filestack[ninclude-1].fname);
                    254:        fatal(junk);
                    255:        }
                    256: return 0;      /* never executed */
                    257: }
                    258: 
                    259: 
                    260: 
                    261: 
                    262: 
                    263: retsh(q)
                    264: char *q;
                    265: {
                    266: register char *p;
                    267: struct shblock *sp;
                    268: char *copys();
                    269: 
                    270: for(p=q+1 ; *p==' '||*p=='\t' ; ++p)  ;
                    271: 
                    272: sp = ALLOC(shblock);
                    273: sp->nxtshblock = NULL;
                    274: sp->shbp = (fin ? copys(p) : p );
                    275: yylval.yshblock = sp;
                    276: zznextc = 0;
                    277: return SHELLINE;
                    278: }
                    279: 
                    280: nextlin()
                    281: {
                    282: static char yytext[INMAX];
                    283: static char *yytextl   = yytext+INMAX;
                    284: char *text, templin[INMAX];
                    285: register char c;
                    286: register char *p, *t;
                    287: char lastch, *lastchp;
                    288: extern char **linesptr;
                    289: int incom;
                    290: int kc;
                    291: 
                    292: again:
                    293: 
                    294:        incom = NO;
                    295:        zznextc = 0;
                    296: 
                    297: if(fin == NULL)
                    298:        {
                    299:        if( (text = *linesptr++) == 0)
                    300:                return 0;
                    301:        ++yylineno;
                    302:        }
                    303: 
                    304: else   {
                    305:        for(p = text = yytext ; p<yytextl ; *p++ = kc)
                    306:                switch(kc = getc(fin))
                    307:                        {
                    308:                        case '\t':
                    309:                                if(p == yytext)
                    310:                                        incom = YES;
                    311:                                break;
                    312: 
                    313:                        case ';':
                    314:                                incom = YES;
                    315:                                break;
                    316: 
                    317:                        case '#':
                    318:                                if(! incom)
                    319:                                        kc = '\0';
                    320:                                break;
                    321: 
                    322:                        case '\n':
                    323:                                ++yylineno;
                    324:                                if(p==yytext || p[-1]!='\\')
                    325:                                        {
                    326:                                        *p = '\0';
                    327:                                        goto endloop;
                    328:                                        }
                    329:                                p[-1] = ' ';
                    330:                                while( (kc=getc(fin))=='\t' || kc==' ' || kc=='\n')
                    331:                                        if(kc == '\n')
                    332:                                                ++yylineno;
                    333:        
                    334:                                if(kc != EOF)
                    335:                                        break;
                    336:                        case EOF:
                    337:                                *p = '\0';
                    338:                                if(ninclude > 1)
                    339:                                        {
                    340:                                        register struct fstack *stp;
                    341:                                        fclose(fin);
                    342:                                        --ninclude;
                    343:                                        stp = filestack + ninclude;
                    344:                                        fin = stp->fin;
                    345:                                        yylineno = stp->lineno;
                    346:                                        free(stp->fname);
                    347:                                        goto again;
                    348:                                        }
                    349:                                return 0;
                    350:                        }
                    351: 
                    352:        fatal("line too long");
                    353:        }
                    354: 
                    355: endloop:
                    356: 
                    357:        if((c = text[0]) == '\t')
                    358:                return retsh(text) ;
                    359:        
                    360:        if(isalpha(c) || isdigit(c) || c==' ' || c=='.')
                    361:                for(p=text+1; *p!='\0'; )
                    362:                        if(*p == ':')
                    363:                                break;
                    364:                        else if(*p++ == '=')
                    365:                                {
                    366:                                eqsign(text);
                    367:                                return MACRODEF;
                    368:                                }
                    369: 
                    370: 
                    371: if(!strncmp(text, "include", 7) && isinclude(text+7))
                    372:        goto again;
                    373: 
                    374: /* substitute for macros on dependency line up to the semicolon if any */
                    375: 
                    376: for(t = yytext ; *t!='\0' && *t!=';' ; ++t)
                    377:        ;
                    378: 
                    379: lastchp = t;
                    380: lastch = *t;
                    381: *t = '\0';     /* replace the semi with a null so subst will stop */
                    382: 
                    383: subst(yytext, templin);                /* Substitute for macros on dependency lines */
                    384: 
                    385: if(lastch)     /* copy the stuff after the semicolon */
                    386:        {
                    387:        *lastchp = lastch;
                    388:        strcat(templin, lastchp);
                    389:        }
                    390: 
                    391: strcpy(yytext, templin);
                    392: 
                    393: for(p = zznextc = text ; *p ; ++p )
                    394:        if(*p!=' ' && *p!='\t')
                    395:                return START;
                    396: goto again;
                    397: }
                    398: 
                    399: 
                    400: 
                    401: isinclude(s)
                    402: register char *s;
                    403: {
                    404: register char *t;
                    405: register struct fstack *p;
                    406: 
                    407: for(t=s; *t==' ' || *t=='\t' ; ++t)
                    408:        ;
                    409: if(t == s)
                    410:        return NO;
                    411: 
                    412: for(s = t; *s!='\n' && *s!='#' && *s!='\0' ; ++s)
                    413:        if(*s == ':')
                    414:                return NO;
                    415: *s = '\0';
                    416: 
                    417: if(ninclude >= MAXINCLUDE)
                    418:        fatal("include depth exceeded");
                    419: p = filestack + ninclude;
                    420: p->fin = fin;
                    421: p->lineno = yylineno;
                    422: p->fname = copys(t);
                    423: if( (fin = fopen(t, "r")) == NULL)
                    424:        fatal1("Cannot open include file %s", t);
                    425: yylineno = 0;
                    426: ++ninclude;
                    427: return YES;
                    428: }
                    429: 
                    430: 
                    431: 
                    432: yyerror(s)
                    433: char *s;
                    434: {
                    435: char buf[100];
                    436: 
                    437: sprintf(buf, "line %d of file %s: %s",
                    438:                yylineno, filestack[ninclude-1].fname, s);
                    439: fatal(buf);
                    440: }

unix.superglobalmegacorp.com

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