示例#1
0
def test_multi_processor_does_not_accept_post_and_pre_order_mix_in_one_slot():
    ParseTreeMultiProcessor(ParseTreeProcessor(pre_order=False),
                            ParseTreeProcessor(pre_order=False))
    ParseTreeMultiProcessor(ParseTreeProcessor(pre_order=True),
                            ParseTreeProcessor(pre_order=True))

    with pytest.raises(RuntimeError):
        ParseTreeMultiProcessor(ParseTreeProcessor(pre_order=True),
                                ParseTreeProcessor(pre_order=False))

    with pytest.raises(RuntimeError):
        ParseTreeMultiProcessor(ParseTreeProcessor(pre_order=False),
                                ParseTreeProcessor(pre_order=True))
示例#2
0
def compile(input_str):

    # TODO Add tests for this one
    """
    This also demonstrates how to express basic processor using functions rather than classes.
    The function is used as process_unrecognised(node).
    It must include "_pre_" in name in order to be registered as pre_order processor.
    """
    def contacts_pre_processor(node):
        # Initialise state in the root
        if node.x.is_root:
            node.x.foreign_lookups = {}
        node.mark_operands(foreign_lookups=node.x.foreign_lookups)
        if node.is_leaf and 'contacts.' in node.a:
            node.x.foreign_lookups[node.a] = node.b
        return node

    def contacts_post_processor(node):
        if node.x.is_root:
            # Do the lookups
            for k, v in node.x.foreign_lookups.items():
                node.x.foreign_lookups[k] = '<looked-up-value-of-{}>'.format(v)

        # Dummy replacement
        if node.is_leaf and node.a in node.x.foreign_lookups:
            node.b = node.x.foreign_lookups[node.a]

        return node

    parse_tree = BetterFiltersG.simple_parse(input_str)
    return (ParseTreeMultiProcessor().slot(contacts_pre_processor).slot(
        ParseTreeInspector()).slot(contacts_post_processor).slot(
            ParseTreeInspector())).process(parse_tree)
示例#3
0
def test_multi_processor_application_order():
    parse_tree = ('and', ('eq', 'a', 'b'), ('not', ('c')))
    calls = []

    class P1(ParseTreeProcessor):
        def process_unrecognised(self, node):
            calls.append(1)
            return node

    class P2(ParseTreeProcessor):
        def process_unrecognised(self, node):
            calls.append(2)
            return node

    class P3(ParseTreeProcessor):
        def process_unrecognised(self, node):
            calls.append(3)
            return node

    # Sequential processing with 2 slots
    pt1 = copy.deepcopy(parse_tree)
    ParseTreeMultiProcessor(P1()).slot(P2()).process(pt1)

    assert calls == [1, 1, 1, 2, 2, 2]

    calls[:] = []

    # Parallel processing with 1 slot
    pt2 = copy.deepcopy(parse_tree)
    ParseTreeMultiProcessor(P1(), P2()).process(pt2)

    assert calls == [1, 2, 1, 2, 1, 2]

    calls[:] = []

    # Parallel processing with 2 slots
    pt2 = copy.deepcopy(parse_tree)
    ParseTreeMultiProcessor(P1(), P2()).slot(P3()).process(pt2)

    assert calls == [1, 2, 1, 2, 1, 2, 3, 3, 3]
示例#4
0
def test_multi_processor_supports_pre_order(parse_tree):
    class DepthMarker(ParseTreeProcessor):
        pre_order = True

        def process_unrecognised(self, node):
            node.x.depth = node.x.depth or 0
            node.mark_operands(depth=node.x.depth + 1)
            return node

    proc = ParseTreeMultiProcessor(DepthMarker())

    pt = proc.process(('eq', 'a', 'b'))
    assert pt.x.depth == 0

    pt = proc.process(('and', ('eq', 'a', 'b'), ('ne', 'c', 'd')))
    assert pt.x.depth == 0
    assert pt.a.x.depth == 1
    assert pt.b.x.depth == 1

    pt = proc.process(parse_tree)
    assert pt.a.b.a.to_tuple() == ('eq', 'type', 'special')
    assert pt.a.b.a.x.depth == 3
示例#5
0
def test_parse_tree_multiprocessor_calls_all_processors(parse_tree):
    class PrimitivesProcessor(ParseTreeProcessor):
        def process_primitive(self, primitive):
            return '{}!'.format(primitive)

    class OperatorsProcessor(ParseTreeProcessor):
        def process_unrecognised(self, parse_tree):
            parse_tree.op = '<{}>'.format(parse_tree.op)
            return parse_tree

    class PostProcessor(ParseTreeProcessor):
        def process_primitive(self, primitive):
            return '{}?'.format(primitive)

    proc = ParseTreeMultiProcessor(PrimitivesProcessor(), OperatorsProcessor(),
                                   PostProcessor())
    pt = proc.process(parse_tree)

    t = pt.to_tuple()
    assert t[0] == '<and>'
    assert t[1] == ('<or>', ('<in>', 'off!?', 'tags!?'),
                    ('<not>', ('<eq>', 'type!?', 'special!?')))
    assert t[2] == ('<gt>', 'weight!?', '100!?')
示例#6
0
def test_strict_multi_processor_raises_exception_if_none_of_same_slot_processors_recognises_a_node(
):
    class LogicalOperatorProcessor(ParseTreeProcessor):
        @ParseTreeProcessor.delegate_of('process_and', 'process_or',
                                        'process_not')
        def process_logical_ops(self, node):
            return node

    class ComparisonOperatorProcessor(ParseTreeProcessor):
        @ParseTreeProcessor.delegate_of('process_eq', 'process_ne')
        def process_comparison_ops(self, node):
            return node

    strict_proc = ParseTreeMultiProcessor().strict_slot(
        LogicalOperatorProcessor(), ComparisonOperatorProcessor())
    strict_proc.process(('or', ('ne', 'a', 'b'), ('eq', 'c', 'd')))

    with pytest.raises(PtNodeNotRecognised) as excinfo:
        strict_proc.process(('or', ('ne', 'a', 'b'), ('=', 'c', 'd')))

    exc = excinfo.value
    assert exc.node.to_tuple() == ('=', 'c', 'd')

    non_strict_proc = ParseTreeMultiProcessor().slot(
        LogicalOperatorProcessor(), ComparisonOperatorProcessor())
    non_strict_proc.process(('or', ('ne', 'a', 'b'), ('eq', 'c', 'd')))
    non_strict_proc.process(('or', ('ne', 'a', 'b'), ('=', 'c', 'd')))
示例#7
0
def test_multi_processor_marks_is_root(parse_tree):
    pt = ParseTreeMultiProcessor(ParseTreeProcessor(),
                                 ParseTreeProcessor()).process(parse_tree)
    assert pt.x.is_root
    assert not pt.a.x.is_root
    assert not pt.b.x.is_root
示例#8
0
def test_multi_processor_with_no_processors_does_nothing(parse_tree):
    parse_tree_copy = copy.deepcopy(parse_tree)
    pt = ParseTreeMultiProcessor().process(parse_tree)
    assert pt.to_tuple() == parse_tree_copy
示例#9
0
 def __init__(self):
     self._grammar = BetterFiltersG
     self._proc = (ParseTreeMultiProcessor().slot(
         EsDslFilterPreprocessor()).strict_slot(EsDslFilterGenerator()))