'What error message should be generated for the various
exception types?
Not very object-oriented code, but I like having all error message
generation within one method rather than spread among all of the
exception classes. This also makes it much easier for the exception
handling because the exception classes do not have to have pointers back
to this object to access utility routines and so on. Also, changing
the message for an exception type would be difficult because you
would have to subclassing exception, but then somehow get ANTLR
to make those kinds of exception objects instead of the default.
This looks weird, but trust me--it makes the most sense in terms
of flexibility.
For grammar debugging, you will want to override this to add
more information such as the stack frame with
getRuleInvocationStack(e, this.getClass().getName()) and,
for no viable alts, the decision description and state etc...
Override this to change the message generated for one or more
exception types.'

def getErrorMessage(self, e, tokenNames):

    if isinstance(e, UnwantedTokenException):
        tokenName = '<unknown>'
        if (e.expecting == EOF):
            tokenName = 'EOF'
        else:
            tokenName = self.tokenNames[e.expecting]
        msg = ('extraneous    input    %s    expecting    %s' % (self.getTokenErrorDisplay(e.getUnexpectedToken()), tokenName))
    elif isinstance(e, MissingTokenException):
        tokenName = '<unknown>'
        if (e.expecting == EOF):
            tokenName = 'EOF'
        else:
            tokenName = self.tokenNames[e.expecting]
        msg = ('missing    %s    at    %s' % (tokenName, self.getTokenErrorDisplay(e.token)))
    elif isinstance(e, MismatchedTokenException):
        tokenName = '<unknown>'
        if (e.expecting == EOF):
            tokenName = 'EOF'
        else:
            tokenName = self.tokenNames[e.expecting]
        msg = ((('mismatched    input    ' + self.getTokenErrorDisplay(e.token)) + '    expecting    ') + tokenName)
    elif isinstance(e, MismatchedTreeNodeException):
        tokenName = '<unknown>'
        if (e.expecting == EOF):
            tokenName = 'EOF'
        else:
            tokenName = self.tokenNames[e.expecting]
        msg = ('mismatched    tree    node:    %s    expecting    %s' % (e.node, tokenName))
    elif isinstance(e, NoViableAltException):
        msg = ('no    viable    alternative    at    input    ' + self.getTokenErrorDisplay(e.token))
    elif isinstance(e, EarlyExitException):
        msg = ('required    (...)+    loop    did    not    match    anything    at    input    ' + self.getTokenErrorDisplay(e.token))
    elif isinstance(e, MismatchedSetException):
        msg = ((('mismatched    input    ' + self.getTokenErrorDisplay(e.token)) + '    expecting    set    ') + repr(e.expecting))
    elif isinstance(e, MismatchedNotSetException):
        msg = ((('mismatched    input    ' + self.getTokenErrorDisplay(e.token)) + '    expecting    set    ') + repr(e.expecting))
    elif isinstance(e, FailedPredicateException):
        msg = (((('rule    ' + e.ruleName) + '    failed    predicate:    {') + e.predicateText) + '}?')
    else:
        msg = str(e)
    return msg
