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 8.1 (Berkeley) 06/06/93";
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
yyerror(s)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
yyinit(argc,argv)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>
main()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
putout(type,string)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
accum(token)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
tab(n)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
newline()373 newline()
374 {
375 static int already;
376 if (already)
377 putout('\n',"\n");
378 else
379 already = 1;
380 }
381
error(mess1,mess2,mess3)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
push(type)396 push(type)
397 int type;
398 {
399 if (++xxstind > xxtop)
400 error("nesting too deep, stack overflow","","");
401 xxstack[xxstind] = type;
402 }
403
pop()404 pop()
405 {
406 if (xxstind <= 0)
407 error("stack exhausted, can't be popped as requested","","");
408 --xxstind;
409 }
410
411
forst()412 forst()
413 {
414 while( (xxval = yylex()) != '\n')
415 {
416 putout(xxval, yylval);
417 free(yylval);
418 }
419 free(yylval);
420 }
421