code: def parse(s):
      
      lexer = iter(BoolExprLexer(s))
      try:
          expr = _expr(lexer)
      except lex.RunError as exc:
          fstr = ("{0.args[0]}: "
                  "(line: {0.lineno}, offset: {0.offset}, text: {0.text})")
          raise Error(fstr.format(exc))
  
      # Check for end of buffer
      _expect_token(lexer, {EndToken})
  
      return expr
docs: Parse a Boolean expression string,
      and return an expression abstract syntax tree.
  
      Parameters
      ----------
      s : str
          String containing a Boolean expression.
          See ``pyeda.parsing.boolexpr.GRAMMAR`` for details.
  
      Examples
      --------
      >>> parse("a | b ^ c & d")
      ('or', ('var', ('a',), ()), ('xor', ('var', ('b',), ()), ('and', ('var', ('c',), ()), ('var', ('d',), ()))))
      >>> parse("p => q")
      ('implies', ('var', ('p',), ()), ('var', ('q',), ()))
  
      Returns
      -------
      An ast tuple, defined recursively:
  
      ast := ('const', bool)
           | ('var', names, indices)
           | ('not', ast)
           | ('implies', ast, ast)
           | ('ite', ast, ast, ast)
           | (func, ast, ...)
  
      bool := 0 | 1
  
      names := (name, ...)
  
      indices := (index, ...)
  
      func := 'or' | 'and'
            | 'nor' | 'nand'
            | 'xor' | 'xnor'
            | 'equal' | 'unequal'
            | 'onehot0' | 'onehot'
            | 'majority' | 'achillesheel'