sdsykes-ferret 0.11.6.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (195) hide show
  1. data/CHANGELOG +24 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README +102 -0
  4. data/Rakefile +338 -0
  5. data/TODO +17 -0
  6. data/TUTORIAL +231 -0
  7. data/bin/ferret-browser +79 -0
  8. data/ext/analysis.c +1555 -0
  9. data/ext/analysis.h +219 -0
  10. data/ext/api.c +69 -0
  11. data/ext/api.h +27 -0
  12. data/ext/array.c +123 -0
  13. data/ext/array.h +53 -0
  14. data/ext/bitvector.c +540 -0
  15. data/ext/bitvector.h +272 -0
  16. data/ext/compound_io.c +383 -0
  17. data/ext/config.h +42 -0
  18. data/ext/document.c +156 -0
  19. data/ext/document.h +53 -0
  20. data/ext/except.c +120 -0
  21. data/ext/except.h +168 -0
  22. data/ext/extconf.rb +14 -0
  23. data/ext/ferret.c +402 -0
  24. data/ext/ferret.h +91 -0
  25. data/ext/filter.c +156 -0
  26. data/ext/fs_store.c +483 -0
  27. data/ext/global.c +418 -0
  28. data/ext/global.h +117 -0
  29. data/ext/hash.c +567 -0
  30. data/ext/hash.h +473 -0
  31. data/ext/hashset.c +170 -0
  32. data/ext/hashset.h +187 -0
  33. data/ext/header.h +58 -0
  34. data/ext/helper.c +62 -0
  35. data/ext/helper.h +13 -0
  36. data/ext/inc/lang.h +48 -0
  37. data/ext/inc/threading.h +31 -0
  38. data/ext/index.c +6425 -0
  39. data/ext/index.h +961 -0
  40. data/ext/lang.h +66 -0
  41. data/ext/libstemmer.c +92 -0
  42. data/ext/libstemmer.h +79 -0
  43. data/ext/mempool.c +87 -0
  44. data/ext/mempool.h +35 -0
  45. data/ext/modules.h +162 -0
  46. data/ext/multimapper.c +310 -0
  47. data/ext/multimapper.h +51 -0
  48. data/ext/posh.c +1006 -0
  49. data/ext/posh.h +1007 -0
  50. data/ext/priorityqueue.c +151 -0
  51. data/ext/priorityqueue.h +143 -0
  52. data/ext/q_boolean.c +1608 -0
  53. data/ext/q_const_score.c +161 -0
  54. data/ext/q_filtered_query.c +209 -0
  55. data/ext/q_fuzzy.c +268 -0
  56. data/ext/q_match_all.c +148 -0
  57. data/ext/q_multi_term.c +677 -0
  58. data/ext/q_parser.c +2825 -0
  59. data/ext/q_phrase.c +1126 -0
  60. data/ext/q_prefix.c +100 -0
  61. data/ext/q_range.c +350 -0
  62. data/ext/q_span.c +2402 -0
  63. data/ext/q_term.c +337 -0
  64. data/ext/q_wildcard.c +171 -0
  65. data/ext/r_analysis.c +2575 -0
  66. data/ext/r_index.c +3472 -0
  67. data/ext/r_qparser.c +585 -0
  68. data/ext/r_search.c +4105 -0
  69. data/ext/r_store.c +513 -0
  70. data/ext/r_utils.c +963 -0
  71. data/ext/ram_store.c +471 -0
  72. data/ext/search.c +1741 -0
  73. data/ext/search.h +885 -0
  74. data/ext/similarity.c +150 -0
  75. data/ext/similarity.h +82 -0
  76. data/ext/sort.c +983 -0
  77. data/ext/stem_ISO_8859_1_danish.c +338 -0
  78. data/ext/stem_ISO_8859_1_danish.h +16 -0
  79. data/ext/stem_ISO_8859_1_dutch.c +635 -0
  80. data/ext/stem_ISO_8859_1_dutch.h +16 -0
  81. data/ext/stem_ISO_8859_1_english.c +1156 -0
  82. data/ext/stem_ISO_8859_1_english.h +16 -0
  83. data/ext/stem_ISO_8859_1_finnish.c +792 -0
  84. data/ext/stem_ISO_8859_1_finnish.h +16 -0
  85. data/ext/stem_ISO_8859_1_french.c +1276 -0
  86. data/ext/stem_ISO_8859_1_french.h +16 -0
  87. data/ext/stem_ISO_8859_1_german.c +512 -0
  88. data/ext/stem_ISO_8859_1_german.h +16 -0
  89. data/ext/stem_ISO_8859_1_italian.c +1091 -0
  90. data/ext/stem_ISO_8859_1_italian.h +16 -0
  91. data/ext/stem_ISO_8859_1_norwegian.c +296 -0
  92. data/ext/stem_ISO_8859_1_norwegian.h +16 -0
  93. data/ext/stem_ISO_8859_1_porter.c +776 -0
  94. data/ext/stem_ISO_8859_1_porter.h +16 -0
  95. data/ext/stem_ISO_8859_1_portuguese.c +1035 -0
  96. data/ext/stem_ISO_8859_1_portuguese.h +16 -0
  97. data/ext/stem_ISO_8859_1_spanish.c +1119 -0
  98. data/ext/stem_ISO_8859_1_spanish.h +16 -0
  99. data/ext/stem_ISO_8859_1_swedish.c +307 -0
  100. data/ext/stem_ISO_8859_1_swedish.h +16 -0
  101. data/ext/stem_KOI8_R_russian.c +701 -0
  102. data/ext/stem_KOI8_R_russian.h +16 -0
  103. data/ext/stem_UTF_8_danish.c +344 -0
  104. data/ext/stem_UTF_8_danish.h +16 -0
  105. data/ext/stem_UTF_8_dutch.c +653 -0
  106. data/ext/stem_UTF_8_dutch.h +16 -0
  107. data/ext/stem_UTF_8_english.c +1176 -0
  108. data/ext/stem_UTF_8_english.h +16 -0
  109. data/ext/stem_UTF_8_finnish.c +808 -0
  110. data/ext/stem_UTF_8_finnish.h +16 -0
  111. data/ext/stem_UTF_8_french.c +1296 -0
  112. data/ext/stem_UTF_8_french.h +16 -0
  113. data/ext/stem_UTF_8_german.c +526 -0
  114. data/ext/stem_UTF_8_german.h +16 -0
  115. data/ext/stem_UTF_8_italian.c +1113 -0
  116. data/ext/stem_UTF_8_italian.h +16 -0
  117. data/ext/stem_UTF_8_norwegian.c +302 -0
  118. data/ext/stem_UTF_8_norwegian.h +16 -0
  119. data/ext/stem_UTF_8_porter.c +794 -0
  120. data/ext/stem_UTF_8_porter.h +16 -0
  121. data/ext/stem_UTF_8_portuguese.c +1055 -0
  122. data/ext/stem_UTF_8_portuguese.h +16 -0
  123. data/ext/stem_UTF_8_russian.c +709 -0
  124. data/ext/stem_UTF_8_russian.h +16 -0
  125. data/ext/stem_UTF_8_spanish.c +1137 -0
  126. data/ext/stem_UTF_8_spanish.h +16 -0
  127. data/ext/stem_UTF_8_swedish.c +313 -0
  128. data/ext/stem_UTF_8_swedish.h +16 -0
  129. data/ext/stopwords.c +401 -0
  130. data/ext/store.c +692 -0
  131. data/ext/store.h +777 -0
  132. data/ext/term_vectors.c +352 -0
  133. data/ext/threading.h +31 -0
  134. data/ext/utilities.c +446 -0
  135. data/ext/win32.h +54 -0
  136. data/lib/ferret.rb +29 -0
  137. data/lib/ferret/browser.rb +246 -0
  138. data/lib/ferret/browser/s/global.js +192 -0
  139. data/lib/ferret/browser/s/style.css +148 -0
  140. data/lib/ferret/browser/views/document/list.rhtml +49 -0
  141. data/lib/ferret/browser/views/document/show.rhtml +27 -0
  142. data/lib/ferret/browser/views/error/index.rhtml +7 -0
  143. data/lib/ferret/browser/views/help/index.rhtml +8 -0
  144. data/lib/ferret/browser/views/home/index.rhtml +29 -0
  145. data/lib/ferret/browser/views/layout.rhtml +22 -0
  146. data/lib/ferret/browser/views/term-vector/index.rhtml +4 -0
  147. data/lib/ferret/browser/views/term/index.rhtml +199 -0
  148. data/lib/ferret/browser/views/term/termdocs.rhtml +1 -0
  149. data/lib/ferret/browser/webrick.rb +14 -0
  150. data/lib/ferret/document.rb +130 -0
  151. data/lib/ferret/field_infos.rb +44 -0
  152. data/lib/ferret/index.rb +786 -0
  153. data/lib/ferret/number_tools.rb +157 -0
  154. data/lib/ferret_version.rb +3 -0
  155. data/setup.rb +1555 -0
  156. data/test/test_all.rb +5 -0
  157. data/test/test_helper.rb +24 -0
  158. data/test/threading/number_to_spoken.rb +132 -0
  159. data/test/threading/thread_safety_index_test.rb +79 -0
  160. data/test/threading/thread_safety_read_write_test.rb +76 -0
  161. data/test/threading/thread_safety_test.rb +133 -0
  162. data/test/unit/analysis/tc_analyzer.rb +548 -0
  163. data/test/unit/analysis/tc_token_stream.rb +646 -0
  164. data/test/unit/index/tc_index.rb +762 -0
  165. data/test/unit/index/tc_index_reader.rb +699 -0
  166. data/test/unit/index/tc_index_writer.rb +437 -0
  167. data/test/unit/index/th_doc.rb +315 -0
  168. data/test/unit/largefile/tc_largefile.rb +46 -0
  169. data/test/unit/query_parser/tc_query_parser.rb +238 -0
  170. data/test/unit/search/tc_filter.rb +135 -0
  171. data/test/unit/search/tc_fuzzy_query.rb +147 -0
  172. data/test/unit/search/tc_index_searcher.rb +61 -0
  173. data/test/unit/search/tc_multi_searcher.rb +128 -0
  174. data/test/unit/search/tc_multiple_search_requests.rb +58 -0
  175. data/test/unit/search/tc_search_and_sort.rb +179 -0
  176. data/test/unit/search/tc_sort.rb +49 -0
  177. data/test/unit/search/tc_sort_field.rb +27 -0
  178. data/test/unit/search/tc_spans.rb +190 -0
  179. data/test/unit/search/tm_searcher.rb +384 -0
  180. data/test/unit/store/tc_fs_store.rb +77 -0
  181. data/test/unit/store/tc_ram_store.rb +35 -0
  182. data/test/unit/store/tm_store.rb +34 -0
  183. data/test/unit/store/tm_store_lock.rb +68 -0
  184. data/test/unit/tc_document.rb +81 -0
  185. data/test/unit/ts_analysis.rb +2 -0
  186. data/test/unit/ts_index.rb +2 -0
  187. data/test/unit/ts_largefile.rb +4 -0
  188. data/test/unit/ts_query_parser.rb +2 -0
  189. data/test/unit/ts_search.rb +2 -0
  190. data/test/unit/ts_store.rb +2 -0
  191. data/test/unit/ts_utils.rb +2 -0
  192. data/test/unit/utils/tc_bit_vector.rb +295 -0
  193. data/test/unit/utils/tc_number_tools.rb +117 -0
  194. data/test/unit/utils/tc_priority_queue.rb +106 -0
  195. metadata +285 -0
@@ -0,0 +1,2825 @@
1
+ /* A Bison parser, made by GNU Bison 2.3. */
2
+
3
+ /* Skeleton implementation for Bison's Yacc-like parsers in C
4
+
5
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
6
+ Free Software Foundation, Inc.
7
+
8
+ This program is free software; you can redistribute it and/or modify
9
+ it under the terms of the GNU General Public License as published by
10
+ the Free Software Foundation; either version 2, or (at your option)
11
+ any later version.
12
+
13
+ This program is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+
18
+ You should have received a copy of the GNU General Public License
19
+ along with this program; if not, write to the Free Software
20
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
21
+ Boston, MA 02110-1301, USA. */
22
+
23
+ /* As a special exception, you may create a larger work that contains
24
+ part or all of the Bison parser skeleton and distribute that work
25
+ under terms of your choice, so long as that work isn't itself a
26
+ parser generator using the skeleton or a modified version thereof
27
+ as a parser skeleton. Alternatively, if you modify or redistribute
28
+ the parser skeleton itself, you may (at your option) remove this
29
+ special exception, which will cause the skeleton and the resulting
30
+ Bison output files to be licensed under the GNU General Public
31
+ License without this special exception.
32
+
33
+ This special exception was added by the Free Software Foundation in
34
+ version 2.2 of Bison. */
35
+
36
+ /* C LALR(1) parser skeleton written by Richard Stallman, by
37
+ simplifying the original so-called "semantic" parser. */
38
+
39
+ /* All symbols defined below should begin with yy or YY, to avoid
40
+ infringing on user name space. This should be done even for local
41
+ variables, as they might otherwise be expanded by user macros.
42
+ There are some unavoidable exceptions within include files to
43
+ define necessary library symbols; they are noted "INFRINGES ON
44
+ USER NAME SPACE" below. */
45
+
46
+ /* Identify Bison output. */
47
+ #define YYBISON 1
48
+
49
+ /* Bison version. */
50
+ #define YYBISON_VERSION "2.3"
51
+
52
+ /* Skeleton name. */
53
+ #define YYSKELETON_NAME "yacc.c"
54
+
55
+ /* Pure parsers. */
56
+ #define YYPURE 1
57
+
58
+ /* Using locations. */
59
+ #define YYLSP_NEEDED 0
60
+
61
+
62
+
63
+ /* Tokens. */
64
+ #ifndef YYTOKENTYPE
65
+ # define YYTOKENTYPE
66
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
67
+ know about them. */
68
+ enum yytokentype {
69
+ QWRD = 258,
70
+ WILD_STR = 259,
71
+ LOW = 260,
72
+ OR = 261,
73
+ AND = 262,
74
+ NOT = 263,
75
+ REQ = 264,
76
+ HIGH = 265
77
+ };
78
+ #endif
79
+ /* Tokens. */
80
+ #define QWRD 258
81
+ #define WILD_STR 259
82
+ #define LOW 260
83
+ #define OR 261
84
+ #define AND 262
85
+ #define NOT 263
86
+ #define REQ 264
87
+ #define HIGH 265
88
+
89
+
90
+
91
+
92
+ /* Copy the first part of user declarations. */
93
+ #line 1 "src/q_parser.y"
94
+
95
+ #include <string.h>
96
+ #include <ctype.h>
97
+ #include <wctype.h>
98
+ #include "except.h"
99
+ #include "search.h"
100
+ #include "array.h"
101
+
102
+ typedef struct Phrase {
103
+ int size;
104
+ int capa;
105
+ int pos_inc;
106
+ PhrasePosition *positions;
107
+ } Phrase;
108
+
109
+ #define BCA_INIT_CAPA 4
110
+ typedef struct BCArray {
111
+ int size;
112
+ int capa;
113
+ BooleanClause **clauses;
114
+ } BCArray;
115
+
116
+ float qp_default_fuzzy_min_sim = 0.5;
117
+ int qp_default_fuzzy_pre_len = 0;
118
+
119
+
120
+
121
+ /* Enabling traces. */
122
+ #ifndef YYDEBUG
123
+ # define YYDEBUG 0
124
+ #endif
125
+
126
+ /* Enabling verbose error messages. */
127
+ #ifdef YYERROR_VERBOSE
128
+ # undef YYERROR_VERBOSE
129
+ # define YYERROR_VERBOSE 1
130
+ #else
131
+ # define YYERROR_VERBOSE 0
132
+ #endif
133
+
134
+ /* Enabling the token table. */
135
+ #ifndef YYTOKEN_TABLE
136
+ # define YYTOKEN_TABLE 0
137
+ #endif
138
+
139
+ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
140
+ typedef union YYSTYPE
141
+ #line 27 "src/q_parser.y"
142
+ {
143
+ Query *query;
144
+ BooleanClause *bcls;
145
+ BCArray *bclss;
146
+ HashSet *hashset;
147
+ Phrase *phrase;
148
+ char *str;
149
+ }
150
+ /* Line 187 of yacc.c. */
151
+ #line 152 "y.tab.c"
152
+ YYSTYPE;
153
+ # define yystype YYSTYPE /* obsolescent; will be withdrawn */
154
+ # define YYSTYPE_IS_DECLARED 1
155
+ # define YYSTYPE_IS_TRIVIAL 1
156
+ #endif
157
+
158
+
159
+
160
+ /* Copy the second part of user declarations. */
161
+ #line 35 "src/q_parser.y"
162
+
163
+ static int yylex(YYSTYPE *lvalp, QParser *qp);
164
+ static int yyerror(QParser *qp, char const *msg);
165
+
166
+ #define PHRASE_INIT_CAPA 4
167
+ static Query *get_bool_q(BCArray *bca);
168
+
169
+ static BCArray *first_cls(BooleanClause *boolean_clause);
170
+ static BCArray *add_and_cls(BCArray *bca, BooleanClause *clause);
171
+ static BCArray *add_or_cls(BCArray *bca, BooleanClause *clause);
172
+ static BCArray *add_default_cls(QParser *qp, BCArray *bca, BooleanClause *clause);
173
+ static void bca_destroy(BCArray *bca);
174
+
175
+ static BooleanClause *get_bool_cls(Query *q, unsigned int occur);
176
+
177
+ static Query *get_term_q(QParser *qp, char *field, char *word);
178
+ static Query *get_fuzzy_q(QParser *qp, char *field, char *word, char *slop);
179
+ static Query *get_wild_q(QParser *qp, char *field, char *pattern);
180
+
181
+ static HashSet *first_field(QParser *qp, char *field);
182
+ static HashSet *add_field(QParser *qp, char *field);
183
+
184
+ static Query *get_phrase_q(QParser *qp, Phrase *phrase, char *slop);
185
+
186
+ static Phrase *ph_first_word(char *word);
187
+ static Phrase *ph_add_word(Phrase *self, char *word);
188
+ static Phrase *ph_add_multi_word(Phrase *self, char *word);
189
+ static void ph_destroy(Phrase *self);
190
+
191
+ static Query *get_r_q(QParser *qp, char *field, char *from, char *to,
192
+ bool inc_lower, bool inc_upper);
193
+
194
+ #define FLDS(q, func) do {\
195
+ TRY {\
196
+ char *field;\
197
+ if (qp->fields->size == 0) {\
198
+ q = NULL;\
199
+ } else if (qp->fields->size == 1) {\
200
+ field = (char *)qp->fields->elems[0];\
201
+ q = func;\
202
+ } else {\
203
+ int i;Query *sq;\
204
+ q = bq_new_max(false, qp->max_clauses);\
205
+ for (i = 0; i < qp->fields->size; i++) {\
206
+ field = (char *)qp->fields->elems[i];\
207
+ sq = func;\
208
+ TRY\
209
+ if (sq) bq_add_query_nr(q, sq, BC_SHOULD);\
210
+ XCATCHALL\
211
+ if (sq) q_deref(sq);\
212
+ XENDTRY\
213
+ }\
214
+ if (((BooleanQuery *)q)->clause_cnt == 0) {\
215
+ q_deref(q);\
216
+ q = NULL;\
217
+ }\
218
+ }\
219
+ } XCATCHALL\
220
+ qp->destruct = true;\
221
+ HANDLED();\
222
+ XENDTRY\
223
+ if (qp->destruct && !qp->recovering && q) {q_deref(q); q = NULL;}\
224
+ } while (0)
225
+
226
+ #define Y if (qp->destruct) goto yyerrorlab;
227
+ #define T TRY
228
+ #define E\
229
+ XCATCHALL\
230
+ qp->destruct = true;\
231
+ HANDLED();\
232
+ XENDTRY\
233
+ if (qp->destruct) Y;
234
+
235
+
236
+ /* Line 216 of yacc.c. */
237
+ #line 238 "y.tab.c"
238
+
239
+ #ifdef short
240
+ # undef short
241
+ #endif
242
+
243
+ #ifdef YYTYPE_UINT8
244
+ typedef YYTYPE_UINT8 yytype_uint8;
245
+ #else
246
+ typedef unsigned char yytype_uint8;
247
+ #endif
248
+
249
+ #ifdef YYTYPE_INT8
250
+ typedef YYTYPE_INT8 yytype_int8;
251
+ #elif (defined __STDC__ || defined __C99__FUNC__ \
252
+ || defined __cplusplus || defined _MSC_VER)
253
+ typedef signed char yytype_int8;
254
+ #else
255
+ typedef short int yytype_int8;
256
+ #endif
257
+
258
+ #ifdef YYTYPE_UINT16
259
+ typedef YYTYPE_UINT16 yytype_uint16;
260
+ #else
261
+ typedef unsigned short int yytype_uint16;
262
+ #endif
263
+
264
+ #ifdef YYTYPE_INT16
265
+ typedef YYTYPE_INT16 yytype_int16;
266
+ #else
267
+ typedef short int yytype_int16;
268
+ #endif
269
+
270
+ #ifndef YYSIZE_T
271
+ # ifdef __SIZE_TYPE__
272
+ # define YYSIZE_T __SIZE_TYPE__
273
+ # elif defined size_t
274
+ # define YYSIZE_T size_t
275
+ # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
276
+ || defined __cplusplus || defined _MSC_VER)
277
+ # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
278
+ # define YYSIZE_T size_t
279
+ # else
280
+ # define YYSIZE_T unsigned int
281
+ # endif
282
+ #endif
283
+
284
+ #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
285
+
286
+ #ifndef YY_
287
+ # if YYENABLE_NLS
288
+ # if ENABLE_NLS
289
+ # include <libintl.h> /* INFRINGES ON USER NAME SPACE */
290
+ # define YY_(msgid) dgettext ("bison-runtime", msgid)
291
+ # endif
292
+ # endif
293
+ # ifndef YY_
294
+ # define YY_(msgid) msgid
295
+ # endif
296
+ #endif
297
+
298
+ /* Suppress unused-variable warnings by "using" E. */
299
+ #if ! defined lint || defined __GNUC__
300
+ # define YYUSE(e) ((void) (e))
301
+ #else
302
+ # define YYUSE(e) /* empty */
303
+ #endif
304
+
305
+ /* Identity function, used to suppress warnings about constant conditions. */
306
+ #ifndef lint
307
+ # define YYID(n) (n)
308
+ #else
309
+ #if (defined __STDC__ || defined __C99__FUNC__ \
310
+ || defined __cplusplus || defined _MSC_VER)
311
+ static int
312
+ YYID (int i)
313
+ #else
314
+ static int
315
+ YYID (i)
316
+ int i;
317
+ #endif
318
+ {
319
+ return i;
320
+ }
321
+ #endif
322
+
323
+ #if ! defined yyoverflow || YYERROR_VERBOSE
324
+
325
+ /* The parser invokes alloca or malloc; define the necessary symbols. */
326
+
327
+ # ifdef YYSTACK_USE_ALLOCA
328
+ # if YYSTACK_USE_ALLOCA
329
+ # ifdef __GNUC__
330
+ # define YYSTACK_ALLOC __builtin_alloca
331
+ # elif defined __BUILTIN_VA_ARG_INCR
332
+ # include <alloca.h> /* INFRINGES ON USER NAME SPACE */
333
+ # elif defined _AIX
334
+ # define YYSTACK_ALLOC __alloca
335
+ # elif defined _MSC_VER
336
+ # include <malloc.h> /* INFRINGES ON USER NAME SPACE */
337
+ # define alloca _alloca
338
+ # else
339
+ # define YYSTACK_ALLOC alloca
340
+ # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
341
+ || defined __cplusplus || defined _MSC_VER)
342
+ # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
343
+ # ifndef _STDLIB_H
344
+ # define _STDLIB_H 1
345
+ # endif
346
+ # endif
347
+ # endif
348
+ # endif
349
+ # endif
350
+
351
+ # ifdef YYSTACK_ALLOC
352
+ /* Pacify GCC's `empty if-body' warning. */
353
+ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
354
+ # ifndef YYSTACK_ALLOC_MAXIMUM
355
+ /* The OS might guarantee only one guard page at the bottom of the stack,
356
+ and a page size can be as small as 4096 bytes. So we cannot safely
357
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
358
+ to allow for a few compiler-allocated temporary stack slots. */
359
+ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
360
+ # endif
361
+ # else
362
+ # define YYSTACK_ALLOC YYMALLOC
363
+ # define YYSTACK_FREE YYFREE
364
+ # ifndef YYSTACK_ALLOC_MAXIMUM
365
+ # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
366
+ # endif
367
+ # if (defined __cplusplus && ! defined _STDLIB_H \
368
+ && ! ((defined YYMALLOC || defined malloc) \
369
+ && (defined YYFREE || defined free)))
370
+ # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
371
+ # ifndef _STDLIB_H
372
+ # define _STDLIB_H 1
373
+ # endif
374
+ # endif
375
+ # ifndef YYMALLOC
376
+ # define YYMALLOC malloc
377
+ # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
378
+ || defined __cplusplus || defined _MSC_VER)
379
+ void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
380
+ # endif
381
+ # endif
382
+ # ifndef YYFREE
383
+ # define YYFREE free
384
+ # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
385
+ || defined __cplusplus || defined _MSC_VER)
386
+ void free (void *); /* INFRINGES ON USER NAME SPACE */
387
+ # endif
388
+ # endif
389
+ # endif
390
+ #endif /* ! defined yyoverflow || YYERROR_VERBOSE */
391
+
392
+
393
+ #if (! defined yyoverflow \
394
+ && (! defined __cplusplus \
395
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
396
+
397
+ /* A type that is properly aligned for any stack member. */
398
+ union yyalloc
399
+ {
400
+ yytype_int16 yyss;
401
+ YYSTYPE yyvs;
402
+ };
403
+
404
+ /* The size of the maximum gap between one aligned stack and the next. */
405
+ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
406
+
407
+ /* The size of an array large to enough to hold all stacks, each with
408
+ N elements. */
409
+ # define YYSTACK_BYTES(N) \
410
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
411
+ + YYSTACK_GAP_MAXIMUM)
412
+
413
+ /* Copy COUNT objects from FROM to TO. The source and destination do
414
+ not overlap. */
415
+ # ifndef YYCOPY
416
+ # if defined __GNUC__ && 1 < __GNUC__
417
+ # define YYCOPY(To, From, Count) \
418
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
419
+ # else
420
+ # define YYCOPY(To, From, Count) \
421
+ do \
422
+ { \
423
+ YYSIZE_T yyi; \
424
+ for (yyi = 0; yyi < (Count); yyi++) \
425
+ (To)[yyi] = (From)[yyi]; \
426
+ } \
427
+ while (YYID (0))
428
+ # endif
429
+ # endif
430
+
431
+ /* Relocate STACK from its old location to the new one. The
432
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
433
+ elements in the stack, and YYPTR gives the new location of the
434
+ stack. Advance YYPTR to a properly aligned location for the next
435
+ stack. */
436
+ # define YYSTACK_RELOCATE(Stack) \
437
+ do \
438
+ { \
439
+ YYSIZE_T yynewbytes; \
440
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
441
+ Stack = &yyptr->Stack; \
442
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
443
+ yyptr += yynewbytes / sizeof (*yyptr); \
444
+ } \
445
+ while (YYID (0))
446
+
447
+ #endif
448
+
449
+ /* YYFINAL -- State number of the termination state. */
450
+ #define YYFINAL 39
451
+ /* YYLAST -- Last index in YYTABLE. */
452
+ #define YYLAST 126
453
+
454
+ /* YYNTOKENS -- Number of terminals. */
455
+ #define YYNTOKENS 26
456
+ /* YYNNTS -- Number of nonterminals. */
457
+ #define YYNNTS 16
458
+ /* YYNRULES -- Number of rules. */
459
+ #define YYNRULES 51
460
+ /* YYNRULES -- Number of states. */
461
+ #define YYNSTATES 80
462
+
463
+ /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
464
+ #define YYUNDEFTOK 2
465
+ #define YYMAXUTOK 265
466
+
467
+ #define YYTRANSLATE(YYX) \
468
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
469
+
470
+ /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
471
+ static const yytype_uint8 yytranslate[] =
472
+ {
473
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
474
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
475
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
476
+ 2, 2, 2, 2, 18, 2, 2, 2, 2, 2,
477
+ 13, 14, 16, 2, 2, 2, 2, 2, 2, 2,
478
+ 2, 2, 2, 2, 2, 2, 2, 2, 10, 2,
479
+ 19, 25, 20, 2, 2, 2, 2, 2, 2, 2,
480
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
481
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
482
+ 2, 21, 2, 22, 12, 2, 2, 2, 2, 2,
483
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
484
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
485
+ 2, 2, 2, 24, 17, 23, 15, 2, 2, 2,
486
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
487
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
488
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
489
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
490
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
491
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
492
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
493
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
494
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
495
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
496
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
497
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
498
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
499
+ 5, 6, 7, 8, 9, 11
500
+ };
501
+
502
+ #if YYDEBUG
503
+ /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
504
+ YYRHS. */
505
+ static const yytype_uint8 yyprhs[] =
506
+ {
507
+ 0, 0, 3, 4, 6, 8, 12, 16, 19, 22,
508
+ 25, 27, 29, 33, 35, 38, 42, 44, 46, 48,
509
+ 50, 52, 56, 59, 61, 62, 67, 68, 69, 75,
510
+ 77, 81, 85, 91, 94, 99, 101, 104, 107, 111,
511
+ 115, 120, 125, 130, 135, 139, 143, 147, 151, 154,
512
+ 158, 162
513
+ };
514
+
515
+ /* YYRHS -- A `-1'-separated list of the rules' RHS. */
516
+ static const yytype_int8 yyrhs[] =
517
+ {
518
+ 27, 0, -1, -1, 28, -1, 29, -1, 28, 7,
519
+ 29, -1, 28, 6, 29, -1, 28, 29, -1, 9,
520
+ 30, -1, 8, 30, -1, 30, -1, 31, -1, 31,
521
+ 12, 3, -1, 32, -1, 13, 14, -1, 13, 28,
522
+ 14, -1, 34, -1, 39, -1, 41, -1, 33, -1,
523
+ 3, -1, 3, 15, 3, -1, 3, 15, -1, 4,
524
+ -1, -1, 38, 10, 31, 35, -1, -1, -1, 16,
525
+ 36, 10, 31, 37, -1, 3, -1, 38, 17, 3,
526
+ -1, 18, 40, 18, -1, 18, 40, 18, 15, 3,
527
+ -1, 18, 18, -1, 18, 18, 15, 3, -1, 3,
528
+ -1, 19, 20, -1, 40, 3, -1, 40, 19, 20,
529
+ -1, 40, 17, 3, -1, 21, 3, 3, 22, -1,
530
+ 21, 3, 3, 23, -1, 24, 3, 3, 22, -1,
531
+ 24, 3, 3, 23, -1, 19, 3, 23, -1, 19,
532
+ 3, 22, -1, 21, 3, 20, -1, 24, 3, 20,
533
+ -1, 19, 3, -1, 19, 25, 3, -1, 20, 25,
534
+ 3, -1, 20, 3, -1
535
+ };
536
+
537
+ /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
538
+ static const yytype_uint8 yyrline[] =
539
+ {
540
+ 0, 128, 128, 129, 131, 132, 133, 134, 136, 137,
541
+ 138, 140, 141, 143, 144, 145, 146, 147, 148, 149,
542
+ 151, 152, 153, 155, 157, 157, 159, 159, 159, 162,
543
+ 163, 165, 166, 167, 168, 170, 171, 172, 173, 174,
544
+ 176, 177, 178, 179, 180, 181, 182, 183, 184, 185,
545
+ 186, 187
546
+ };
547
+ #endif
548
+
549
+ #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
550
+ /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
551
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
552
+ static const char *const yytname[] =
553
+ {
554
+ "$end", "error", "$undefined", "QWRD", "WILD_STR", "LOW", "OR", "AND",
555
+ "NOT", "REQ", "':'", "HIGH", "'^'", "'('", "')'", "'~'", "'*'", "'|'",
556
+ "'\"'", "'<'", "'>'", "'['", "']'", "'}'", "'{'", "'='", "$accept",
557
+ "bool_q", "bool_clss", "bool_cls", "boosted_q", "q", "term_q", "wild_q",
558
+ "field_q", "@1", "@2", "@3", "field", "phrase_q", "ph_words", "range_q", 0
559
+ };
560
+ #endif
561
+
562
+ # ifdef YYPRINT
563
+ /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
564
+ token YYLEX-NUM. */
565
+ static const yytype_uint16 yytoknum[] =
566
+ {
567
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
568
+ 58, 265, 94, 40, 41, 126, 42, 124, 34, 60,
569
+ 62, 91, 93, 125, 123, 61
570
+ };
571
+ # endif
572
+
573
+ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
574
+ static const yytype_uint8 yyr1[] =
575
+ {
576
+ 0, 26, 27, 27, 28, 28, 28, 28, 29, 29,
577
+ 29, 30, 30, 31, 31, 31, 31, 31, 31, 31,
578
+ 32, 32, 32, 33, 35, 34, 36, 37, 34, 38,
579
+ 38, 39, 39, 39, 39, 40, 40, 40, 40, 40,
580
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
581
+ 41, 41
582
+ };
583
+
584
+ /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
585
+ static const yytype_uint8 yyr2[] =
586
+ {
587
+ 0, 2, 0, 1, 1, 3, 3, 2, 2, 2,
588
+ 1, 1, 3, 1, 2, 3, 1, 1, 1, 1,
589
+ 1, 3, 2, 1, 0, 4, 0, 0, 5, 1,
590
+ 3, 3, 5, 2, 4, 1, 2, 2, 3, 3,
591
+ 4, 4, 4, 4, 3, 3, 3, 3, 2, 3,
592
+ 3, 2
593
+ };
594
+
595
+ /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
596
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
597
+ means the default is an error. */
598
+ static const yytype_uint8 yydefact[] =
599
+ {
600
+ 2, 20, 23, 0, 0, 0, 26, 0, 0, 0,
601
+ 0, 0, 0, 3, 4, 10, 11, 13, 19, 16,
602
+ 0, 17, 18, 22, 9, 8, 14, 0, 0, 35,
603
+ 33, 0, 0, 48, 0, 51, 0, 0, 0, 1,
604
+ 0, 0, 7, 0, 0, 0, 21, 15, 0, 0,
605
+ 36, 37, 0, 31, 0, 45, 44, 49, 50, 0,
606
+ 46, 0, 47, 6, 5, 12, 24, 30, 27, 34,
607
+ 39, 0, 38, 40, 41, 42, 43, 25, 28, 32
608
+ };
609
+
610
+ /* YYDEFGOTO[NTERM-NUM]. */
611
+ static const yytype_int8 yydefgoto[] =
612
+ {
613
+ -1, 12, 13, 14, 15, 16, 17, 18, 19, 77,
614
+ 28, 78, 20, 21, 32, 22
615
+ };
616
+
617
+ /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
618
+ STATE-NUM. */
619
+ #define YYPACT_NINF -30
620
+ static const yytype_int8 yypact[] =
621
+ {
622
+ 83, -4, -30, 102, 102, 64, -30, 7, -2, -1,
623
+ 6, 15, 31, 45, -30, -30, 29, -30, -30, -30,
624
+ -5, -30, -30, 40, -30, -30, -30, 26, 47, -30,
625
+ 55, 42, 19, -15, 68, -30, 71, 0, 1, -30,
626
+ 83, 83, -30, 72, 102, 73, -30, -30, 102, 76,
627
+ -30, -30, 78, 74, 70, -30, -30, -30, -30, -6,
628
+ -30, 33, -30, -30, -30, -30, -30, -30, -30, -30,
629
+ -30, 90, -30, -30, -30, -30, -30, -30, -30, -30
630
+ };
631
+
632
+ /* YYPGOTO[NTERM-NUM]. */
633
+ static const yytype_int8 yypgoto[] =
634
+ {
635
+ -30, -30, 89, -13, 56, -29, -30, -30, -30, -30,
636
+ -30, -30, -30, -30, -30, -30
637
+ };
638
+
639
+ /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
640
+ positive, shift that token. If negative, reduce the rule which
641
+ number is the opposite. If zero, do what YYDEFACT says.
642
+ If YYTABLE_NINF, syntax error. */
643
+ #define YYTABLE_NINF -30
644
+ static const yytype_int8 yytable[] =
645
+ {
646
+ 42, 33, 35, 59, 61, 44, -29, 55, 56, 37,
647
+ 29, 23, 45, -29, 42, 66, 73, 74, 38, 68,
648
+ 60, 62, 51, 34, 36, 30, 31, 63, 64, 1,
649
+ 2, 39, 40, 41, 3, 4, 52, 53, 54, 5,
650
+ 47, 43, 6, 46, 7, 8, 9, 10, 1, 2,
651
+ 11, 40, 41, 3, 4, 75, 76, 48, 5, 24,
652
+ 25, 6, 50, 7, 8, 9, 10, 1, 2, 11,
653
+ 49, 57, 3, 4, 58, 65, 67, 5, 26, 69,
654
+ 6, 70, 7, 8, 9, 10, 1, 2, 11, 71,
655
+ 72, 3, 4, 79, 27, 0, 5, 0, 0, 6,
656
+ 0, 7, 8, 9, 10, 1, 2, 11, 0, 0,
657
+ 0, 0, 0, 0, 0, 5, 0, 0, 6, 0,
658
+ 7, 8, 9, 10, 0, 0, 11
659
+ };
660
+
661
+ static const yytype_int8 yycheck[] =
662
+ {
663
+ 13, 3, 3, 3, 3, 10, 10, 22, 23, 3,
664
+ 3, 15, 17, 17, 27, 44, 22, 23, 3, 48,
665
+ 20, 20, 3, 25, 25, 18, 19, 40, 41, 3,
666
+ 4, 0, 6, 7, 8, 9, 17, 18, 19, 13,
667
+ 14, 12, 16, 3, 18, 19, 20, 21, 3, 4,
668
+ 24, 6, 7, 8, 9, 22, 23, 10, 13, 3,
669
+ 4, 16, 20, 18, 19, 20, 21, 3, 4, 24,
670
+ 15, 3, 8, 9, 3, 3, 3, 13, 14, 3,
671
+ 16, 3, 18, 19, 20, 21, 3, 4, 24, 15,
672
+ 20, 8, 9, 3, 5, -1, 13, -1, -1, 16,
673
+ -1, 18, 19, 20, 21, 3, 4, 24, -1, -1,
674
+ -1, -1, -1, -1, -1, 13, -1, -1, 16, -1,
675
+ 18, 19, 20, 21, -1, -1, 24
676
+ };
677
+
678
+ /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
679
+ symbol of state STATE-NUM. */
680
+ static const yytype_uint8 yystos[] =
681
+ {
682
+ 0, 3, 4, 8, 9, 13, 16, 18, 19, 20,
683
+ 21, 24, 27, 28, 29, 30, 31, 32, 33, 34,
684
+ 38, 39, 41, 15, 30, 30, 14, 28, 36, 3,
685
+ 18, 19, 40, 3, 25, 3, 25, 3, 3, 0,
686
+ 6, 7, 29, 12, 10, 17, 3, 14, 10, 15,
687
+ 20, 3, 17, 18, 19, 22, 23, 3, 3, 3,
688
+ 20, 3, 20, 29, 29, 3, 31, 3, 31, 3,
689
+ 3, 15, 20, 22, 23, 22, 23, 35, 37, 3
690
+ };
691
+
692
+ #define yyerrok (yyerrstatus = 0)
693
+ #define yyclearin (yychar = YYEMPTY)
694
+ #define YYEMPTY (-2)
695
+ #define YYEOF 0
696
+
697
+ #define YYACCEPT goto yyacceptlab
698
+ #define YYABORT goto yyabortlab
699
+ #define YYERROR goto yyerrorlab
700
+
701
+
702
+ /* Like YYERROR except do call yyerror. This remains here temporarily
703
+ to ease the transition to the new meaning of YYERROR, for GCC.
704
+ Once GCC version 2 has supplanted version 1, this can go. */
705
+
706
+ #define YYFAIL goto yyerrlab
707
+
708
+ #define YYRECOVERING() (!!yyerrstatus)
709
+
710
+ #define YYBACKUP(Token, Value) \
711
+ do \
712
+ if (yychar == YYEMPTY && yylen == 1) \
713
+ { \
714
+ yychar = (Token); \
715
+ yylval = (Value); \
716
+ yytoken = YYTRANSLATE (yychar); \
717
+ YYPOPSTACK (1); \
718
+ goto yybackup; \
719
+ } \
720
+ else \
721
+ { \
722
+ yyerror (qp, YY_("syntax error: cannot back up")); \
723
+ YYERROR; \
724
+ } \
725
+ while (YYID (0))
726
+
727
+
728
+ #define YYTERROR 1
729
+ #define YYERRCODE 256
730
+
731
+
732
+ /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
733
+ If N is 0, then set CURRENT to the empty location which ends
734
+ the previous symbol: RHS[0] (always defined). */
735
+
736
+ #define YYRHSLOC(Rhs, K) ((Rhs)[K])
737
+ #ifndef YYLLOC_DEFAULT
738
+ # define YYLLOC_DEFAULT(Current, Rhs, N) \
739
+ do \
740
+ if (YYID (N)) \
741
+ { \
742
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
743
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
744
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
745
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
746
+ } \
747
+ else \
748
+ { \
749
+ (Current).first_line = (Current).last_line = \
750
+ YYRHSLOC (Rhs, 0).last_line; \
751
+ (Current).first_column = (Current).last_column = \
752
+ YYRHSLOC (Rhs, 0).last_column; \
753
+ } \
754
+ while (YYID (0))
755
+ #endif
756
+
757
+
758
+ /* YY_LOCATION_PRINT -- Print the location on the stream.
759
+ This macro was not mandated originally: define only if we know
760
+ we won't break user code: when these are the locations we know. */
761
+
762
+ #ifndef YY_LOCATION_PRINT
763
+ # if YYLTYPE_IS_TRIVIAL
764
+ # define YY_LOCATION_PRINT(File, Loc) \
765
+ fprintf (File, "%d.%d-%d.%d", \
766
+ (Loc).first_line, (Loc).first_column, \
767
+ (Loc).last_line, (Loc).last_column)
768
+ # else
769
+ # define YY_LOCATION_PRINT(File, Loc) ((void) 0)
770
+ # endif
771
+ #endif
772
+
773
+
774
+ /* YYLEX -- calling `yylex' with the right arguments. */
775
+
776
+ #ifdef YYLEX_PARAM
777
+ # define YYLEX yylex (&yylval, YYLEX_PARAM)
778
+ #else
779
+ # define YYLEX yylex (&yylval, qp)
780
+ #endif
781
+
782
+ /* Enable debugging if requested. */
783
+ #if YYDEBUG
784
+
785
+ # ifndef YYFPRINTF
786
+ # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
787
+ # define YYFPRINTF fprintf
788
+ # endif
789
+
790
+ # define YYDPRINTF(Args) \
791
+ do { \
792
+ if (yydebug) \
793
+ YYFPRINTF Args; \
794
+ } while (YYID (0))
795
+
796
+ # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
797
+ do { \
798
+ if (yydebug) \
799
+ { \
800
+ YYFPRINTF (stderr, "%s ", Title); \
801
+ yy_symbol_print (stderr, \
802
+ Type, Value, qp); \
803
+ YYFPRINTF (stderr, "\n"); \
804
+ } \
805
+ } while (YYID (0))
806
+
807
+
808
+ /*--------------------------------.
809
+ | Print this symbol on YYOUTPUT. |
810
+ `--------------------------------*/
811
+
812
+ /*ARGSUSED*/
813
+ #if (defined __STDC__ || defined __C99__FUNC__ \
814
+ || defined __cplusplus || defined _MSC_VER)
815
+ static void
816
+ yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, QParser *qp)
817
+ #else
818
+ static void
819
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, qp)
820
+ FILE *yyoutput;
821
+ int yytype;
822
+ YYSTYPE const * const yyvaluep;
823
+ QParser *qp;
824
+ #endif
825
+ {
826
+ if (!yyvaluep)
827
+ return;
828
+ YYUSE (qp);
829
+ # ifdef YYPRINT
830
+ if (yytype < YYNTOKENS)
831
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
832
+ # else
833
+ YYUSE (yyoutput);
834
+ # endif
835
+ switch (yytype)
836
+ {
837
+ default:
838
+ break;
839
+ }
840
+ }
841
+
842
+
843
+ /*--------------------------------.
844
+ | Print this symbol on YYOUTPUT. |
845
+ `--------------------------------*/
846
+
847
+ #if (defined __STDC__ || defined __C99__FUNC__ \
848
+ || defined __cplusplus || defined _MSC_VER)
849
+ static void
850
+ yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, QParser *qp)
851
+ #else
852
+ static void
853
+ yy_symbol_print (yyoutput, yytype, yyvaluep, qp)
854
+ FILE *yyoutput;
855
+ int yytype;
856
+ YYSTYPE const * const yyvaluep;
857
+ QParser *qp;
858
+ #endif
859
+ {
860
+ if (yytype < YYNTOKENS)
861
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
862
+ else
863
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
864
+
865
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, qp);
866
+ YYFPRINTF (yyoutput, ")");
867
+ }
868
+
869
+ /*------------------------------------------------------------------.
870
+ | yy_stack_print -- Print the state stack from its BOTTOM up to its |
871
+ | TOP (included). |
872
+ `------------------------------------------------------------------*/
873
+
874
+ #if (defined __STDC__ || defined __C99__FUNC__ \
875
+ || defined __cplusplus || defined _MSC_VER)
876
+ static void
877
+ yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
878
+ #else
879
+ static void
880
+ yy_stack_print (bottom, top)
881
+ yytype_int16 *bottom;
882
+ yytype_int16 *top;
883
+ #endif
884
+ {
885
+ YYFPRINTF (stderr, "Stack now");
886
+ for (; bottom <= top; ++bottom)
887
+ YYFPRINTF (stderr, " %d", *bottom);
888
+ YYFPRINTF (stderr, "\n");
889
+ }
890
+
891
+ # define YY_STACK_PRINT(Bottom, Top) \
892
+ do { \
893
+ if (yydebug) \
894
+ yy_stack_print ((Bottom), (Top)); \
895
+ } while (YYID (0))
896
+
897
+
898
+ /*------------------------------------------------.
899
+ | Report that the YYRULE is going to be reduced. |
900
+ `------------------------------------------------*/
901
+
902
+ #if (defined __STDC__ || defined __C99__FUNC__ \
903
+ || defined __cplusplus || defined _MSC_VER)
904
+ static void
905
+ yy_reduce_print (YYSTYPE *yyvsp, int yyrule, QParser *qp)
906
+ #else
907
+ static void
908
+ yy_reduce_print (yyvsp, yyrule, qp)
909
+ YYSTYPE *yyvsp;
910
+ int yyrule;
911
+ QParser *qp;
912
+ #endif
913
+ {
914
+ int yynrhs = yyr2[yyrule];
915
+ int yyi;
916
+ unsigned long int yylno = yyrline[yyrule];
917
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
918
+ yyrule - 1, yylno);
919
+ /* The symbols being reduced. */
920
+ for (yyi = 0; yyi < yynrhs; yyi++)
921
+ {
922
+ fprintf (stderr, " $%d = ", yyi + 1);
923
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
924
+ &(yyvsp[(yyi + 1) - (yynrhs)])
925
+ , qp);
926
+ fprintf (stderr, "\n");
927
+ }
928
+ }
929
+
930
+ # define YY_REDUCE_PRINT(Rule) \
931
+ do { \
932
+ if (yydebug) \
933
+ yy_reduce_print (yyvsp, Rule, qp); \
934
+ } while (YYID (0))
935
+
936
+ /* Nonzero means print parse trace. It is left uninitialized so that
937
+ multiple parsers can coexist. */
938
+ int yydebug;
939
+ #else /* !YYDEBUG */
940
+ # define YYDPRINTF(Args)
941
+ # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
942
+ # define YY_STACK_PRINT(Bottom, Top)
943
+ # define YY_REDUCE_PRINT(Rule)
944
+ #endif /* !YYDEBUG */
945
+
946
+
947
+ /* YYINITDEPTH -- initial size of the parser's stacks. */
948
+ #ifndef YYINITDEPTH
949
+ # define YYINITDEPTH 200
950
+ #endif
951
+
952
+ /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
953
+ if the built-in stack extension method is used).
954
+
955
+ Do not make this value too large; the results are undefined if
956
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
957
+ evaluated with infinite-precision integer arithmetic. */
958
+
959
+ #ifndef YYMAXDEPTH
960
+ # define YYMAXDEPTH 10000
961
+ #endif
962
+
963
+
964
+
965
+ #if YYERROR_VERBOSE
966
+
967
+ # ifndef yystrlen
968
+ # if defined __GLIBC__ && defined _STRING_H
969
+ # define yystrlen strlen
970
+ # else
971
+ /* Return the length of YYSTR. */
972
+ #if (defined __STDC__ || defined __C99__FUNC__ \
973
+ || defined __cplusplus || defined _MSC_VER)
974
+ static YYSIZE_T
975
+ yystrlen (const char *yystr)
976
+ #else
977
+ static YYSIZE_T
978
+ yystrlen (yystr)
979
+ const char *yystr;
980
+ #endif
981
+ {
982
+ YYSIZE_T yylen;
983
+ for (yylen = 0; yystr[yylen]; yylen++)
984
+ continue;
985
+ return yylen;
986
+ }
987
+ # endif
988
+ # endif
989
+
990
+ # ifndef yystpcpy
991
+ # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
992
+ # define yystpcpy stpcpy
993
+ # else
994
+ /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
995
+ YYDEST. */
996
+ #if (defined __STDC__ || defined __C99__FUNC__ \
997
+ || defined __cplusplus || defined _MSC_VER)
998
+ static char *
999
+ yystpcpy (char *yydest, const char *yysrc)
1000
+ #else
1001
+ static char *
1002
+ yystpcpy (yydest, yysrc)
1003
+ char *yydest;
1004
+ const char *yysrc;
1005
+ #endif
1006
+ {
1007
+ char *yyd = yydest;
1008
+ const char *yys = yysrc;
1009
+
1010
+ while ((*yyd++ = *yys++) != '\0')
1011
+ continue;
1012
+
1013
+ return yyd - 1;
1014
+ }
1015
+ # endif
1016
+ # endif
1017
+
1018
+ # ifndef yytnamerr
1019
+ /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
1020
+ quotes and backslashes, so that it's suitable for yyerror. The
1021
+ heuristic is that double-quoting is unnecessary unless the string
1022
+ contains an apostrophe, a comma, or backslash (other than
1023
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
1024
+ null, do not copy; instead, return the length of what the result
1025
+ would have been. */
1026
+ static YYSIZE_T
1027
+ yytnamerr (char *yyres, const char *yystr)
1028
+ {
1029
+ if (*yystr == '"')
1030
+ {
1031
+ YYSIZE_T yyn = 0;
1032
+ char const *yyp = yystr;
1033
+
1034
+ for (;;)
1035
+ switch (*++yyp)
1036
+ {
1037
+ case '\'':
1038
+ case ',':
1039
+ goto do_not_strip_quotes;
1040
+
1041
+ case '\\':
1042
+ if (*++yyp != '\\')
1043
+ goto do_not_strip_quotes;
1044
+ /* Fall through. */
1045
+ default:
1046
+ if (yyres)
1047
+ yyres[yyn] = *yyp;
1048
+ yyn++;
1049
+ break;
1050
+
1051
+ case '"':
1052
+ if (yyres)
1053
+ yyres[yyn] = '\0';
1054
+ return yyn;
1055
+ }
1056
+ do_not_strip_quotes: ;
1057
+ }
1058
+
1059
+ if (! yyres)
1060
+ return yystrlen (yystr);
1061
+
1062
+ return yystpcpy (yyres, yystr) - yyres;
1063
+ }
1064
+ # endif
1065
+
1066
+ /* Copy into YYRESULT an error message about the unexpected token
1067
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
1068
+ including the terminating null byte. If YYRESULT is null, do not
1069
+ copy anything; just return the number of bytes that would be
1070
+ copied. As a special case, return 0 if an ordinary "syntax error"
1071
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
1072
+ size calculation. */
1073
+ static YYSIZE_T
1074
+ yysyntax_error (char *yyresult, int yystate, int yychar)
1075
+ {
1076
+ int yyn = yypact[yystate];
1077
+
1078
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
1079
+ return 0;
1080
+ else
1081
+ {
1082
+ int yytype = YYTRANSLATE (yychar);
1083
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
1084
+ YYSIZE_T yysize = yysize0;
1085
+ YYSIZE_T yysize1;
1086
+ int yysize_overflow = 0;
1087
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
1088
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
1089
+ int yyx;
1090
+
1091
+ # if 0
1092
+ /* This is so xgettext sees the translatable formats that are
1093
+ constructed on the fly. */
1094
+ YY_("syntax error, unexpected %s");
1095
+ YY_("syntax error, unexpected %s, expecting %s");
1096
+ YY_("syntax error, unexpected %s, expecting %s or %s");
1097
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
1098
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
1099
+ # endif
1100
+ char *yyfmt;
1101
+ char const *yyf;
1102
+ static char const yyunexpected[] = "syntax error, unexpected %s";
1103
+ static char const yyexpecting[] = ", expecting %s";
1104
+ static char const yyor[] = " or %s";
1105
+ char yyformat[sizeof yyunexpected
1106
+ + sizeof yyexpecting - 1
1107
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
1108
+ * (sizeof yyor - 1))];
1109
+ char const *yyprefix = yyexpecting;
1110
+
1111
+ /* Start YYX at -YYN if negative to avoid negative indexes in
1112
+ YYCHECK. */
1113
+ int yyxbegin = yyn < 0 ? -yyn : 0;
1114
+
1115
+ /* Stay within bounds of both yycheck and yytname. */
1116
+ int yychecklim = YYLAST - yyn + 1;
1117
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1118
+ int yycount = 1;
1119
+
1120
+ yyarg[0] = yytname[yytype];
1121
+ yyfmt = yystpcpy (yyformat, yyunexpected);
1122
+
1123
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1124
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1125
+ {
1126
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
1127
+ {
1128
+ yycount = 1;
1129
+ yysize = yysize0;
1130
+ yyformat[sizeof yyunexpected - 1] = '\0';
1131
+ break;
1132
+ }
1133
+ yyarg[yycount++] = yytname[yyx];
1134
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
1135
+ yysize_overflow |= (yysize1 < yysize);
1136
+ yysize = yysize1;
1137
+ yyfmt = yystpcpy (yyfmt, yyprefix);
1138
+ yyprefix = yyor;
1139
+ }
1140
+
1141
+ yyf = YY_(yyformat);
1142
+ yysize1 = yysize + yystrlen (yyf);
1143
+ yysize_overflow |= (yysize1 < yysize);
1144
+ yysize = yysize1;
1145
+
1146
+ if (yysize_overflow)
1147
+ return YYSIZE_MAXIMUM;
1148
+
1149
+ if (yyresult)
1150
+ {
1151
+ /* Avoid sprintf, as that infringes on the user's name space.
1152
+ Don't have undefined behavior even if the translation
1153
+ produced a string with the wrong number of "%s"s. */
1154
+ char *yyp = yyresult;
1155
+ int yyi = 0;
1156
+ while ((*yyp = *yyf) != '\0')
1157
+ {
1158
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
1159
+ {
1160
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
1161
+ yyf += 2;
1162
+ }
1163
+ else
1164
+ {
1165
+ yyp++;
1166
+ yyf++;
1167
+ }
1168
+ }
1169
+ }
1170
+ return yysize;
1171
+ }
1172
+ }
1173
+ #endif /* YYERROR_VERBOSE */
1174
+
1175
+
1176
+ /*-----------------------------------------------.
1177
+ | Release the memory associated to this symbol. |
1178
+ `-----------------------------------------------*/
1179
+
1180
+ /*ARGSUSED*/
1181
+ #if (defined __STDC__ || defined __C99__FUNC__ \
1182
+ || defined __cplusplus || defined _MSC_VER)
1183
+ static void
1184
+ yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, QParser *qp)
1185
+ #else
1186
+ static void
1187
+ yydestruct (yymsg, yytype, yyvaluep, qp)
1188
+ const char *yymsg;
1189
+ int yytype;
1190
+ YYSTYPE *yyvaluep;
1191
+ QParser *qp;
1192
+ #endif
1193
+ {
1194
+ YYUSE (yyvaluep);
1195
+ YYUSE (qp);
1196
+
1197
+ if (!yymsg)
1198
+ yymsg = "Deleting";
1199
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1200
+
1201
+ switch (yytype)
1202
+ {
1203
+ case 27: /* "bool_q" */
1204
+ #line 123 "src/q_parser.y"
1205
+ { if ((yyvaluep->query) && qp->destruct) q_deref((yyvaluep->query)); };
1206
+ #line 1207 "y.tab.c"
1207
+ break;
1208
+ case 28: /* "bool_clss" */
1209
+ #line 125 "src/q_parser.y"
1210
+ { if ((yyvaluep->bclss) && qp->destruct) bca_destroy((yyvaluep->bclss)); };
1211
+ #line 1212 "y.tab.c"
1212
+ break;
1213
+ case 29: /* "bool_cls" */
1214
+ #line 124 "src/q_parser.y"
1215
+ { if ((yyvaluep->bcls) && qp->destruct) bc_deref((yyvaluep->bcls)); };
1216
+ #line 1217 "y.tab.c"
1217
+ break;
1218
+ case 30: /* "boosted_q" */
1219
+ #line 123 "src/q_parser.y"
1220
+ { if ((yyvaluep->query) && qp->destruct) q_deref((yyvaluep->query)); };
1221
+ #line 1222 "y.tab.c"
1222
+ break;
1223
+ case 31: /* "q" */
1224
+ #line 123 "src/q_parser.y"
1225
+ { if ((yyvaluep->query) && qp->destruct) q_deref((yyvaluep->query)); };
1226
+ #line 1227 "y.tab.c"
1227
+ break;
1228
+ case 32: /* "term_q" */
1229
+ #line 123 "src/q_parser.y"
1230
+ { if ((yyvaluep->query) && qp->destruct) q_deref((yyvaluep->query)); };
1231
+ #line 1232 "y.tab.c"
1232
+ break;
1233
+ case 33: /* "wild_q" */
1234
+ #line 123 "src/q_parser.y"
1235
+ { if ((yyvaluep->query) && qp->destruct) q_deref((yyvaluep->query)); };
1236
+ #line 1237 "y.tab.c"
1237
+ break;
1238
+ case 34: /* "field_q" */
1239
+ #line 123 "src/q_parser.y"
1240
+ { if ((yyvaluep->query) && qp->destruct) q_deref((yyvaluep->query)); };
1241
+ #line 1242 "y.tab.c"
1242
+ break;
1243
+ case 39: /* "phrase_q" */
1244
+ #line 123 "src/q_parser.y"
1245
+ { if ((yyvaluep->query) && qp->destruct) q_deref((yyvaluep->query)); };
1246
+ #line 1247 "y.tab.c"
1247
+ break;
1248
+ case 40: /* "ph_words" */
1249
+ #line 126 "src/q_parser.y"
1250
+ { if ((yyvaluep->phrase) && qp->destruct) ph_destroy((yyvaluep->phrase)); };
1251
+ #line 1252 "y.tab.c"
1252
+ break;
1253
+ case 41: /* "range_q" */
1254
+ #line 123 "src/q_parser.y"
1255
+ { if ((yyvaluep->query) && qp->destruct) q_deref((yyvaluep->query)); };
1256
+ #line 1257 "y.tab.c"
1257
+ break;
1258
+
1259
+ default:
1260
+ break;
1261
+ }
1262
+ }
1263
+
1264
+
1265
+ /* Prevent warnings from -Wmissing-prototypes. */
1266
+
1267
+ #ifdef YYPARSE_PARAM
1268
+ #if defined __STDC__ || defined __cplusplus
1269
+ int yyparse (void *YYPARSE_PARAM);
1270
+ #else
1271
+ int yyparse ();
1272
+ #endif
1273
+ #else /* ! YYPARSE_PARAM */
1274
+ #if defined __STDC__ || defined __cplusplus
1275
+ int yyparse (QParser *qp);
1276
+ #else
1277
+ int yyparse ();
1278
+ #endif
1279
+ #endif /* ! YYPARSE_PARAM */
1280
+
1281
+
1282
+
1283
+
1284
+
1285
+
1286
+ /*----------.
1287
+ | yyparse. |
1288
+ `----------*/
1289
+
1290
+ #ifdef YYPARSE_PARAM
1291
+ #if (defined __STDC__ || defined __C99__FUNC__ \
1292
+ || defined __cplusplus || defined _MSC_VER)
1293
+ int
1294
+ yyparse (void *YYPARSE_PARAM)
1295
+ #else
1296
+ int
1297
+ yyparse (YYPARSE_PARAM)
1298
+ void *YYPARSE_PARAM;
1299
+ #endif
1300
+ #else /* ! YYPARSE_PARAM */
1301
+ #if (defined __STDC__ || defined __C99__FUNC__ \
1302
+ || defined __cplusplus || defined _MSC_VER)
1303
+ int
1304
+ yyparse (QParser *qp)
1305
+ #else
1306
+ int
1307
+ yyparse (qp)
1308
+ QParser *qp;
1309
+ #endif
1310
+ #endif
1311
+ {
1312
+ /* The look-ahead symbol. */
1313
+ int yychar;
1314
+
1315
+ /* The semantic value of the look-ahead symbol. */
1316
+ YYSTYPE yylval;
1317
+
1318
+ /* Number of syntax errors so far. */
1319
+ int yynerrs;
1320
+
1321
+ int yystate;
1322
+ int yyn;
1323
+ int yyresult;
1324
+ /* Number of tokens to shift before error messages enabled. */
1325
+ int yyerrstatus;
1326
+ /* Look-ahead token as an internal (translated) token number. */
1327
+ int yytoken = 0;
1328
+ #if YYERROR_VERBOSE
1329
+ /* Buffer for error messages, and its allocated size. */
1330
+ char yymsgbuf[128];
1331
+ char *yymsg = yymsgbuf;
1332
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1333
+ #endif
1334
+
1335
+ /* Three stacks and their tools:
1336
+ `yyss': related to states,
1337
+ `yyvs': related to semantic values,
1338
+ `yyls': related to locations.
1339
+
1340
+ Refer to the stacks thru separate pointers, to allow yyoverflow
1341
+ to reallocate them elsewhere. */
1342
+
1343
+ /* The state stack. */
1344
+ yytype_int16 yyssa[YYINITDEPTH];
1345
+ yytype_int16 *yyss = yyssa;
1346
+ yytype_int16 *yyssp;
1347
+
1348
+ /* The semantic value stack. */
1349
+ YYSTYPE yyvsa[YYINITDEPTH];
1350
+ YYSTYPE *yyvs = yyvsa;
1351
+ YYSTYPE *yyvsp;
1352
+
1353
+
1354
+
1355
+ #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1356
+
1357
+ YYSIZE_T yystacksize = YYINITDEPTH;
1358
+
1359
+ /* The variables used to return semantic value and location from the
1360
+ action routines. */
1361
+ YYSTYPE yyval;
1362
+
1363
+
1364
+ /* The number of symbols on the RHS of the reduced rule.
1365
+ Keep to zero when no symbol should be popped. */
1366
+ int yylen = 0;
1367
+
1368
+ YYDPRINTF ((stderr, "Starting parse\n"));
1369
+
1370
+ yystate = 0;
1371
+ yyerrstatus = 0;
1372
+ yynerrs = 0;
1373
+ yychar = YYEMPTY; /* Cause a token to be read. */
1374
+
1375
+ /* Initialize stack pointers.
1376
+ Waste one element of value and location stack
1377
+ so that they stay on the same level as the state stack.
1378
+ The wasted elements are never initialized. */
1379
+
1380
+ yyssp = yyss;
1381
+ yyvsp = yyvs;
1382
+
1383
+ goto yysetstate;
1384
+
1385
+ /*------------------------------------------------------------.
1386
+ | yynewstate -- Push a new state, which is found in yystate. |
1387
+ `------------------------------------------------------------*/
1388
+ yynewstate:
1389
+ /* In all cases, when you get here, the value and location stacks
1390
+ have just been pushed. So pushing a state here evens the stacks. */
1391
+ yyssp++;
1392
+
1393
+ yysetstate:
1394
+ *yyssp = yystate;
1395
+
1396
+ if (yyss + yystacksize - 1 <= yyssp)
1397
+ {
1398
+ /* Get the current used size of the three stacks, in elements. */
1399
+ YYSIZE_T yysize = yyssp - yyss + 1;
1400
+
1401
+ #ifdef yyoverflow
1402
+ {
1403
+ /* Give user a chance to reallocate the stack. Use copies of
1404
+ these so that the &'s don't force the real ones into
1405
+ memory. */
1406
+ YYSTYPE *yyvs1 = yyvs;
1407
+ yytype_int16 *yyss1 = yyss;
1408
+
1409
+
1410
+ /* Each stack pointer address is followed by the size of the
1411
+ data in use in that stack, in bytes. This used to be a
1412
+ conditional around just the two extra args, but that might
1413
+ be undefined if yyoverflow is a macro. */
1414
+ yyoverflow (YY_("memory exhausted"),
1415
+ &yyss1, yysize * sizeof (*yyssp),
1416
+ &yyvs1, yysize * sizeof (*yyvsp),
1417
+
1418
+ &yystacksize);
1419
+
1420
+ yyss = yyss1;
1421
+ yyvs = yyvs1;
1422
+ }
1423
+ #else /* no yyoverflow */
1424
+ # ifndef YYSTACK_RELOCATE
1425
+ goto yyexhaustedlab;
1426
+ # else
1427
+ /* Extend the stack our own way. */
1428
+ if (YYMAXDEPTH <= yystacksize)
1429
+ goto yyexhaustedlab;
1430
+ yystacksize *= 2;
1431
+ if (YYMAXDEPTH < yystacksize)
1432
+ yystacksize = YYMAXDEPTH;
1433
+
1434
+ {
1435
+ yytype_int16 *yyss1 = yyss;
1436
+ union yyalloc *yyptr =
1437
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1438
+ if (! yyptr)
1439
+ goto yyexhaustedlab;
1440
+ YYSTACK_RELOCATE (yyss);
1441
+ YYSTACK_RELOCATE (yyvs);
1442
+
1443
+ # undef YYSTACK_RELOCATE
1444
+ if (yyss1 != yyssa)
1445
+ YYSTACK_FREE (yyss1);
1446
+ }
1447
+ # endif
1448
+ #endif /* no yyoverflow */
1449
+
1450
+ yyssp = yyss + yysize - 1;
1451
+ yyvsp = yyvs + yysize - 1;
1452
+
1453
+
1454
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1455
+ (unsigned long int) yystacksize));
1456
+
1457
+ if (yyss + yystacksize - 1 <= yyssp)
1458
+ YYABORT;
1459
+ }
1460
+
1461
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1462
+
1463
+ goto yybackup;
1464
+
1465
+ /*-----------.
1466
+ | yybackup. |
1467
+ `-----------*/
1468
+ yybackup:
1469
+
1470
+ /* Do appropriate processing given the current state. Read a
1471
+ look-ahead token if we need one and don't already have one. */
1472
+
1473
+ /* First try to decide what to do without reference to look-ahead token. */
1474
+ yyn = yypact[yystate];
1475
+ if (yyn == YYPACT_NINF)
1476
+ goto yydefault;
1477
+
1478
+ /* Not known => get a look-ahead token if don't already have one. */
1479
+
1480
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
1481
+ if (yychar == YYEMPTY)
1482
+ {
1483
+ YYDPRINTF ((stderr, "Reading a token: "));
1484
+ yychar = YYLEX;
1485
+ }
1486
+
1487
+ if (yychar <= YYEOF)
1488
+ {
1489
+ yychar = yytoken = YYEOF;
1490
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
1491
+ }
1492
+ else
1493
+ {
1494
+ yytoken = YYTRANSLATE (yychar);
1495
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1496
+ }
1497
+
1498
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
1499
+ detect an error, take that action. */
1500
+ yyn += yytoken;
1501
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1502
+ goto yydefault;
1503
+ yyn = yytable[yyn];
1504
+ if (yyn <= 0)
1505
+ {
1506
+ if (yyn == 0 || yyn == YYTABLE_NINF)
1507
+ goto yyerrlab;
1508
+ yyn = -yyn;
1509
+ goto yyreduce;
1510
+ }
1511
+
1512
+ if (yyn == YYFINAL)
1513
+ YYACCEPT;
1514
+
1515
+ /* Count tokens shifted since error; after three, turn off error
1516
+ status. */
1517
+ if (yyerrstatus)
1518
+ yyerrstatus--;
1519
+
1520
+ /* Shift the look-ahead token. */
1521
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1522
+
1523
+ /* Discard the shifted token unless it is eof. */
1524
+ if (yychar != YYEOF)
1525
+ yychar = YYEMPTY;
1526
+
1527
+ yystate = yyn;
1528
+ *++yyvsp = yylval;
1529
+
1530
+ goto yynewstate;
1531
+
1532
+
1533
+ /*-----------------------------------------------------------.
1534
+ | yydefault -- do the default action for the current state. |
1535
+ `-----------------------------------------------------------*/
1536
+ yydefault:
1537
+ yyn = yydefact[yystate];
1538
+ if (yyn == 0)
1539
+ goto yyerrlab;
1540
+ goto yyreduce;
1541
+
1542
+
1543
+ /*-----------------------------.
1544
+ | yyreduce -- Do a reduction. |
1545
+ `-----------------------------*/
1546
+ yyreduce:
1547
+ /* yyn is the number of a rule to reduce with. */
1548
+ yylen = yyr2[yyn];
1549
+
1550
+ /* If YYLEN is nonzero, implement the default value of the action:
1551
+ `$$ = $1'.
1552
+
1553
+ Otherwise, the following line sets YYVAL to garbage.
1554
+ This behavior is undocumented and Bison
1555
+ users should not rely upon it. Assigning to YYVAL
1556
+ unconditionally makes the parser a bit smaller, and it avoids a
1557
+ GCC warning that YYVAL may be used uninitialized. */
1558
+ yyval = yyvsp[1-yylen];
1559
+
1560
+
1561
+ YY_REDUCE_PRINT (yyn);
1562
+ switch (yyn)
1563
+ {
1564
+ case 2:
1565
+ #line 128 "src/q_parser.y"
1566
+ { qp->result = (yyval.query) = NULL; }
1567
+ break;
1568
+
1569
+ case 3:
1570
+ #line 129 "src/q_parser.y"
1571
+ { T qp->result = (yyval.query) = get_bool_q((yyvsp[(1) - (1)].bclss)); E }
1572
+ break;
1573
+
1574
+ case 4:
1575
+ #line 131 "src/q_parser.y"
1576
+ { T (yyval.bclss) = first_cls((yyvsp[(1) - (1)].bcls)); E }
1577
+ break;
1578
+
1579
+ case 5:
1580
+ #line 132 "src/q_parser.y"
1581
+ { T (yyval.bclss) = add_and_cls((yyvsp[(1) - (3)].bclss), (yyvsp[(3) - (3)].bcls)); E }
1582
+ break;
1583
+
1584
+ case 6:
1585
+ #line 133 "src/q_parser.y"
1586
+ { T (yyval.bclss) = add_or_cls((yyvsp[(1) - (3)].bclss), (yyvsp[(3) - (3)].bcls)); E }
1587
+ break;
1588
+
1589
+ case 7:
1590
+ #line 134 "src/q_parser.y"
1591
+ { T (yyval.bclss) = add_default_cls(qp, (yyvsp[(1) - (2)].bclss), (yyvsp[(2) - (2)].bcls)); E }
1592
+ break;
1593
+
1594
+ case 8:
1595
+ #line 136 "src/q_parser.y"
1596
+ { T (yyval.bcls) = get_bool_cls((yyvsp[(2) - (2)].query), BC_MUST); E }
1597
+ break;
1598
+
1599
+ case 9:
1600
+ #line 137 "src/q_parser.y"
1601
+ { T (yyval.bcls) = get_bool_cls((yyvsp[(2) - (2)].query), BC_MUST_NOT); E }
1602
+ break;
1603
+
1604
+ case 10:
1605
+ #line 138 "src/q_parser.y"
1606
+ { T (yyval.bcls) = get_bool_cls((yyvsp[(1) - (1)].query), BC_SHOULD); E }
1607
+ break;
1608
+
1609
+ case 12:
1610
+ #line 141 "src/q_parser.y"
1611
+ { T if ((yyvsp[(1) - (3)].query)) sscanf((yyvsp[(3) - (3)].str),"%f",&((yyvsp[(1) - (3)].query)->boost)); (yyval.query)=(yyvsp[(1) - (3)].query); E }
1612
+ break;
1613
+
1614
+ case 14:
1615
+ #line 144 "src/q_parser.y"
1616
+ { T (yyval.query) = bq_new_max(true, qp->max_clauses); E }
1617
+ break;
1618
+
1619
+ case 15:
1620
+ #line 145 "src/q_parser.y"
1621
+ { T (yyval.query) = get_bool_q((yyvsp[(2) - (3)].bclss)); E }
1622
+ break;
1623
+
1624
+ case 20:
1625
+ #line 151 "src/q_parser.y"
1626
+ { FLDS((yyval.query), get_term_q(qp, field, (yyvsp[(1) - (1)].str))); Y}
1627
+ break;
1628
+
1629
+ case 21:
1630
+ #line 152 "src/q_parser.y"
1631
+ { FLDS((yyval.query), get_fuzzy_q(qp, field, (yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str))); Y}
1632
+ break;
1633
+
1634
+ case 22:
1635
+ #line 153 "src/q_parser.y"
1636
+ { FLDS((yyval.query), get_fuzzy_q(qp, field, (yyvsp[(1) - (2)].str), NULL)); Y}
1637
+ break;
1638
+
1639
+ case 23:
1640
+ #line 155 "src/q_parser.y"
1641
+ { FLDS((yyval.query), get_wild_q(qp, field, (yyvsp[(1) - (1)].str))); Y}
1642
+ break;
1643
+
1644
+ case 24:
1645
+ #line 157 "src/q_parser.y"
1646
+ { qp->fields = qp->def_fields; }
1647
+ break;
1648
+
1649
+ case 25:
1650
+ #line 158 "src/q_parser.y"
1651
+ { (yyval.query) = (yyvsp[(3) - (4)].query); }
1652
+ break;
1653
+
1654
+ case 26:
1655
+ #line 159 "src/q_parser.y"
1656
+ { qp->fields = qp->all_fields; }
1657
+ break;
1658
+
1659
+ case 27:
1660
+ #line 159 "src/q_parser.y"
1661
+ {qp->fields = qp->def_fields;}
1662
+ break;
1663
+
1664
+ case 28:
1665
+ #line 160 "src/q_parser.y"
1666
+ { (yyval.query) = (yyvsp[(4) - (5)].query); }
1667
+ break;
1668
+
1669
+ case 29:
1670
+ #line 162 "src/q_parser.y"
1671
+ { (yyval.hashset) = first_field(qp, (yyvsp[(1) - (1)].str)); }
1672
+ break;
1673
+
1674
+ case 30:
1675
+ #line 163 "src/q_parser.y"
1676
+ { (yyval.hashset) = add_field(qp, (yyvsp[(3) - (3)].str));}
1677
+ break;
1678
+
1679
+ case 31:
1680
+ #line 165 "src/q_parser.y"
1681
+ { (yyval.query) = get_phrase_q(qp, (yyvsp[(2) - (3)].phrase), NULL); }
1682
+ break;
1683
+
1684
+ case 32:
1685
+ #line 166 "src/q_parser.y"
1686
+ { (yyval.query) = get_phrase_q(qp, (yyvsp[(2) - (5)].phrase), (yyvsp[(5) - (5)].str)); }
1687
+ break;
1688
+
1689
+ case 33:
1690
+ #line 167 "src/q_parser.y"
1691
+ { (yyval.query) = NULL; }
1692
+ break;
1693
+
1694
+ case 34:
1695
+ #line 168 "src/q_parser.y"
1696
+ { (yyval.query) = NULL; (void)(yyvsp[(4) - (4)].str);}
1697
+ break;
1698
+
1699
+ case 35:
1700
+ #line 170 "src/q_parser.y"
1701
+ { (yyval.phrase) = ph_first_word((yyvsp[(1) - (1)].str)); }
1702
+ break;
1703
+
1704
+ case 36:
1705
+ #line 171 "src/q_parser.y"
1706
+ { (yyval.phrase) = ph_first_word(NULL); }
1707
+ break;
1708
+
1709
+ case 37:
1710
+ #line 172 "src/q_parser.y"
1711
+ { (yyval.phrase) = ph_add_word((yyvsp[(1) - (2)].phrase), (yyvsp[(2) - (2)].str)); }
1712
+ break;
1713
+
1714
+ case 38:
1715
+ #line 173 "src/q_parser.y"
1716
+ { (yyval.phrase) = ph_add_word((yyvsp[(1) - (3)].phrase), NULL); }
1717
+ break;
1718
+
1719
+ case 39:
1720
+ #line 174 "src/q_parser.y"
1721
+ { (yyval.phrase) = ph_add_multi_word((yyvsp[(1) - (3)].phrase), (yyvsp[(3) - (3)].str)); }
1722
+ break;
1723
+
1724
+ case 40:
1725
+ #line 176 "src/q_parser.y"
1726
+ { FLDS((yyval.query), get_r_q(qp, field, (yyvsp[(2) - (4)].str), (yyvsp[(3) - (4)].str), true, true)); Y}
1727
+ break;
1728
+
1729
+ case 41:
1730
+ #line 177 "src/q_parser.y"
1731
+ { FLDS((yyval.query), get_r_q(qp, field, (yyvsp[(2) - (4)].str), (yyvsp[(3) - (4)].str), true, false)); Y}
1732
+ break;
1733
+
1734
+ case 42:
1735
+ #line 178 "src/q_parser.y"
1736
+ { FLDS((yyval.query), get_r_q(qp, field, (yyvsp[(2) - (4)].str), (yyvsp[(3) - (4)].str), false, true)); Y}
1737
+ break;
1738
+
1739
+ case 43:
1740
+ #line 179 "src/q_parser.y"
1741
+ { FLDS((yyval.query), get_r_q(qp, field, (yyvsp[(2) - (4)].str), (yyvsp[(3) - (4)].str), false, false)); Y}
1742
+ break;
1743
+
1744
+ case 44:
1745
+ #line 180 "src/q_parser.y"
1746
+ { FLDS((yyval.query), get_r_q(qp, field, NULL,(yyvsp[(2) - (3)].str), false, false)); Y}
1747
+ break;
1748
+
1749
+ case 45:
1750
+ #line 181 "src/q_parser.y"
1751
+ { FLDS((yyval.query), get_r_q(qp, field, NULL,(yyvsp[(2) - (3)].str), false, true)); Y}
1752
+ break;
1753
+
1754
+ case 46:
1755
+ #line 182 "src/q_parser.y"
1756
+ { FLDS((yyval.query), get_r_q(qp, field, (yyvsp[(2) - (3)].str), NULL,true, false)); Y}
1757
+ break;
1758
+
1759
+ case 47:
1760
+ #line 183 "src/q_parser.y"
1761
+ { FLDS((yyval.query), get_r_q(qp, field, (yyvsp[(2) - (3)].str), NULL,false, false)); Y}
1762
+ break;
1763
+
1764
+ case 48:
1765
+ #line 184 "src/q_parser.y"
1766
+ { FLDS((yyval.query), get_r_q(qp, field, NULL,(yyvsp[(2) - (2)].str), false, false)); Y}
1767
+ break;
1768
+
1769
+ case 49:
1770
+ #line 185 "src/q_parser.y"
1771
+ { FLDS((yyval.query), get_r_q(qp, field, NULL,(yyvsp[(3) - (3)].str), false, true)); Y}
1772
+ break;
1773
+
1774
+ case 50:
1775
+ #line 186 "src/q_parser.y"
1776
+ { FLDS((yyval.query), get_r_q(qp, field, (yyvsp[(3) - (3)].str), NULL,true, false)); Y}
1777
+ break;
1778
+
1779
+ case 51:
1780
+ #line 187 "src/q_parser.y"
1781
+ { FLDS((yyval.query), get_r_q(qp, field, (yyvsp[(2) - (2)].str), NULL,false, false)); Y}
1782
+ break;
1783
+
1784
+
1785
+ /* Line 1267 of yacc.c. */
1786
+ #line 1787 "y.tab.c"
1787
+ default: break;
1788
+ }
1789
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
1790
+
1791
+ YYPOPSTACK (yylen);
1792
+ yylen = 0;
1793
+ YY_STACK_PRINT (yyss, yyssp);
1794
+
1795
+ *++yyvsp = yyval;
1796
+
1797
+
1798
+ /* Now `shift' the result of the reduction. Determine what state
1799
+ that goes to, based on the state we popped back to and the rule
1800
+ number reduced by. */
1801
+
1802
+ yyn = yyr1[yyn];
1803
+
1804
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1805
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1806
+ yystate = yytable[yystate];
1807
+ else
1808
+ yystate = yydefgoto[yyn - YYNTOKENS];
1809
+
1810
+ goto yynewstate;
1811
+
1812
+
1813
+ /*------------------------------------.
1814
+ | yyerrlab -- here on detecting error |
1815
+ `------------------------------------*/
1816
+ yyerrlab:
1817
+ /* If not already recovering from an error, report this error. */
1818
+ if (!yyerrstatus)
1819
+ {
1820
+ ++yynerrs;
1821
+ #if ! YYERROR_VERBOSE
1822
+ yyerror (qp, YY_("syntax error"));
1823
+ #else
1824
+ {
1825
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
1826
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
1827
+ {
1828
+ YYSIZE_T yyalloc = 2 * yysize;
1829
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
1830
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
1831
+ if (yymsg != yymsgbuf)
1832
+ YYSTACK_FREE (yymsg);
1833
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
1834
+ if (yymsg)
1835
+ yymsg_alloc = yyalloc;
1836
+ else
1837
+ {
1838
+ yymsg = yymsgbuf;
1839
+ yymsg_alloc = sizeof yymsgbuf;
1840
+ }
1841
+ }
1842
+
1843
+ if (0 < yysize && yysize <= yymsg_alloc)
1844
+ {
1845
+ (void) yysyntax_error (yymsg, yystate, yychar);
1846
+ yyerror (qp, yymsg);
1847
+ }
1848
+ else
1849
+ {
1850
+ yyerror (qp, YY_("syntax error"));
1851
+ if (yysize != 0)
1852
+ goto yyexhaustedlab;
1853
+ }
1854
+ }
1855
+ #endif
1856
+ }
1857
+
1858
+
1859
+
1860
+ if (yyerrstatus == 3)
1861
+ {
1862
+ /* If just tried and failed to reuse look-ahead token after an
1863
+ error, discard it. */
1864
+
1865
+ if (yychar <= YYEOF)
1866
+ {
1867
+ /* Return failure if at end of input. */
1868
+ if (yychar == YYEOF)
1869
+ YYABORT;
1870
+ }
1871
+ else
1872
+ {
1873
+ yydestruct ("Error: discarding",
1874
+ yytoken, &yylval, qp);
1875
+ yychar = YYEMPTY;
1876
+ }
1877
+ }
1878
+
1879
+ /* Else will try to reuse look-ahead token after shifting the error
1880
+ token. */
1881
+ goto yyerrlab1;
1882
+
1883
+
1884
+ /*---------------------------------------------------.
1885
+ | yyerrorlab -- error raised explicitly by YYERROR. |
1886
+ `---------------------------------------------------*/
1887
+ yyerrorlab:
1888
+
1889
+ /* Pacify compilers like GCC when the user code never invokes
1890
+ YYERROR and the label yyerrorlab therefore never appears in user
1891
+ code. */
1892
+ if (/*CONSTCOND*/ 0)
1893
+ goto yyerrorlab;
1894
+
1895
+ /* Do not reclaim the symbols of the rule which action triggered
1896
+ this YYERROR. */
1897
+ YYPOPSTACK (yylen);
1898
+ yylen = 0;
1899
+ YY_STACK_PRINT (yyss, yyssp);
1900
+ yystate = *yyssp;
1901
+ goto yyerrlab1;
1902
+
1903
+
1904
+ /*-------------------------------------------------------------.
1905
+ | yyerrlab1 -- common code for both syntax error and YYERROR. |
1906
+ `-------------------------------------------------------------*/
1907
+ yyerrlab1:
1908
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
1909
+
1910
+ for (;;)
1911
+ {
1912
+ yyn = yypact[yystate];
1913
+ if (yyn != YYPACT_NINF)
1914
+ {
1915
+ yyn += YYTERROR;
1916
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1917
+ {
1918
+ yyn = yytable[yyn];
1919
+ if (0 < yyn)
1920
+ break;
1921
+ }
1922
+ }
1923
+
1924
+ /* Pop the current state because it cannot handle the error token. */
1925
+ if (yyssp == yyss)
1926
+ YYABORT;
1927
+
1928
+
1929
+ yydestruct ("Error: popping",
1930
+ yystos[yystate], yyvsp, qp);
1931
+ YYPOPSTACK (1);
1932
+ yystate = *yyssp;
1933
+ YY_STACK_PRINT (yyss, yyssp);
1934
+ }
1935
+
1936
+ if (yyn == YYFINAL)
1937
+ YYACCEPT;
1938
+
1939
+ *++yyvsp = yylval;
1940
+
1941
+
1942
+ /* Shift the error token. */
1943
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
1944
+
1945
+ yystate = yyn;
1946
+ goto yynewstate;
1947
+
1948
+
1949
+ /*-------------------------------------.
1950
+ | yyacceptlab -- YYACCEPT comes here. |
1951
+ `-------------------------------------*/
1952
+ yyacceptlab:
1953
+ yyresult = 0;
1954
+ goto yyreturn;
1955
+
1956
+ /*-----------------------------------.
1957
+ | yyabortlab -- YYABORT comes here. |
1958
+ `-----------------------------------*/
1959
+ yyabortlab:
1960
+ yyresult = 1;
1961
+ goto yyreturn;
1962
+
1963
+ #ifndef yyoverflow
1964
+ /*-------------------------------------------------.
1965
+ | yyexhaustedlab -- memory exhaustion comes here. |
1966
+ `-------------------------------------------------*/
1967
+ yyexhaustedlab:
1968
+ yyerror (qp, YY_("memory exhausted"));
1969
+ yyresult = 2;
1970
+ /* Fall through. */
1971
+ #endif
1972
+
1973
+ yyreturn:
1974
+ if (yychar != YYEOF && yychar != YYEMPTY)
1975
+ yydestruct ("Cleanup: discarding lookahead",
1976
+ yytoken, &yylval, qp);
1977
+ /* Do not reclaim the symbols of the rule which action triggered
1978
+ this YYABORT or YYACCEPT. */
1979
+ YYPOPSTACK (yylen);
1980
+ YY_STACK_PRINT (yyss, yyssp);
1981
+ while (yyssp != yyss)
1982
+ {
1983
+ yydestruct ("Cleanup: popping",
1984
+ yystos[*yyssp], yyvsp, qp);
1985
+ YYPOPSTACK (1);
1986
+ }
1987
+ #ifndef yyoverflow
1988
+ if (yyss != yyssa)
1989
+ YYSTACK_FREE (yyss);
1990
+ #endif
1991
+ #if YYERROR_VERBOSE
1992
+ if (yymsg != yymsgbuf)
1993
+ YYSTACK_FREE (yymsg);
1994
+ #endif
1995
+ /* Make sure YYID is used. */
1996
+ return YYID (yyresult);
1997
+ }
1998
+
1999
+
2000
+ #line 189 "src/q_parser.y"
2001
+
2002
+
2003
+ const char *special_char = "&:()[]{}!\"~^|<>=*?+-";
2004
+ const char *not_word = " \t()[]{}!\"~^|<>=";
2005
+
2006
+ static int get_word(YYSTYPE *lvalp, QParser *qp)
2007
+ {
2008
+ bool is_wild = false;
2009
+ int len;
2010
+ char c;
2011
+ char *buf = qp->buf[qp->buf_index];
2012
+ char *bufp = buf;
2013
+ qp->buf_index = (qp->buf_index + 1) % QP_CONC_WORDS;
2014
+
2015
+ if (qp->dynbuf) {
2016
+ free(qp->dynbuf);
2017
+ qp->dynbuf = NULL;
2018
+ }
2019
+
2020
+ qp->qstrp--; /* need to back up one character */
2021
+
2022
+ while (!strchr(not_word, (c = *qp->qstrp++))) {
2023
+ switch (c) {
2024
+ case '\\':
2025
+ if ((c = *qp->qstrp) == '\0') {
2026
+ *bufp++ = '\\';
2027
+ }
2028
+ else {
2029
+ *bufp++ = c;
2030
+ qp->qstrp++;
2031
+ }
2032
+ break;
2033
+ case ':':
2034
+ if ((*qp->qstrp) == ':') {
2035
+ qp->qstrp++;
2036
+ *bufp++ = ':';
2037
+ *bufp++ = ':';
2038
+ }
2039
+ else {
2040
+ goto get_word_done;
2041
+ }
2042
+ break;
2043
+ case '*': case '?':
2044
+ is_wild = true;
2045
+ /* fall through */
2046
+ default:
2047
+ *bufp++ = c;
2048
+ }
2049
+ /* we've exceeded the static buffer. switch to the dynamic
2050
+ one. */
2051
+ if (!qp->dynbuf && ((bufp - buf) == MAX_WORD_SIZE)) {
2052
+ qp->dynbuf = ALLOC_AND_ZERO_N(char, strlen(qp->qstr) + 1);
2053
+ strncpy(qp->dynbuf, buf, MAX_WORD_SIZE);
2054
+ buf = qp->dynbuf;
2055
+ bufp = buf + MAX_WORD_SIZE;
2056
+ }
2057
+ }
2058
+ get_word_done:
2059
+ qp->qstrp--;
2060
+ /* check for keywords. There are only four so we have a bit of a hack which
2061
+ * just checks for all of them. */
2062
+ *bufp = '\0';
2063
+ len = (int)(bufp - buf);
2064
+ if (qp->use_keywords) {
2065
+ if (len == 3) {
2066
+ if (buf[0] == 'A' && buf[1] == 'N' && buf[2] == 'D') return AND;
2067
+ if (buf[0] == 'N' && buf[1] == 'O' && buf[2] == 'T') return NOT;
2068
+ if (buf[0] == 'R' && buf[1] == 'E' && buf[2] == 'Q') return REQ;
2069
+ }
2070
+ if (len == 2 && buf[0] == 'O' && buf[1] == 'R') return OR;
2071
+ }
2072
+
2073
+ /* found a word so return it. */
2074
+ lvalp->str = buf;
2075
+ if (is_wild) {
2076
+ return WILD_STR;
2077
+ }
2078
+ return QWRD;
2079
+ }
2080
+
2081
+ static int yylex(YYSTYPE *lvalp, QParser *qp)
2082
+ {
2083
+ char c, nc;
2084
+
2085
+ while ((c=*qp->qstrp++) == ' ' || c == '\t') {
2086
+ }
2087
+
2088
+ if (c == '\0') return 0;
2089
+
2090
+ if (strchr(special_char, c)) { /* comment */
2091
+ nc = *qp->qstrp;
2092
+ switch (c) {
2093
+ case '-': case '!': return NOT;
2094
+ case '+': return REQ;
2095
+ case '*':
2096
+ if (nc == ':') return c;
2097
+ break;
2098
+ case '?':
2099
+ break;
2100
+ case '&':
2101
+ if (nc == '&') {
2102
+ qp->qstrp++;
2103
+ return AND;
2104
+ }
2105
+ break; /* Don't return single & character. Use in word. */
2106
+ case '|':
2107
+ if (nc == '|') {
2108
+ qp->qstrp++;
2109
+ return OR;
2110
+ }
2111
+ default:
2112
+ return c;
2113
+ }
2114
+ }
2115
+
2116
+ return get_word(lvalp, qp);
2117
+ }
2118
+
2119
+ static int yyerror(QParser *qp, char const *msg)
2120
+ {
2121
+ qp->destruct = true;
2122
+ if (!qp->handle_parse_errors) {
2123
+ char buf[1024];
2124
+ buf[1023] = '\0';
2125
+ strncpy(buf, qp->qstr, 1023);
2126
+ if (qp->clean_str) {
2127
+ free(qp->qstr);
2128
+ }
2129
+ mutex_unlock(&qp->mutex);
2130
+ snprintf(xmsg_buffer, XMSG_BUFFER_SIZE,
2131
+ "couldn't parse query ``%s''. Error message "
2132
+ " was %s", buf, (char *)msg);
2133
+ }
2134
+ return 0;
2135
+ }
2136
+
2137
+ #define BQ(query) ((BooleanQuery *)(query))
2138
+
2139
+ static TokenStream *get_cached_ts(QParser *qp, char *field, char *text)
2140
+ {
2141
+ TokenStream *ts;
2142
+ if (!qp->tokenized_fields || hs_exists(qp->tokenized_fields, field)) {
2143
+ ts = h_get(qp->ts_cache, field);
2144
+ if (!ts) {
2145
+ ts = a_get_ts(qp->analyzer, field, text);
2146
+ h_set(qp->ts_cache, estrdup(field), ts);
2147
+ }
2148
+ else {
2149
+ ts->reset(ts, text);
2150
+ }
2151
+ }
2152
+ else {
2153
+ ts = qp->non_tokenizer;
2154
+ ts->reset(ts, text);
2155
+ }
2156
+ return ts;
2157
+ }
2158
+
2159
+ static char *get_cached_field(HashTable *field_cache, const char *field)
2160
+ {
2161
+ char *cached_field = h_get(field_cache, field);
2162
+ if (!cached_field) {
2163
+ cached_field = estrdup(field);
2164
+ h_set(field_cache, cached_field, cached_field);
2165
+ }
2166
+ return cached_field;
2167
+ }
2168
+
2169
+ static Query *get_bool_q(BCArray *bca)
2170
+ {
2171
+ Query *q;
2172
+ const int clause_count = bca->size;
2173
+
2174
+ if (clause_count == 0) {
2175
+ q = NULL;
2176
+ free(bca->clauses);
2177
+ }
2178
+ else if (clause_count == 1) {
2179
+ BooleanClause *bc = bca->clauses[0];
2180
+ if (bc->is_prohibited) {
2181
+ q = bq_new(false);
2182
+ bq_add_query_nr(q, bc->query, BC_MUST_NOT);
2183
+ bq_add_query_nr(q, maq_new(), BC_MUST);
2184
+ }
2185
+ else {
2186
+ q = bc->query;
2187
+ }
2188
+ free(bc);
2189
+ free(bca->clauses);
2190
+ }
2191
+ else {
2192
+ q = bq_new(false);
2193
+ /* copy clauses into query */
2194
+
2195
+ BQ(q)->clause_cnt = clause_count;
2196
+ BQ(q)->clause_capa = bca->capa;
2197
+ free(BQ(q)->clauses);
2198
+ BQ(q)->clauses = bca->clauses;
2199
+ }
2200
+ free(bca);
2201
+ return q;
2202
+ }
2203
+
2204
+ static void bca_add_clause(BCArray *bca, BooleanClause *clause)
2205
+ {
2206
+ if (bca->size >= bca->capa) {
2207
+ bca->capa <<= 1;
2208
+ REALLOC_N(bca->clauses, BooleanClause *, bca->capa);
2209
+ }
2210
+ bca->clauses[bca->size] = clause;
2211
+ bca->size++;
2212
+ }
2213
+
2214
+ static BCArray *first_cls(BooleanClause *clause)
2215
+ {
2216
+ BCArray *bca = ALLOC_AND_ZERO(BCArray);
2217
+ bca->capa = BCA_INIT_CAPA;
2218
+ bca->clauses = ALLOC_N(BooleanClause *, BCA_INIT_CAPA);
2219
+ if (clause) {
2220
+ bca_add_clause(bca, clause);
2221
+ }
2222
+ return bca;
2223
+ }
2224
+
2225
+ static BCArray *add_and_cls(BCArray *bca, BooleanClause *clause)
2226
+ {
2227
+ if (clause) {
2228
+ if (bca->size == 1) {
2229
+ if (!bca->clauses[0]->is_prohibited) {
2230
+ bc_set_occur(bca->clauses[0], BC_MUST);
2231
+ }
2232
+ }
2233
+ if (!clause->is_prohibited) {
2234
+ bc_set_occur(clause, BC_MUST);
2235
+ }
2236
+ bca_add_clause(bca, clause);
2237
+ }
2238
+ return bca;
2239
+ }
2240
+
2241
+ static BCArray *add_or_cls(BCArray *bca, BooleanClause *clause)
2242
+ {
2243
+ if (clause) {
2244
+ bca_add_clause(bca, clause);
2245
+ }
2246
+ return bca;
2247
+ }
2248
+
2249
+ static BCArray *add_default_cls(QParser *qp, BCArray *bca,
2250
+ BooleanClause *clause)
2251
+ {
2252
+ if (qp->or_default) {
2253
+ add_or_cls(bca, clause);
2254
+ }
2255
+ else {
2256
+ add_and_cls(bca, clause);
2257
+ }
2258
+ return bca;
2259
+ }
2260
+
2261
+ static void bca_destroy(BCArray *bca)
2262
+ {
2263
+ int i;
2264
+ for (i = 0; i < bca->size; i++) {
2265
+ bc_deref(bca->clauses[i]);
2266
+ }
2267
+ free(bca->clauses);
2268
+ free(bca);
2269
+ }
2270
+
2271
+ static BooleanClause *get_bool_cls(Query *q, unsigned int occur)
2272
+ {
2273
+ if (q) {
2274
+ return bc_new(q, occur);
2275
+ }
2276
+ else {
2277
+ return NULL;
2278
+ }
2279
+ }
2280
+
2281
+ static Query *get_term_q(QParser *qp, char *field, char *word)
2282
+ {
2283
+ Query *q;
2284
+ Token *token;
2285
+ TokenStream *stream = get_cached_ts(qp, field, word);
2286
+
2287
+ if ((token = ts_next(stream)) == NULL) {
2288
+ q = NULL;
2289
+ }
2290
+ else {
2291
+ q = tq_new(field, token->text);
2292
+ if ((token = ts_next(stream)) != NULL) {
2293
+ /* Less likely case, destroy the term query and create a
2294
+ * phrase query instead */
2295
+ Query *phq = phq_new(field);
2296
+ phq_add_term(phq, ((TermQuery *)q)->term, 0);
2297
+ q->destroy_i(q);
2298
+ q = phq;
2299
+ do {
2300
+ if (token->pos_inc) {
2301
+ phq_add_term(q, token->text, token->pos_inc);
2302
+ /* add some slop since single term was expected */
2303
+ ((PhraseQuery *)q)->slop++;
2304
+ }
2305
+ else {
2306
+ phq_append_multi_term(q, token->text);
2307
+ }
2308
+ } while ((token = ts_next(stream)) != NULL);
2309
+ }
2310
+ }
2311
+ return q;
2312
+ }
2313
+
2314
+ static Query *get_fuzzy_q(QParser *qp, char *field, char *word, char *slop_str)
2315
+ {
2316
+ Query *q;
2317
+ Token *token;
2318
+ TokenStream *stream = get_cached_ts(qp, field, word);
2319
+
2320
+ if ((token = ts_next(stream)) == NULL) {
2321
+ q = NULL;
2322
+ }
2323
+ else {
2324
+ /* it only makes sense to find one term in a fuzzy query */
2325
+ float slop = qp_default_fuzzy_min_sim;
2326
+ if (slop_str) {
2327
+ sscanf(slop_str, "%f", &slop);
2328
+ }
2329
+ q = fuzq_new_conf(field, token->text, slop, qp_default_fuzzy_pre_len,
2330
+ qp->max_clauses);
2331
+ }
2332
+ return q;
2333
+ }
2334
+
2335
+ static char *lower_str(char *str)
2336
+ {
2337
+ const int max_len = (int)strlen(str) + 1;
2338
+ int cnt;
2339
+ wchar_t *wstr = ALLOC_N(wchar_t, max_len);
2340
+ if ((cnt = mbstowcs(wstr, str, max_len)) > 0) {
2341
+ wchar_t *w = wstr;
2342
+ while (*w) {
2343
+ *w = towlower(*w);
2344
+ w++;
2345
+ }
2346
+ wcstombs(str, wstr, max_len);
2347
+ }
2348
+ else {
2349
+ char *s = str;
2350
+ while (*s) {
2351
+ *s = tolower(*s);
2352
+ s++;
2353
+ }
2354
+ }
2355
+ free(wstr);
2356
+ str[max_len] = '\0';
2357
+ return str;
2358
+ }
2359
+
2360
+ static Query *get_wild_q(QParser *qp, char *field, char *pattern)
2361
+ {
2362
+ Query *q;
2363
+ bool is_prefix = false;
2364
+ char *p;
2365
+ int len = (int)strlen(pattern);
2366
+
2367
+ if (qp->wild_lower
2368
+ && (!qp->tokenized_fields || hs_exists(qp->tokenized_fields, field))) {
2369
+ lower_str(pattern);
2370
+ }
2371
+
2372
+ /* simplify the wildcard query to a prefix query if possible. Basically a
2373
+ * prefix query is any wildcard query that has a '*' as the last character
2374
+ * and no other wildcard characters before it. "*" by itself will expand
2375
+ * to a MatchAllQuery */
2376
+ if (strcmp(pattern, "*") == 0) {
2377
+ return maq_new();
2378
+ }
2379
+ if (pattern[len - 1] == '*') {
2380
+ is_prefix = true;
2381
+ for (p = &pattern[len - 2]; p >= pattern; p--) {
2382
+ if (*p == '*' || *p == '?') {
2383
+ is_prefix = false;
2384
+ break;
2385
+ }
2386
+ }
2387
+ }
2388
+ if (is_prefix) {
2389
+ /* chop off the '*' temporarily to create the query */
2390
+ pattern[len - 1] = 0;
2391
+ q = prefixq_new(field, pattern);
2392
+ pattern[len - 1] = '*';
2393
+ }
2394
+ else {
2395
+ q = wcq_new(field, pattern);
2396
+ }
2397
+ MTQMaxTerms(q) = qp->max_clauses;
2398
+ return q;
2399
+ }
2400
+
2401
+ static HashSet *add_field(QParser *qp, char *field)
2402
+ {
2403
+ if (qp->allow_any_fields || hs_exists(qp->all_fields, field)) {
2404
+ hs_add(qp->fields, get_cached_field(qp->field_cache, field));
2405
+ }
2406
+ return qp->fields;
2407
+ }
2408
+
2409
+ static HashSet *first_field(QParser *qp, char *field)
2410
+ {
2411
+ qp->fields = qp->fields_buf;
2412
+ qp->fields->size = 0;
2413
+ h_clear(qp->fields->ht);
2414
+ return add_field(qp, field);
2415
+ }
2416
+
2417
+ static void ph_destroy(Phrase *self)
2418
+ {
2419
+ int i;
2420
+ for (i = 0; i < self->size; i++) {
2421
+ ary_destroy(self->positions[i].terms, &free);
2422
+ }
2423
+ free(self->positions);
2424
+ free(self);
2425
+ }
2426
+
2427
+
2428
+ static Phrase *ph_new()
2429
+ {
2430
+ Phrase *self = ALLOC_AND_ZERO(Phrase);
2431
+ self->capa = PHRASE_INIT_CAPA;
2432
+ self->positions = ALLOC_AND_ZERO_N(PhrasePosition, PHRASE_INIT_CAPA);
2433
+ return self;
2434
+ }
2435
+
2436
+ static Phrase *ph_first_word(char *word)
2437
+ {
2438
+ Phrase *self = ph_new();
2439
+ if (word) { /* no point in adding NULL in start */
2440
+ self->positions[0].terms = ary_new_type_capa(char *, 1);
2441
+ ary_push(self->positions[0].terms, estrdup(word));
2442
+ self->size = 1;
2443
+ }
2444
+ return self;
2445
+ }
2446
+
2447
+ static Phrase *ph_add_word(Phrase *self, char *word)
2448
+ {
2449
+ if (word) {
2450
+ const int index = self->size;
2451
+ PhrasePosition *pp = self->positions;
2452
+ if (index >= self->capa) {
2453
+ self->capa <<= 1;
2454
+ REALLOC_N(pp, PhrasePosition, self->capa);
2455
+ self->positions = pp;
2456
+ }
2457
+ pp[index].pos = self->pos_inc;
2458
+ pp[index].terms = ary_new_type_capa(char *, 1);
2459
+ ary_push(pp[index].terms, estrdup(word));
2460
+ self->size++;
2461
+ self->pos_inc = 0;
2462
+ }
2463
+ else {
2464
+ self->pos_inc++;
2465
+ }
2466
+ return self;
2467
+ }
2468
+
2469
+ static Phrase *ph_add_multi_word(Phrase *self, char *word)
2470
+ {
2471
+ const int index = self->size - 1;
2472
+ PhrasePosition *pp = self->positions;
2473
+
2474
+ if (word) {
2475
+ ary_push(pp[index].terms, estrdup(word));
2476
+ }
2477
+ return self;
2478
+ }
2479
+
2480
+ static Query *get_phrase_query(QParser *qp, char *field,
2481
+ Phrase *phrase, char *slop_str)
2482
+ {
2483
+ const int pos_cnt = phrase->size;
2484
+ Query *q = NULL;
2485
+
2486
+ if (pos_cnt == 1) {
2487
+ char **words = phrase->positions[0].terms;
2488
+ const int word_count = ary_size(words);
2489
+ if (word_count == 1) {
2490
+ q = get_term_q(qp, field, words[0]);
2491
+ }
2492
+ else {
2493
+ int i;
2494
+ int term_cnt = 0;
2495
+ Token *token;
2496
+ char *last_word = NULL;
2497
+
2498
+ for (i = 0; i < word_count; i++) {
2499
+ token = ts_next(get_cached_ts(qp, field, words[i]));
2500
+ free(words[i]);
2501
+ if (token) {
2502
+ last_word = words[i] = estrdup(token->text);
2503
+ ++term_cnt;
2504
+ }
2505
+ else {
2506
+ words[i] = estrdup("");
2507
+ }
2508
+ }
2509
+
2510
+ switch (term_cnt) {
2511
+ case 0:
2512
+ q = bq_new(false);
2513
+ break;
2514
+ case 1:
2515
+ q = tq_new(field, last_word);
2516
+ break;
2517
+ default:
2518
+ q = multi_tq_new_conf(field, term_cnt, 0.0);
2519
+ for (i = 0; i < word_count; i++) {
2520
+ if (words[i][0]) {
2521
+ multi_tq_add_term(q, words[i]);
2522
+ }
2523
+ }
2524
+ break;
2525
+ }
2526
+ }
2527
+ }
2528
+ else if (pos_cnt > 1) {
2529
+ Token *token;
2530
+ TokenStream *stream;
2531
+ int i, j;
2532
+ int pos_inc = 0;
2533
+ q = phq_new(field);
2534
+ if (slop_str) {
2535
+ int slop;
2536
+ sscanf(slop_str,"%d",&slop);
2537
+ ((PhraseQuery *)q)->slop = slop;
2538
+ }
2539
+
2540
+ for (i = 0; i < pos_cnt; i++) {
2541
+ char **words = phrase->positions[i].terms;
2542
+ const int word_count = ary_size(words);
2543
+ if (pos_inc) {
2544
+ ((PhraseQuery *)q)->slop++;
2545
+ }
2546
+ pos_inc += phrase->positions[i].pos + 1; /* Actually holds pos_inc*/
2547
+
2548
+ if (word_count == 1) {
2549
+ stream = get_cached_ts(qp, field, words[0]);
2550
+ while ((token = ts_next(stream))) {
2551
+ if (token->pos_inc) {
2552
+ phq_add_term(q, token->text,
2553
+ pos_inc ? pos_inc : token->pos_inc);
2554
+ }
2555
+ else {
2556
+ phq_append_multi_term(q, token->text);
2557
+ ((PhraseQuery *)q)->slop++;
2558
+ }
2559
+ pos_inc = 0;
2560
+ }
2561
+ }
2562
+ else {
2563
+ bool added_position = false;
2564
+
2565
+ for (j = 0; j < word_count; j++) {
2566
+ stream = get_cached_ts(qp, field, words[j]);
2567
+ if ((token = ts_next(stream))) {
2568
+ if (!added_position) {
2569
+ phq_add_term(q, token->text,
2570
+ pos_inc ? pos_inc : token->pos_inc);
2571
+ added_position = true;
2572
+ pos_inc = 0;
2573
+ }
2574
+ else {
2575
+ phq_append_multi_term(q, token->text);
2576
+ }
2577
+ }
2578
+ }
2579
+ }
2580
+ }
2581
+ }
2582
+ return q;
2583
+ }
2584
+
2585
+ static Query *get_phrase_q(QParser *qp, Phrase *phrase, char *slop_str)
2586
+ {
2587
+ Query *q = NULL;
2588
+ FLDS(q, get_phrase_query(qp, field, phrase, slop_str));
2589
+ ph_destroy(phrase);
2590
+ return q;
2591
+ }
2592
+
2593
+ static Query *get_r_q(QParser *qp, char *field, char *from, char *to,
2594
+ bool inc_lower, bool inc_upper)
2595
+ {
2596
+ Query *rq;
2597
+ if (qp->wild_lower) {
2598
+ if (from) {
2599
+ lower_str(from);
2600
+ }
2601
+ if (to) {
2602
+ lower_str(to);
2603
+ }
2604
+ }
2605
+ /*
2606
+ if (from) {
2607
+ TokenStream *stream = get_cached_ts(qp, field, from);
2608
+ Token *token = ts_next(stream);
2609
+ from = token ? estrdup(token->text) : NULL;
2610
+ }
2611
+ if (to) {
2612
+ TokenStream *stream = get_cached_ts(qp, field, to);
2613
+ Token *token = ts_next(stream);
2614
+ to = token ? estrdup(token->text) : NULL;
2615
+ }
2616
+ */
2617
+
2618
+ rq = rq_new(field, from, to, inc_lower, inc_upper);
2619
+ return rq;
2620
+ }
2621
+
2622
+ void qp_destroy(QParser *self)
2623
+ {
2624
+ if (self->close_def_fields) {
2625
+ hs_destroy(self->def_fields);
2626
+ }
2627
+ if (self->tokenized_fields) {
2628
+ hs_destroy(self->tokenized_fields);
2629
+ }
2630
+ if (self->dynbuf) {
2631
+ free(self->dynbuf);
2632
+ }
2633
+ hs_destroy(self->all_fields);
2634
+ hs_destroy(self->fields_buf);
2635
+ h_destroy(self->field_cache);
2636
+ h_destroy(self->ts_cache);
2637
+ tk_destroy(self->non_tokenizer);
2638
+ a_deref(self->analyzer);
2639
+ free(self);
2640
+ }
2641
+
2642
+ QParser *qp_new(HashSet *all_fields, HashSet *def_fields,
2643
+ HashSet *tokenized_fields, Analyzer *analyzer)
2644
+ {
2645
+ int i;
2646
+ QParser *self = ALLOC(QParser);
2647
+ self->or_default = true;
2648
+ self->wild_lower = true;
2649
+ self->clean_str = false;
2650
+ self->max_clauses = QP_MAX_CLAUSES;
2651
+ self->handle_parse_errors = false;
2652
+ self->allow_any_fields = false;
2653
+ self->use_keywords = true;
2654
+ self->def_slop = 0;
2655
+ self->fields_buf = hs_new_str(NULL);
2656
+ self->all_fields = all_fields;
2657
+ self->tokenized_fields = tokenized_fields;
2658
+ if (def_fields) {
2659
+ self->def_fields = def_fields;
2660
+ for (i = 0; i < self->def_fields->size; i++) {
2661
+ if (!hs_exists(self->all_fields, self->def_fields->elems[i])) {
2662
+ hs_add(self->all_fields, estrdup(self->def_fields->elems[i]));
2663
+ }
2664
+ }
2665
+ self->close_def_fields = true;
2666
+ }
2667
+ else {
2668
+ self->def_fields = all_fields;
2669
+ self->close_def_fields = false;
2670
+ }
2671
+ self->field_cache = h_new_str((free_ft)NULL, &free);
2672
+ for (i = 0; i < self->all_fields->size; i++) {
2673
+ char *field = estrdup(self->all_fields->elems[i]);
2674
+ h_set(self->field_cache, field, field);
2675
+ }
2676
+ self->fields = self->def_fields;
2677
+ /* make sure all_fields contains the default fields */
2678
+ self->analyzer = analyzer;
2679
+ self->ts_cache = h_new_str(&free, (free_ft)&ts_deref);
2680
+ self->buf_index = 0;
2681
+ self->dynbuf = 0;
2682
+ self->non_tokenizer = non_tokenizer_new();
2683
+ mutex_init(&self->mutex, NULL);
2684
+ return self;
2685
+ }
2686
+
2687
+ /* these chars have meaning within phrases */
2688
+ static const char *PHRASE_CHARS = "<>|\"";
2689
+
2690
+ static void str_insert(char *str, int len, char chr)
2691
+ {
2692
+ memmove(str+1, str, len*sizeof(char));
2693
+ *str = chr;
2694
+ }
2695
+
2696
+ char *qp_clean_str(char *str)
2697
+ {
2698
+ int b, pb = -1;
2699
+ int br_cnt = 0;
2700
+ bool quote_open = false;
2701
+ char *sp, *nsp;
2702
+
2703
+ /* leave a little extra */
2704
+ char *new_str = ALLOC_N(char, strlen(str)*2 + 1);
2705
+
2706
+ for (sp = str, nsp = new_str; *sp; sp++) {
2707
+ b = *sp;
2708
+ /* ignore escaped characters */
2709
+ if (pb == '\\') {
2710
+ if (quote_open && strrchr(PHRASE_CHARS, b)) {
2711
+ *nsp++ = '\\'; /* this was left off the first time through */
2712
+ }
2713
+ *nsp++ = b;
2714
+ /* \\ has escaped itself so has no power. Assign pb random char : */
2715
+ pb = ((b == '\\') ? ':' : b);
2716
+ continue;
2717
+ }
2718
+ switch (b) {
2719
+ case '\\':
2720
+ if (!quote_open) { /* We do our own escaping below */
2721
+ *nsp++ = b;
2722
+ }
2723
+ break;
2724
+ case '"':
2725
+ quote_open = !quote_open;
2726
+ *nsp++ = b;
2727
+ break;
2728
+ case '(':
2729
+ if (!quote_open) {
2730
+ br_cnt++;
2731
+ }
2732
+ else {
2733
+ *nsp++ = '\\';
2734
+ }
2735
+ *nsp++ = b;
2736
+ break;
2737
+ case ')':
2738
+ if (!quote_open) {
2739
+ if (br_cnt == 0) {
2740
+ str_insert(new_str, (int)(nsp - new_str), '(');
2741
+ nsp++;
2742
+ }
2743
+ else {
2744
+ br_cnt--;
2745
+ }
2746
+ }
2747
+ else {
2748
+ *nsp++ = '\\';
2749
+ }
2750
+ *nsp++ = b;
2751
+ break;
2752
+ case '>':
2753
+ if (quote_open) {
2754
+ if (pb == '<') {
2755
+ /* remove the escape character */
2756
+ nsp--;
2757
+ nsp[-1] = '<';
2758
+ }
2759
+ else {
2760
+ *nsp++ = '\\';
2761
+ }
2762
+ }
2763
+ *nsp++ = b;
2764
+ break;
2765
+ default:
2766
+ if (quote_open) {
2767
+ if (strrchr(special_char, b) && b != '|') {
2768
+ *nsp++ = '\\';
2769
+ }
2770
+ }
2771
+ *nsp++ = b;
2772
+ }
2773
+ pb = b;
2774
+ }
2775
+ if (quote_open) {
2776
+ *nsp++ = '"';
2777
+ }
2778
+ for (;br_cnt > 0; br_cnt--) {
2779
+ *nsp++ = ')';
2780
+ }
2781
+ *nsp = '\0';
2782
+ return new_str;
2783
+ }
2784
+
2785
+ Query *qp_get_bad_query(QParser *qp, char *str)
2786
+ {
2787
+ Query *volatile q = NULL;
2788
+ qp->recovering = true;
2789
+ FLDS(q, get_term_q(qp, field, str));
2790
+ return q;
2791
+ }
2792
+
2793
+ Query *qp_parse(QParser *self, char *qstr)
2794
+ {
2795
+ Query *result = NULL;
2796
+ mutex_lock(&self->mutex);
2797
+ self->recovering = self->destruct = false;
2798
+ if (self->clean_str) {
2799
+ self->qstrp = self->qstr = qp_clean_str(qstr);
2800
+ }
2801
+ else {
2802
+ self->qstrp = self->qstr = qstr;
2803
+ }
2804
+ self->fields = self->def_fields;
2805
+ self->result = NULL;
2806
+
2807
+ if (0 == yyparse(self)) result = self->result;
2808
+ if (!result && self->handle_parse_errors) {
2809
+ self->destruct = false;
2810
+ result = qp_get_bad_query(self, self->qstr);
2811
+ }
2812
+ if (self->destruct && !self->handle_parse_errors) {
2813
+ xraise(PARSE_ERROR, xmsg_buffer);
2814
+ }
2815
+ if (!result) {
2816
+ result = bq_new(false);
2817
+ }
2818
+ if (self->clean_str) {
2819
+ free(self->qstr);
2820
+ }
2821
+
2822
+ mutex_unlock(&self->mutex);
2823
+ return result;
2824
+ }
2825
+