Package lepl :: Package core :: Package _test :: Module rewriters
[hide private]
[frames] | no frames]

Source Code for Module lepl.core._test.rewriters

  1   
  2  # The contents of this file are subject to the Mozilla Public License 
  3  # (MPL) Version 1.1 (the "License"); you may not use this file except 
  4  # in compliance with the License. You may obtain a copy of the License 
  5  # at http://www.mozilla.org/MPL/ 
  6  # 
  7  # Software distributed under the License is distributed on an "AS IS" 
  8  # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 
  9  # the License for the specific language governing rights and 
 10  # limitations under the License. 
 11  # 
 12  # The Original Code is LEPL (http://www.acooke.org/lepl) 
 13  # The Initial Developer of the Original Code is Andrew Cooke. 
 14  # Portions created by the Initial Developer are Copyright (C) 2009-2010 
 15  # Andrew Cooke (andrew@acooke.org). All Rights Reserved. 
 16  # 
 17  # Alternatively, the contents of this file may be used under the terms 
 18  # of the LGPL license (the GNU Lesser General Public License, 
 19  # http://www.gnu.org/licenses/lgpl.html), in which case the provisions 
 20  # of the LGPL License are applicable instead of those above. 
 21  # 
 22  # If you wish to allow use of your version of this file only under the 
 23  # terms of the LGPL License and not to allow others to use your version 
 24  # of this file under the MPL, indicate your decision by deleting the 
 25  # provisions above and replace them with the notice and other provisions 
 26  # required by the LGPL License.  If you do not delete the provisions 
 27  # above, a recipient may use your version of this file under either the 
 28  # MPL or the LGPL License. 
 29   
 30  ''' 
 31  Tests for the lepl.core.rewriters module. 
 32  ''' 
 33   
 34  #from logging import basicConfig, DEBUG 
 35  from re import sub 
 36  from unittest import TestCase 
 37   
 38  from lepl.support.node import Node 
 39  from lepl.matchers.core import Any, Delayed 
 40  from lepl.matchers.derived import Optional, Drop, And, Join, Digit 
 41  from lepl.matchers.combine import Or 
 42  from lepl.support.graph import preorder 
 43  from lepl.matchers.matcher import Matcher, is_child 
 44  from lepl.matchers.support import TransformableWrapper 
 45   
 46   
 47  # pylint: disable-msg=C0103, C0111, C0301, W0702, C0324, C0321 
 48  # (dude this is just a test) 
 49   
 50       
51 -def str26(value):
52 ''' 53 Hack 2.6 string conversion 54 ''' 55 string = str(value) 56 return string.replace("u'", "'")
57 58 59 #class DelayedCloneTest(TestCase): 60 # 61 # def assert_clone(self, matcher): 62 # _copy = matcher.postorder(DelayedClone(), Matcher) 63 # 64 # def _assert_clone(self, matcher, copy): 65 # original = preorder(matcher, Matcher) 66 # duplicate = preorder(copy, Matcher) 67 # try: 68 # while True: 69 # o = next(original) 70 # d = next(duplicate) 71 # assert type(o) == type(d), (str(o), str(d), o, d) 72 # if isinstance(o, Matcher): 73 # assert o is not d, (str(o), str(d), o, d) 74 # else: 75 # assert o is d, (str(o), str(d), o, d) 76 # except StopIteration: 77 # self.assert_empty(original, 'original') 78 # self.assert_empty(duplicate, 'duplicate') 79 # 80 # def assert_relative(self, matcher): 81 # copy = matcher.postorder(DelayedClone(), Matcher) 82 # def pairs(matcher): 83 # for a in preorder(matcher, Matcher): 84 # for b in preorder(matcher, Matcher): 85 # yield (a, b) 86 # for ((a,b), (c,d)) in zip(pairs(matcher), pairs(copy)): 87 # if a is b: 88 # assert c is d 89 # else: 90 # assert c is not d 91 # if type(a) is type(b): 92 # assert type(c) is type(d) 93 # else: 94 # assert type(c) is not type(d) 95 # 96 # def assert_empty(self, generator, name): 97 # try: 98 # next(generator) 99 # assert False, name + ' not empty' 100 # except StopIteration: 101 # pass 102 # 103 # def test_no_delayed(self): 104 # matcher = Any('a') | Any('b')[1:2,...] 105 # self.assert_clone(matcher) 106 # self.assert_relative(matcher) 107 # 108 # def test_simple_loop(self): 109 # delayed = Delayed() 110 # matcher = Any('a') | Any('b')[1:2,...] | delayed 111 # self.assert_clone(matcher) 112 # self.assert_relative(matcher) 113 # 114 # def test_complex_loop(self): 115 # delayed1 = Delayed() 116 # delayed2 = Delayed() 117 # line1 = Any('a') | Any('b')[1:2,...] | delayed1 118 # line2 = delayed1 & delayed2 119 # matcher = line1 | line2 | delayed1 | delayed2 > 'foo' 120 # self.assert_clone(matcher) 121 # self.assert_relative(matcher) 122 # 123 # def test_common_child(self): 124 # a = Any('a') 125 # b = a | Any('b') 126 # c = a | b | Any('c') 127 # matcher = a | b | c 128 # self.assert_clone(matcher) 129 # self.assert_relative(matcher) 130 # 131 # def test_full_config_loop(self): 132 # matcher = Delayed() 133 # matcher += Any() & matcher 134 # matcher.config.no_full_first_match().no_memoize() 135 # copy = matcher.get_parse_string().matcher 136 # self._assert_clone(matcher, copy) 137 # 138 # def test_transformed_etc(self): 139 # class Term(Node): pass 140 # class Factor(Node): pass 141 # class Expression(Node): pass 142 # 143 # expression = Delayed() 144 # number = Digit()[1:,...] > 'number' 145 # term = (number | '(' / expression / ')') > Term 146 # muldiv = Any('*/') > 'operator' 147 # factor = (term / (muldiv / term)[0::]) > Factor 148 # addsub = Any('+-') > 'operator' 149 # expression += (factor / (addsub / factor)[0::]) > Expression 150 # 151 # self.assert_clone(expression) 152 # self.assert_relative(expression) 153 # expression.config.no_full_first_match().no_compile_to_regexp() 154 # expression.config.no_compose_transforms().no_direct_eval() 155 # expression.config.no_flatten().no_memoize() 156 # copy = expression.get_parse_string().matcher 157 # self._assert_clone(expression, copy) 158 159
160 -def append(x):
161 return lambda l: l[0] + x
162
163 -class ComposeTransformsTest(TestCase):
164
165 - def test_null(self):
166 matcher = Any() > append('x') 167 matcher.config.clear() 168 parser = matcher.get_parse() 169 result = parser('a')[0] 170 assert result == 'ax', result
171
172 - def test_simple(self):
173 matcher = Any() > append('x') 174 matcher.config.clear().compose_transforms() 175 parser = matcher.get_parse() 176 result = parser('a')[0] 177 assert result == 'ax', result
178
179 - def test_double(self):
180 matcher = (Any() > append('x')) > append('y') 181 matcher.config.clear().compose_transforms() 182 parser = matcher.get_parse() 183 result = parser('a')[0] 184 assert result == 'axy', result 185 assert isinstance(parser.matcher, TransformableWrapper) 186 assert len(parser.matcher.wrapper.functions) == 2
187 188 # And is no longer transformable 189 # def test_and(self): 190 # matcher = (Any() & Optional(Any())) > append('x') 191 # matcher.config.clear().compose_transforms() 192 # parser = matcher.get_parse() 193 # result = parser('a')[0] 194 # assert result == 'ax', result 195 # assert is_child(parser.matcher, And), type(parser.matcher) 196
197 - def test_loop(self):
198 matcher = Delayed() 199 matcher += (Any() | matcher) > append('x') 200 matcher.config.clear().compose_transforms() 201 parser = matcher.get_parse() 202 result = parser('a')[0] 203 assert result == 'ax', result 204 assert isinstance(parser.matcher, Delayed)
205
206 - def test_node(self):
207 208 class Term(Node): pass 209 210 number = Any('1') > 'number' 211 term = number > Term 212 factor = term | Drop(Optional(term)) 213 214 factor.config.clear().compose_transforms() 215 p = factor.get_parse_string() 216 ast = p('1')[0] 217 assert type(ast) == Term, type(ast) 218 assert ast[0] == '1', ast[0] 219 assert str26(ast) == """Term 220 `- number '1'""", ast
221 222
223 -class OptimizeOrTest(TestCase):
224
225 - def test_conservative(self):
226 matcher = Delayed() 227 matcher += matcher | Any() 228 assert isinstance(matcher.matcher.matchers[0], Delayed) 229 matcher.config.clear().optimize_or(True) 230 matcher.get_parse_string() 231 # TODO - better test 232 assert isinstance(matcher.matcher.matchers[0], 233 TransformableWrapper)
234
235 - def test_liberal(self):
236 matcher = Delayed() 237 matcher += matcher | Any() 238 assert isinstance(matcher.matcher.matchers[0], Delayed) 239 matcher.config.clear().optimize_or(False) 240 matcher.get_parse_string() 241 # TODO - better test 242 assert isinstance(matcher.matcher.matchers[0], 243 TransformableWrapper)
244 245
246 -class AndNoTrampolineTest(TestCase):
247
248 - def test_replace(self):
249 #basicConfig(level=DEBUG) 250 matcher = And('a', 'b') 251 matcher.config.clear().direct_eval() 252 parser = matcher.get_parse() 253 text = str(parser.matcher) 254 assert "AndNoTrampoline(Literal, Literal)" == text, text 255 result = parser('ab') 256 assert result == ['a', 'b'], result
257 258
259 -class FlattenTest(TestCase):
260
261 - def test_flatten_and(self):
262 matcher = And('a', And('b', 'c')) 263 matcher.config.clear().flatten() 264 parser = matcher.get_parse() 265 text = str(parser.matcher) 266 assert text == "And(Literal, Literal, Literal)", text 267 result = parser('abcd') 268 assert result == ['a', 'b', 'c'], result
269
270 - def test_no_flatten_and(self):
271 matcher = And('a', Join(And('b', 'c'))) 272 matcher.config.clear().flatten() 273 parser = matcher.get_parse() 274 text = str(parser.matcher) 275 assert text == "And(Literal, Transform)", text 276 result = parser('abcd') 277 assert result == ['a', 'bc'], result
278
280 matcher = Join(And('a', And('b', 'c'))) 281 matcher.config.clear().flatten() 282 parser = matcher.get_parse() 283 text = sub('<.*>', '<>', str(parser.matcher)) 284 assert text == "Transform(And, TransformationWrapper(<>))", text 285 result = parser('abcd') 286 assert result == ['abc'], result
287
288 - def test_flatten_or(self):
289 matcher = Or('a', Or('b', 'c')) 290 matcher.config.clear().flatten() 291 parser = matcher.get_parse() 292 text = str(parser.matcher) 293 assert text == "Or(Literal, Literal, Literal)", text 294 result = parser('abcd') 295 assert result == ['a'], result
296
297 - def test_no_flatten_or(self):
298 matcher = Or('a', Join(Or('b', 'c'))) 299 matcher.config.clear().flatten() 300 parser = matcher.get_parse() 301 text = str(parser.matcher) 302 assert text == "Or(Literal, Transform)", text 303 result = parser('abcd') 304 assert result == ['a'], result
305
306 - def test_bug(self):
307 matcher = Any()[:,...] > 'bar' 308 parser = matcher.get_parse_string() 309 result = parser('foo') 310 assert result == [('bar', 'foo')], result
311