new copyright; att/bsd/shared
[unix-history] / usr / src / usr.bin / struct / beautify / beauty.y
CommitLineData
daf69fb4
RH
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%{
0fc6e47b
KB
17/*-
18 * %sccs.include.proprietary.c%
19 */
20
daf69fb4 21#ifndef lint
0fc6e47b
KB
22static char sccsid[] = "@(#)beauty.y 5.1 (Berkeley) %G%";
23#endif /* not lint */
daf69fb4
RH
24
25#include "b.h"
26#include <stdio.h>
13c5231e 27
13c5231e 28extern struct node *checkneg(), *addroot();
daf69fb4
RH
29%}
30
31%%
32%{
33struct node *t;
34%}
35
36
37allprog: prog xxnew
38 ;
39
40prog: stat
41 | prog stat
42 ;
43
44stat: 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
59xxtab: = {
60 if (!xxlablast) tab(xxindent);
61 xxlablast = 0;
62 }
63
64xxnl: = newline();
65xxnew: = putout('\n',"\n");
66nlevel: pindent stat mindent;
67pindent: =
68 {
69 if (xxstack[xxstind] != xxlb)
70 ++xxindent;
71 };
72mindent: =
73 {if (xxstack[xxstind] != xxlb && xxstack[xxstind] != xxelseif)
74 --xxindent;
75 pop();
76 };
77caseseq: casetok caseseq
78 | casetok
79 ;
80
81casetok: xxtab xxctok predlist pindent prog mindent
82 | xxtab xxctok predlist pindent mindent
83 | xxtab deftok pindent prog mindent
84 | xxnl comtok casetok
85 ;
86
87xxctok: xxcase = {putout(xxcase,"case "); free ($1); push(xxcase); }
88
89
90deftok: xxdefault ':' = {
91 putout(xxcase,"default");
92 free($1);
93 putout(':',":");
94 free($2);
95 push(xxcase);
96 }
97swtok: xxswitch = {putout(xxswitch,"switch"); free($1); push(xxswitch); }
98
99fstok: 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
116identtok: 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
124predlist: explist ':' = {
125 yield($1,0);
126 putout(':',":");
127 freetree($1);
128 }
129explist: expr ',' explist = $$ = addroot($2,xxexplist,checkneg($1,0),$3);
130 | expr = $$ = checkneg($1,0);
131 ;
132
133
134oppred: pred
135 |
136 ;
137
138pred: '(' expr ')' = { t = checkneg($2,0);
139 yield(t,100); freetree(t); };
140
141expr: '(' 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
162iftok: 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 }
180elsetok: xxelse =
181 {
182 tab(xxindent);
183 putout(xxelse,"else");
184 free($1);
185 push(xxelse);
186 }
187whtok: xxwhile = {
188 putout(xxwhile,"while");
189 free($1);
190 push(xxwhile);
191 }
192rpttok: xxrept = {
193 putout(xxrept,"repeat");
194 free($1);
195 push(xxrept);
196 }
197optuntil: xxtab unttok pred
198 |
199 ;
200
201unttok: xxuntil = {
202 putout('\t',"\t");
203 putout(xxuntil,"until");
204 free($1);
205 }
206dotok: dopart opdotok
207 ;
208dopart: 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 }
220opdotok: ',' expr = {
221 putout(',',",");
222 puttree($2);
223 }
224 | ;
225lbtok: '{' = {
226 putout('{'," {");
227 push(xxlb);
228 }
229rbtok: '}' = { putout('}',"}"); pop(); }
230labtok: xxnum = {
231 tab(xxindent);
232 putout(xxnum,$1);
233 putout(' '," ");
234 xxlablast = 1;
235 }
236comtok: 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
241yyerror(s)
242char *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
256yyinit(argc, argv) /* initialize pushdown store */
257int argc;
258char *argv[];
259 {
260 xxindent = 0;
261 xxbpertab = 8;
262 xxmaxchars = 120;
263 }
264
265
266#include <signal.h>
267main()
268 {
269 int exit();
270 if ( signal(SIGINT, SIG_IGN) != SIG_IGN)
271 signal(SIGINT, exit);
272 yyinit();
273 yyparse();
274 }
275
276
277putout(type,string) /* output string with proper indentation */
278int type;
279char *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
300accum(token) /* fill output buffer, generate continuation lines */
301char *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
364tab(n)
365int n;
366 {
367 int i;
368 newline();
369 for ( i = 0; i < n; ++i)
370 putout('\t',"\t");
371 }
372
373newline()
374 {
375 static int already;
376 if (already)
377 putout('\n',"\n");
378 else
379 already = 1;
380 }
381
382error(mess1, mess2, mess3)
383char *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
396push(type)
397int type;
398 {
399 if (++xxstind > xxtop)
400 error("nesting too deep, stack overflow","","");
401 xxstack[xxstind] = type;
402 }
403
404pop()
405 {
406 if (xxstind <= 0)
407 error("stack exhausted, can't be popped as requested","","");
408 --xxstind;
409 }
410
411
412forst()
413 {
414 while( (xxval = yylex()) != '\n')
415 {
416 putout(xxval, yylval);
417 free(yylval);
418 }
419 free(yylval);
420 }