1: # include "y.tab.h" 2: #include "b.h" 3: #include <stdio.h> 4: 5: 6: addroot(string,type,n1,n2) 7: char *string; 8: int type; 9: struct node *n1, *n2; 10: { 11: struct node *p; 12: p = malloc(sizeof(*p)); 13: p->left = n1; 14: p->right = n2; 15: p->op = type; 16: p->lit = malloc(slength(string) + 1); 17: str_copy(string,p->lit,slength(string) + 1); 18: return(p); 19: } 20: 21: 22: freetree(tree) 23: struct node *tree; 24: { 25: if (tree) 26: {freetree(tree->left); 27: freetree(tree->right); 28: freenode(tree); 29: } 30: } 31: 32: freenode(treenode) 33: struct node *treenode; 34: { 35: free(treenode->lit); 36: free(treenode); 37: } 38: 39: int compop[] { '&', '|', '<', '>', xxeq, xxle, xxne, xxge}; 40: int notop[] { '|', '&', xxge, xxle, xxne, '>', xxeq, '<'}; 41: char *opstring[] { "||", "&&", ">=", "<=", "!=", ">", "==", "<"}; 42: 43: checkneg(tree,neg) /* eliminate nots if possible */ 44: struct node *tree; 45: int neg; 46: { 47: int i; 48: struct node *t; 49: if (!tree) return(0); 50: for (i = 0; i < 8; ++i) 51: if (tree->op == compop[i]) break; 52: if (i > 1 && i < 8 && tree ->left ->op == '-' && str_eq(tree->right->lit,"0")) 53: { 54: t = tree->right; 55: tree->right = tree->left->right; 56: freenode(t); 57: t = tree->left; 58: tree->left = tree->left->left; 59: freenode(t); 60: } 61: 62: 63: if (neg) 64: { 65: if (tree ->op == '!') 66: { 67: t = tree->left; 68: freenode(tree); 69: return(checkneg(t,0)); 70: } 71: if (i < 8) 72: { 73: tree->op = notop[i]; 74: free(tree->lit); 75: tree->lit = malloc(slength(opstring[i])+1); 76: str_copy(opstring[i],tree->lit, slength(opstring[i])+1); 77: if (tree->op == '&' || tree->op == '|') 78: { 79: tree->left = checkneg(tree->left,1); 80: tree->right = checkneg(tree->right,1); 81: } 82: return(tree); 83: } 84: if (tree->op == xxident && str_eq(tree->lit,".false.")) 85: str_copy(".true.",tree->lit, slength(".true.")+1); 86: else if (tree->op == xxident && str_eq(tree->lit,".true.")) 87: { 88: free(tree->lit); 89: tree->lit = malloc(slength(".false.")+1); 90: str_copy(".false.",tree->lit, slength(".false.")+1); 91: } 92: else 93: { 94: tree = addroot("!",'!',tree,0); 95: tree->lit = malloc(2); 96: str_copy("!",tree->lit, slength("!")+1); 97: } 98: return(tree); 99: } 100: else 101: if (tree->op == '!') 102: { 103: t = tree; 104: tree = tree->left; 105: freenode(t); 106: return(checkneg(tree,1)); 107: } 108: else 109: {tree->left = checkneg(tree->left,0); 110: tree->right = checkneg(tree->right,0); 111: return(tree); 112: } 113: } 114: 115: yield(tree,fprec) 116: struct node *tree; 117: int fprec; /* fprec is precedence of father of this node */ 118: { 119: int paren,p; 120: static int oplast; /* oplast = 1 iff last char printed was operator */ 121: if (!tree) return; 122: p = prec(tree ->op); 123: paren = (p < fprec || (oplast && tree->op == xxuminus)) ? 1 : 0; 124: 125: if (paren) 126: { 127: putout('(',"("); 128: oplast = 0; 129: } 130: 131: switch(tree->op) 132: { 133: case xxuminus: 134: tree->op = '-'; 135: case '!': 136: putout(tree->op,tree->lit); 137: oplast = 1; 138: yield(tree->left,p); 139: break; 140: case '&': 141: case '|': 142: case '<': 143: case '>': 144: case xxeq: 145: case xxle: 146: case xxge: 147: case '+': 148: case '-': 149: case '*': 150: case '/': 151: case '^': 152: yield(tree->left,p); 153: putout(tree->op, tree->lit); 154: oplast = 1; 155: yield(tree->right,p); 156: break; 157: case xxidpar: 158: yield(tree->left,0); 159: putout('(',"("); 160: oplast = 0; 161: yield(tree->right,0); 162: putout('(',")"); 163: oplast = 0; 164: break; 165: default: 166: yield(tree->left,p); 167: putout(tree->op, tree->lit); 168: oplast = 0; 169: yield(tree->right,p); 170: break; 171: } 172: if (paren) 173: { 174: putout(')',")"); 175: oplast = 0; 176: } 177: } 178: 179: puttree(tree) 180: struct node *tree; 181: { 182: yield(tree,0); 183: freetree(tree); 184: } 185: 186: 187: prec(oper) 188: int oper; 189: { 190: switch(oper) 191: { 192: case ',': return(0); 193: case '|': return(1); 194: case '&': return(2); 195: case '!': return(3); 196: 197: case '<': case '>': case xxeq: 198: case xxne: case xxle: case xxge: 199: return(4); 200: case '+': 201: case '-': return(5); 202: case '*': 203: case '/': return(6); 204: case xxuminus: return(7); 205: case '^': return(8); 206: default: return(9); 207: } 208: } 209: str_copy(s,ptr,length) /* copy s at ptr, return length of s */ 210: char *s, *ptr; 211: int length; 212: {int i; 213: for (i = 0; i < length; i++) 214: { 215: ptr[i] = s[i]; 216: if (ptr[i] == '\0') 217: return(i + 1); 218: } 219: fprintf(2,"string %s too long to be copied by str_copy at address %d\n", 220: *s,ptr); 221: exit(1); 222: } 223: str_eq(s,t) 224: char s[],t[]; 225: {int j; 226: for (j = 0; s[j] == t[j]; j++) 227: {if (s[j] == '\0') return(1);} 228: return(0); 229: } 230: 231: slength(s) /* return number of chars in s, not counting '\0' */ 232: char *s; 233: { 234: int i; 235: if (!s) return(-1); 236: for (i = 0; s[i] != '\0'; i++); 237: return(i); 238: }