def test_depth(self): #basicConfig(level=DEBUG) matcher = DepthFirst(self.matcher(), 1, 2) matcher.config.no_full_first_match() matcher = matcher.get_match() results = list(map(''.join, map(lambda x: x[0], matcher('123')))) assert results == ['12', '1'], results
def test_depth(self): # basicConfig(level=DEBUG) matcher = DepthFirst(self.matcher(), 1, 2) matcher.config.no_full_first_match() matcher = matcher.get_match() results = list(map("".join, map(lambda x: x[0], matcher("123")))) assert results == ["12", "1"], results
def Repeat(matcher, start=0, stop=None, algorithm=DEPTH_FIRST, separator=None, add_=False): ''' This is called by the [] operator. It repeats the given matcher between start and stop number of times (inclusive). If ``add`` is true then the results are joined with `Add`. If ``separator`` is given then each repetition is separated by that matcher. ''' first = coerce_(matcher) if separator is None: rest = first else: rest = And(coerce_(separator, Regexp), first) if start is None: start = 0 assert_type('The start index for Repeat or [...]', start, int) assert_type('The stop index for Repeat or [...]', stop, int, none_ok=True) assert_type('The algorithm/increment for Repeat or [...]', algorithm, str) if start < 0: raise ValueError('Repeat or [...] cannot have a negative start.') if stop is not None and stop < start: raise ValueError('Repeat or [...] must have a stop ' 'value greater than or equal to the start.') if 'dbgn'.find(algorithm) == -1: raise ValueError('Repeat or [...] must have a step (algorithm) ' 'of d, b, g or n.') add_ = Add if add_ else Identity return {DEPTH_FIRST: add_(DepthFirst(first=first, start=start, stop=stop, rest=rest)), BREADTH_FIRST: add_(BreadthFirst(first=first, start=start, stop=stop, rest=rest)), GREEDY: add_(OrderByResultCount(BreadthFirst(first=first, start=start, stop=stop, rest=rest))), NON_GREEDY: add_(OrderByResultCount(BreadthFirst(first=first, start=start, stop=stop, rest=rest), False)) }[algorithm]
def Repeat(matcher, start=0, stop=None, limit=None, algorithm=DEPTH_FIRST, separator=None, add_=False, reduce=None): ''' This is called by the [] operator. It repeats the given matcher between `start` and `stop` number of times (inclusive). If `limit` is given it is an upper limit on the number of different results returned on backtracking. `algorithm` selects the repeat algorithm to use. If `separator` is given then each repetition is separated by that matcher. If `add_` is true then the results are joined with `Add` (once all results are obtained). If `reduce` is given it should be a pair (zero, join) where `join(results, next)` is used to accumulate results and `zero` is the initial value of `results`. This is implemented via `Reduce`. `reduce` and `add_` cannot be given together. ''' first = coerce_(matcher) if separator is None: rest = first else: rest = And(coerce_(separator, Regexp), first) if start is None: start = 0 # allow duck typing (mutable values - IntVar etc) # assert_type('The start index for Repeat or [...]', start, int) # assert_type('The stop index for Repeat or [...]', stop, int, none_ok=True) # assert_type('The limit value (step index) for Repeat or [...]', limit, int, none_ok=True) # assert_type('The algorithm (step index) for Repeat or [...]', algorithm, str) # if start < 0: # raise ValueError('Repeat or [...] cannot have a negative start.') # if stop is not None and stop < start: # raise ValueError('Repeat or [...] must have a stop ' # 'value greater than or equal to the start.') # if 'dbgn'.find(algorithm) == -1: # raise ValueError('Repeat or [...] must have a step (algorithm) ' # 'of d, b, g or n.') if add_ and reduce: raise ValueError('Repeat cannot apply both add_ and reduce') elif add_: process = Add elif reduce: process = lambda r: Reduce(r, reduce[0], reduce[1]) else: process = Identity matcher = { DEPTH_FIRST: process(DepthFirst(first=first, start=start, stop=stop, rest=rest)), BREADTH_FIRST: process(BreadthFirst(first=first, start=start, stop=stop, rest=rest)), GREEDY: process( OrderByResultCount( BreadthFirst(first=first, start=start, stop=stop, rest=rest))), NON_GREEDY: process( OrderByResultCount( BreadthFirst(first=first, start=start, stop=stop, rest=rest), False)) }[algorithm] if limit is not None: matcher = Limit(matcher, count=limit) return matcher