A semantic search engine for source code https://bitshift.benkurtovic.com/
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

118 linhas
3.3 KiB

  1. """
  2. This subpackage contains code to parse search queries received from the
  3. frontend into trees that can be used by the database backend.
  4. """
  5. from shlex import split
  6. from .nodes import * ## TODO
  7. from .tree import Tree
  8. from ..languages import LANGS
  9. __all__ = ["QueryParseException", "parse_query"]
  10. class QueryParseException(Exception):
  11. """Raised by parse_query() when a query is invalid."""
  12. pass
  13. class _QueryParser(object):
  14. """Wrapper class with methods to parse queries. Used as a singleton."""
  15. def __init__(self):
  16. self._prefixes = {
  17. self._parse_language: ["l", "lang", "language"],
  18. self._parse_author: ["a", "author"],
  19. self._parse_modified: ["m", "mod", "modified", "modify"],
  20. self._parse_created: ["cr", "create", "created"],
  21. self._parse_symbol: ["s", "sym", "symb", "symbol"],
  22. self._parse_function: ["f", "fn", "func", "function"],
  23. self._parse_class: ["cl", "class", "clss"],
  24. self._parse_variable: ["v", "var", "variable"]
  25. }
  26. def _parse_language(self, term):
  27. pass
  28. def _parse_author(self, term):
  29. pass
  30. def _parse_modified(self, term):
  31. pass
  32. def _parse_created(self, term):
  33. pass
  34. def _parse_symbol(self, term):
  35. pass
  36. def _parse_function(self, term):
  37. pass
  38. def _parse_class(self, term):
  39. pass
  40. def _parse_variable(self, term):
  41. pass
  42. def _parse_literal(self, literal):
  43. """Parse part of a search query into a string or regular expression."""
  44. if literal.startswith(("r:", "re:", "regex:", "regexp:")):
  45. return Regex(literal.split(":", 1)[1])
  46. return String(literal)
  47. def _parse_term(self, term):
  48. """Parse a query term into a tree node and return it."""
  49. if ":" in term and not term[0] == ":":
  50. prefix, arg = term.split(":", 1)
  51. for meth, prefixes in self._prefixes.iteritems():
  52. if prefix in prefixes:
  53. return meth(arg)
  54. return Text(self._parse_literal(term))
  55. def parse(self, query):
  56. """
  57. Parse a search query.
  58. The result is normalized with a sorting function so that ``"foo OR bar"``
  59. and ``"bar OR foo"`` result in the same tree. This is important for caching
  60. purposes.
  61. :param query: The query be converted.
  62. :type query: str
  63. :return: A tree storing the data in the query.
  64. :rtype: :py:class:`~.query.tree.Tree`
  65. :raises: :py:class:`.QueryParseException`
  66. """
  67. print "input:", query
  68. for term in split(query):
  69. print "term: ", term
  70. node = self._parse_term(term)
  71. print "parse:", node
  72. tree = Tree(node)
  73. print "tree: ", tree
  74. return tree
  75. ## TODO
  76. # language:"Python"
  77. # lang:
  78. # l:
  79. # author:"Ben Kurtovic"
  80. # modified:before
  81. # modified:after
  82. # created:before
  83. # created:after:"Jaunary 4, 2014"
  84. # func:"foobar"
  85. # func:re|gex:"foo?b|car"
  86. # "foo" -> Tree()
  87. # "foo bar" -> "foo bar" OR ("foo" or "bar")
  88. # "foo bar baz" -> ""foo bar baz" OR ("foo" OR "bar baz") OR ("foo" OR "bar baz") OR ('foo' OR 'bar' OR 'baz')"
  89. parse_query = _QueryParser().parse