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: %{ 23: struct node *t; 24: %} 25: 26: 27: allprog: prog xxnew 28: ; 29: 30: prog: stat 31: | prog stat 32: ; 33: 34: stat: 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: 49: xxtab: = { 50: if (!xxlablast) tab(xxindent); 51: xxlablast = 0; 52: } 53: 54: xxnl: = newline(); 55: xxnew: = putout('\n',"\n"); 56: nlevel: pindent stat mindent; 57: pindent: = 58: { 59: if (xxstack[xxstind] != xxlb) 60: ++xxindent; 61: }; 62: mindent: = 63: {if (xxstack[xxstind] != xxlb && xxstack[xxstind] != xxelseif) 64: --xxindent; 65: pop(); 66: }; 67: caseseq: casetok caseseq 68: | casetok 69: ; 70: 71: casetok: xxtab xxctok predlist pindent prog mindent 72: | xxtab xxctok predlist pindent mindent 73: | xxtab deftok pindent prog mindent 74: | xxnl comtok casetok 75: ; 76: 77: xxctok: xxcase = {putout(xxcase,"case "); free ($1); push(xxcase); } 78: 79: 80: deftok: xxdefault ':' = { 81: putout(xxcase,"default"); 82: free($1); 83: putout(':',":"); 84: free($2); 85: push(xxcase); 86: } 87: swtok: xxswitch = {putout(xxswitch,"switch"); free($1); push(xxswitch); } 88: 89: fstok: 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: 106: identtok: 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: 114: predlist: explist ':' = { 115: yield($1,0); 116: putout(':',":"); 117: freetree($1); 118: } 119: explist: expr ',' explist = $$ = addroot($2,xxexplist,checkneg($1,0),$3); 120: | expr = $$ = checkneg($1,0); 121: ; 122: 123: 124: oppred: pred 125: | 126: ; 127: 128: pred: '(' expr ')' = { t = checkneg($2,0); 129: yield(t,100); freetree(t); }; 130: 131: expr: '(' 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: 153: iftok: 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: } 171: elsetok: xxelse = 172: { 173: tab(xxindent); 174: putout(xxelse,"else"); 175: free($1); 176: push(xxelse); 177: } 178: whtok: xxwhile = { 179: putout(xxwhile,"while"); 180: free($1); 181: push(xxwhile); 182: } 183: rpttok: xxrept = { 184: putout(xxrept,"repeat"); 185: free($1); 186: push(xxrept); 187: } 188: optuntil: xxtab unttok pred 189: | 190: ; 191: 192: unttok: xxuntil = { 193: putout('\t',"\t"); 194: putout(xxuntil,"until"); 195: free($1); 196: } 197: dotok: dopart opdotok 198: ; 199: dopart: 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: } 211: opdotok: ',' expr = { 212: putout(',',","); 213: puttree($2); 214: } 215: | ; 216: lbtok: '{' = { 217: putout('{'," {"); 218: push(xxlb); 219: } 220: rbtok: '}' = { putout('}',"}"); pop(); } 221: labtok: xxnum = { 222: tab(xxindent); 223: putout(xxnum,$1); 224: putout(' '," "); 225: xxlablast = 1; 226: } 227: comtok: 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: 232: yyerror(s) 233: char *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: 247: yyinit(argc, argv) /* initialize pushdown store */ 248: int argc; 249: char *argv[]; 250: { 251: xxindent = 0; 252: xxbpertab = 8; 253: xxmaxchars = 120; 254: } 255: 256: 257: #include <signal.h> 258: main() 259: { 260: int exit(); 261: if ( signal(SIGINT, SIG_IGN) != SIG_IGN) 262: signal(SIGINT, exit); 263: yyinit(); 264: yyparse(); 265: } 266: 267: 268: putout(type,string) /* output string with proper indentation */ 269: int type; 270: char *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: 291: accum(token) /* fill output buffer, generate continuation lines */ 292: char *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: 355: tab(n) 356: int n; 357: { 358: int i; 359: newline(); 360: for ( i = 0; i < n; ++i) 361: putout('\t',"\t"); 362: } 363: 364: newline() 365: { 366: static int already; 367: if (already) 368: putout('\n',"\n"); 369: else 370: already = 1; 371: } 372: 373: error(mess1, mess2, mess3) 374: char *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: 387: push(type) 388: int type; 389: { 390: if (++xxstind > xxtop) 391: error("nesting too deep, stack overflow","",""); 392: xxstack[xxstind] = type; 393: } 394: 395: pop() 396: { 397: if (xxstind <= 0) 398: error("stack exhausted, can't be popped as requested","",""); 399: --xxstind; 400: } 401: 402: 403: forst() 404: { 405: while( (xxval = yylex()) != '\n') 406: { 407: putout(xxval, yylval); 408: free(yylval); 409: } 410: free(yylval); 411: }