'Display a friendly error message when parsing a tree string fails.
:param s: The string we\'re parsing.
:param match: regexp match of the problem token.
:param expecting: what we expected to see instead.'

@classmethod
def _parse_error(cls, s, match, expecting):

    if (match == u'end-of-string'):
        (pos, token) = (len(s), u'end-of-string')
    else:
        (pos, token) = (match.start(), match.group())
    msg = (u'%s.read():    expected    %r    but    got    %r\n%sat    index    %d.' % (cls.__name__, expecting, token, (u'    ' * 12), pos))
    s = s.replace(u'\n', u'    ').replace(u' DCTB ', u'    ')
    offset = pos
    if (len(s) > (pos + 10)):
        s = (s[:(pos + 10)] + u'...')
    if (pos > 10):
        s = (u'...' + s[(pos - 10):])
        offset = 13
    msg += (u'\n%s"%s"\n%s^' % ((u'    ' * 16), s, (u'    ' * (17 + offset))))
    raise ValueError(msg)
