def _group(tlist, cls, match, valid_prev=(lambda t: True), valid_next=(lambda t: True), post=None, extend=True, recurse=True):
 tidx_offset = 0
 (pidx, prev_) = (None, None)
 for (idx, token) in enumerate(list(tlist)):
  tidx = (idx - tidx_offset)
  if token.is_whitespace:
   continue
  if (recurse and token.is_group and (not isinstance(token, cls))):
   _group(token, cls, match, valid_prev, valid_next, post, extend)
  if match(token):
   (nidx, next_) = tlist.token_next(tidx)
   if (prev_ and valid_prev(prev_) and valid_next(next_)):
    (from_idx, to_idx) = post(tlist, pidx, tidx, nidx)
    grp = tlist.group_tokens(cls, from_idx, to_idx, extend=extend)
    tidx_offset += (to_idx - from_idx)
    (pidx, prev_) = (from_idx, grp)
    continue
  (pidx, prev_) = (tidx, token)

def _group ( tlist , cls , match , valid_prev = ( lambda t : True ) , valid_next = ( lambda t : True ) , post = None , extend = True , recurse = True ) : tidx_offset = 0 ( pidx , prev_ ) = ( None , None ) for ( idx , token ) in enumerate ( list ( tlist ) ) : tidx = ( idx - tidx_offset ) if token . is_whitespace : continue if ( recurse and token . is_group and ( not isinstance ( token , cls ) ) ) : _group ( token , cls , match , valid_prev , valid_next , post , extend ) if match ( token ) : ( nidx , next_ ) = tlist . token_next ( tidx ) if ( prev_ and valid_prev ( prev_ ) and valid_next ( next_ ) ) : ( from_idx , to_idx ) = post ( tlist , pidx , tidx , nidx ) grp = tlist . group_tokens ( cls , from_idx , to_idx , extend = extend ) tidx_offset += ( to_idx - from_idx ) ( pidx , prev_ ) = ( from_idx , grp ) continue ( pidx , prev_ ) = ( tidx , token )
groups together tokens that are joined by a middle token .