code: def lex(
      module=None,
      object=None,
      debug=False,
      optimize=False,
      lextab="lextab",
      reflags=int(re.VERBOSE),
      nowarn=False,
      outputdir=None,
      debuglog=None,
      errorlog=None,
  ):
      if lextab is None:
          lextab = "lextab"
  
      global lexer
  
      ldict = None
      stateinfo = {"INITIAL": "inclusive"}
      lexobj = Lexer()
      lexobj.lexoptimize = optimize
      global token, input
  
      if errorlog is None:
          errorlog = PlyLogger(sys.stderr)
  
      if debug:
          if debuglog is None:
              debuglog = PlyLogger(sys.stderr)
  
      # Get the module dictionary used for the lexer
      if object:
          module = object
  
      # Get the module dictionary used for the parser
      if module:
          _items = [(k, getattr(module, k)) for k in dir(module)]
          ldict = dict(_items)
          # If no __file__ attribute is available, try to obtain it from the __module__ instead
          if "__file__" not in ldict:
              ldict["__file__"] = sys.modules[
                  ldict["__module__"]
              ].__file__
      else:
          ldict = get_caller_module_dict(2)
  
      # Determine if the module is package of a package or not.
      # If so, fix the tabmodule setting so that tables load correctly
      pkg = ldict.get("__package__")
      if pkg and isinstance(lextab, str):
          if "." not in lextab:
              lextab = pkg + "." + lextab
  
      # Collect parser information from the dictionary
      linfo = LexerReflect(ldict, log=errorlog, reflags=reflags)
      linfo.get_all()
      if not optimize:
          if linfo.validate_all():
              raise SyntaxError("Can't build lexer")
  
      if optimize and lextab:
          try:
              lexobj.readtab(lextab, ldict)
              token = lexobj.token
              input = lexobj.input
              lexer = lexobj
              return lexobj
  
          except ImportError:
              pass
  
      # Dump some basic debugging information
      if debug:
          debuglog.info("lex: tokens   = %r", linfo.tokens)
          debuglog.info("lex: literals = %r", linfo.literals)
          debuglog.info("lex: states   = %r", linfo.stateinfo)
  
      # Build a dictionary of valid token names
      lexobj.lextokens = set()
      for n in linfo.tokens:
          lexobj.lextokens.add(n)
  
      # Get literals specification
      if isinstance(linfo.literals, (list, tuple)):
          lexobj.lexliterals = type(linfo.literals[0])().join(
              linfo.literals
          )
      else:
          lexobj.lexliterals = linfo.literals
  
      lexobj.lextokens_all = lexobj.lextokens | set(lexobj.lexliterals)
  
      # Get the stateinfo dictionary
      stateinfo = linfo.stateinfo
  
      regexs = {}
      # Build the master regular expressions
      for state in stateinfo:
          regex_list = []
  
          # Add rules defined by functions first
          for fname, f in linfo.funcsym[state]:
              regex_list.append("(?P<%s>%s)" % (fname, _get_regex(f)))
              if debug:
                  debuglog.info(
                      "lex: Adding rule %s -> '%s' (state '%s')",
                      fname,
                      _get_regex(f),
                      state,
                  )
  
          # Now add all of the simple rules
          for name, r in linfo.strsym[state]:
              regex_list.append("(?P<%s>%s)" % (name, r))
              if debug:
                  debuglog.info(
                      "lex: Adding rule %s -> '%s' (state '%s')",
                      name,
                      r,
                      state,
                  )
  
          regexs[state] = regex_list
  
      # Build the master regular expressions
  
      if debug:
          debuglog.info("lex: ==== MASTER REGEXS FOLLOW ====")
  
      for state in regexs:
          lexre, re_text, re_names = _form_master_re(
              regexs[state], reflags, ldict, linfo.toknames
          )
          lexobj.lexstatere[state] = lexre
          lexobj.lexstateretext[state] = re_text
          lexobj.lexstaterenames[state] = re_names
          if debug:
              for i, text in enumerate(re_text):
                  debuglog.info(
                      "lex: state '%s' : regex[%d] = '%s'",
                      state,
                      i,
                      text,
                  )
  
      # For inclusive states, we need to add the regular expressions from the INITIAL state
      for state, stype in stateinfo.items():
          if state != "INITIAL" and stype == "inclusive":
              lexobj.lexstatere[state].extend(
                  lexobj.lexstatere["INITIAL"]
              )
              lexobj.lexstateretext[state].extend(
                  lexobj.lexstateretext["INITIAL"]
              )
              lexobj.lexstaterenames[state].extend(
                  lexobj.lexstaterenames["INITIAL"]
              )
  
      lexobj.lexstateinfo = stateinfo
      lexobj.lexre = lexobj.lexstatere["INITIAL"]
      lexobj.lexretext = lexobj.lexstateretext["INITIAL"]
      lexobj.lexreflags = reflags
  
      # Set up ignore variables
      lexobj.lexstateignore = linfo.ignore
      lexobj.lexignore = lexobj.lexstateignore.get("INITIAL", "")
  
      # Set up error functions
      lexobj.lexstateerrorf = linfo.errorf
      lexobj.lexerrorf = linfo.errorf.get("INITIAL", None)
      if not lexobj.lexerrorf:
          errorlog.warning("No t_error rule is defined")
  
      # Set up eof functions
      lexobj.lexstateeoff = linfo.eoff
      lexobj.lexeoff = linfo.eoff.get("INITIAL", None)
  
      # Check state information for ignore and error rules
      for s, stype in stateinfo.items():
          if stype == "exclusive":
              if s not in linfo.errorf:
                  errorlog.warning(
                      "No error rule is defined for exclusive state '%s'",
                      s,
                  )
              if s not in linfo.ignore and lexobj.lexignore:
                  errorlog.warning(
                      "No ignore rule is defined for exclusive state '%s'",
                      s,
                  )
          elif stype == "inclusive":
              if s not in linfo.errorf:
                  linfo.errorf[s] = linfo.errorf.get("INITIAL", None)
              if s not in linfo.ignore:
                  linfo.ignore[s] = linfo.ignore.get("INITIAL", "")
  
      # Create global versions of the token() and input() functions
      token = lexobj.token
      input = lexobj.input
      lexer = lexobj
  
      # If in optimize mode, we write the lextab
      if lextab and optimize:
          if outputdir is None:
              # If no output directory is set, the location of the output files
              # is determined according to the following rules:
              #     - If lextab specifies a package, files go into that package directory
              #     - Otherwise, files go in the same directory as the specifying module
              if isinstance(lextab, types.ModuleType):
                  srcfile = lextab.__file__
              else:
                  if "." not in lextab:
                      srcfile = ldict["__file__"]
                  else:
                      parts = lextab.split(".")
                      pkgname = ".".join(parts[:-1])
                      exec("import %s" % pkgname)
                      srcfile = getattr(
                          sys.modules[pkgname], "__file__", ""
                      )
              outputdir = os.path.dirname(srcfile)
          try:
              lexobj.writetab(lextab, outputdir)
              if lextab in sys.modules:
                  del sys.modules[lextab]
          except IOError as e:
              errorlog.warning(
                  "Couldn't write lextab module %r. %s" % (lextab, e)
              )
  
      return lexobj
  
imports: import re
  import sys
  import types
  import copy
  import os
  import inspect
label_desc: Use image node_id 7 for calling a global function with example usage: lex(module, object, debug, optimize, lextab, reflags, nowarn, outputdir, debuglog, errorlog) and returns: lexobj, lexobj