It seems that BPTTIterator expects a dataset of one example, so I transformed my training dataset as follows:
def dataset2example(dataset):
    examples = list(map(lambda example: ['_bos_']+ example.text + ['_eos_'], dataset.examples))
    examples = [item for example in examples for item in example]
    example = tt.data.Example()
    setattr(example, 'text', examples)
    return tt.data.Dataset([example], fields={'text': TEXT})

train_example = dataset2example(train)
valid_example = dataset2example(valid)

Now I can pass those train_example to the BPTTIterator like this:
train_iter, valid_iter = tt.data.BPTTIterator.splits((train_example, valid_example), batch_size=batch_size, bptt_len=30)