code: def repp(file, config=None, module=None, active=None,
           format=None, trace_level=0):
      
      from delphin.repp import REPP
  
      if config is not None and module is not None:
          raise ValueError("cannot specify both 'config' and 'module'")
      if config is not None and active:
          raise ValueError("'active' cannot be used with 'config'")
      if config:
          r = REPP.from_config(config)
      elif module:
          r = REPP.from_file(module, active=active)
      else:
          r = REPP()  # just tokenize
  
      if hasattr(file, 'read'):
          for line in file:
              _repp(r, line, format, trace_level)
      else:
          with io.open(file, encoding='utf-8') as fh:
              for line in fh:
                  _repp(r, line, format, trace_level)
docs: Tokenize with a Regular Expression PreProcessor (REPP).
  
      Results are printed directly to stdout. If more programmatic
      access is desired, the :mod:`delphin.repp` module provides a
      similar interface.
  
      Args:
          file (str, file): filename, open file, or stream of sentence
              inputs
          config (str): path to a PET REPP configuration (.set) file
          module (str): path to a top-level REPP module; other modules
              are found by external group calls
          active (list): select which modules are active; if `None`, all
              are used; incompatible with *config* (default: `None`)
          format (str): the output format (`"yy"`, `"string"`, `"line"`,
              or `"triple"`; default: `"yy"`)
          trace_level (int): if `0` no trace info is printed; if `1`,
              applied rules are printed, if greather than `1`, both
              applied and unapplied rules (in order) are printed
              (default: `0`)