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