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