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