def debug_reduce(self, rule, tokens, parent, last_token_pos):
        """Customized format and print for our kind of tokens
        which gets called in debugging grammar reduce rules
        """
        def fix(c):
            s = str(c)
            last_token_pos = s.find('_')
            if last_token_pos == -1:
                return s
            else:
                return s[:last_token_pos]

        prefix = ''
        if parent and tokens:
            p_token = tokens[parent]
            if hasattr(p_token, 'linestart') and p_token.linestart:
                prefix = 'L.%3d: ' % p_token.linestart
            else:
                prefix = '       '
            if hasattr(p_token, 'offset'):
                prefix += "%3s" % fix(p_token.offset)
                if len(rule[1]) > 1:
                    prefix += '-%-3s ' % fix(tokens[last_token_pos-1].offset)
                else:
                    prefix += '     '
        else:
            prefix = '               '

        print("%s%s ::= %s (%d)" % (prefix, rule[0], ' '.join(rule[1]), last_token_pos))
Customized format and print for our kind of tokens
        which gets called in debugging grammar reduce rules