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