}
1;
+=head1 APPENDIX: QUERYPARSER SYNTAX
+
+The native syntax of the QueryParser module is described by the following
+grammar:
+
+ regexp := valid PCRE
+ word := valid UTF-8 non-whitespace characters
+ whitespace := string matching PCRE /\s+/s
+ boolean_word := 'yes' | 'no' | 'true' | 'false' | '1' | '0'
+ modifier_marker := '#' ### configurable, default
+ phrase_boundary := '"'
+ phrase_left_anchor := '^'
+ phrase_right_anchor := '$'
+ 1_word_phrase_marker := '+'
+ negator := '-'
+ search_seperator := ':' | '='
+ class_field_seperator := '|'
+ boolean_and := '&&' ### configurable, EG default
+ boolean_or := '||' ### configurable, EG default
+ subquery_start := '(' ### configurable, default
+ subquery_end := ')' ### configurable, default
+
+ word_list := word { ',' word }
+ negated_word := negator word
+ required_word := 1_word_phrase_marker word ### one-word phrase shortcut
+ phrase := phrase_boundary { phrase_left_anchor } word \
+ { whitespace word } { phrase_right_anchor } phrase_boundary
+ term := word | negated_word | required_word |
+ phrase { whitespace term }
+
+ boolean_operator := boolean_and | boolean_or
+
+ registered_class := 'keyword' | 'title' | 'author' | 'subject' | 'series'
+ ### configurable, default for EG
+ class_alias := regexp
+ ### 'kw', 'ti', 'au', 'su', 'se' and many more, configurable,
+ ### loaded from IDL class cmsa where field is null
+ search_class := registered_class | class_alias
+ registered_field := word
+ ### configurable, loaded from IDL class cmf where search_field is true
+ field_alias := regexp
+ ### configurable, loaded from IDL class cmsa where field is not null
+ registered_facet := word
+ ### configurable, loaded from IDL class cmf where facet_field is true
+
+ classed_search := search_class search_seperator term
+ search_field_list := registered_field { class_field_seperator search_field_list }
+ fielded_search := search_class class_field_seperator \
+ { search_field_list } search_seperator term
+ field_alias_search := field_alias search_seperator term
+ facet_list := registered_facet { class_field_seperator facet_list }
+ facet_value_list := term { ' # ' term }
+ facet_search := search_class [ class_field_seperator { facet_list } ] \
+ '[' facet_value_list ']'
+ search := term | classed_search | fielded_search |
+ field_alias_search | facet_search
+
+ registered_modifier := 'available' | 'staff' | 'descending'
+ ### and many more, defined in QueryParser implementation driver class_alias
+ search_modifier := modifier_marker registered_modifier |
+ registered_modifier '(' boolean_word ')'
+ registered_filter := 'site' | 'sort' | 'item_type'
+ ### and many more, defined in QueryParser implementation driver class_alias
+ search_filter := registered_filter '(' word_list ')' |
+ registered_filter ':' word_list
+
+ boolean_term := term boolean_op term
+
+ subquery := subquery_start query subquery_end
+ query := term | boolean_term | search | search_modifier |
+ search_filter | subquery { [boolean_op] query }
+
+=cut