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