Parse a list of output lines.
    The algorithm starts at the graph node 'start'
    1. detach the first output line into *line* and *rest* and call
        *parse_line*
    2. find an edge that matches to current line
    a) if a match was found
        3. construct an *OutputLine*
        4. set the current node to the target node of the edge
        5. add the entry to the list *current*
        6. recurse with *rest* as new *output*
    b) if no match was found
        7. construct an *OutputEvent* from *current*
        8. if the current node is 'start', set *output* to *rest*
            else, keep *output* to try again with 'start'
        9. recurse with 'start'
    10. add the last event and exit the recursion

def simple_parse_process(
        parser: Parser[A, B],
        node: str,
        output: List[str],
        result: List[OutputEvent[A, B]],
        current: List[OutputLine[A]],
) -> List[OutputEvent[A, B]]:
    '''
    Parse a list of output lines.
    The algorithm starts at the graph node 'start'
    1. detach the first output line into *line* and *rest* and call
        *parse_line*
    2. find an edge that matches to current line
    a) if a match was found
        3. construct an *OutputLine*
        4. set the current node to the target node of the edge
        5. add the entry to the list *current*
        6. recurse with *rest* as new *output*
    b) if no match was found
        7. construct an *OutputEvent* from *current*
        8. if the current node is 'start', set *output* to *rest*
            else, keep *output* to try again with 'start'
        9. recurse with 'start'
    10. add the last event and exit the recursion
    '''
    def add_event() -> List[OutputEvent[A, B]]:
        new = Nil if current.empty else parser.cons_events(current)
        return result + new
    def parse_line(line: str, rest: List[str]) -> Tuple[bool, tuple]:
        log.debug2(lambda: f'parsing line: {line}')
        @do(Either[str, Tuple[OutputLine[A], str]])
        def match(step: Step) -> Do:
            match = yield step.data.regex.match(line)
            log.debug2(lambda: f'matched edge to {step.node}')
            output_line = yield cons_output_line(step.data.cons_output_line)(match)
            return output_line, step.node
        def cont(entry: OutputLine[A], next_node: str) -> Tuple[bool, tuple]:
            return True, (parser, next_node, rest, result, current.cat(entry))
        def next_event() -> Tuple[bool, tuple]:
            new_output = rest if node == 'start' and current.empty else output
            return True, (parser, 'start', new_output, add_event(), List())
        return match_edge(parser.graph, node, match).map2(cont) | next_event
    quit = lambda: (False, add_event())
    return output.detach_head.map2(parse_line) | quit