<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def tokenize(template, def_ldel='{{', def_rdel='}}'):
 """Tokenize a mustache template Tokenizes a mustache template in a generator fashion, using file-like objects. It also accepts a string containing the template. Arguments: template -- a file-like object, or a string of a mustache template def_ldel -- The default left delimiter ("{{" by default, as in spec compliant mustache) def_rdel -- The default right delimiter ("}}" by default, as in spec compliant mustache) Returns: A generator of mustache tags in the form of a tuple -- (tag_type, tag_key) Where tag_type is one of: * literal * section * inverted section * end * partial * no escape And tag_key is either the key or in the case of a literal tag, the literal itself. """


    global _CURRENT_LINE, _LAST_TAG_LINE
    _CURRENT_LINE = 1
    _LAST_TAG_LINE = None
    # If the template is a file-like object then read it
    try:
        template = template.read()
    except AttributeError:
        pass

    is_standalone = True
    open_sections = []
    l_del = def_ldel
    r_del = def_rdel

    while template:
        literal, template = grab_literal(template, l_del)

        # If the template is completed
        if not template:
            # Then yield the literal and leave
            yield ('literal', literal)
            break

        # Do the first check to see if we could be a standalone
        is_standalone = l_sa_check(template, literal, is_standalone)

        # Parse the tag
        tag, template = parse_tag(template, l_del, r_del)
        tag_type, tag_key = tag

        # Special tag logic

        # If we are a set delimiter tag
        if tag_type == 'set delimiter':
            # Then get and set the delimiters
            dels = tag_key.strip().split(' ')
            l_del, r_del = dels[0], dels[-1]

        # If we are a section tag
        elif tag_type in ['section', 'inverted section']:
            # Then open a new section
            open_sections.append(tag_key)
            _LAST_TAG_LINE = _CURRENT_LINE

        # If we are an end tag
        elif tag_type == 'end':
            # Then check to see if the last opened section
            # is the same as us
            try:
                last_section = open_sections.pop()
            except IndexError:
                raise ChevronError('Trying to close tag "{0}"\n'
                                   'Looks like it was not opened.\n'
                                   'line {1}'
                                   .format(tag_key, _CURRENT_LINE + 1))
            if tag_key != last_section:
                # Otherwise we need to complain
                raise ChevronError('Trying to close tag "{0}"\n'
                                   'last open tag is "{1}"\n'
                                   'line {2}'
                                   .format(tag_key, last_section,
                                           _CURRENT_LINE + 1))

        # Do the second check to see if we're a standalone
        is_standalone = r_sa_check(template, tag_type, is_standalone)

        # Which if we are
        if is_standalone:
            # Remove the stuff before the newline
            template = template.split('\n', 1)[-1]

            # Partials need to keep the spaces on their left
            if tag_type != 'partial':
                # But other tags don't
                literal = literal.rstrip(' ')

        # Start yielding
        # Ignore literals that are empty
        if literal != '':
            yield ('literal', literal)

        # Ignore comments and set delimiters
        if tag_type not in ['comment', 'set delimiter?']:
            yield (tag_type, tag_key)

    # If there are any open sections when we're done
    if open_sections:
        # Then we need to complain
        raise ChevronError('Unexpected EOF\n'
                           'the tag "{0}" was never closed\n'
                           'was opened at line {1}'
                           .format(open_sections[-1], _LAST_TAG_LINE))