|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.