def test_convert_simple_value_boolean_query_to_and_boolean_queries():
    parse_tree = \
        parser.SimpleQuery(
            parser.SpiresKeywordQuery(
                parser.InspireKeyword('author'),
                parser.Value(
                    parser.SimpleValueBooleanQuery(
                        parser.SimpleValue('foo'),
                        parser.And(),
                        parser.SimpleValueBooleanQuery(
                            parser.SimpleValue('bar'),
                            parser.Or(),
                            parser.SimpleValueNegation(parser.SimpleValue('foobar'))
                        )
                    )
                )
            )
        )

    expected_parse_tree = \
        AndOp(
            KeywordOp(Keyword('author'), Value('foo')),
            OrOp(
                KeywordOp(Keyword('author'), Value('bar')),
                NotOp(KeywordOp(Keyword('author'), Value('foobar')))
            )
        )

    restructuring_visitor = RestructuringVisitor()
    parse_tree = parse_tree.accept(restructuring_visitor)

    assert parse_tree == expected_parse_tree
def test_foo_bar():
    query_str = 'find j Nucl.Phys. and not vol A531 and a ellis'
    print("Parsing: " + query_str)
    stateful_parser = StatefulParser()
    restructuring_visitor = RestructuringVisitor()
    _, parse_tree = stateful_parser.parse(query_str, parser.Query)
    parse_tree = parse_tree.accept(restructuring_visitor)
    expected_parse_tree = AndOp(
        KeywordOp(Keyword('journal'), Value('Nucl.Phys.')),
        KeywordOp(Keyword('author'), Value('ellis')))

    assert parse_tree == expected_parse_tree
    def _get_volume_keyword_op_and_remaining_subtree(right_subtree):
        if isinstance(right_subtree, NotOp) and isinstance(right_subtree.op, KeywordOp) \
                and right_subtree.op.left == Keyword('volume'):
            return None, None

        elif isinstance(right_subtree, AndOp) and isinstance(right_subtree.left, NotOp) \
                and isinstance(right_subtree.left.op, KeywordOp) and right_subtree.left.op.left == Keyword('volume'):
            return None, right_subtree.right

        elif isinstance(right_subtree,
                        KeywordOp) and right_subtree.left == Keyword('volume'):
            return right_subtree, None

        elif isinstance(
                right_subtree,
                AndOp) and right_subtree.left.left == Keyword('volume'):
            return right_subtree.left, right_subtree.right
    def visit_boolean_query(self, node):
        """Convert BooleanRule into AndOp or OrOp nodes."""
        left = node.left.accept(self)
        right = node.right.accept(self)

        is_journal_keyword_op = isinstance(
            left, KeywordOp) and left.left == Keyword('journal')

        if is_journal_keyword_op:
            journal_and_volume_conjunction = _restructure_if_volume_follows_journal(
                left, right)

            if journal_and_volume_conjunction:
                return journal_and_volume_conjunction

        return AndOp(left, right) if isinstance(node.bool_op, And) else OrOp(
            left, right)
Example #5
0
    def visit_invenio_keyword_query(self, node):
        """Transform an :class:`InvenioKeywordQuery` into a :class:`KeywordOp`.

        Notes:
            In case the value being a :class:`SimpleValueBooleanQuery`, the subtree is transformed to chained
            :class:`AndOp` queries containing :class:`KeywordOp`, whose keyword is the keyword of the current node and
            values, all the :class:`SimpleValueBooleanQuery` values (either :class:`SimpleValues` or
            :class:`SimpleValueNegation`.)
        """
        try:
            keyword = node.left.accept(self)
        except AttributeError:
            # The keywords whose values aren't an InspireKeyword are simple strings.
            keyword = Keyword(node.left)

        value = node.right.accept(self)

        if isinstance(value, SimpleValueBooleanQuery):
            return _convert_simple_value_boolean_query_to_and_boolean_queries(
                value, keyword)

        return KeywordOp(keyword, value)
Example #6
0
 def visit_inspire_keyword(self, node):
     return Keyword(node.value)
Example #7
0
 def visit_nested_keyword_query(self, node):
     return ast.NestedKeywordOp(Keyword(node.left), node.right.accept(self))
from inspire_query_parser.ast import (
    AndOp, EmptyQuery, ExactMatchValue, GreaterEqualThanOp, GreaterThanOp,
    Keyword, KeywordOp, LessEqualThanOp, LessThanOp, MalformedQuery,
    NestedKeywordOp, NotOp, OrOp, PartialMatchValue, QueryWithMalformedPart,
    RangeOp, RegexValue, Value, ValueOp)
from inspire_query_parser.stateful_pypeg_parser import StatefulParser
from inspire_query_parser.visitors.restructuring_visitor import \
    RestructuringVisitor


@pytest.mark.parametrize(
    ['query_str', 'expected_parse_tree'],
    [
        # Find keyword combined with other production rules
        ('FIN author:\'ellis\'',
         KeywordOp(Keyword('author'), PartialMatchValue('ellis'))),
        ('Find author "ellis"',
         KeywordOp(Keyword('author'), ExactMatchValue('ellis'))),
        ('f author ellis', KeywordOp(Keyword('author'), Value('ellis'))),

        # Invenio like search
        ('author:ellis and title:boson',
         AndOp(KeywordOp(Keyword('author'), Value('ellis')),
               KeywordOp(Keyword('title'), Value('boson')))),
        ('unknown_keyword:\'bar\'',
         KeywordOp(Keyword('unknown_keyword'), PartialMatchValue('bar'))),
        ('dotted.keyword:\'bar\'',
         KeywordOp(Keyword('dotted.keyword'), PartialMatchValue('bar'))),

        # Boolean operator testing (And/Or)
        ('author ellis and title \'boson\'',