Source code for pathex.machines.decomposers.visitors.difference_visitor

from collections import deque
from pathex.machines.decomposers.visitors.decorators import nary_operator_visitor
from pathex.expressions.nary_operators.difference import Difference
from pathex.expressions.terms.empty_word import EMPTY_WORD

from pathex.machines.decomposers.decomposer import Branches, DecomposerMatchMismatch

__all__ = ['difference_visitor']

[docs]@nary_operator_visitor def difference_visitor(machine: DecomposerMatchMismatch, exp: Difference) -> Branches: for head1, tail1 in machine._transform(exp.args_head): if head1 is EMPTY_WORD and tail1 is not EMPTY_WORD: yield EMPTY_WORD, exp.__class__(tail1, *exp.args_tail) else: matches = set() mismatches = {} alts = deque([Difference(exp.args_tail)]) while alts: other = alts.popleft() for head2, tail2 in machine._transform(other): if head2 is EMPTY_WORD and tail2 is not EMPTY_WORD: alts.append(tail2) else: tail = EMPTY_WORD if tail1 is tail2 is EMPTY_WORD \ else Difference(tail1, tail2) for match in machine.match(head1, head2): matches.add(match) if match in mismatches: del mismatches[match] if tail is not EMPTY_WORD: yield match, tail for m, h in machine.mismatch(head1, head2): if h is not head2: break if m not in matches: mismatches[m] = tail for m in mismatches: yield m, mismatches[m]