code: def _create_token_collection(version_info):
      # Note: we use unicode matching for names ("\w") but ascii matching for
      # number literals.
      Whitespace = r"[ \f\t]*"
      whitespace = _compile(Whitespace)
      Comment = r"#[^\r\n]*"
      # Python 2 is pretty much not working properly anymore, we just ignore
      # parsing unicode properly, which is fine, I guess.
      if version_info[0] == 2:
          Name = r"([A-Za-z_0-9]+)"
      elif sys.version_info[0] == 2:
          # Unfortunately the regex engine cannot deal with the regex below, so
          # just use this one.
          Name = r"(\w+)"
      else:
          Name = "([A-Za-z_0-9\u0080-" + MAX_UNICODE + "]+)"
  
      if version_info >= (3, 6):
          Hexnumber = r"0[xX](?:_?[0-9a-fA-F])+"
          Binnumber = r"0[bB](?:_?[01])+"
          Octnumber = r"0[oO](?:_?[0-7])+"
          Decnumber = r"(?:0(?:_?0)*|[1-9](?:_?[0-9])*)"
          Intnumber = group(Hexnumber, Binnumber, Octnumber, Decnumber)
          Exponent = r"[eE][-+]?[0-9](?:_?[0-9])*"
          Pointfloat = group(
              r"[0-9](?:_?[0-9])*\.(?:[0-9](?:_?[0-9])*)?",
              r"\.[0-9](?:_?[0-9])*",
          ) + maybe(Exponent)
          Expfloat = r"[0-9](?:_?[0-9])*" + Exponent
          Floatnumber = group(Pointfloat, Expfloat)
          Imagnumber = group(
              r"[0-9](?:_?[0-9])*[jJ]", Floatnumber + r"[jJ]"
          )
      else:
          Hexnumber = r"0[xX][0-9a-fA-F]+"
          Binnumber = r"0[bB][01]+"
          if version_info.major >= 3:
              Octnumber = r"0[oO][0-7]+"
          else:
              Octnumber = "0[oO]?[0-7]+"
          Decnumber = r"(?:0+|[1-9][0-9]*)"
          Intnumber = group(Hexnumber, Binnumber, Octnumber, Decnumber)
          if version_info[0] < 3:
              Intnumber += "[lL]?"
          Exponent = r"[eE][-+]?[0-9]+"
          Pointfloat = group(r"[0-9]+\.[0-9]*", r"\.[0-9]+") + maybe(
              Exponent
          )
          Expfloat = r"[0-9]+" + Exponent
          Floatnumber = group(Pointfloat, Expfloat)
          Imagnumber = group(r"[0-9]+[jJ]", Floatnumber + r"[jJ]")
      Number = group(Imagnumber, Floatnumber, Intnumber)
  
      # Note that since _all_string_prefixes includes the empty string,
      #  StringPrefix can be the empty string (making it optional).
      possible_prefixes = _all_string_prefixes(version_info)
      StringPrefix = group(*possible_prefixes)
      StringPrefixWithF = group(
          *_all_string_prefixes(version_info, include_fstring=True)
      )
      fstring_prefixes = _all_string_prefixes(
          version_info, include_fstring=True, only_fstring=True
      )
      FStringStart = group(*fstring_prefixes)
  
      # Tail end of ' string.
      Single = r"(?:\\.|[^'\\])*'"
      # Tail end of " string.
      Double = r'(?:\\.|[^"\\])*"'
      # Tail end of ''' string.
      Single3 = r"(?:\\.|'(?!'')|[^'\\])*'''"
      # Tail end of """ string.
      Double3 = r'(?:\\.|"(?!"")|[^"\\])*"""'
      Triple = group(
          StringPrefixWithF + "'''", StringPrefixWithF + '"""'
      )
  
      # Because of leftmost-then-longest match semantics, be sure to put the
      # longest operators first (e.g., if = came before ==, == would get
      # recognized as two instances of =).
      Operator = group(
          r"\*\*=?",
          r">>=?",
          r"<<=?",
          r"//=?",
          r"->",
          r"[+\-*/%&@`|^!=<>]=?",
          r"~",
      )
  
      Bracket = "[][(){}]"
  
      special_args = [r"\r\n?", r"\n", r"[;.,@]"]
      if version_info >= (3, 0):
          special_args.insert(0, r"\.\.\.")
      if version_info >= (3, 8):
          special_args.insert(0, ":=?")
      else:
          special_args.insert(0, ":")
      Special = group(*special_args)
  
      Funny = group(Operator, Bracket, Special)
  
      # First (or only) line of ' or " string.
      ContStr = group(
          StringPrefix
          + r"'[^\r\n'\\]*(?:\\.[^\r\n'\\]*)*"
          + group("'", r"\\(?:\r\n?|\n)"),
          StringPrefix
          + r'"[^\r\n"\\]*(?:\\.[^\r\n"\\]*)*'
          + group('"', r"\\(?:\r\n?|\n)"),
      )
      pseudo_extra_pool = [Comment, Triple]
      all_quotes = '"', "'", '"""', "'''"
      if fstring_prefixes:
          pseudo_extra_pool.append(FStringStart + group(*all_quotes))
  
      PseudoExtras = group(r"\\(?:\r\n?|\n)|\Z", *pseudo_extra_pool)
      PseudoToken = group(Whitespace, capture=True) + group(
          PseudoExtras, Number, Funny, ContStr, Name, capture=True
      )
  
      # For a given string prefix plus quotes, endpats maps it to a regex
      #  to match the remainder of that string. _prefix can be empty, for
      #  a normal single or triple quoted string (with no prefix).
      endpats = {}
      for _prefix in possible_prefixes:
          endpats[_prefix + "'"] = _compile(Single)
          endpats[_prefix + '"'] = _compile(Double)
          endpats[_prefix + "'''"] = _compile(Single3)
          endpats[_prefix + '"""'] = _compile(Double3)
  
      # A set of all of the single and triple quoted string prefixes,
      #  including the opening quotes.
      single_quoted = set()
      triple_quoted = set()
      fstring_pattern_map = {}
      for t in possible_prefixes:
          for quote in '"', "'":
              single_quoted.add(t + quote)
  
          for quote in '"""', "'''":
              triple_quoted.add(t + quote)
  
      for t in fstring_prefixes:
          for quote in all_quotes:
              fstring_pattern_map[t + quote] = quote
  
      ALWAYS_BREAK_TOKENS = (
          ";",
          "import",
          "class",
          "def",
          "try",
          "except",
          "finally",
          "while",
          "with",
          "return",
          "continue",
          "break",
          "del",
          "pass",
          "global",
          "assert",
      )
      if version_info >= (3, 5):
          ALWAYS_BREAK_TOKENS += ("nonlocal",)
      pseudo_token_compiled = _compile(PseudoToken)
      return TokenCollection(
          pseudo_token_compiled,
          single_quoted,
          triple_quoted,
          endpats,
          whitespace,
          fstring_pattern_map,
          set(ALWAYS_BREAK_TOKENS),
      )
  
imports: from __future__ import absolute_import
  import sys
  import re
  from collections import namedtuple
  import itertools
  from codecs import BOM_UTF8
  from parso.python.token import PythonTokenTypes
  from parso.utils import split_lines
label_desc: Use image node_id 6 for calling a global function with example usage: _create_token_collection(version_info) and returns: TokenCollection