У меня есть набор документов на основе токен-индекса, который предлагает метод запроса.Пользователь вручную (!) Вводит строку запроса, которую необходимо проанализировать и оценить.Корпус должен затем вернуть список всех документов, соответствующих заданной строке запроса.Язык запросов содержит простые логические операторы AND, NOT и OR, которые также могут быть расставлены по приоритетам в скобках.После некоторого исследования я уже использовал ANTLR для анализа данной строки запроса в синтаксическом дереве.
Например: запрос
"Bill OR (John AND Jim) OR (NOT Simon AND Mike)"
транслируется в следующее синтаксическое дерево:
РЕДАКТИРОВАТЬ: Пожалуйста, смотрите правильный график в записи Барт Киерс (скопировано здесь):
Все узлы в дереве являются простыми строками и каждый узелзнает своих родителей и детей, но не своих братьев и сестер.Как вы можете видеть, грамматика ANTLR уже диктовала порядок, в котором должны выполняться операции: те, что находятся внизу дерева, идут первыми.
Так что мне, вероятно, нужно сделать рекурсивную (?) Оценку всех операндов в дереве.В общем, я могу выполнить простой поиск в моем корпусе, используя метод Get (строковый термин) для каждого листа в дереве (например, «Билл» или «Джон»).Get () возвращает список документов, содержащих термин в листе.Я также могу оценить родителя каждого листа, чтобы распознать возможный оператор NOT, который затем привел бы к списку результатов документов, не содержащих термин в листе (используя метод Not () вместо Get ()).
Операторы AND и OR должны быть преобразованы в вызовы методов, для которых требуется два параметра:
- И должен вызывать метод Intersect (list1, list2), который возвращает список документов, которые находятся в list1 AND вlist2.
- ИЛИ должен вызывать метод Union (list1, list2), который возвращает список документов, которые находятся либо в list1, либо в list2.
Параметры list1 и list2 содержатдокументы, которые я получил до использования Get () или Not ().
Мой вопрос: как я могу - семантически и синтаксически в C # - оценить все необходимые поисковые термины и использовать их для вызова правильных методов оператора в правильномпорядок?Интуитивно это звучит как рекурсия, но почему-то я не могу это представить - тем более что не все методы, которые нужно вызывать, имеют одинаковое количество параметров.Или, может быть, есть и другие способы сделать это?