import re


def parse_frames(string):
    """Parse the resulting frames list from a frame list string.

    Examples
        >>> parse_frames("0-3;30")
        [0, 1, 2, 3, 30]
        >>> parse_frames("0,2,4,-10")
        [0, 2, 4, -10]
        >>> parse_frames("-10--5,-2")
        [-10, -9, -8, -7, -6, -5, -2]

    Args:
        string (str): The string to parse for frames.

    Returns:
        list: A list of frames

    """

    result = list()
    if not string.strip():
        raise ValueError("Can't parse an empty frame string.")

    if not re.match("^[-0-9,; ]*$", string):
        raise ValueError("Invalid symbols in frame string: {}".format(string))

    for raw in re.split(";|,", string):

        # Skip empty elements
        value = raw.strip().replace(" ", "")
        if not value:
            continue

        # Check for sequences (1-20) including negatives (-10--8)
        sequence = re.search("(-?[0-9]+)-(-?[0-9]+)", value)

        # Sequence
        if sequence:
            start, end = sequence.groups()
            frames = range(int(start), int(end) + 1)
            result.extend(frames)

        # Single frame
        else:
            try:
                frame = int(value)
            except ValueError:
                raise ValueError("Invalid frame description: "
                                 "'{0}'".format(value))

            result.append(frame)

    if not result:
        # This happens when only spaces are entered with a separator like `,` or `;`
        raise ValueError("Unable to parse any frames from string: {}".format(string))

    return result