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