ferret 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (202) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README +109 -0
  3. data/Rakefile +275 -0
  4. data/TODO +9 -0
  5. data/TUTORIAL +197 -0
  6. data/ext/extconf.rb +3 -0
  7. data/ext/ferret.c +23 -0
  8. data/ext/ferret.h +85 -0
  9. data/ext/index_io.c +543 -0
  10. data/ext/priority_queue.c +227 -0
  11. data/ext/ram_directory.c +316 -0
  12. data/ext/segment_merge_queue.c +41 -0
  13. data/ext/string_helper.c +42 -0
  14. data/ext/tags +240 -0
  15. data/ext/term.c +261 -0
  16. data/ext/term_buffer.c +299 -0
  17. data/ext/util.c +12 -0
  18. data/lib/ferret.rb +41 -0
  19. data/lib/ferret/analysis.rb +11 -0
  20. data/lib/ferret/analysis/analyzers.rb +93 -0
  21. data/lib/ferret/analysis/standard_tokenizer.rb +65 -0
  22. data/lib/ferret/analysis/token.rb +79 -0
  23. data/lib/ferret/analysis/token_filters.rb +86 -0
  24. data/lib/ferret/analysis/token_stream.rb +26 -0
  25. data/lib/ferret/analysis/tokenizers.rb +107 -0
  26. data/lib/ferret/analysis/word_list_loader.rb +27 -0
  27. data/lib/ferret/document.rb +2 -0
  28. data/lib/ferret/document/document.rb +152 -0
  29. data/lib/ferret/document/field.rb +304 -0
  30. data/lib/ferret/index.rb +26 -0
  31. data/lib/ferret/index/compound_file_io.rb +343 -0
  32. data/lib/ferret/index/document_writer.rb +288 -0
  33. data/lib/ferret/index/field_infos.rb +259 -0
  34. data/lib/ferret/index/fields_io.rb +175 -0
  35. data/lib/ferret/index/index.rb +228 -0
  36. data/lib/ferret/index/index_file_names.rb +33 -0
  37. data/lib/ferret/index/index_reader.rb +462 -0
  38. data/lib/ferret/index/index_writer.rb +488 -0
  39. data/lib/ferret/index/multi_reader.rb +363 -0
  40. data/lib/ferret/index/multiple_term_doc_pos_enum.rb +105 -0
  41. data/lib/ferret/index/segment_infos.rb +130 -0
  42. data/lib/ferret/index/segment_merge_info.rb +47 -0
  43. data/lib/ferret/index/segment_merge_queue.rb +16 -0
  44. data/lib/ferret/index/segment_merger.rb +337 -0
  45. data/lib/ferret/index/segment_reader.rb +380 -0
  46. data/lib/ferret/index/segment_term_enum.rb +178 -0
  47. data/lib/ferret/index/segment_term_vector.rb +58 -0
  48. data/lib/ferret/index/term.rb +49 -0
  49. data/lib/ferret/index/term_buffer.rb +88 -0
  50. data/lib/ferret/index/term_doc_enum.rb +283 -0
  51. data/lib/ferret/index/term_enum.rb +52 -0
  52. data/lib/ferret/index/term_info.rb +41 -0
  53. data/lib/ferret/index/term_infos_io.rb +312 -0
  54. data/lib/ferret/index/term_vector_offset_info.rb +20 -0
  55. data/lib/ferret/index/term_vectors_io.rb +552 -0
  56. data/lib/ferret/query_parser.rb +274 -0
  57. data/lib/ferret/query_parser/query_parser.tab.rb +819 -0
  58. data/lib/ferret/search.rb +49 -0
  59. data/lib/ferret/search/boolean_clause.rb +100 -0
  60. data/lib/ferret/search/boolean_query.rb +303 -0
  61. data/lib/ferret/search/boolean_scorer.rb +294 -0
  62. data/lib/ferret/search/caching_wrapper_filter.rb +40 -0
  63. data/lib/ferret/search/conjunction_scorer.rb +99 -0
  64. data/lib/ferret/search/disjunction_sum_scorer.rb +203 -0
  65. data/lib/ferret/search/exact_phrase_scorer.rb +32 -0
  66. data/lib/ferret/search/explanation.rb +41 -0
  67. data/lib/ferret/search/field_cache.rb +216 -0
  68. data/lib/ferret/search/field_doc.rb +31 -0
  69. data/lib/ferret/search/field_sorted_hit_queue.rb +184 -0
  70. data/lib/ferret/search/filter.rb +11 -0
  71. data/lib/ferret/search/filtered_query.rb +130 -0
  72. data/lib/ferret/search/filtered_term_enum.rb +79 -0
  73. data/lib/ferret/search/fuzzy_query.rb +153 -0
  74. data/lib/ferret/search/fuzzy_term_enum.rb +244 -0
  75. data/lib/ferret/search/hit_collector.rb +34 -0
  76. data/lib/ferret/search/hit_queue.rb +11 -0
  77. data/lib/ferret/search/index_searcher.rb +173 -0
  78. data/lib/ferret/search/match_all_docs_query.rb +104 -0
  79. data/lib/ferret/search/multi_phrase_query.rb +204 -0
  80. data/lib/ferret/search/multi_term_query.rb +65 -0
  81. data/lib/ferret/search/non_matching_scorer.rb +22 -0
  82. data/lib/ferret/search/phrase_positions.rb +55 -0
  83. data/lib/ferret/search/phrase_query.rb +217 -0
  84. data/lib/ferret/search/phrase_scorer.rb +153 -0
  85. data/lib/ferret/search/prefix_query.rb +47 -0
  86. data/lib/ferret/search/query.rb +111 -0
  87. data/lib/ferret/search/query_filter.rb +51 -0
  88. data/lib/ferret/search/range_filter.rb +103 -0
  89. data/lib/ferret/search/range_query.rb +139 -0
  90. data/lib/ferret/search/req_excl_scorer.rb +125 -0
  91. data/lib/ferret/search/req_opt_sum_scorer.rb +70 -0
  92. data/lib/ferret/search/score_doc.rb +38 -0
  93. data/lib/ferret/search/score_doc_comparator.rb +114 -0
  94. data/lib/ferret/search/scorer.rb +91 -0
  95. data/lib/ferret/search/similarity.rb +278 -0
  96. data/lib/ferret/search/sloppy_phrase_scorer.rb +47 -0
  97. data/lib/ferret/search/sort.rb +105 -0
  98. data/lib/ferret/search/sort_comparator.rb +60 -0
  99. data/lib/ferret/search/sort_field.rb +87 -0
  100. data/lib/ferret/search/spans.rb +12 -0
  101. data/lib/ferret/search/spans/near_spans_enum.rb +304 -0
  102. data/lib/ferret/search/spans/span_first_query.rb +79 -0
  103. data/lib/ferret/search/spans/span_near_query.rb +108 -0
  104. data/lib/ferret/search/spans/span_not_query.rb +130 -0
  105. data/lib/ferret/search/spans/span_or_query.rb +176 -0
  106. data/lib/ferret/search/spans/span_query.rb +25 -0
  107. data/lib/ferret/search/spans/span_scorer.rb +74 -0
  108. data/lib/ferret/search/spans/span_term_query.rb +105 -0
  109. data/lib/ferret/search/spans/span_weight.rb +84 -0
  110. data/lib/ferret/search/spans/spans_enum.rb +44 -0
  111. data/lib/ferret/search/term_query.rb +128 -0
  112. data/lib/ferret/search/term_scorer.rb +181 -0
  113. data/lib/ferret/search/top_docs.rb +24 -0
  114. data/lib/ferret/search/top_field_docs.rb +17 -0
  115. data/lib/ferret/search/weight.rb +54 -0
  116. data/lib/ferret/search/wildcard_query.rb +26 -0
  117. data/lib/ferret/search/wildcard_term_enum.rb +61 -0
  118. data/lib/ferret/stemmers.rb +1 -0
  119. data/lib/ferret/stemmers/porter_stemmer.rb +218 -0
  120. data/lib/ferret/store.rb +5 -0
  121. data/lib/ferret/store/buffered_index_io.rb +191 -0
  122. data/lib/ferret/store/directory.rb +139 -0
  123. data/lib/ferret/store/fs_store.rb +338 -0
  124. data/lib/ferret/store/index_io.rb +259 -0
  125. data/lib/ferret/store/ram_store.rb +282 -0
  126. data/lib/ferret/utils.rb +7 -0
  127. data/lib/ferret/utils/bit_vector.rb +105 -0
  128. data/lib/ferret/utils/date_tools.rb +138 -0
  129. data/lib/ferret/utils/number_tools.rb +91 -0
  130. data/lib/ferret/utils/parameter.rb +41 -0
  131. data/lib/ferret/utils/priority_queue.rb +120 -0
  132. data/lib/ferret/utils/string_helper.rb +47 -0
  133. data/lib/ferret/utils/weak_key_hash.rb +51 -0
  134. data/rake_utils/code_statistics.rb +106 -0
  135. data/setup.rb +1551 -0
  136. data/test/benchmark/tb_ram_store.rb +76 -0
  137. data/test/benchmark/tb_rw_vint.rb +26 -0
  138. data/test/longrunning/tc_numbertools.rb +60 -0
  139. data/test/longrunning/tm_store.rb +19 -0
  140. data/test/test_all.rb +9 -0
  141. data/test/test_helper.rb +6 -0
  142. data/test/unit/analysis/tc_analyzer.rb +21 -0
  143. data/test/unit/analysis/tc_letter_tokenizer.rb +20 -0
  144. data/test/unit/analysis/tc_lower_case_filter.rb +20 -0
  145. data/test/unit/analysis/tc_lower_case_tokenizer.rb +27 -0
  146. data/test/unit/analysis/tc_per_field_analyzer_wrapper.rb +39 -0
  147. data/test/unit/analysis/tc_porter_stem_filter.rb +16 -0
  148. data/test/unit/analysis/tc_standard_analyzer.rb +20 -0
  149. data/test/unit/analysis/tc_standard_tokenizer.rb +20 -0
  150. data/test/unit/analysis/tc_stop_analyzer.rb +20 -0
  151. data/test/unit/analysis/tc_stop_filter.rb +14 -0
  152. data/test/unit/analysis/tc_white_space_analyzer.rb +21 -0
  153. data/test/unit/analysis/tc_white_space_tokenizer.rb +20 -0
  154. data/test/unit/analysis/tc_word_list_loader.rb +32 -0
  155. data/test/unit/document/tc_document.rb +47 -0
  156. data/test/unit/document/tc_field.rb +80 -0
  157. data/test/unit/index/tc_compound_file_io.rb +107 -0
  158. data/test/unit/index/tc_field_infos.rb +119 -0
  159. data/test/unit/index/tc_fields_io.rb +167 -0
  160. data/test/unit/index/tc_index.rb +140 -0
  161. data/test/unit/index/tc_index_reader.rb +622 -0
  162. data/test/unit/index/tc_index_writer.rb +57 -0
  163. data/test/unit/index/tc_multiple_term_doc_pos_enum.rb +80 -0
  164. data/test/unit/index/tc_segment_infos.rb +74 -0
  165. data/test/unit/index/tc_segment_term_docs.rb +17 -0
  166. data/test/unit/index/tc_segment_term_enum.rb +60 -0
  167. data/test/unit/index/tc_segment_term_vector.rb +71 -0
  168. data/test/unit/index/tc_term.rb +22 -0
  169. data/test/unit/index/tc_term_buffer.rb +57 -0
  170. data/test/unit/index/tc_term_info.rb +19 -0
  171. data/test/unit/index/tc_term_infos_io.rb +192 -0
  172. data/test/unit/index/tc_term_vector_offset_info.rb +18 -0
  173. data/test/unit/index/tc_term_vectors_io.rb +108 -0
  174. data/test/unit/index/th_doc.rb +244 -0
  175. data/test/unit/query_parser/tc_query_parser.rb +84 -0
  176. data/test/unit/search/tc_filter.rb +113 -0
  177. data/test/unit/search/tc_fuzzy_query.rb +136 -0
  178. data/test/unit/search/tc_index_searcher.rb +188 -0
  179. data/test/unit/search/tc_search_and_sort.rb +98 -0
  180. data/test/unit/search/tc_similarity.rb +37 -0
  181. data/test/unit/search/tc_sort.rb +48 -0
  182. data/test/unit/search/tc_sort_field.rb +27 -0
  183. data/test/unit/search/tc_spans.rb +153 -0
  184. data/test/unit/store/tc_fs_store.rb +84 -0
  185. data/test/unit/store/tc_ram_store.rb +35 -0
  186. data/test/unit/store/tm_store.rb +180 -0
  187. data/test/unit/store/tm_store_lock.rb +68 -0
  188. data/test/unit/ts_analysis.rb +16 -0
  189. data/test/unit/ts_document.rb +4 -0
  190. data/test/unit/ts_index.rb +18 -0
  191. data/test/unit/ts_query_parser.rb +3 -0
  192. data/test/unit/ts_search.rb +10 -0
  193. data/test/unit/ts_store.rb +6 -0
  194. data/test/unit/ts_utils.rb +10 -0
  195. data/test/unit/utils/tc_bit_vector.rb +65 -0
  196. data/test/unit/utils/tc_date_tools.rb +50 -0
  197. data/test/unit/utils/tc_number_tools.rb +59 -0
  198. data/test/unit/utils/tc_parameter.rb +40 -0
  199. data/test/unit/utils/tc_priority_queue.rb +62 -0
  200. data/test/unit/utils/tc_string_helper.rb +21 -0
  201. data/test/unit/utils/tc_weak_key_hash.rb +25 -0
  202. metadata +251 -0
@@ -0,0 +1,274 @@
1
+ require 'racc/parser'
2
+ module Ferret
3
+ # = QueryParser
4
+ #
5
+ # The Ferret::QueryParser is used to parse Ferret Query Language (FQL) into
6
+ # a Ferret Query. FQL is described Bellow.
7
+ #
8
+ # == Ferret Query Language
9
+ #
10
+ # === Preamble
11
+ #
12
+ # The following characters are special characters in FQL;
13
+ #
14
+ # :, (, ), [, ], {, }, !, +, ", ~, ^, -, |, <, >, =, *, ?, \
15
+ #
16
+ # If you want to use one of these characters in one of your terms you need
17
+ # to escape it with a \ character. \ escapes itself. The exception to this
18
+ # rule is within Phrases which a strings surrounded by double quotes (and
19
+ # will be explained further bellow in the section on PhraseQueries). In
20
+ # Phrases, only ", | and <> have special meaning and need to be escaped if
21
+ # you want the literal value. <> is escaped \<\>.
22
+ #
23
+ # In the following examples I have only written the query string. This would
24
+ # be parse like;
25
+ #
26
+ # query = query_parser.parse("pet:(dog AND cat)")
27
+ # puts query # => "+pet:dog +pet:cat"
28
+ #
29
+ # === TermQuery
30
+ #
31
+ # A term query is the most basic query of all and is what most of the other
32
+ # queries are built upon. The term consists of a single word. eg;
33
+ #
34
+ # 'term'
35
+ #
36
+ # Note that the analyzer will be run on the term and if it splits the term
37
+ # in two then it will be turned into a phrase query. For example, with the
38
+ # plain Ferret::Analysis::Analyzer, the following;
39
+ #
40
+ # 'dave12balmain'
41
+ #
42
+ # is equivalent to;
43
+ #
44
+ # '"dave balmain"'
45
+ #
46
+ # Which we will explain now...
47
+ #
48
+ # === PhraseQuery
49
+ #
50
+ # A phrase query is a string of terms surrounded by double quotes. For
51
+ # example you could write;
52
+ #
53
+ # '"quick brown fox"'
54
+ #
55
+ # But if a "fast" fox is just as good as a quick one you could use the |
56
+ # character to specify alternate terms.
57
+ #
58
+ # '"quick|speedy|fast brown fox"'
59
+ #
60
+ # What if we don't care what colour the fox is. We can use the <> to specify
61
+ # a place setter. eg;
62
+ #
63
+ # '"quick|speedy|fast <> fox"'
64
+ #
65
+ # This will match any word in between quick and fox. Alternatively we could
66
+ # set the "slop" for the phrase which allows a certain variation in the
67
+ # match of the phrase. The slop for a phrase is an integer indicating how
68
+ # many positions you are allowed to move the terms to get a match. Read more
69
+ # about the slop factor in Ferret::Search::PhraseQuery. To set the slop
70
+ # factor for a phrase you can type;
71
+ #
72
+ # '"big house"~2'
73
+ #
74
+ # This would match "big house", "big red house", "big red brick house" and
75
+ # even "house big". That's right, you don't need to have th terms in order
76
+ # if you allow some slop in your phrases. (See Ferret::Search::Spans if you
77
+ # need a phrase type query with ordered terms.)
78
+ #
79
+ # These basic queries will be run on the default field which is set when you
80
+ # create the query_parser. But what if you want to search a different field.
81
+ # You'll be needing a ...
82
+ #
83
+ # === FieldQuery
84
+ #
85
+ # A field query is any field prefixed by <fieldname>:. For example, to
86
+ # search for all instances of the term "ski" in field "sport", you'd write;
87
+ #
88
+ # 'sport:ski'
89
+ # Or we can apply a field to phrase;
90
+ #
91
+ # 'sport:"skiing is fun"'
92
+ #
93
+ # Now we have a few types of queries, we'll be needing to glue them together
94
+ # with a ...
95
+ #
96
+ # === BooleanQuery
97
+ #
98
+ # There are a couple of ways of writing boolean queries. Firstly you can
99
+ # specify which terms are required, optional or required not to exist (not).
100
+ #
101
+ # * '+' or "REQ" can be used to indicate a required query. "REQ" must be
102
+ # surrounded by white space.
103
+ # * '-', '!' or "NOT" are used to indicate query that is required to be
104
+ # false. "NOT" must be surrounded by white space.
105
+ # * all other queries are optional if the above symbols are used.
106
+ #
107
+ # Some examples;
108
+ #
109
+ # '+sport:ski -sport:snowboard sport:taboggen'
110
+ # '+ingredient:chocolate +ingredient:strawberries -ingredient:wheat'
111
+ #
112
+ # You may also use the boolean operators "AND", "&&", "OR" and "||". eg;
113
+ #
114
+ # 'sport:ski AND NOT sport:snowboard OR sport:taboggen'
115
+ # 'ingredient:chocolate AND ingredient:strawberries AND NOT ingredient:wheat'
116
+ #
117
+ # You can set the default operator when you create the query parse.
118
+ #
119
+ # === RangeQuery
120
+ #
121
+ # A range query finds all documents with terms between the two query terms.
122
+ # This can be very useful in particular for dates. eg;
123
+ #
124
+ # 'date:[20050725 20050905]' # all dates >= 20050725 and <= 20050905
125
+ # 'date:[20050725 20050905}' # all dates >= 20050725 and < 20050905
126
+ # 'date:{20050725 20050905]' # all dates > 20050725 and <= 20050905
127
+ # 'date:{20050725 20050905}' # all dates > 20050725 and < 20050905
128
+ #
129
+ # You can also do open ended queries like this;
130
+ #
131
+ # 'date:[20050725|' # all dates >= 20050725
132
+ # 'date:{20050725|' # all dates > 20050725
133
+ # 'date:|20050905]' # all dates <= 20050905
134
+ # 'date:|20050905}' # all dates < 20050905
135
+ #
136
+ # Or like this;
137
+ #
138
+ # 'date: >= 20050725'
139
+ # 'date: > 20050725'
140
+ # 'date: <= 20050905'
141
+ # 'date: < 20050905'
142
+ #
143
+ # If you prefer the above style you could use a boolean query but like this;
144
+ #
145
+ # 'date:( >= 20050725 AND <= 20050905)'
146
+ #
147
+ # But rangequery only solution shown first will be faster.
148
+ #
149
+ # === WildQuery
150
+ #
151
+ # A wild query is a query using the pattern matching characters * and ?. *
152
+ # matchs 0 or more characters while ? matchs a single character. This type
153
+ # of query can be really useful for matching heirarchical categories for
154
+ # example. Let's say we had this structure;
155
+ #
156
+ # /sport/skiing
157
+ # /sport/cycling
158
+ # /coding1/ruby
159
+ # /coding1/c
160
+ # /coding2/python
161
+ # /coding2/perl
162
+ #
163
+ # If you wanted all categories with programming languages you could use the
164
+ # query;
165
+ #
166
+ # 'category:/coding?/*'
167
+ #
168
+ # Note that this query can be quite expensive if not used carefully. In the
169
+ # example above there would be no problem but you should be careful not use
170
+ # the wild characters at the beginning of the query as it'll have to iterate
171
+ # through every term in that field. Having said that, some fields like the
172
+ # category field above will only have a small number of distinct fields so
173
+ # this could be ok.
174
+ #
175
+ # === FuzzyQuery
176
+ #
177
+ # This is like the sloppy phrase query above, except you are now adding slop
178
+ # to a term. Basically it measures the Levenshtein distance between two
179
+ # terms and if the value is below the slop threshold the term is a match.
180
+ # This time though the slop must be a float between 0 and 1.0, 1.0 being a
181
+ # perfect match and 0 being far from a match. The default is set to 0.5 so
182
+ # you don't need to give a slop value if you don't want to. You can set the
183
+ # default in the Ferret::Search::FuzzyQuery class. Here are a couple of
184
+ # examples;
185
+ #
186
+ # 'content:ferret~'
187
+ # 'content:Ostralya~0.4'
188
+ #
189
+ # Note that this query can be quite expensive. If you'd like to use this
190
+ # query, you may want to set a mininum prefix length in the FuzzyQuery
191
+ # class. This can substantially reduce the number of terms that the query
192
+ # will iterate over.
193
+ #
194
+ # Well, that's it for the query language. Next we have...
195
+ #
196
+ # == Extending the Query Parser
197
+ #
198
+ # The query parser has a number of methods which you may want to subclass if
199
+ # you are interested in extending the query parser.
200
+ #
201
+ # get_term_query:: Called for each term in the query. You may want
202
+ # to discard all but the first token instead or
203
+ # doing a phrase query.
204
+ #
205
+ # get_fuzzy_query:: These are expensive. You could set the default
206
+ # prefix or perhaps disallow these all together by
207
+ # raising an exception.
208
+ #
209
+ # get_range_query:: You'll probably want to leave this as is.
210
+ #
211
+ # get_phrase_query:: This method is passed an array of terms or
212
+ # perhaps an array of arrays of terms in the case
213
+ # of a multi-term phrase query as well as the slop
214
+ # and it returns a phrase query. Perhaps you'd
215
+ # like to use a span query instead of the standard
216
+ # phrase query to ensure the order of the terms
217
+ # remains intact.
218
+ #
219
+ # get_normal_phrase_query:: Called for phrases without any multi-terms. This
220
+ # method is called by the standard
221
+ # get_phrase_query.
222
+ #
223
+ # get_multi_phrase_query:: Called for phrases with multi-terms. This method
224
+ # is called by the standard get_phrase_query.
225
+ #
226
+ # get_boolean_query:: Called with an array of clauses.
227
+ #
228
+ class QueryParser < Racc::Parser
229
+ include Ferret::Search
230
+ include Ferret::Index
231
+
232
+ # Create a new QueryParser.
233
+ #
234
+ # default_field:: all queries without a specified query string are run on
235
+ # this field.
236
+ # options:: the following options exist;
237
+ #
238
+ # * *analyzer* the analyzer is used to break phrases up into terms and
239
+ # to turn terms in tokens recognized in the index. Analysis::Analyzer
240
+ # is the default
241
+ # * *occur_default* Set to either BooleanClause::Occur::SHOULD (default)
242
+ # or BooleanClause::Occur::MUST to specify the default Occur operator.
243
+ # * *wild_lower* Set to false if you don't want the terms in fuzzy and
244
+ # wild queries to be set to lower case. You should do this if your
245
+ # analyzer doesn't downcase. The default is true.
246
+ # * *default_slop* Set the default slop for phrase queries. This defaults
247
+ # to 0.
248
+ def initialize(default_field = "", options = {})
249
+ end
250
+
251
+ # parses a string into a Ferret::Search::Query. The string needs to be
252
+ # parseable FQL.
253
+ def parse(str)
254
+ end
255
+
256
+ # Set to false if you don't want the terms in fuzzy and wild queries to be
257
+ # set to lower case. You should do this if your analyzer doesn't downcase.
258
+ def wild_lower()
259
+ end
260
+
261
+ # Returns the value of wild_lower. See #wild_lower.
262
+ def wild_lower?()
263
+ end
264
+
265
+ # Processes the query string escaping all special characters within
266
+ # phrases and making sure that double quotes and brackets are matching.
267
+ # This class will be called by the parse method so you should subclass it
268
+ # if you'd like to do your own query string cleaning.
269
+ def clean_string(str)
270
+ end
271
+ end
272
+ end
273
+
274
+ require 'ferret/query_parser/query_parser.tab.rb'
@@ -0,0 +1,819 @@
1
+ #
2
+ # DO NOT MODIFY!!!!
3
+ # This file is automatically generated by racc 1.4.4
4
+ # from racc grammer file "lib/ferret/query_parser/query_parser.y".
5
+ #
6
+
7
+ require 'racc/parser'
8
+
9
+
10
+ module Ferret
11
+
12
+ class QueryParser < Racc::Parser
13
+
14
+ module_eval <<'..end lib/ferret/query_parser/query_parser.y modeval..id4dd1430e53', 'lib/ferret/query_parser/query_parser.y', 121
15
+ attr_accessor :default_field
16
+
17
+ # true if you want to downcase wild card queries. This is set to try by
18
+ # default.
19
+ attr_accessor :wild_lower
20
+
21
+ def wild_lower?() @wild_lower end
22
+
23
+
24
+ def initialize(default_field = "", options = {})
25
+ @yydebug = true
26
+ @field = @default_field = default_field
27
+ @analyzer = options[:analyzer] || Analysis::Analyzer.new
28
+ @wild_lower = options[:wild_lower].nil? ? true : options[:wild_lower]
29
+ @occur_default = options[:occur_default] || BooleanClause::Occur::SHOULD
30
+ @default_slop = options[:default_slop] || 0
31
+ end
32
+
33
+ RESERVED = {
34
+ 'AND' => :AND,
35
+ '&&' => :AND,
36
+ 'OR' => :OR,
37
+ '||' => :OR,
38
+ 'NOT' => :NOT,
39
+ '!' => :NOT,
40
+ '-' => :NOT,
41
+ 'REQ' => :REQ,
42
+ '+' => :REQ
43
+ }
44
+
45
+ ECHR = %q,:()\[\]{}!+"~^\-\|<>\=\*\?,
46
+ EWCHR = %q,:()\[\]{}!+"~^\-\|<>\=,
47
+
48
+ def parse(str)
49
+ str = clean_string(str)
50
+ str.strip!
51
+ @q = []
52
+
53
+ until str.empty? do
54
+ case str
55
+ when /\A\s+/
56
+ ;
57
+ when /\A[#{ECHR}]/
58
+ @q.push [ RESERVED[$&]||$&, $& ]
59
+ when /\A(\&\&|\|\|)/
60
+ @q.push [ RESERVED[$&], $& ]
61
+ when /\A(\\[#{ECHR}]|[^\s#{ECHR}])+[?*](\\[#{EWCHR}]|[^\s#{EWCHR}])*/
62
+ str = $'
63
+ unescaped = $&.gsub(/\\(?!\\)/,"")
64
+ @q.push [ :WILD_STRING, unescaped ]
65
+ next
66
+ when /\A(\\[#{ECHR}]|[^\s#{ECHR}])+/
67
+ symbol = RESERVED[$&]
68
+ if symbol
69
+ @q.push [ symbol, $& ]
70
+ else
71
+ str = $'
72
+ unescaped = $&.gsub(/\\(?!\\)/,"")
73
+ @q.push [ :WORD, unescaped ]
74
+ next
75
+ end
76
+ else
77
+ raise RuntimeError, "shouldn't happen"
78
+ end
79
+ str = $'
80
+ end
81
+ @q.push [ false, '$' ]
82
+ #p @q
83
+
84
+ do_parse
85
+ end
86
+
87
+ def next_token
88
+ @q.shift
89
+ end
90
+
91
+ PHRASE_CHARS = [?<, ?>, ?|, ?"] # these chars have meaning within phrases
92
+ def clean_string(str)
93
+ escape_chars = ECHR.gsub(/\\/,"").unpack("c*")
94
+ pb = nil
95
+ br_stack = []
96
+ quote_open = false
97
+ # leave a little extra
98
+ new_str = []
99
+
100
+ str.each_byte do |b|
101
+ # ignore escaped characters
102
+ if pb == ?\\
103
+ if quote_open and PHRASE_CHARS.index(b)
104
+ new_str << ?\\ # this was left off the first time through
105
+ end
106
+
107
+ new_str << b
108
+ pb = (b == ?\\ ? ?: : b) # \\ has escaped itself so does nothing more
109
+ next
110
+ end
111
+ case b
112
+ when ?\\
113
+ new_str << b if !quote_open # We do our own escaping below
114
+ when ?"
115
+ quote_open = !quote_open
116
+ new_str << b
117
+ when ?(
118
+ if !quote_open
119
+ br_stack << b
120
+ else
121
+ new_str << ?\\
122
+ end
123
+ new_str << b
124
+ when ?)
125
+ if !quote_open
126
+ if br_stack.size == 0
127
+ new_str.unshift(?()
128
+ else
129
+ br_stack.pop
130
+ end
131
+ else
132
+ new_str << ?\\
133
+ end
134
+ new_str << b
135
+ when ?>
136
+ if quote_open
137
+ if pb == ?<
138
+ new_str.delete_at(-2)
139
+ else
140
+ new_str << ?\\
141
+ end
142
+ end
143
+ new_str << b
144
+ else
145
+ if quote_open
146
+ if escape_chars.index(b) and b != ?|
147
+ new_str << ?\\
148
+ end
149
+ end
150
+ new_str << b
151
+ end
152
+ pb = b
153
+ end
154
+ new_str << ?" if quote_open
155
+ br_stack.each { |b| new_str << ?) }
156
+ return new_str.pack("c*")
157
+ end
158
+
159
+ def get_range_query(start_word, end_word, inc_upper, inc_lower)
160
+ return RangeQuery.new(@field, start_word, end_word, inc_upper, inc_lower)
161
+ end
162
+
163
+ def get_term_query(word)
164
+ tokens = []
165
+ stream = @analyzer.token_stream(@field, word)
166
+ while token = stream.next
167
+ tokens << token
168
+ end
169
+ if tokens.length == 0
170
+ return nil
171
+ elsif tokens.length == 1
172
+ return TermQuery.new(Term.new(@field, tokens[0].term_text))
173
+ else
174
+ pq = PhraseQuery.new()
175
+ tokens.each do |token|
176
+ pq.add(Term.new(@field, token.term_text), nil, token.position_increment)
177
+ end
178
+ return pq
179
+ end
180
+ end
181
+
182
+ def get_fuzzy_query(word, min_sim = nil)
183
+ tokens = []
184
+ stream = @analyzer.token_stream(@field, word)
185
+ if token = stream.next # only makes sense to look at one term for fuzzy
186
+ if min_sim
187
+ return FuzzyQuery.new(Term.new(@field, token.term_text), min_sim.to_f)
188
+ else
189
+ return FuzzyQuery.new(Term.new(@field, token.term_text))
190
+ end
191
+ else
192
+ return nil
193
+ end
194
+ end
195
+
196
+ def add_multi_word(words, word)
197
+ last_word = words[-1]
198
+ if not last_word.is_a?(Array)
199
+ last_word = words[-1] = [words[-1]]
200
+ end
201
+ last_word << word
202
+ return words
203
+ end
204
+
205
+ def get_normal_phrase_query(positions)
206
+ pq = PhraseQuery.new()
207
+ pq.slop = @default_slop
208
+ pos_inc = 0
209
+
210
+ positions.each do |position|
211
+ if position.nil?
212
+ pos_inc += 1
213
+ next
214
+ end
215
+ stream = @analyzer.token_stream(@field, position)
216
+ tokens = []
217
+ while token = stream.next
218
+ tokens << token
219
+ end
220
+ tokens.each do |token|
221
+ pq.add(Term.new(@field, token.term_text), nil,
222
+ token.position_increment + pos_inc)
223
+ pos_inc = 0
224
+ end
225
+ end
226
+ return pq
227
+ end
228
+
229
+ def get_multi_phrase_query(positions)
230
+ mpq = MultiPhraseQuery.new()
231
+ mpq.slop = @default_slop
232
+ pos_inc = 0
233
+
234
+ positions.each do |position|
235
+ if position.nil?
236
+ pos_inc += 1
237
+ next
238
+ end
239
+ if position.is_a?(Array)
240
+ position.compact! # it doesn't make sense to have an empty spot here
241
+ terms = []
242
+ position.each do |word|
243
+ stream = @analyzer.token_stream(@field, word)
244
+ if token = stream.next # only put one term per word
245
+ terms << Term.new(@field, token.term_text)
246
+ end
247
+ end
248
+ mpq.add(terms, nil, pos_inc + 1) # must go at least one forward
249
+ pos_inc = 0
250
+ else
251
+ stream = @analyzer.token_stream(@field, position)
252
+ tokens = []
253
+ while token = stream.next
254
+ tokens << token
255
+ end
256
+ tokens.each do |token|
257
+ mpq.add([Term.new(@field, token.term_text)], nil,
258
+ token.position_increment + pos_inc)
259
+ pos_inc = 0
260
+ end
261
+ end
262
+ end
263
+ return mpq
264
+ end
265
+
266
+ def get_phrase_query(positions, slop = nil)
267
+ if positions.size == 1 and not positions[0].is_a?(Array)
268
+ return get_term_query(words[0])
269
+ end
270
+
271
+ multi_phrase = false
272
+ positions.each do |position|
273
+ if position.is_a?(Array)
274
+ position.compact!
275
+ if position.size > 1
276
+ multi_phrase = true
277
+ end
278
+ end
279
+ end
280
+
281
+ q = nil
282
+ if not multi_phrase
283
+ q = get_normal_phrase_query(positions.flatten)
284
+ else
285
+ q = get_multi_phrase_query(positions)
286
+ end
287
+ q.slop = slop if slop
288
+ return q
289
+ end
290
+
291
+ def add_and_clause(clauses, clause)
292
+ clauses.compact!
293
+ if (clauses.length == 1)
294
+ last_cl = clauses[0]
295
+ last_cl.occur = BooleanClause::Occur::MUST if not last_cl.prohibited?
296
+ end
297
+
298
+ return if clause.nil? # incase a query got destroyed by the analyzer
299
+
300
+ clause.occur = BooleanClause::Occur::MUST if not clause.prohibited?
301
+ clauses << clause
302
+ end
303
+
304
+ def add_or_clause(clauses, clause)
305
+ clauses << clause
306
+ end
307
+
308
+ def add_default_clause(clauses, clause)
309
+ if @occur_default == BooleanClause::Occur::MUST
310
+ add_and_clause(clauses, clause)
311
+ else
312
+ add_or_clause(clauses, clause)
313
+ end
314
+ end
315
+
316
+ def get_boolean_query(clauses)
317
+ # possible that we got all nil clauses so check
318
+ return nil if clauses.nil?
319
+ clauses.compact!
320
+ return nil if clauses.size == 0
321
+
322
+ if clauses.size == 1 and not clauses[0].prohibited?
323
+ return clauses[0].query
324
+ end
325
+ bq = BooleanQuery.new()
326
+ clauses.each {|clause| bq << clause }
327
+ return bq
328
+ end
329
+
330
+ def get_boolean_clause(query, occur)
331
+ return nil if query.nil?
332
+ return BooleanClause.new(query, occur)
333
+ end
334
+
335
+ ..end lib/ferret/query_parser/query_parser.y modeval..id4dd1430e53
336
+
337
+ ##### racc 1.4.4 generates ###
338
+
339
+ racc_reduce_table = [
340
+ 0, 0, :racc_error,
341
+ 1, 25, :_reduce_1,
342
+ 1, 26, :_reduce_2,
343
+ 3, 26, :_reduce_3,
344
+ 3, 26, :_reduce_4,
345
+ 2, 26, :_reduce_5,
346
+ 2, 27, :_reduce_6,
347
+ 2, 27, :_reduce_7,
348
+ 1, 27, :_reduce_8,
349
+ 1, 29, :_reduce_none,
350
+ 3, 29, :_reduce_10,
351
+ 1, 28, :_reduce_none,
352
+ 3, 28, :_reduce_12,
353
+ 1, 28, :_reduce_none,
354
+ 1, 28, :_reduce_none,
355
+ 1, 28, :_reduce_none,
356
+ 1, 28, :_reduce_none,
357
+ 1, 30, :_reduce_17,
358
+ 3, 30, :_reduce_18,
359
+ 2, 30, :_reduce_19,
360
+ 1, 34, :_reduce_20,
361
+ 0, 36, :_reduce_21,
362
+ 4, 31, :_reduce_22,
363
+ 1, 35, :_reduce_23,
364
+ 3, 32, :_reduce_24,
365
+ 5, 32, :_reduce_25,
366
+ 2, 32, :_reduce_26,
367
+ 4, 32, :_reduce_27,
368
+ 1, 37, :_reduce_28,
369
+ 2, 37, :_reduce_29,
370
+ 3, 37, :_reduce_30,
371
+ 3, 37, :_reduce_31,
372
+ 4, 33, :_reduce_32,
373
+ 4, 33, :_reduce_33,
374
+ 4, 33, :_reduce_34,
375
+ 4, 33, :_reduce_35,
376
+ 3, 33, :_reduce_36,
377
+ 3, 33, :_reduce_37,
378
+ 3, 33, :_reduce_38,
379
+ 3, 33, :_reduce_39,
380
+ 2, 33, :_reduce_40,
381
+ 3, 33, :_reduce_41,
382
+ 3, 33, :_reduce_42,
383
+ 2, 33, :_reduce_43 ]
384
+
385
+ racc_reduce_n = 44
386
+
387
+ racc_shift_n = 73
388
+
389
+ racc_action_table = [
390
+ 7, 10, 61, 47, 38, 36, 48, 21, 3, 41,
391
+ 60, 6, 9, 12, 14, 16, 18, 37, 35, 1,
392
+ 7, 10, 33, 34, 58, 59, 40, 21, 3, 45,
393
+ -23, 6, 9, 12, 14, 16, 18, 7, 10, 1,
394
+ 55, 42, 30, 56, 21, 3, 44, 28, 6, 9,
395
+ 12, 14, 16, 18, 43, 57, 1, 7, 10, 33,
396
+ 34, 70, 71, 39, 21, 3, 63, 64, 6, 9,
397
+ 12, 14, 16, 18, 7, 10, 1, 27, 62, 25,
398
+ 66, 21, 3, 67, 68, 6, 9, 12, 14, 16,
399
+ 18, 7, 10, 1, 69, 23, 72, nil, 21, 3,
400
+ nil, nil, 6, 9, 12, 14, 16, 18, 21, 3,
401
+ 1, nil, 6, 9, 12, 14, 16, 18, 21, 3,
402
+ 1, nil, 6, 9, 12, 14, 16, 18, 21, 3,
403
+ 1, nil, 6, 9, 12, 14, 16, 18, 52, nil,
404
+ 1, nil, nil, 49, 50, nil, 51 ]
405
+
406
+ racc_action_check = [
407
+ 0, 0, 41, 27, 14, 12, 28, 0, 0, 18,
408
+ 41, 0, 0, 0, 0, 0, 0, 14, 12, 0,
409
+ 24, 24, 24, 24, 40, 40, 16, 24, 24, 24,
410
+ 21, 24, 24, 24, 24, 24, 24, 3, 3, 24,
411
+ 35, 21, 9, 37, 3, 3, 23, 9, 3, 3,
412
+ 3, 3, 3, 3, 23, 39, 3, 11, 11, 11,
413
+ 11, 61, 61, 15, 11, 11, 44, 44, 11, 11,
414
+ 11, 11, 11, 11, 34, 34, 11, 8, 42, 5,
415
+ 48, 34, 34, 49, 50, 34, 34, 34, 34, 34,
416
+ 34, 33, 33, 34, 51, 1, 67, nil, 33, 33,
417
+ nil, nil, 33, 33, 33, 33, 33, 33, 10, 10,
418
+ 33, nil, 10, 10, 10, 10, 10, 10, 25, 25,
419
+ 10, nil, 25, 25, 25, 25, 25, 25, 7, 7,
420
+ 25, nil, 7, 7, 7, 7, 7, 7, 29, nil,
421
+ 7, nil, nil, 29, 29, nil, 29 ]
422
+
423
+ racc_action_pointer = [
424
+ -3, 85, nil, 34, nil, 77, nil, 118, 77, 32,
425
+ 98, 54, -5, nil, -6, 54, 16, nil, -1, nil,
426
+ nil, 28, nil, 36, 17, 108, nil, 3, -7, 128,
427
+ nil, nil, nil, 88, 71, 30, nil, 33, nil, 45,
428
+ 4, -8, 68, nil, 46, nil, nil, nil, 70, 70,
429
+ 67, 84, nil, nil, nil, nil, nil, nil, nil, nil,
430
+ nil, 41, nil, nil, nil, nil, nil, 86, nil, nil,
431
+ nil, nil, nil ]
432
+
433
+ racc_action_default = [
434
+ -44, -44, -15, -44, -16, -44, -20, -44, -44, -44,
435
+ -44, -1, -44, -2, -44, -9, -44, -8, -44, -11,
436
+ -13, -17, -14, -44, -44, -44, -6, -44, -26, -44,
437
+ -28, -7, -5, -44, -44, -44, -40, -44, -43, -44,
438
+ -44, -44, -19, -39, -44, -12, -21, 73, -44, -24,
439
+ -44, -44, -29, -3, -4, -41, -42, -10, -37, -36,
440
+ -38, -44, -18, -34, -35, -22, -27, -44, -30, -31,
441
+ -32, -33, -25 ]
442
+
443
+ racc_goto_table = [
444
+ 32, 26, 11, 8, 31, 24, 65, 29, nil, nil,
445
+ nil, nil, nil, 32, nil, nil, nil, nil, nil, 46,
446
+ nil, nil, 53, 54 ]
447
+
448
+ racc_goto_check = [
449
+ 3, 4, 2, 1, 4, 2, 12, 13, nil, nil,
450
+ nil, nil, nil, 3, nil, nil, nil, nil, nil, 4,
451
+ nil, nil, 3, 3 ]
452
+
453
+ racc_goto_pointer = [
454
+ nil, 3, 2, -11, -6, nil, nil, nil, nil, nil,
455
+ nil, nil, -40, -2 ]
456
+
457
+ racc_goto_default = [
458
+ nil, nil, nil, 13, 15, 17, 19, 20, 22, 2,
459
+ 4, 5, nil, nil ]
460
+
461
+ racc_token_table = {
462
+ false => 0,
463
+ Object.new => 1,
464
+ ":" => 2,
465
+ :REQ => 3,
466
+ :NOT => 4,
467
+ :AND => 5,
468
+ :OR => 6,
469
+ :HIGH => 7,
470
+ :LOW => 8,
471
+ "^" => 9,
472
+ :WORD => 10,
473
+ "(" => 11,
474
+ ")" => 12,
475
+ "~" => 13,
476
+ :WILD_STRING => 14,
477
+ "\"" => 15,
478
+ "<" => 16,
479
+ ">" => 17,
480
+ "|" => 18,
481
+ "[" => 19,
482
+ "]" => 20,
483
+ "}" => 21,
484
+ "{" => 22,
485
+ "=" => 23 }
486
+
487
+ racc_use_result_var = false
488
+
489
+ racc_nt_base = 24
490
+
491
+ Racc_arg = [
492
+ racc_action_table,
493
+ racc_action_check,
494
+ racc_action_default,
495
+ racc_action_pointer,
496
+ racc_goto_table,
497
+ racc_goto_check,
498
+ racc_goto_default,
499
+ racc_goto_pointer,
500
+ racc_nt_base,
501
+ racc_reduce_table,
502
+ racc_token_table,
503
+ racc_shift_n,
504
+ racc_reduce_n,
505
+ racc_use_result_var ]
506
+
507
+ Racc_token_to_s_table = [
508
+ '$end',
509
+ 'error',
510
+ '":"',
511
+ 'REQ',
512
+ 'NOT',
513
+ 'AND',
514
+ 'OR',
515
+ 'HIGH',
516
+ 'LOW',
517
+ '"^"',
518
+ 'WORD',
519
+ '"("',
520
+ '")"',
521
+ '"~"',
522
+ 'WILD_STRING',
523
+ '"\""',
524
+ '"<"',
525
+ '">"',
526
+ '"|"',
527
+ '"["',
528
+ '"]"',
529
+ '"}"',
530
+ '"{"',
531
+ '"="',
532
+ '$start',
533
+ 'top_query',
534
+ 'bool_query',
535
+ 'bool_clause',
536
+ 'query',
537
+ 'boosted_query',
538
+ 'term_query',
539
+ 'field_query',
540
+ 'phrase_query',
541
+ 'range_query',
542
+ 'wild_query',
543
+ 'field_name',
544
+ '@1',
545
+ 'phrase_words']
546
+
547
+ Racc_debug_parser = false
548
+
549
+ ##### racc system variables end #####
550
+
551
+ # reduce 0 omitted
552
+
553
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 19
554
+ def _reduce_1( val, _values)
555
+ get_boolean_query(val[0])
556
+ end
557
+ .,.,
558
+
559
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 24
560
+ def _reduce_2( val, _values)
561
+ [val[0]]
562
+ end
563
+ .,.,
564
+
565
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 28
566
+ def _reduce_3( val, _values)
567
+ add_and_clause(val[0], val[2])
568
+ end
569
+ .,.,
570
+
571
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 32
572
+ def _reduce_4( val, _values)
573
+ add_or_clause(val[0], val[2])
574
+ end
575
+ .,.,
576
+
577
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 36
578
+ def _reduce_5( val, _values)
579
+ add_default_clause(val[0], val[1])
580
+ end
581
+ .,.,
582
+
583
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 41
584
+ def _reduce_6( val, _values)
585
+ get_boolean_clause(val[1], BooleanClause::Occur::MUST)
586
+ end
587
+ .,.,
588
+
589
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 45
590
+ def _reduce_7( val, _values)
591
+ get_boolean_clause(val[1], BooleanClause::Occur::MUST_NOT)
592
+ end
593
+ .,.,
594
+
595
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 49
596
+ def _reduce_8( val, _values)
597
+ get_boolean_clause(val[0], BooleanClause::Occur::SHOULD)
598
+ end
599
+ .,.,
600
+
601
+ # reduce 9 omitted
602
+
603
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 51
604
+ def _reduce_10( val, _values)
605
+ val[0].boost = val[2].to_f; return val[0]
606
+ end
607
+ .,.,
608
+
609
+ # reduce 11 omitted
610
+
611
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 58
612
+ def _reduce_12( val, _values)
613
+ get_boolean_query(val[1])
614
+ end
615
+ .,.,
616
+
617
+ # reduce 13 omitted
618
+
619
+ # reduce 14 omitted
620
+
621
+ # reduce 15 omitted
622
+
623
+ # reduce 16 omitted
624
+
625
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 67
626
+ def _reduce_17( val, _values)
627
+ get_term_query(val[0])
628
+ end
629
+ .,.,
630
+
631
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 71
632
+ def _reduce_18( val, _values)
633
+ get_fuzzy_query(val[0], val[2])
634
+ end
635
+ .,.,
636
+
637
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 75
638
+ def _reduce_19( val, _values)
639
+ get_fuzzy_query(val[0])
640
+ end
641
+ .,.,
642
+
643
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 80
644
+ def _reduce_20( val, _values)
645
+ WildcardQuery.new(Term.new(@field, val[0]))
646
+ end
647
+ .,.,
648
+
649
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 81
650
+ def _reduce_21( val, _values)
651
+ @field = @default_field
652
+ end
653
+ .,.,
654
+
655
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 85
656
+ def _reduce_22( val, _values)
657
+ val[2]
658
+ end
659
+ .,.,
660
+
661
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 86
662
+ def _reduce_23( val, _values)
663
+ @field = val[0]
664
+ end
665
+ .,.,
666
+
667
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 92
668
+ def _reduce_24( val, _values)
669
+ get_phrase_query(val[1])
670
+ end
671
+ .,.,
672
+
673
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 96
674
+ def _reduce_25( val, _values)
675
+ get_phrase_query(val[1], val[4].to_i)
676
+ end
677
+ .,.,
678
+
679
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 96
680
+ def _reduce_26( val, _values)
681
+ nil
682
+ end
683
+ .,.,
684
+
685
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 97
686
+ def _reduce_27( val, _values)
687
+ nil
688
+ end
689
+ .,.,
690
+
691
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 99
692
+ def _reduce_28( val, _values)
693
+ [val[0]]
694
+ end
695
+ .,.,
696
+
697
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 100
698
+ def _reduce_29( val, _values)
699
+ val[0] << val[1]
700
+ end
701
+ .,.,
702
+
703
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 101
704
+ def _reduce_30( val, _values)
705
+ val[0] << nil
706
+ end
707
+ .,.,
708
+
709
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 102
710
+ def _reduce_31( val, _values)
711
+ add_multi_word(val[0], val[2])
712
+ end
713
+ .,.,
714
+
715
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 104
716
+ def _reduce_32( val, _values)
717
+ get_range_query(val[1], val[2], true, true)
718
+ end
719
+ .,.,
720
+
721
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 105
722
+ def _reduce_33( val, _values)
723
+ get_range_query(val[1], val[2], true, false)
724
+ end
725
+ .,.,
726
+
727
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 106
728
+ def _reduce_34( val, _values)
729
+ get_range_query(val[1], val[2], false, true)
730
+ end
731
+ .,.,
732
+
733
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 107
734
+ def _reduce_35( val, _values)
735
+ get_range_query(val[1], val[2], false, false)
736
+ end
737
+ .,.,
738
+
739
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 108
740
+ def _reduce_36( val, _values)
741
+ get_range_query(nil, val[1], false, false)
742
+ end
743
+ .,.,
744
+
745
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 109
746
+ def _reduce_37( val, _values)
747
+ get_range_query(nil, val[1], false, true)
748
+ end
749
+ .,.,
750
+
751
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 110
752
+ def _reduce_38( val, _values)
753
+ get_range_query(val[1], nil, true, false)
754
+ end
755
+ .,.,
756
+
757
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 111
758
+ def _reduce_39( val, _values)
759
+ get_range_query(val[1], nil, false, false)
760
+ end
761
+ .,.,
762
+
763
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 112
764
+ def _reduce_40( val, _values)
765
+ get_range_query(nil, val[1], false, false)
766
+ end
767
+ .,.,
768
+
769
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 113
770
+ def _reduce_41( val, _values)
771
+ get_range_query(nil, val[2], false, true)
772
+ end
773
+ .,.,
774
+
775
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 114
776
+ def _reduce_42( val, _values)
777
+ get_range_query(val[2], nil, true, false)
778
+ end
779
+ .,.,
780
+
781
+ module_eval <<'.,.,', 'lib/ferret/query_parser/query_parser.y', 115
782
+ def _reduce_43( val, _values)
783
+ get_range_query(val[1], nil, false, false)
784
+ end
785
+ .,.,
786
+
787
+ def _reduce_none( val, _values)
788
+ val[0]
789
+ end
790
+
791
+ end # class QueryParser
792
+
793
+ end # module Ferret
794
+
795
+
796
+ if __FILE__ == $0
797
+ $:.unshift File.join(File.dirname(__FILE__), '..')
798
+ require 'utils'
799
+ require 'analysis'
800
+ require 'document'
801
+ require 'store'
802
+ require 'index'
803
+ require 'search'
804
+
805
+ st = "\033[7m"
806
+ en = "\033[m"
807
+
808
+ parser = Ferret::QueryParser.new("default")
809
+
810
+ $stdin.each do |line|
811
+ query = parser.parse(line)
812
+ if query
813
+ puts "#{query.class}"
814
+ puts query.to_s(parser.default_field)
815
+ else
816
+ puts "No query was returned"
817
+ end
818
+ end
819
+ end