Research V7 development
[unix-history] / usr / src / cmd / struct / beauty.y
CommitLineData
0cd95c78
BB
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 %prec xxuminus = $$ = $2;
134 | '!' expr = $$ = addroot($1,'!',$2,0);
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 '<' expr = $$ = addroot($2,'<',$1,$3);
144 | expr xxeq expr = $$ = addroot($2,xxeq,$1,$3);
145 | expr xxle expr = $$ = addroot($2,xxle,$1,$3);
146 | expr xxge expr = $$ = addroot($2,xxge,$1,$3);
147 | expr xxne expr = $$ = addroot($2,xxne,$1,$3);
148 | identtok = $$ = $1;
149 | xxnum = $$ = addroot($1,xxnum,0,0);
150 | xxstring = $$ = addroot($1,xxstring,0,0);
151 ;
152
153iftok: xxif =
154 {
155 if (xxstack[xxstind] == xxelse && !xxlablast)
156 {
157 --xxindent;
158 xxstack[xxstind] = xxelseif;
159 putout(' '," ");
160 }
161 else
162 {
163 if (!xxlablast)
164 tab(xxindent);
165 xxlablast = 0;
166 }
167 putout(xxif,"if");
168 free($1);
169 push(xxif);
170 }
171elsetok: xxelse =
172 {
173 tab(xxindent);
174 putout(xxelse,"else");
175 free($1);
176 push(xxelse);
177 }
178whtok: xxwhile = {
179 putout(xxwhile,"while");
180 free($1);
181 push(xxwhile);
182 }
183rpttok: xxrept = {
184 putout(xxrept,"repeat");
185 free($1);
186 push(xxrept);
187 }
188optuntil: xxtab unttok pred
189 |
190 ;
191
192unttok: xxuntil = {
193 putout('\t',"\t");
194 putout(xxuntil,"until");
195 free($1);
196 }
197dotok: dopart opdotok
198 ;
199dopart: xxdo identtok '=' expr ',' expr =
200 {push(xxdo);
201 putout(xxdo,"do");
202 free($1);
203 puttree($2);
204 putout('=',"=");
205 free($3);
206 puttree($4);
207 putout(',',",");
208 free($5);
209 puttree($6);
210 }
211opdotok: ',' expr = {
212 putout(',',",");
213 puttree($2);
214 }
215 | ;
216lbtok: '{' = {
217 putout('{'," {");
218 push(xxlb);
219 }
220rbtok: '}' = { putout('}',"}"); pop(); }
221labtok: xxnum = {
222 tab(xxindent);
223 putout(xxnum,$1);
224 putout(' '," ");
225 xxlablast = 1;
226 }
227comtok: xxcom = { putout(xxcom,$1); free($1); xxlablast = 0; }
228 | comtok xxcom = { putout ('\n',"\n"); putout(xxcom,$2); free($2); xxlablast = 0; };
229%%
230#define ASSERT(X,Y) if (!(X)) error("struct bug: assertion 'X' invalid in routine Y","","");
231
232yyerror(s)
233char *s;
234 {
235 extern int yychar;
236 fprintf(stderr,"\n%s",s);
237 fprintf(stderr," in beautifying, output line %d,",xxlineno + 1);
238 fprintf(stderr," on input: ");
239 switch (yychar) {
240 case '\t': fprintf(stderr,"\\t\n"); return;
241 case '\n': fprintf(stderr,"\\n\n"); return;
242 case '\0': fprintf(stderr,"$end\n"); return;
243 default: fprintf(stderr,"%c\n",yychar); return;
244 }
245 }
246
247yyinit(argc, argv) /* initialize pushdown store */
248int argc;
249char *argv[];
250 {
251 xxindent = 0;
252 xxbpertab = 8;
253 xxmaxchars = 120;
254 }
255
256
257#include <signal.h>
258main()
259 {
260 int exit();
261 if ( signal(SIGINT, SIG_IGN) != SIG_IGN)
262 signal(SIGINT, exit);
263 yyinit();
264 yyparse();
265 }
266
267
268putout(type,string) /* output string with proper indentation */
269int type;
270char *string;
271 {
272 static int lasttype;
273 if ( (lasttype != 0) && (lasttype != '\n') && (lasttype != ' ') && (lasttype != '\t') && (type == xxcom))
274 accum("\t");
275 else if (lasttype == xxcom && type != '\n')
276 tab(xxindent);
277 else
278 if (lasttype == xxif ||
279 lasttype == xxwhile ||
280 lasttype == xxdo ||
281 type == '=' ||
282 lasttype == '=' ||
283 (lasttype == xxident && (type == xxident || type == xxnum) ) ||
284 (lasttype == xxnum && type == xxnum) )
285 accum(" ");
286 accum(string);
287 lasttype = type;
288 }
289
290
291accum(token) /* fill output buffer, generate continuation lines */
292char *token;
293 {
294 static char *buffer;
295 static int lstatus,llen,bufind;
296 int tstatus,tlen,i;
297
298#define NEW 0
299#define MID 1
300#define CONT 2
301
302 if (buffer == 0)
303 {
304 buffer = malloc(xxmaxchars);
305 if (buffer == 0) error("malloc out of space","","");
306 }
307 tlen = slength(token);
308 if (tlen == 0) return;
309 for (i = 0; i < tlen; ++i)
310 ASSERT(token[i] != '\n' || tlen == 1,accum);
311 switch(token[tlen-1])
312 {
313 case '\n': tstatus = NEW;
314 break;
315 case '+':
316 case '-':
317 case '*':
318 case ',':
319 case '|':
320 case '&':
321 case '(': tstatus = CONT;
322 break;
323 default: tstatus = MID;
324 }
325 if (llen + bufind + tlen > xxmaxchars && lstatus == CONT && tstatus != NEW)
326 {
327 putchar('\n');
328 ++xxlineno;
329 for (i = 0; i < xxindent; ++i)
330 putchar('\t');
331 putchar(' ');putchar(' ');
332 llen = 2 + xxindent * xxbpertab;
333 lstatus = NEW;
334 }
335 if (lstatus == CONT && tstatus == MID)
336 { /* store in buffer in case need \n after last CONT char */
337 ASSERT(bufind + tlen < xxmaxchars,accum);
338 for (i = 0; i < tlen; ++i)
339 buffer[bufind++] = token[i];
340 }
341 else
342 {
343 for (i = 0; i < bufind; ++i)
344 putchar(buffer[i]);
345 llen += bufind;
346 bufind = 0;
347 for (i = 0; i < tlen; ++i)
348 putchar(token[i]);
349 if (tstatus == NEW) ++xxlineno;
350 llen = (tstatus == NEW) ? 0 : llen + tlen;
351 lstatus = tstatus;
352 }
353 }
354
355tab(n)
356int n;
357 {
358 int i;
359 newline();
360 for ( i = 0; i < n; ++i)
361 putout('\t',"\t");
362 }
363
364newline()
365 {
366 static int already;
367 if (already)
368 putout('\n',"\n");
369 else
370 already = 1;
371 }
372
373error(mess1, mess2, mess3)
374char *mess1, *mess2, *mess3;
375 {
376 fprintf(stderr,"\nerror in beautifying, output line %d: %s %s %s \n",
377 xxlineno, mess1, mess2, mess3);
378 exit(1);
379 }
380
381
382
383
384
385
386
387push(type)
388int type;
389 {
390 if (++xxstind > xxtop)
391 error("nesting too deep, stack overflow","","");
392 xxstack[xxstind] = type;
393 }
394
395pop()
396 {
397 if (xxstind <= 0)
398 error("stack exhausted, can't be popped as requested","","");
399 --xxstind;
400 }
401
402
403forst()
404 {
405 while( (xxval = yylex()) != '\n')
406 {
407 putout(xxval, yylval);
408 free(yylval);
409 }
410 free(yylval);
411 }