Shakespeare and dictionaries
Python's standard library includes a class that would simplify your first snippet: collections.defaultdict. This class allows you to set a default for missing keys, so if you make it a list you can append without having to check if it already exists. 

You could also simplify the iteration using zip; see e.g. "Iterate a list as pair (current, next) in Python".

Using that would make it:

from collections import defaultdict

def build_successors_table(tokens):
    table = defaultdict(list)
    for prev, word in zip(['.']+tokens, tokens):
        table[prev].append(word)
    return table




For the second snippet note that, per the style guide, all imports should happen at the start of your script - there's no benefit to trying to import random every time the function is called.

Continually appending strings is relatively inefficient, as a new string object is created each time. Instead, it's typical to create a list of words and then use ' '.join(words) to combine them back together.

It is more efficient to test membership (x in y) on a set (O(1)) than a list (O(n)).

import random

def construct_sent(word, table):
    words = []
    while word not in {'.', '!', '?'}:
        words.append(word)
        word = random.choice(table[word])
    return ' '.join(words) + word




Both functions would benefit from docstrings explaining what they do and how to use them (e.g. what the parameters are expected to be).