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