docs: def from_string(cls, s):
          """
          Instantiate a `Derivation` from a UDF or UDX string representation.
  
          The UDF/UDX representations are as output by a processor like the
          `LKB <http://moin.delph-in.net/LkbTop>`_ or
          `ACE <http://sweaglesw.org/linguistics/ace/>`_, or from the
          :meth:`UdfNode.to_udf` or :meth:`UdfNode.to_udx` methods.
  
          Args:
              s (str): UDF or UDX serialization
          """
          if not (s.startswith('(') and s.endswith(')')):
              raise ValueError(
                  'Derivations must begin and end with parentheses: ( )'
              )
          s_ = s[1:]  # get rid of initial open-parenthesis
          stack = []
          deriv = None
          try:
              matches = cls.udf_re.finditer(s_)
              for match in matches:
                  if match.group('done'):
                      node = stack.pop()
                      if len(stack) == 0:
                          deriv = node
                          break
                      else:
                          stack[-1].daughters.append(node)
                  elif match.group('form'):
                      if len(stack) == 0:
                          raise ValueError('Possible leaf node with no parent.')
                      gd = match.groupdict()
                      # ignore LKB-style start/end data if it exists on gd
                      term = UdfTerminal(
                          _unquote(gd['form']),
                          tokens=_udf_tokens(gd.get('tokens')),
                          parent=stack[-1] if stack else None
                      )
                      stack[-1].daughters.append(term)
                  elif match.group('id'):
                      gd = match.groupdict()
                      head = None
                      entity, _, type = gd['entity'].partition('@')
                      if entity[0] == '^':
                          entity = entity[1:]
                          head = True
                      if type == '':
                          type = None
                      udf = UdfNode(gd['id'], entity, gd['score'],
                                    gd['start'], gd['end'],
                                    head=head, type=type,
                                    parent=stack[-1] if stack else None)
                      stack.append(udf)
                  elif match.group('root'):
                      udf = UdfNode(None, match.group('root'))
                      stack.append(udf)
          except (ValueError, AttributeError):
              raise ValueError('Invalid derivation: %s' % s)
          if stack or deriv is None:
              raise ValueError('Invalid derivation; possibly unbalanced '
                               'parentheses: %s' % s)
          return cls(*deriv, head=deriv._head, type=deriv.type)