def parse(specifiers):
specifiers = "<STR_LIT>".join(specifiers.split())<EOL>for specifier in specifiers.split('<STR_LIT:U+002C>'):<EOL><INDENT>if len(specifier) == <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>count = specifier.count('<STR_LIT:->')<EOL>if (count and specifier[<NUM_LIT:0>] == '<STR_LIT:->') or not count:<EOL><INDENT>yield int(specifier), int(specifier)<EOL>continue<EOL><DEDENT>specifier = list(map(int, specifier.split('<STR_LIT:->')))<EOL>if len(specifier) == <NUM_LIT:2>:<EOL><INDENT>if specifier[<NUM_LIT:0>] < <NUM_LIT:0> or specifier[<NUM_LIT:1>] < <NUM_LIT:0>:<EOL><INDENT>raise ValueError(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>if specifier[<NUM_LIT:1>] < specifier[<NUM_LIT:0>]:<EOL><INDENT>raise ValueError(<EOL>"<STR_LIT>")<EOL><DEDENT>yield tuple(specifier)<EOL>continue<EOL><DEDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>
Consumes set specifiers as text and forms a generator to retrieve
the requested ranges.

@param[in] specifiers
    Expected syntax is from the byte-range-specifier ABNF found in the
    [RFC 2616]; eg. 15-17,151,-16,26-278,15

@returns
    Consecutive tuples that describe the requested range; eg. (1, 72) or
    (1, 1) [read as 1 to 72 or 1 to 1].