Ниже показана трассировка его обработки. Финальным объектом в стеке _query_stack является объект класса NotQuery:

evalNot() : incomplete!

push on _current_op ( size == 1 )

evalWord() : daddy

pop _current_op : NotQuery

add operand: WordQuery : NotQuery complete!

push NotQuery on _query_stack

Текст, расположенный с отступом под функциями eval, показывает, как выполняется операция.

Во втором примере - составном запросе типа OrQuery - встречаются оба случая. Здесь же иллюстрируется помещение полного оператора в стек _query_stack:

== fiery || untamed || shyly

evalWord() : fiery

push word on _query_stack

evalOr() : incomplete!

pop _query_stack : fiery

add operand : WordQuery : OrQuery incomplete!

push OrQuery on _current_op ( size == 1 )

evalWord() : untamed

pop _current_op : OrQuery

add operand : WordQuery : OrQuery complete!

push OrQuery on _query_stack

evalOr() : incomplete!

pop _query_stack : OrQuery

add operand : OrQuery : OrQuery incomplete!

push OrQuery on _current_op ( size == 1 )

evalWord() : shyly

pop _current_op : OrQuery

add operand : WordQuery : OrQuery complete!

push OrQuery on _query_stack

В последнем примере рассматривается составной запрос и применение скобок для изменения порядка вычислений:

== fiery && ( bird || untamed )

evalWord() : fiery

push word on _query_stack

evalAnd() : incomplete!

pop _query_stack : fiery

add operand : WordQuery : AndQuery incomplete!

push AndQuery on _current_op ( size == 1 )

evalWord() : bird

_paren is set to 1

push word on _query_stack

evalOr() : incomplete!

pop _query_stack : bird

add operand : WordQuery : OrQuery incomplete!

push OrQuery on _current_op ( size == 2 )

evalWord() : untamed

pop _current_op : OrQuery

add operand : WordQuery : OrQuery complete!

push OrQuery on _query_stack

evalRParen() :

_paren: 0 _current_op.size(): 1

pop _query_stack : OrQuery

pop _current_op : AndQuery

add operand : OrQuery : AndQuery complete!

push AndQuery on _query_stack

Реализация системы текстового поиска состоит из трех компонентов:

класс TextQuery, где производится обработка текста (подробно он рассматривался в разделе 16.4). Для него нет производных классов;

объектно-ориентированная иерархия Query для представления и обработки различных типов запросов;

класс UserQuery, с помощью которого представлен конечный автомат для построения иерархии Query.

До настоящего момента мы реализовали эти три компонента практически независимо друг от друга и без каких бы то ни было конфликтов. Но, к сожалению, иерархия классов Query не поддерживает требований к конструированию объектов, предъявляемых реализацией UserQuery:

классы AndQuery, OrQuery и NotQuery требуют, чтобы каждый операнд присутствовал в момент определения объекта. Однако принятая нами схема обработки подразумевает наличие неполных объектов;

наша схема предполагает отложенное добавление операнда к объектам AndQuery, OrQuery и NotQuery. Более того, такая операция должна быть виртуальной. Операнд приходится добавлять через указатель типа Query*, находящийся в стеке _current_op. Однако способ добавления операнда зависит от типа: для унарных (NotQuery) и бинарных (AndQuery и OrQuery) операций он различен. Наша иерархия классов Query подобные операции не поддерживает.

Перейти на страницу:

Похожие книги