| Home | Trees | Indices | Help |
|---|
|
|
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 # Contributor(s): 18 # - "mereandor" / mereandor at gmail dot com (Roman) 19 # Portions created by the Contributors are Copyright (C) 2009 20 # The Contributors. All Rights Reserved. 21 # 22 # Alternatively, the contents of this file may be used under the terms 23 # of the LGPL license (the GNU Lesser General Public License, 24 # http://www.gnu.org/licenses/lgpl.html), in which case the provisions 25 # of the LGPL License are applicable instead of those above. 26 # 27 # If you wish to allow use of your version of this file only under the 28 # terms of the LGPL License and not to allow others to use your version 29 # of this file under the MPL, indicate your decision by deleting the 30 # provisions above and replace them with the notice and other provisions 31 # required by the LGPL License. If you do not delete the provisions 32 # above, a recipient may use your version of this file under either the 33 # MPL or the LGPL License. 34 35 ''' 36 Contributed matchers. 37 ''' 38 39 from copy import copy 40 41 from lepl.matchers.derived import Optional 42 from lepl.matchers.combine import And, Or, BaseSearch 43 from lepl.matchers.matcher import is_child 44 from lepl.matchers.transform import Transform 45 from lepl.matchers.operators import _BaseSeparator 46 47 48 # (c) 2009 "mereandor" / mereandor at gmail dot com (Roman), Andrew Cooke 49 50 # pylint: disable-msg=R090352 ''' 53 A substitute `Separator` with different semantics for optional matchers. 54 This identifies optional matchers by type (whether they subclass 55 `BaseSearch`) and then constructs a replacement that adds space only 56 when both matchers are used. 57 58 See also `SmartSeparator1`, which is more general but less efficient. 59 ''' 60112 return (and_, self._repeat(separator)) 11362 ''' 63 Provide alternative definitions of '&` and `[]`. 64 ''' 65 66 def non_optional_copy(matcher): 67 ''' 68 Check whether a matcher is optional and, if so, make it not so. 69 ''' 70 # both of the "copy" calls below make me nervous - it's not the 71 # way the rest of lepl works - but i don't have any specific 72 # criticism, or a good alternative. 73 required, optional = matcher, False 74 if isinstance(matcher, Transform): 75 temp, optional = non_optional_copy(matcher.matcher) 76 if optional: 77 required = copy(matcher) 78 required.matcher = temp 79 elif is_child(matcher, BaseSearch, fail=False): 80 # this introspection only works because Repeat sets named 81 # (ie kargs) arguments. 82 optional = (matcher.start == 0) 83 if optional: 84 required = copy(matcher) 85 required.start = 1 86 if required.stop == 1: 87 required = required.first 88 return required, optional89 90 # pylint: disable-msg=W0141 91 def and_(matcher_a, matcher_b): 92 ''' 93 Combine two matchers. 94 ''' 95 (requireda, optionala) = non_optional_copy(matcher_a) 96 (requiredb, optionalb) = non_optional_copy(matcher_b) 97 98 if not (optionala or optionalb): 99 return And(matcher_a, separator, matcher_b) 100 else: 101 matcher = Or( 102 *filter((lambda x: x is not None), [ 103 And(Optional(And(requireda, separator)), requiredb) 104 if optionala else None, 105 And(requireda, Optional(And(separator, requiredb))) 106 if optionalb else None])) 107 if optionala and optionalb: 108 # making this explicit allows chaining (we can detect it 109 # when called again in a tree of "ands") 110 matcher = Optional(matcher) 111 return matcher
| Home | Trees | Indices | Help |
|---|
| Generated by Epydoc 3.0.1 on Sun Jan 8 17:18:57 2012 | http://epydoc.sourceforge.net |