Show More
@@ -108,3 +108,80 b' def prettyformat(tree, leafnodes):' | |||
|
108 | 108 | _prettyformat(tree, leafnodes, 0, lines) |
|
109 | 109 | output = '\n'.join((' ' * l + s) for l, s in lines) |
|
110 | 110 | return output |
|
111 | ||
|
112 | def simplifyinfixops(tree, targetnodes): | |
|
113 | """Flatten chained infix operations to reduce usage of Python stack | |
|
114 | ||
|
115 | >>> def f(tree): | |
|
116 | ... print prettyformat(simplifyinfixops(tree, ('or',)), ('symbol',)) | |
|
117 | >>> f(('or', | |
|
118 | ... ('or', | |
|
119 | ... ('symbol', '1'), | |
|
120 | ... ('symbol', '2')), | |
|
121 | ... ('symbol', '3'))) | |
|
122 | (or | |
|
123 | ('symbol', '1') | |
|
124 | ('symbol', '2') | |
|
125 | ('symbol', '3')) | |
|
126 | >>> f(('func', | |
|
127 | ... ('symbol', 'p1'), | |
|
128 | ... ('or', | |
|
129 | ... ('or', | |
|
130 | ... ('func', | |
|
131 | ... ('symbol', 'sort'), | |
|
132 | ... ('list', | |
|
133 | ... ('or', | |
|
134 | ... ('or', | |
|
135 | ... ('symbol', '1'), | |
|
136 | ... ('symbol', '2')), | |
|
137 | ... ('symbol', '3')), | |
|
138 | ... ('negate', | |
|
139 | ... ('symbol', 'rev')))), | |
|
140 | ... ('and', | |
|
141 | ... ('symbol', '4'), | |
|
142 | ... ('group', | |
|
143 | ... ('or', | |
|
144 | ... ('or', | |
|
145 | ... ('symbol', '5'), | |
|
146 | ... ('symbol', '6')), | |
|
147 | ... ('symbol', '7'))))), | |
|
148 | ... ('symbol', '8')))) | |
|
149 | (func | |
|
150 | ('symbol', 'p1') | |
|
151 | (or | |
|
152 | (func | |
|
153 | ('symbol', 'sort') | |
|
154 | (list | |
|
155 | (or | |
|
156 | ('symbol', '1') | |
|
157 | ('symbol', '2') | |
|
158 | ('symbol', '3')) | |
|
159 | (negate | |
|
160 | ('symbol', 'rev')))) | |
|
161 | (and | |
|
162 | ('symbol', '4') | |
|
163 | (group | |
|
164 | (or | |
|
165 | ('symbol', '5') | |
|
166 | ('symbol', '6') | |
|
167 | ('symbol', '7')))) | |
|
168 | ('symbol', '8'))) | |
|
169 | """ | |
|
170 | if not isinstance(tree, tuple): | |
|
171 | return tree | |
|
172 | op = tree[0] | |
|
173 | if op not in targetnodes: | |
|
174 | return (op,) + tuple(simplifyinfixops(x, targetnodes) for x in tree[1:]) | |
|
175 | ||
|
176 | # walk down left nodes taking each right node. no recursion to left nodes | |
|
177 | # because infix operators are left-associative, i.e. left tree is deep. | |
|
178 | # e.g. '1 + 2 + 3' -> (+ (+ 1 2) 3) -> (+ 1 2 3) | |
|
179 | simplified = [] | |
|
180 | x = tree | |
|
181 | while x[0] == op: | |
|
182 | l, r = x[1:] | |
|
183 | simplified.append(simplifyinfixops(r, targetnodes)) | |
|
184 | x = l | |
|
185 | simplified.append(simplifyinfixops(x, targetnodes)) | |
|
186 | simplified.append(op) | |
|
187 | return tuple(reversed(simplified)) |
General Comments 0
You need to be logged in to leave comments.
Login now