1 %term  xxif 300 xxelse 301 xxwhile 302 xxrept 303 xxdo 304 xxrb 305 xxpred 306
2 %term xxident 307 xxle 308 xxge 309 xxne 310 xxnum 311 xxcom 312
3 %term xxstring 313 xxexplist 314 xxidpar 315 xxelseif 316  xxlb 318 xxend 319
4 %term xxcase 320 xxswitch 321 xxuntil 322 xxdefault 323
5 %term xxeq 324
6 
7 %left	'|'
8 %left	'&'
9 %left	'!'
10 %binary	'<' '>' xxeq xxne xxge xxle
11 %left	'+' '-'
12 %left	'*' '/'
13 %left	xxuminus
14 %right	'^'
15 
16 %{
17 #ifndef lint
18 static char sccsid[] = "@(#)beauty.y	4.2	(Berkeley)	07/22/88";
19 #endif not lint
20 
21 #include "b.h"
22 #include <stdio.h>
23 
24 extern char *malloc();
25 extern struct node *checkneg(), *addroot();
26 %}
27 
28 %%
29 %{
30 struct node *t;
31 %}
32 
33 
34 allprog:	prog xxnew
35 	;
36 
37 prog:	stat
38 	|	prog stat
39 	;
40 
41 stat:		 iftok pred nlevel elsetok nlevel
42 	|	 iftok  pred  nlevel
43 	|	xxtab whtok  pred  nlevel
44 	|	xxtab rpttok nlevel optuntil
45 	|	xxtab dotok nlevel
46 	|	xxtab swtok oppred pindent lbtok caseseq xxtab rbtok mindent
47 	|	xxtab fstok
48 	|	lbtok prog xxtab rbtok
49 	|	lbtok rbtok
50 	|	 labtok stat
51 	|	xxnl comtok stat
52 	|	error
53 	;
54 
55 
56 xxtab:		=	{
57 			if (!xxlablast) tab(xxindent);
58 			xxlablast = 0;
59 			}
60 
61 xxnl:	=	newline();
62 xxnew:	=	putout('\n',"\n");
63 nlevel:	pindent stat mindent;
64 pindent:		=
65 				{
66 				if (xxstack[xxstind] != xxlb)
67 					++xxindent;
68 				};
69 mindent:			=
70 				{if (xxstack[xxstind] != xxlb && xxstack[xxstind] != xxelseif)
71 					--xxindent;
72 				pop();
73 				};
74 caseseq:	casetok caseseq
75 	|	casetok
76 	;
77 
78 casetok:	xxtab xxctok predlist pindent prog mindent
79 	|	xxtab xxctok predlist pindent mindent
80 	|	xxtab deftok pindent prog mindent
81 	|	xxnl comtok casetok
82 	;
83 
84 xxctok:	xxcase		=	{putout(xxcase,"case "); free ($1); push(xxcase); }
85 
86 
87 deftok:		xxdefault ':'		=		{
88 						putout(xxcase,"default");
89 						free($1);
90 						putout(':',":");
91 						free($2);
92 						push(xxcase);
93 						}
94 swtok:	xxswitch			=	{putout(xxswitch,"switch"); free($1); push(xxswitch); }
95 
96 fstok:	xxend		=	{
97 				free($1);
98 				putout(xxident,"end");
99 				putout('\n',"\n");
100 				putout('\n',"\n");
101 				putout('\n',"\n");
102 				}
103 	|	xxident	=	{
104 				putout(xxident,$1);
105 				free($1);
106 				newflag = 1;
107 				forst();
108 				newflag = 0;
109 				};
110 
111 
112 
113 identtok:	xxident '(' explist ')'	=	{
114 				xxt = addroot($1,xxident,0,0);
115 				$$ = addroot("",xxidpar,xxt,$3);
116 				}
117 
118 	|	xxident		=	$$ = addroot($1,xxident,0,0);
119 	;
120 
121 predlist:	explist  ':'		=	{
122 				yield($1,0);
123 				putout(':',":");
124 				freetree($1);
125 				}
126 explist:	expr ',' explist		=	$$ = addroot($2,xxexplist,checkneg($1,0),$3);
127 	|	expr					=	$$ = checkneg($1,0);
128 	;
129 
130 
131 oppred:	pred
132 	|
133 	;
134 
135 pred:	'(' expr ')'	=	{ t = checkneg($2,0);
136 				yield(t,100);  freetree(t);	};
137 
138 expr:		'(' expr ')'	=	$$ = $2;
139 	|	'-' expr	%prec xxuminus	=	$$ = addroot($1,xxuminus,$2,0);
140 	|	'!' expr	=	$$ = addroot($1,'!',$2,0);
141 	|	expr '+' expr	=	$$ = addroot($2,'+',$1,$3);
142 	|	expr '-' expr	=	$$ = addroot($2,'-',$1,$3);
143 	|	expr '*' expr	=	$$ = addroot($2,'*',$1,$3);
144 	|	expr '/' expr	=	$$ = addroot($2,'/',$1,$3);
145 	|	expr '^' expr	=	$$ = addroot($2,'^',$1,$3);
146 	|	expr '|' expr	=	$$ = addroot($2,'|',$1,$3);
147 	|	expr '&' expr	=	$$ = addroot($2,'&',$1,$3);
148 	|	expr '>' expr	=	$$ = addroot($2,'>',$1,$3);
149 	|	expr '<' expr	=	$$ = addroot($2,'<',$1,$3);
150 	|	expr xxeq expr	=	$$ = addroot($2,xxeq,$1,$3);
151 	|	expr xxle expr	=	$$ = addroot($2,xxle,$1,$3);
152 	|	expr xxge expr	=	$$ = addroot($2,xxge,$1,$3);
153 	|	expr xxne expr	=	$$ = addroot($2,xxne,$1,$3);
154 	|	identtok		=	$$ = $1;
155 	|	xxnum		=	$$ = addroot($1,xxnum,0,0);
156 	|	xxstring		=	$$ = addroot($1,xxstring,0,0);
157 	;
158 
159 iftok:	xxif		=
160 				{
161 				if (xxstack[xxstind] == xxelse && !xxlablast)
162 					{
163 					--xxindent;
164 					xxstack[xxstind] = xxelseif;
165 					putout(' '," ");
166 					}
167 				else
168 					{
169 					if (!xxlablast)
170 						tab(xxindent);
171 					xxlablast = 0;
172 					}
173 				putout(xxif,"if");
174 				free($1);
175 				push(xxif);
176 				}
177 elsetok:	xxelse	=
178 				{
179 				tab(xxindent);
180 				putout(xxelse,"else");
181 				free($1);
182 				push(xxelse);
183 				}
184 whtok:	xxwhile		=	{
185 				putout(xxwhile,"while");
186 				free($1);
187 				push(xxwhile);
188 				}
189 rpttok:	xxrept	=			{
190 					putout(xxrept,"repeat");
191 					free($1);
192 					push(xxrept);
193 					}
194 optuntil:	xxtab unttok pred
195 		|
196 		;
197 
198 unttok:	xxuntil	  = 	{
199 			putout('\t',"\t");
200 			putout(xxuntil,"until");
201 			free($1);
202 			}
203 dotok:	dopart opdotok
204 	;
205 dopart:	xxdo	identtok '=' expr  ',' expr 		=
206 					{push(xxdo);
207 					putout(xxdo,"do");
208 					free($1);
209 					puttree($2);
210 					putout('=',"=");
211 					free($3);
212 					puttree($4);
213 					putout(',',",");
214 					free($5);
215 					puttree($6);
216 					}
217 opdotok:	',' expr		=	{
218 						putout(',',",");
219 						puttree($2);
220 						}
221 	|	;
222 lbtok:	'{'		=	{
223 				putout('{'," {");
224 				push(xxlb);
225 				}
226 rbtok:	'}'			=	{ putout('}',"}");  pop();   }
227 labtok:	xxnum		=	{
228 				tab(xxindent);
229 				putout(xxnum,$1);
230 				putout(' ',"  ");
231 				xxlablast = 1;
232 				}
233 comtok:	xxcom		=	{ putout(xxcom,$1);  free($1);  xxlablast = 0; }
234 	|	comtok xxcom		= { putout ('\n',"\n"); putout(xxcom,$2);  free($2);  xxlablast = 0; };
235 %%
236 #define ASSERT(X,Y)	if (!(X)) error("struct bug: assertion 'X' invalid in routine Y","","");
237 
238 yyerror(s)
239 char *s;
240 	{
241 	extern int yychar;
242 	fprintf(stderr,"\n%s",s);
243 	fprintf(stderr," in beautifying, output line %d,",xxlineno + 1);
244 	fprintf(stderr," on input: ");
245 		switch (yychar) {
246 			case '\t': fprintf(stderr,"\\t\n"); return;
247 			case '\n': fprintf(stderr,"\\n\n"); return;
248 			case '\0': fprintf(stderr,"$end\n"); return;
249 			default: fprintf(stderr,"%c\n",yychar); return;
250 			}
251 	}
252 
253 yyinit(argc, argv)			/* initialize pushdown store */
254 int argc;
255 char *argv[];
256 	{
257 	xxindent = 0;
258 	xxbpertab = 8;
259 	xxmaxchars = 120;
260 	}
261 
262 
263 #include <signal.h>
264 main()
265 	{
266 	int exit();
267 	if ( signal(SIGINT, SIG_IGN) != SIG_IGN)
268 		signal(SIGINT, exit);
269 	yyinit();
270 	yyparse();
271 	}
272 
273 
274 putout(type,string)			/* output string with proper indentation */
275 int type;
276 char *string;
277 	{
278 	static int lasttype;
279 	if ( (lasttype != 0) && (lasttype != '\n') && (lasttype != ' ') && (lasttype != '\t') && (type == xxcom))
280 		accum("\t");
281 	else if (lasttype == xxcom && type != '\n')
282 		tab(xxindent);
283 	else
284 		if (lasttype == xxif	||
285 			lasttype == xxwhile	||
286 			lasttype == xxdo	||
287 			type == '='	||
288 			lasttype == '='	||
289 			(lasttype == xxident && (type == xxident || type == xxnum) )	||
290 			(lasttype == xxnum && type == xxnum) )
291 			accum(" ");
292 	accum(string);
293 	lasttype = type;
294 	}
295 
296 
297 accum(token)		/* fill output buffer, generate continuation lines */
298 char *token;
299 	{
300 	static char *buffer;
301 	static int lstatus,llen,bufind;
302 	int tstatus,tlen,i;
303 
304 #define NEW	0
305 #define MID	1
306 #define CONT	2
307 
308 	if (buffer == 0)
309 		{
310 		buffer = malloc(xxmaxchars);
311 		if (buffer == 0) error("malloc out of space","","");
312 		}
313 	tlen = slength(token);
314 	if (tlen == 0) return;
315 	for (i = 0; i < tlen; ++i)
316 		ASSERT(token[i] != '\n' || tlen == 1,accum);
317 	switch(token[tlen-1])
318 		{
319 		case '\n':	tstatus = NEW;
320 				break;
321 		case '+':
322 		case '-':
323 		case '*':
324 		case ',':
325 		case '|':
326 		case '&':
327 		case '(':	tstatus = CONT;
328 				break;
329 		default:	tstatus = MID;
330 		}
331 	if (llen + bufind + tlen > xxmaxchars && lstatus == CONT && tstatus != NEW)
332 		{
333 		putchar('\n');
334 		++xxlineno;
335 		for (i = 0; i < xxindent; ++i)
336 			putchar('\t');
337 		putchar(' ');putchar(' ');
338 		llen = 2 + xxindent * xxbpertab;
339 		lstatus = NEW;
340 		}
341 	if (lstatus == CONT && tstatus == MID)
342 		{			/* store in buffer in case need \n after last CONT char */
343 		ASSERT(bufind + tlen < xxmaxchars,accum);
344 		for (i = 0; i < tlen; ++i)
345 			buffer[bufind++] = token[i];
346 		}
347 	else
348 		{
349 		for (i = 0; i < bufind; ++i)
350 			putchar(buffer[i]);
351 		llen += bufind;
352 		bufind = 0;
353 		for (i = 0; i < tlen; ++i)
354 			putchar(token[i]);
355 		if (tstatus == NEW) ++xxlineno;
356 		llen = (tstatus == NEW) ? 0 : llen + tlen;
357 		lstatus = tstatus;
358 		}
359 	}
360 
361 tab(n)
362 int n;
363 	{
364 	int i;
365 	newline();
366 	for ( i = 0;  i < n; ++i)
367 		putout('\t',"\t");
368 	}
369 
370 newline()
371 	{
372 	static int already;
373 	if (already)
374 		putout('\n',"\n");
375 	else
376 		already = 1;
377 	}
378 
379 error(mess1, mess2, mess3)
380 char *mess1, *mess2, *mess3;
381 	{
382 	fprintf(stderr,"\nerror in beautifying, output line %d: %s %s %s \n",
383 		xxlineno, mess1, mess2, mess3);
384 	exit(1);
385 	}
386 
387 
388 
389 
390 
391 
392 
393 push(type)
394 int type;
395 	{
396 	if (++xxstind > xxtop)
397 		error("nesting too deep, stack overflow","","");
398 	xxstack[xxstind] = type;
399 	}
400 
401 pop()
402 	{
403 	if (xxstind <= 0)
404 		error("stack exhausted, can't be popped as requested","","");
405 	--xxstind;
406 	}
407 
408 
409 forst()
410 	{
411 	while( (xxval = yylex()) != '\n')
412 		{
413 		putout(xxval, yylval);
414 		free(yylval);
415 		}
416 	free(yylval);
417 	}
418