def iterate_from(self, start_tok):
        # Start by feeding from the cache, if possible.
        if self._cache[0] <= start_tok < self._cache[1]:
            for tok in self._cache[2][start_tok-self._cache[0]:]:
                yield tok
                start_tok += 1

        # Decide where in the file we should start.  If `start` is in
        # our mapping, then we can jump straight to the correct block;
        # otherwise, start at the last block we've processed.
        if start_tok < self._toknum[-1]:
            block_index = bisect.bisect_right(self._toknum, start_tok)-1
            toknum = self._toknum[block_index]
            filepos = self._filepos[block_index]
        else:
            block_index = len(self._toknum)-1
            toknum = self._toknum[-1]
            filepos = self._filepos[-1]

        # Open the stream, if it's not open already.
        if self._stream is None:
            self._open()

        # Each iteration through this loop, we read a single block
        # from the stream.
        while filepos < self._eofpos:
            # Read the next block.
            self._stream.seek(filepos)
            self._current_toknum = toknum
            self._current_blocknum = block_index
            tokens = self.read_block(self._stream)
            assert isinstance(tokens, (tuple, list, AbstractLazySequence)), (
                'block reader %s() should return list or tuple.' %
                self.read_block.__name__)
            num_toks = len(tokens)
            new_filepos = self._stream.tell()
            assert new_filepos > filepos, (
                'block reader %s() should consume at least 1 byte (filepos=%d)' %
                (self.read_block.__name__, filepos))

            # Update our cache.
            self._cache = (toknum, toknum+num_toks, list(tokens))

            # Update our mapping.
            assert toknum <= self._toknum[-1]
            if num_toks > 0:
                block_index += 1
                if toknum == self._toknum[-1]:
                    assert new_filepos > self._filepos[-1] # monotonic!
                    self._filepos.append(new_filepos)
                    self._toknum.append(toknum+num_toks)
                else:
                    # Check for consistency:
                    assert new_filepos == self._filepos[block_index], (
                        'inconsistent block reader (num chars read)')
                    assert toknum+num_toks == self._toknum[block_index], (
                        'inconsistent block reader (num tokens returned)')

            # If we reached the end of the file, then update self._len
            if new_filepos == self._eofpos:
                self._len = toknum + num_toks
            # Generate the tokens in this block (but skip any tokens
            # before start_tok).  Note that between yields, our state
            # may be modified.
            for tok in tokens[max(0, start_tok-toknum):]:
                yield tok
            # If we're at the end of the file, then we're done.
            assert new_filepos <= self._eofpos
            if new_filepos == self._eofpos:
                break
            # Update our indices
            toknum += num_toks
            filepos = new_filepos

        # If we reach this point, then we should know our length.
        assert self._len is not None
        # Enforce closing of stream once we reached end of file
        # We should have reached EOF once we're out of the while loop.
        self.close()

    # Use concat for these, so we can use a ConcatenatedCorpusView
    # when possible.
dataset/ETHPy150Open nltk/nltk/nltk/corpus/reader/util.py/StreamBackedCorpusView.iterate_from/original