static char *sccsid = "@(#)gram.y 4.2 (Berkeley) 87/10/22";
%term NAME SHELLINE START MACRODEF COLON DOUBLECOLON GREATER
struct shblock *yshblock;
struct depblock *ydepblock;
struct nameblock *ynameblock;
%type <yshblock> SHELLINE, shlist, shellist
%type <ynameblock> NAME, namelist
%type <ydepblock> deplist, dlist
FSTATIC struct shblock *prevshp;
FSTATIC struct nameblock *lefts[NLEFTS];
struct lineblock *lp, *lpp;
FSTATIC struct depblock *prevdep;
| START namelist deplist shellist = {
else if(leftp->septype != sepc)
fprintf(stderr, "Inconsistent rules lines for `%s'\n",
else if(sepc==ALLDEPS && *(leftp->namep)!='.' && $4!=0)
for(lp=leftp->linep; lp->nxtlineblock!=0; lp=lp->nxtlineblock)
fprintf(stderr, "Multiple rules lines for `%s'\n",
if(! unequal(leftp->namep, ".SUFFIXES") && $3==0)
else if(leftp->linep == 0)
for(lpp = leftp->linep; lpp->nxtlineblock;
lpp = lpp->nxtlineblock) ;
if(sepc==ALLDEPS && leftp->namep[0]=='.')
namelist: NAME = { lefts[0] = $1; nlefts = 1; }
| namelist NAME = { lefts[nlefts++] = $2;
if(nlefts>=NLEFTS) fatal("Too many lefts"); }
(void)sprintf(junk, "%d", yylineno);
fatal1("Must be a separator on rules line %s", junk);
dlist: sepchar = { prevdep = 0; $$ = 0; }
if(prevdep == 0) $$ = pp;
else prevdep->nxtdepblock = pp;
sepchar: COLON = { sepc = ALLDEPS; }
| DOUBLECOLON = { sepc = SOMEDEPS; }
shlist: SHELLINE = { $$ = $1; prevshp = $1; }
| shlist SHELLINE = { $$ = $1;
prevshp->nxtshblock = $2;
char *zznextc; /* zero if need another line; otherwise points to next char */
while( isspace(*zznextc) )
return( retsh(zznextc) );
while( ! ( funny[*p] & TERMINAL) )
if((yylval.ynameblock=srchname(word))==0)
yylval.ynameblock = makename(word);
fprintf(stderr,"Bad character %c (octal %o), line %d",
*zznextc,*zznextc,yylineno);
return(0); /* never executed */
for(p=q+1 ; *p==' '||*p=='\t' ; ++p) ;
sp->shbp = (fin == NULL ? p : copys(p) );
static char yytext[INMAX];
static char *yytextl = yytext+INMAX;
char *text, templin[INMAX];
if( (text = *linesptr++) == 0)
for(p = text = yytext ; p<yytextl ; *p++ = kc)
if(p==yytext || p[-1]!='\\')
while( (kc=getc(fin))=='\t' || kc==' ' || kc=='\n')
if((c = text[0]) == '\t')
if(isalpha(c) || isdigit(c) || c==' ' || c=='.')
for(p=text+1; *p!='\0'; )
/* substitute for macros on dependency line up to the semicolon if any */
for(t = yytext ; *t!='\0' && *t!=';' ; ++t)
subst(yytext, templin); /* Substitute for macros on dependency lines */
for(t = templin ; *t ; ++t)
while( *++t = *++lastchp ) ;
for(p = zznextc = text ; *p ; ++p )