code: def extract_tokens(representation, separators=SEPARATOR_CHARACTERS):
      
      buff = ""
      elements = []
      last_index = 0
      last_token = None
  
      for index, c in enumerate(representation):
          # if separator character is found, push
          # the content of the buffer in the elements list
          if c in separators:
              if buff:
                  # If the last found token is invalid,
                  # raise and InvalidTokenError
                  if not valid_token(buff):
                      raise InvalidTokenError(
                          "Duration representation {0} contains "
                          "an invalid token: {1}".format(representation, buff)
                      )
  
                  # If buffer content is a separator word, for example
                  # "and", just ignore it
                  if not buff.strip() in SEPARATOR_TOKENS:
                      elements.append(buff)
  
              # Anyway, reset buffer and last token marker
              # to their zero value
              buff = ""
              last_token = None
          else:
              token = compute_char_token(c)
              if (token is not None and last_token is not None and token != last_token):
                  elements.append(buff)
                  buff = c
              else:
                  buff += c
  
              last_token = token
  
      # push the content left in representation
      # in the elements list
      elements.append(buff)
  
      return list(zip(elements[::2], elements[1::2]))
docs: Extracts durations tokens from a duration representation.
  
      Parses the string representation incrementaly and raises
      on first error met.
  
      :param  representation: duration representation
      :type   representation: string