code: def make_tokenizer(specs):
      
  
      def compile_spec(spec):
          name, args = spec
          return name, re.compile(*args)
  
      compiled = [compile_spec(s) for s in specs]
  
      def match_specs(specs, str, i, position):
          line, pos = position
          for type, regexp in specs:
              m = regexp.match(str, i)
              if m is not None:
                  value = m.group()
                  nls = value.count(u'\n')
                  n_line = line + nls
                  if nls == 0:
                      n_pos = pos + len(value)
                  else:
                      n_pos = len(value) - value.rfind(u'\n') - 1
                  return Token(type, value, (line, pos + 1), (n_line, n_pos))
          else:
              errline = str.splitlines()[line - 1]
              raise LexerError((line, pos + 1), errline)
  
      def f(str):
          length = len(str)
          line, pos = 1, 0
          i = 0
          while i < length:
              t = match_specs(compiled, str, i, (line, pos))
              yield t
              line, pos = t.end
              i += len(t.value)
  
      return f
docs: [(str, (str, int?))] -> (str -> Iterable(Token))