-- Repeatedly call a parser **until** a end conditional is matched. There may be
-- zero or more results.
many :: [Token] -> ([Token] -> ParserResult) -> ([Token] -> Bool)
        -> ParserResultList
many ta par cond =
    if cond ta then return ([], ta)
    else do
        (ab, tb) <- par ta
        (ac, tc) <- many tb par cond
        return (ab : ac, tc)


-- Like many, but instead of taking a conditional function, it takes an expected
-- separator. When the separator is no longer matched, it returns a
-- ParserResultList. Because of parsing limitations, we assume one or more
-- results. An empty list will fail.
many :: [Token] -> ([Token] -> ParserResult) -> ([Token] -> Bool)
        -> ParserResultList
many ta par cond =
    if cond ta then return ([], ta)
    else do
        (ab, tb) <- par ta
        (ac, tc) <- many tb par cond
        return (ab : ac, tc)


-- Like many, but instead of taking a conditional function, it takes an expected
-- separator. When the separator is no longer matched, it returns a
-- ParserResultList. Because of parsing limitations, we assume one or more
-- results. An empty list will fail.
many ta par cond =
    if cond ta then return ([], ta)
    else do
        (ab, tb) <- par ta
        (ac, tc) <- many tb par cond
        return (ab : ac, tc)


-- Like many, but instead of taking a conditional function, it takes an expected
-- separator. When the separator is no longer matched, it returns a
-- ParserResultList. Because of parsing limitations, we assume one or more
-- results. An empty list will fail.