def separated(p, sep, mint, maxt=None, end=None):
    '''Repeat a parser `p` separated by `s` between `mint` and `maxt` times.
    When `end` is None, a trailing separator is optional.
    When `end` is True, a trailing separator is required.
    When `end` is False, a trailing separator is not allowed.
    MATCHES AS MUCH AS POSSIBLE.
    Return list of values returned by `p`.'''
    maxt = maxt if maxt else mint
    @Parser
    def sep_parser(text, index):
        cnt, values, res = 0, Value.success(index, []), None
        while cnt < maxt:
            if end in [False, None] and cnt > 0:
                res = sep(text, index)
                if res.status:
                    index, values = res.index, Value.success(
                        res.index, values.value)
                elif cnt < mint:
                    return res
                else:
                    break
            res = p(text, index)
            if res.status:
                values = values.aggregate(
                    Value.success(res.index, [res.value]))
                index, cnt = res.index, cnt + 1
            elif cnt >= mint:
                break
            else:
                return res
            if end is True:
                res = sep(text, index)
                if res.status:
                    index, values = res.index, Value.success(
                        res.index, values.value)
                else:
                    return res
            if cnt >= maxt:
                break
        return values
    return sep_parser