docs: def _start_operation(self, ast, operation, precedence):
          """
          Returns an AST where all operations of lower precedence are finalized.
          """
          if TRACE_PARSE:
              print('   start_operation:', repr(operation), 'AST:', ast)
  
          op_prec = precedence[operation]
          while True:
              if ast[1] is None:
                  # [None, None, x]
                  if TRACE_PARSE: print('     start_op: ast[1] is None:', repr(ast))
                  ast[1] = operation
                  if TRACE_PARSE: print('     --> start_op: ast[1] is None:', repr(ast))
                  return ast
  
              prec = precedence[ast[1]]
              if prec > op_prec:  # op=&, [ast, |, x, y] -> [[ast, |, x], &, y]
                  if TRACE_PARSE: print('     start_op: prec > op_prec:', repr(ast))
                  ast = [ast, operation, ast.pop(-1)]
                  if TRACE_PARSE: print('     --> start_op: prec > op_prec:', repr(ast))
                  return ast
  
              if prec == op_prec:  # op=&, [ast, &, x] -> [ast, &, x]
                  if TRACE_PARSE: print('     start_op: prec == op_prec:', repr(ast))
                  return ast
  
              if not (inspect.isclass(ast[1]) and issubclass(ast[1], Function)):
                  # the top ast node should be a function subclass at this stage
                  raise ParseError(error_code=PARSE_INVALID_NESTING)
  
              if ast[0] is None:  # op=|, [None, &, x, y] -> [None, |, x&y]
                  if TRACE_PARSE: print('     start_op: ast[0] is None:', repr(ast))
                  subexp = ast[1](*ast[2:])
                  new_ast = [ast[0], operation, subexp]
                  if TRACE_PARSE: print('     --> start_op: ast[0] is None:', repr(new_ast))
                  return new_ast
  
              else:  # op=|, [[ast, &, x], ~, y] -> [ast, &, x, ~y]
                  if TRACE_PARSE: print('     start_op: else:', repr(ast))
                  ast[0].append(ast[1](*ast[2:]))
                  ast = ast[0]
                  if TRACE_PARSE: print('     --> start_op: else:', repr(ast))