class_docstr: Manipulate expressions using paths.
  
  EPath grammar in EBNF notation::
  
      literal   ::= /[A-Za-z_][A-Za-z_0-9]*/
      number    ::= /-?\d+/
      type      ::= literal
      attribute ::= literal "?"
      all       ::= "*"
      slice     ::= "[" number? (":" number? (":" number?)?)? "]"
      range     ::= all | slice
      query     ::= (type | attribute) ("|" (type | attribute))*
      selector  ::= range | query range?
      path      ::= "/" selector ("/" selector)*
  
  See the docstring of the epath() function.
class_docstr_tok: ["Manipulate","expressions","using","paths",".","EPath","grammar","in","EBNF","notation",":",":","literal",":",":=","\/","[","A-Za-z_","]","[","A-Za-z_0-9","]","*","\/","number",":",":=","\/-","?","\\d+\/","type",":",":=","literal","attribute",":",":=","literal","``","?","''","all",":",":=","``","*","''","slice",":",":=","``","[","``","number","?","(","``",":","''","number","?","(","``",":","''","number","?",")","?",")","?","``","]","''","range",":",":=","all","|","slice","query",":",":=","(","type","|","attribute",")","(","``","|","''","(","type","|","attribute",")",")","*","selector",":",":=","range","|","query","range","?","path",":",":=","``","\/","''","selector","(","``","\/","''","selector",")","*","See","the","docstring","of","the","epath","(",")","function","."]
docstr: Construct new EPath. 
docstr_tok: ["Construct","new","EPath","."]
code: def __new__(cls, path):
      """Construct new EPath."""
      if isinstance(path, EPath):
          return path
  
      if not path:
          raise ValueError("empty EPath")
  
      _path = path
  
      if path[0] == "/":
          path = path[1:]
      else:
          raise NotImplementedError("non-root EPath")
  
      epath = []
  
      for selector in path.split("/"):
          selector = selector.strip()
  
          if not selector:
              raise ValueError("empty selector")
  
          index = 0
  
          for c in selector:
              if c.isalnum() or c in ("_", "|", "?"):
                  index += 1
              else:
                  break
  
          attrs = []
          types = []
  
          if index:
              elements = selector[:index]
              selector = selector[index:]
  
              for element in elements.split("|"):
                  element = element.strip()
  
                  if not element:
                      raise ValueError("empty element")
  
                  if element.endswith("?"):
                      attrs.append(element[:-1])
                  else:
                      types.append(element)
  
          span = None
  
          if selector == "*":
              pass
          else:
              if selector.startswith("["):
                  try:
                      i = selector.index("]")
                  except ValueError:
                      raise ValueError("expected ']', got EOL")
  
                  _span, span = selector[1:i], []
  
                  if ":" not in _span:
                      span = int(_span)
                  else:
                      for elt in _span.split(":", 3):
                          if not elt:
                              span.append(None)
                          else:
                              span.append(int(elt))
  
                      span = slice(*span)
  
                  selector = selector[i + 1 :]
  
              if selector:
                  raise ValueError("trailing characters in selector")
  
          epath.append((attrs, types, span))
  
      obj = object.__new__(cls)
  
      obj._path = _path
      obj._epath = epath
  
      return obj
  
file_path: sympy/sympy/simplify/epathtools.py
imports: from sympy.core import Basic
label_desc: Use image node_id 1 for calling the EPath obj's underlying member method code with example usage: obj.__new__(cls, path) and returns: obj, path