def test_successExits(self): n1 = Node(matcher=1) n2 = Node(matcher=2) n3 = Node(matcher=3) n1.success.append(setRule(node=n2)) n1.failure.append(setRule(node=n3)) exits = list(successExits(n1)) self.assertNotIn(n1, exits) self.assertIn(n2, exits) self.assertIn(n3, exits)
def _multipleAlternativesOr(self, alternatives): matchers = [self.compileRule(rule) for rule in alternatives] for current_node, next_node in zip(matchers, matchers[1:]): count = 0 while current_node is not None: current_node.failure.append(setRule(node=next_node)) if count > 0: current_node.failure.append(backtrack(count=count)) count += 1 if not current_node.success: break current_node = getSuccessNode(current_node) return matchers[0]
def handle_And(self, term): elements = term.args[0].args matchers = [self.compileRule(rule) for rule in elements] seen = [] for current_node, next_node in zip(matchers, matchers[1:]): for x in successExits(current_node): # XXX this is dirty - should successExits actually return the same # node more than once? if x in seen: continue seen.append(x) if issubclass(next_node.matcher[0], noop): x.success.extend(next_node.success) else: x.success.append(setRule(node=next_node)) return matchers[0]