'Read a bracketed tree string and return the resulting tree.
Trees are represented as nested brackettings, such as::
(S (NP (NNP John)) (VP (V runs)))
:type s: str
:param s: The string to read
:type brackets: str (length=2)
:param brackets: The bracket characters used to mark the
beginning and end of trees and subtrees.
:type read_node: function
:type read_leaf: function
:param read_node, read_leaf: If specified, these functions
are applied to the substrings of ``s`` corresponding to
nodes and leaves (respectively) to obtain the values for
those nodes and leaves.  They should have the following
signature:
read_node(str) -> value
For example, these functions could be used to process nodes
and leaves whose values should be some type other than
string (such as ``FeatStruct``).
Note that by default, node strings and leaf strings are
delimited by whitespace and brackets; to override this
default, use the ``node_pattern`` and ``leaf_pattern``
arguments.
:type node_pattern: str
:type leaf_pattern: str
:param node_pattern, leaf_pattern: Regular expression patterns
used to find node and leaf substrings in ``s``.  By
default, both nodes patterns are defined to match any
sequence of non-whitespace non-bracket characters.
:type remove_empty_top_bracketing: bool
:param remove_empty_top_bracketing: If the resulting tree has
an empty node label, and is length one, then return its
single child instead.  This is useful for treebank trees,
which sometimes contain an extra level of bracketing.
:return: A tree corresponding to the string representation ``s``.
If this class method is called using a subclass of Tree,
then it will return a tree of that type.
:rtype: Tree'

@classmethod
def fromstring(cls, s, brackets=u'()', read_node=None, read_leaf=None, node_pattern=None, leaf_pattern=None, remove_empty_top_bracketing=False):

    if ((not isinstance(brackets, string_types)) or (len(brackets) != 2)):
        raise TypeError(u'brackets    must    be    a    length-2    string')
    if re.search(u'\\s', brackets):
        raise TypeError(u'whitespace    brackets    not    allowed')
    (open_b, close_b) = brackets
    (open_pattern, close_pattern) = (re.escape(open_b), re.escape(close_b))
    if (node_pattern is None):
        node_pattern = (u'[^\\s%s%s]+' % (open_pattern, close_pattern))
    if (leaf_pattern is None):
        leaf_pattern = (u'[^\\s%s%s]+' % (open_pattern, close_pattern))
    token_re = re.compile((u'%s\\s*(%s)?|%s|(%s)' % (open_pattern, node_pattern, close_pattern, leaf_pattern)))
    stack = [(None, [])]
    for match in token_re.finditer(s):
        token = match.group()
        if (token[0] == open_b):
            if ((len(stack) == 1) and (len(stack[0][1]) > 0)):
                cls._parse_error(s, match, u'end-of-string')
            label = token[1:].lstrip()
            if (read_node is not None):
                label = read_node(label)
            stack.append((label, []))
        elif (token == close_b):
            if (len(stack) == 1):
                if (len(stack[0][1]) == 0):
                    cls._parse_error(s, match, open_b)
                else:
                    cls._parse_error(s, match, u'end-of-string')
            (label, children) = stack.pop()
            stack[(-1)][1].append(cls(label, children))
        else:
            if (len(stack) == 1):
                cls._parse_error(s, match, open_b)
            if (read_leaf is not None):
                token = read_leaf(token)
            stack[(-1)][1].append(token)
    if (len(stack) > 1):
        cls._parse_error(s, u'end-of-string', close_b)
    elif (len(stack[0][1]) == 0):
        cls._parse_error(s, u'end-of-string', open_b)
    else:
        assert (stack[0][0] is None)
        assert (len(stack[0][1]) == 1)
    tree = stack[0][1][0]
    if (remove_empty_top_bracketing and (tree._label == u'') and (len(tree) == 1)):
        tree = tree[0]
    return tree
