1: %{#include "defs"
2: /* static char *sccsid = "@(#)gram.y 4.1 (Berkeley) 81/02/28"; */
3: %}
4:
5: %term NAME SHELLINE START MACRODEF COLON DOUBLECOLON GREATER
6: %union
7: {
8: struct shblock *yshblock;
9: struct depblock *ydepblock;
10: struct nameblock *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: %}
32:
33:
34: file:
35: | file comline
36: ;
37:
38: comline: START
39: | MACRODEF
40: | START namelist deplist shellist = {
41: while( --nlefts >= 0)
42: {
43: leftp = lefts[nlefts];
44: if(leftp->septype == 0)
45: leftp->septype = sepc;
46: else if(leftp->septype != sepc)
47: fprintf(stderr, "Inconsistent rules lines for `%s'\n",
48: leftp->namep);
49: else if(sepc==ALLDEPS && *(leftp->namep)!='.' && $4!=0)
50: {
51: for(lp=leftp->linep; lp->nxtlineblock!=0; lp=lp->nxtlineblock)
52: if(lp->shp)
53: fprintf(stderr, "Multiple rules lines for `%s'\n",
54: leftp->namep);
55: }
56:
57: lp = ALLOC(lineblock);
58: lp->nxtlineblock = NULL;
59: lp->depp = $3;
60: lp->shp = $4;
61:
62: if(! unequal(leftp->namep, ".SUFFIXES") && $3==0)
63: leftp->linep = 0;
64: else if(leftp->linep == 0)
65: leftp->linep = lp;
66: else {
67: for(lpp = leftp->linep; lpp->nxtlineblock;
68: lpp = lpp->nxtlineblock) ;
69: if(sepc==ALLDEPS && leftp->namep[0]=='.')
70: lpp->shp = 0;
71: lpp->nxtlineblock = lp;
72: }
73: }
74: }
75: | error
76: ;
77:
78: namelist: NAME = { lefts[0] = $1; nlefts = 1; }
79: | namelist NAME = { lefts[nlefts++] = $2;
80: if(nlefts>=NLEFTS) fatal("Too many lefts"); }
81: ;
82:
83: deplist:
84: {
85: char junk[10];
86: sprintf(junk, "%d", yylineno);
87: fatal1("Must be a separator on rules line %s", junk);
88: }
89: | dlist
90: ;
91:
92: dlist: sepchar = { prevdep = 0; $$ = 0; }
93: | dlist NAME = {
94: pp = ALLOC(depblock);
95: pp->nxtdepblock = NULL;
96: pp->depname = $2;
97: if(prevdep == 0) $$ = pp;
98: else prevdep->nxtdepblock = pp;
99: prevdep = pp;
100: }
101: ;
102:
103: sepchar: COLON = { sepc = ALLDEPS; }
104: | DOUBLECOLON = { sepc = SOMEDEPS; }
105: ;
106:
107: shellist: = {$$ = 0; }
108: | shlist = { $$ = $1; }
109: ;
110:
111: shlist: SHELLINE = { $$ = $1; prevshp = $1; }
112: | shlist SHELLINE = { $$ = $1;
113: prevshp->nxtshblock = $2;
114: prevshp = $2;
115: }
116: ;
117:
118: %%
119:
120: char *zznextc; /* zero if need another line; otherwise points to next char */
121: int yylineno;
122: extern FILE * fin;
123:
124: yylex()
125: {
126: register char *p;
127: register char *q;
128: char word[INMAX];
129:
130: if(zznextc == 0)
131: return( nextlin() );
132:
133: while( isspace(*zznextc) )
134: ++zznextc;
135:
136: if(*zznextc == '\0')
137: return( nextlin() );
138:
139: if(*zznextc == ':')
140: {
141: if(*++zznextc == ':')
142: {
143: ++zznextc;
144: return(DOUBLECOLON);
145: }
146: else return(COLON);
147: }
148:
149: if(*zznextc == '>')
150: {
151: ++zznextc;
152: return(GREATER);
153: }
154:
155: if(*zznextc == ';')
156: return( retsh(zznextc) );
157:
158: p = zznextc;
159: q = word;
160:
161: while( ! ( funny[*p] & TERMINAL) )
162: *q++ = *p++;
163:
164: if(p != zznextc)
165: {
166: *q = '\0';
167: if((yylval.ynameblock=srchname(word))==0)
168: yylval.ynameblock = makename(word);
169: zznextc = p;
170: return(NAME);
171: }
172:
173: else {
174: fprintf(stderr,"Bad character %c (octal %o), line %d",
175: *zznextc,*zznextc,yylineno);
176: fatal( (char *) NULL );
177: }
178: return(0); /* never executed */
179: }
180:
181:
182:
183:
184:
185: retsh(q)
186: char *q;
187: {
188: register char *p;
189: struct shblock *sp;
190: char *copys();
191:
192: for(p=q+1 ; *p==' '||*p=='\t' ; ++p) ;
193:
194: sp = ALLOC(shblock);
195: sp->nxtshblock = NULL;
196: sp->shbp = (fin == NULL ? p : copys(p) );
197: yylval.yshblock = sp;
198: zznextc = 0;
199: return(SHELLINE);
200: }
201:
202: nextlin()
203: {
204: static char yytext[INMAX];
205: static char *yytextl = yytext+INMAX;
206: char *text, templin[INMAX];
207: register char c;
208: register char *p, *t;
209: char lastch, *lastchp;
210: extern char **linesptr;
211: int incom;
212: int kc;
213:
214: again:
215:
216: incom = NO;
217: zznextc = 0;
218:
219: if(fin == NULL)
220: {
221: if( (text = *linesptr++) == 0)
222: return(0);
223: ++yylineno;
224: }
225:
226: else {
227: for(p = text = yytext ; p<yytextl ; *p++ = kc)
228: switch(kc = getc(fin))
229: {
230: case '\t':
231: if(p != yytext)
232: break;
233: case ';':
234: incom = YES;
235: break;
236:
237: case '#':
238: if(! incom)
239: kc = '\0';
240: break;
241:
242: case '\n':
243: ++yylineno;
244: if(p==yytext || p[-1]!='\\')
245: {
246: *p = '\0';
247: goto endloop;
248: }
249: p[-1] = ' ';
250: while( (kc=getc(fin))=='\t' || kc==' ' || kc=='\n')
251: if(kc == '\n')
252: ++yylineno;
253:
254: if(kc != EOF)
255: break;
256: case EOF:
257: *p = '\0';
258: return(0);
259: }
260:
261: fatal("line too long");
262: }
263:
264: endloop:
265:
266: if((c = text[0]) == '\t')
267: return( retsh(text) );
268:
269: if(isalpha(c) || isdigit(c) || c==' ' || c=='.')
270: for(p=text+1; *p!='\0'; )
271: if(*p == ':')
272: break;
273: else if(*p++ == '=')
274: {
275: eqsign(text);
276: return(MACRODEF);
277: }
278:
279: /* substitute for macros on dependency line up to the semicolon if any */
280:
281: for(t = yytext ; *t!='\0' && *t!=';' ; ++t)
282: ;
283:
284: lastchp = t;
285: lastch = *t;
286: *t = '\0';
287:
288: subst(yytext, templin); /* Substitute for macros on dependency lines */
289:
290: if(lastch)
291: {
292: for(t = templin ; *t ; ++t)
293: ;
294: *t = lastch;
295: while( *++t = *++lastchp ) ;
296: }
297:
298: p = templin;
299: t = yytext;
300: while( *t++ = *p++ )
301: ;
302:
303: for(p = zznextc = text ; *p ; ++p )
304: if(*p!=' ' && *p!='\t')
305: return(START);
306: goto again;
307: }
Defined functions
Defined variables