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