From c9258f35e48a76641cf684e68f0d98b0740d7dca Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Thu, 8 May 2014 14:39:06 -0400 Subject: [PATCH] Literal parsing; term parsing hooks; unit test stubs. --- bitshift/query/__init__.py | 45 ++++++++++++++++++++++++++++++++------------- test/__init__.py | 0 test/test_query_parser.py | 17 +++++++++++++++++ 3 files changed, 49 insertions(+), 13 deletions(-) create mode 100644 test/__init__.py create mode 100644 test/test_query_parser.py diff --git a/bitshift/query/__init__.py b/bitshift/query/__init__.py index 711e359..1f115a5 100644 --- a/bitshift/query/__init__.py +++ b/bitshift/query/__init__.py @@ -19,15 +19,15 @@ class _QueryParser(object): """Wrapper class with methods to parse queries. Used as a singleton.""" def __init__(self): - prefixes = { - "language": _parse_language, - "author": _parse_author, - "modified": _parse_modified, - "created": _parse_created, - "symbol": _parse_symbol, - "function": _parse_function, - "class": _parse_class, - "variable": _parse_variable + self._prefixes = { + self._parse_language: ["l", "lang", "language"], + self._parse_author: ["a", "author"], + self._parse_modified: ["m", "mod", "modified", "modify"], + self._parse_created: ["cr", "create", "created"], + self._parse_symbol: ["s", "sym", "symb", "symbol"], + self._parse_function: ["f", "fn", "func", "function"], + self._parse_class: ["cl", "class", "clss"], + self._parse_variable: ["v", "var", "variable"] } def _parse_language(self, term): @@ -54,6 +54,21 @@ class _QueryParser(object): def _parse_variable(self, term): pass + def _parse_literal(self, literal): + """Parse part of a search query into a string or regular expression.""" + if literal.startswith(("r:", "re:", "regex:", "regexp:")): + return Regex(literal.split(":", 1)[1]) + return String(literal) + + def _parse_term(self, term): + """Parse a query term into a tree node and return it.""" + if ":" in term and not term[0] == ":": + prefix, arg = term.split(":", 1) + for meth, prefixes in self._prefixes.iteritems(): + if prefix in prefixes: + return meth(arg) + return Text(self._parse_literal(term)) + def parse(self, query): """ Parse a search query. @@ -70,11 +85,15 @@ class _QueryParser(object): :raises: :py:class:`.QueryParseException` """ + print "input:", query for term in split(query): - if ":" in term and not term[0] == ":": - prefix = term.split(":")[0] - - + print "term: ", term + node = self._parse_term(term) + print "parse:", node + tree = Tree(node) + print "tree: ", tree + return tree + ## TODO # language:"Python" # lang: diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/test_query_parser.py b/test/test_query_parser.py new file mode 100644 index 0000000..c74da4a --- /dev/null +++ b/test/test_query_parser.py @@ -0,0 +1,17 @@ +from __future__ import unicode_literals +import unittest + +from bitshift.query import parse_query + +class TestQueryParser(unittest.TestCase): + """Unit tests for the query parser in :py:mod:`bitshift.query`.""" + + def test_parse(self): + """test basic query parsing""" + pq = lambda s: parse_query(s).serialize() + self.assertEqual("Tree(Text(String('test')))", pq("test")) + self.assertEqual("Tree(Text(Regex('test')))", pq("re:test")) + + +if __name__ == "__main__": + unittest.main(verbosity=2)