|
|
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.