def parse_logical_names(phy_type, log_names, cell_pins):
    """
    Parses logical cell names. Extracts the cell name, input pin  name and
    output pin name. Uses dumped library cell definitions to achive that since
    a logical name string uses "_" as a separator and "_" can also occur in
    cell/pin name.

    Returns a list of tuples with (cell_name, src_pin, dst_pin)
    """

    log_cells = []

    # Process logical names that should correspond to bel timings
    for log_name in log_names.split(","):

        # Since both cell and pin names may also contain "_" the
        # logical name is split iteratively.

        # The timing type is the first, it has to equal the timing
        # type of the speed model
        if not log_name.startswith(phy_type):
            continue
        log_name = log_name[len(phy_type) + 1:]

        # Find the cell name in the library and strip it
        for c in cell_pins:
            if log_name.startswith(c):
                log_cell = c
                log_name = log_name[len(c) + 1:]
                break
        else:
            continue

        log_pins = cell_pins[log_cell]

        # Find the input pin in the library and strip it
        for p in log_pins:
            if log_name.startswith(p):
                log_src = p
                log_name = log_name[len(p) + 1:]
                break
        else:
            continue

        # Find the output pin in the library and strip it
        for p in log_pins:
            if log_name == p:
                log_dst = p
                break
        else:
            continue

        # Append
        log_cells.append((
            log_cell,
            log_src,
            log_dst,
        ))

    return log_cells