Merge pull request #409 from Alkarex/patch-1
[mono.git] / mcs / tools / monkeydoc / Lucene.Net / Lucene.Net / QueryParser / QueryParser.cs
1 /* 
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  * 
9  * http://www.apache.org/licenses/LICENSE-2.0
10  * 
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 /* Generated By:JavaCC: Do not edit this line. QueryParser.java */
19
20 using System;
21
22 using Analyzer = Mono.Lucene.Net.Analysis.Analyzer;
23 using CachingTokenFilter = Mono.Lucene.Net.Analysis.CachingTokenFilter;
24 using TokenStream = Mono.Lucene.Net.Analysis.TokenStream;
25 using PositionIncrementAttribute = Mono.Lucene.Net.Analysis.Tokenattributes.PositionIncrementAttribute;
26 using TermAttribute = Mono.Lucene.Net.Analysis.Tokenattributes.TermAttribute;
27 using DateField = Mono.Lucene.Net.Documents.DateField;
28 using DateTools = Mono.Lucene.Net.Documents.DateTools;
29 using Term = Mono.Lucene.Net.Index.Term;
30 using Parameter = Mono.Lucene.Net.Util.Parameter;
31 using BooleanClause = Mono.Lucene.Net.Search.BooleanClause;
32 using BooleanQuery = Mono.Lucene.Net.Search.BooleanQuery;
33 using FuzzyQuery = Mono.Lucene.Net.Search.FuzzyQuery;
34 using MatchAllDocsQuery = Mono.Lucene.Net.Search.MatchAllDocsQuery;
35 using MultiPhraseQuery = Mono.Lucene.Net.Search.MultiPhraseQuery;
36 using MultiTermQuery = Mono.Lucene.Net.Search.MultiTermQuery;
37 using PhraseQuery = Mono.Lucene.Net.Search.PhraseQuery;
38 using PrefixQuery = Mono.Lucene.Net.Search.PrefixQuery;
39 using Query = Mono.Lucene.Net.Search.Query;
40 using TermQuery = Mono.Lucene.Net.Search.TermQuery;
41 using TermRangeQuery = Mono.Lucene.Net.Search.TermRangeQuery;
42 using WildcardQuery = Mono.Lucene.Net.Search.WildcardQuery;
43 using Version = Mono.Lucene.Net.Util.Version;
44
45 namespace Mono.Lucene.Net.QueryParsers
46 {
47         
48         /// <summary> This class is generated by JavaCC.  The most important method is
49         /// {@link #Parse(String)}.
50         /// 
51         /// The syntax for query strings is as follows:
52         /// A Query is a series of clauses.
53         /// A clause may be prefixed by:
54         /// <ul>
55         /// <li> a plus (<code>+</code>) or a minus (<code>-</code>) sign, indicating
56         /// that the clause is required or prohibited respectively; or</li>
57         /// <li> a term followed by a colon, indicating the field to be searched.
58         /// This enables one to construct queries which search multiple fields.</li>
59         /// </ul>
60         /// 
61         /// A clause may be either:
62         /// <ul>
63         /// <li> a term, indicating all the documents that contain this term; or</li>
64         /// <li> a nested query, enclosed in parentheses.  Note that this may be used
65         /// with a <code>+</code>/<code>-</code> prefix to require any of a set of
66         /// terms.</li>
67         /// </ul>
68         /// 
69         /// Thus, in BNF, the query grammar is:
70         /// <pre>
71         /// Query  ::= ( Clause )*
72         /// Clause ::= ["+", "-"] [&lt;TERM&gt; ":"] ( &lt;TERM&gt; | "(" Query ")" )
73         /// </pre>
74         /// 
75         /// <p/>
76         /// Examples of appropriately formatted queries can be found in the <a
77         /// href="../../../../../../queryparsersyntax.html">query syntax
78         /// documentation</a>.
79         /// <p/>
80         /// 
81         /// <p/>
82         /// In {@link TermRangeQuery}s, QueryParser tries to detect date values, e.g.
83         /// <tt>date:[6/1/2005 TO 6/4/2005]</tt> produces a range query that searches
84         /// for "date" fields between 2005-06-01 and 2005-06-04. Note that the format
85         /// of the accepted input depends on {@link #SetLocale(Locale) the locale}.
86         /// By default a date is converted into a search term using the deprecated
87         /// {@link DateField} for compatibility reasons.
88         /// To use the new {@link DateTools} to convert dates, a
89         /// {@link Mono.Lucene.Net.Documents.DateTools.Resolution} has to be set.
90         /// <p/>
91         /// <p/>
92         /// The date resolution that shall be used for RangeQueries can be set
93         /// using {@link #SetDateResolution(DateTools.Resolution)}
94         /// or {@link #SetDateResolution(String, DateTools.Resolution)}. The former
95         /// sets the default date resolution for all fields, whereas the latter can
96         /// be used to set field specific date resolutions. Field specific date
97         /// resolutions take, if set, precedence over the default date resolution.
98         /// <p/>
99         /// <p/>
100         /// If you use neither {@link DateField} nor {@link DateTools} in your
101         /// index, you can create your own
102         /// query parser that inherits QueryParser and overwrites
103         /// {@link #GetRangeQuery(String, String, String, boolean)} to
104         /// use a different method for date conversion.
105         /// <p/>
106         /// 
107         /// <p/>Note that QueryParser is <em>not</em> thread-safe.<p/> 
108         /// 
109         /// <p/><b>NOTE</b>: there is a new QueryParser in contrib, which matches
110         /// the same syntax as this class, but is more modular,
111         /// enabling substantial customization to how a query is created.
112         /// 
113         /// <p/><b>NOTE</b>: there is a new QueryParser in contrib, which matches
114         /// the same syntax as this class, but is more modular,
115         /// enabling substantial customization to how a query is created.
116         /// <b>NOTE</b>: You must specify the required {@link Version} compatibility when
117         /// creating QueryParser:
118         /// <ul>
119         /// <li>As of 2.9, {@link #SetEnablePositionIncrements} is true by default.</li>
120         /// </ul>
121         /// </summary>
122         public class QueryParser : QueryParserConstants
123         {
124                 private void  InitBlock()
125                 {
126                         multiTermRewriteMethod = MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT;
127                         fuzzyMinSim = FuzzyQuery.defaultMinSimilarity;
128                         fuzzyPrefixLength = FuzzyQuery.defaultPrefixLength;
129                         jj_2_rtns = new JJCalls[1];
130                         jj_ls = new LookaheadSuccess();
131                 }
132                 
133                 private const int CONJ_NONE = 0;
134                 private const int CONJ_AND = 1;
135                 private const int CONJ_OR = 2;
136                 
137                 private const int MOD_NONE = 0;
138                 private const int MOD_NOT = 10;
139                 private const int MOD_REQ = 11;
140                 
141                 // make it possible to call setDefaultOperator() without accessing 
142                 // the nested class:
143                 /// <summary>Alternative form of QueryParser.Operator.AND </summary>
144                 public static readonly Operator AND_OPERATOR = Operator.AND;
145                 /// <summary>Alternative form of QueryParser.Operator.OR </summary>
146                 public static readonly Operator OR_OPERATOR = Operator.OR;
147                 
148                 /// <summary>The actual operator that parser uses to combine query terms </summary>
149                 private Operator operator_Renamed = OR_OPERATOR;
150                 
151                 internal bool lowercaseExpandedTerms = true;
152                 internal MultiTermQuery.RewriteMethod multiTermRewriteMethod;
153                 internal bool allowLeadingWildcard = false;
154                 internal bool enablePositionIncrements = true;
155                 
156                 internal Analyzer analyzer;
157                 internal System.String field;
158                 internal int phraseSlop = 0;
159                 internal float fuzzyMinSim;
160                 internal int fuzzyPrefixLength;
161                 internal System.Globalization.CultureInfo locale = System.Threading.Thread.CurrentThread.CurrentCulture;
162                 
163                 // the default date resolution
164                 internal DateTools.Resolution dateResolution = null;
165                 // maps field names to date resolutions
166                 internal System.Collections.IDictionary fieldToDateResolution = null;
167                 
168                 // The collator to use when determining range inclusion,
169                 // for use when constructing RangeQuerys.
170                 internal System.Globalization.CompareInfo rangeCollator = null;
171                 
172                 /// <summary>The default operator for parsing queries. 
173                 /// Use {@link QueryParser#setDefaultOperator} to change it.
174                 /// </summary>
175                 [Serializable]
176                 public sealed class Operator:Parameter
177                 {
178                         internal Operator(System.String name):base(name)
179                         {
180                         }
181                         public static readonly Operator OR = new Operator("OR");
182                         public static readonly Operator AND = new Operator("AND");
183                 }
184                 
185                 
186                 /// <summary>Constructs a query parser.</summary>
187                 /// <param name="f"> the default field for query terms.
188                 /// </param>
189                 /// <param name="a">  used to find terms in the query text.
190                 /// </param>
191                 /// <deprecated> Use {@link #QueryParser(Version, String, Analyzer)} instead
192                 /// </deprecated>
193         [Obsolete("Use QueryParser(Version, String, Analyzer) instead")]
194                 public QueryParser(System.String f, Analyzer a):this(Version.LUCENE_24, f, a)
195                 {
196                 }
197                 
198                 /// <summary> Constructs a query parser.
199                 /// 
200                 /// </summary>
201                 /// <param name="matchVersion">Lucene version to match. See <a href="#version">above</a>)
202                 /// </param>
203                 /// <param name="f">the default field for query terms.
204                 /// </param>
205                 /// <param name="a">used to find terms in the query text.
206                 /// </param>
207                 public QueryParser(Version matchVersion, System.String f, Analyzer a):this(new FastCharStream(new System.IO.StringReader("")))
208                 {
209                         analyzer = a;
210                         field = f;
211                         if (matchVersion.OnOrAfter(Version.LUCENE_29))
212                         {
213                                 enablePositionIncrements = true;
214                         }
215                         else
216                         {
217                                 enablePositionIncrements = false;
218                         }
219                 }
220                 
221                 /// <summary>Parses a query string, returning a {@link Mono.Lucene.Net.Search.Query}.</summary>
222                 /// <param name="query"> the query string to be parsed.
223                 /// </param>
224                 /// <throws>  ParseException if the parsing fails </throws>
225                 public virtual Query Parse(System.String query)
226                 {
227                         ReInit(new FastCharStream(new System.IO.StringReader(query)));
228                         try
229                         {
230                                 // TopLevelQuery is a Query followed by the end-of-input (EOF)
231                                 Query res = TopLevelQuery(field);
232                                 return res != null?res:NewBooleanQuery(false);
233                         }
234                         catch (ParseException tme)
235                         {
236                                 // rethrow to include the original query:
237                                 ParseException e = new ParseException("Cannot parse '" + query + "': " + tme.Message, tme);
238                                 throw e;
239                         }
240                         catch (TokenMgrError tme)
241                         {
242                                 ParseException e = new ParseException("Cannot parse '" + query + "': " + tme.Message, tme);
243                                 throw e;
244                         }
245                         catch (BooleanQuery.TooManyClauses tmc)
246                         {
247                                 ParseException e = new ParseException("Cannot parse '" + query + "': too many boolean clauses", tmc);
248                                 throw e;
249                         }
250                 }
251                 
252                 /// <returns> Returns the analyzer.
253                 /// </returns>
254                 public virtual Analyzer GetAnalyzer()
255                 {
256                         return analyzer;
257                 }
258                 
259                 /// <returns> Returns the field.
260                 /// </returns>
261                 public virtual System.String GetField()
262                 {
263                         return field;
264                 }
265                 
266                 /// <summary> Get the minimal similarity for fuzzy queries.</summary>
267                 public virtual float GetFuzzyMinSim()
268                 {
269                         return fuzzyMinSim;
270                 }
271                 
272                 /// <summary> Set the minimum similarity for fuzzy queries.
273                 /// Default is 0.5f.
274                 /// </summary>
275                 public virtual void  SetFuzzyMinSim(float fuzzyMinSim)
276                 {
277                         this.fuzzyMinSim = fuzzyMinSim;
278                 }
279                 
280                 /// <summary> Get the prefix length for fuzzy queries. </summary>
281                 /// <returns> Returns the fuzzyPrefixLength.
282                 /// </returns>
283                 public virtual int GetFuzzyPrefixLength()
284                 {
285                         return fuzzyPrefixLength;
286                 }
287                 
288                 /// <summary> Set the prefix length for fuzzy queries. Default is 0.</summary>
289                 /// <param name="fuzzyPrefixLength">The fuzzyPrefixLength to set.
290                 /// </param>
291                 public virtual void  SetFuzzyPrefixLength(int fuzzyPrefixLength)
292                 {
293                         this.fuzzyPrefixLength = fuzzyPrefixLength;
294                 }
295                 
296                 /// <summary> Sets the default slop for phrases.  If zero, then exact phrase matches
297                 /// are required.  Default value is zero.
298                 /// </summary>
299                 public virtual void  SetPhraseSlop(int phraseSlop)
300                 {
301                         this.phraseSlop = phraseSlop;
302                 }
303                 
304                 /// <summary> Gets the default slop for phrases.</summary>
305                 public virtual int GetPhraseSlop()
306                 {
307                         return phraseSlop;
308                 }
309                 
310                 
311                 /// <summary> Set to <code>true</code> to allow leading wildcard characters.
312                 /// <p/>
313                 /// When set, <code>*</code> or <code>?</code> are allowed as 
314                 /// the first character of a PrefixQuery and WildcardQuery.
315                 /// Note that this can produce very slow
316                 /// queries on big indexes. 
317                 /// <p/>
318                 /// Default: false.
319                 /// </summary>
320                 public virtual void  SetAllowLeadingWildcard(bool allowLeadingWildcard)
321                 {
322                         this.allowLeadingWildcard = allowLeadingWildcard;
323                 }
324                 
325                 /// <seealso cref="SetAllowLeadingWildcard(boolean)">
326                 /// </seealso>
327                 public virtual bool GetAllowLeadingWildcard()
328                 {
329                         return allowLeadingWildcard;
330                 }
331                 
332                 /// <summary> Set to <code>true</code> to enable position increments in result query.
333                 /// <p/>
334                 /// When set, result phrase and multi-phrase queries will
335                 /// be aware of position increments.
336                 /// Useful when e.g. a StopFilter increases the position increment of
337                 /// the token that follows an omitted token.
338                 /// <p/>
339                 /// Default: false.
340                 /// </summary>
341                 public virtual void  SetEnablePositionIncrements(bool enable)
342                 {
343                         this.enablePositionIncrements = enable;
344                 }
345                 
346                 /// <seealso cref="SetEnablePositionIncrements(boolean)">
347                 /// </seealso>
348                 public virtual bool GetEnablePositionIncrements()
349                 {
350                         return enablePositionIncrements;
351                 }
352                 
353                 /// <summary> Sets the boolean operator of the QueryParser.
354                 /// In default mode (<code>OR_OPERATOR</code>) terms without any modifiers
355                 /// are considered optional: for example <code>capital of Hungary</code> is equal to
356                 /// <code>capital OR of OR Hungary</code>.<br/>
357                 /// In <code>AND_OPERATOR</code> mode terms are considered to be in conjunction: the
358                 /// above mentioned query is parsed as <code>capital AND of AND Hungary</code>
359                 /// </summary>
360                 public virtual void  SetDefaultOperator(Operator op)
361                 {
362                         this.operator_Renamed = op;
363                 }
364                 
365                 
366                 /// <summary> Gets implicit operator setting, which will be either AND_OPERATOR
367                 /// or OR_OPERATOR.
368                 /// </summary>
369                 public virtual Operator GetDefaultOperator()
370                 {
371                         return operator_Renamed;
372                 }
373                 
374                 
375                 /// <summary> Whether terms of wildcard, prefix, fuzzy and range queries are to be automatically
376                 /// lower-cased or not.  Default is <code>true</code>.
377                 /// </summary>
378                 public virtual void  SetLowercaseExpandedTerms(bool lowercaseExpandedTerms)
379                 {
380                         this.lowercaseExpandedTerms = lowercaseExpandedTerms;
381                 }
382                 
383                 
384                 /// <seealso cref="SetLowercaseExpandedTerms(boolean)">
385                 /// </seealso>
386                 public virtual bool GetLowercaseExpandedTerms()
387                 {
388                         return lowercaseExpandedTerms;
389                 }
390                 
391                 /// <deprecated> Please use {@link #setMultiTermRewriteMethod} instead.
392                 /// </deprecated>
393         [Obsolete("Please use SetMultiTermRewriteMethod instead.")]
394                 public virtual void  SetUseOldRangeQuery(bool useOldRangeQuery)
395                 {
396                         if (useOldRangeQuery)
397                         {
398                                 SetMultiTermRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);
399                         }
400                         else
401                         {
402                                 SetMultiTermRewriteMethod(MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT);
403                         }
404                 }
405                 
406                 
407                 /// <deprecated> Please use {@link #getMultiTermRewriteMethod} instead.
408                 /// </deprecated>
409         [Obsolete("Please use GetMultiTermRewriteMethod} instead.")]
410                 public virtual bool GetUseOldRangeQuery()
411                 {
412                         if (GetMultiTermRewriteMethod() == MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE)
413                         {
414                                 return true;
415                         }
416                         else
417                         {
418                                 return false;
419                         }
420                 }
421                 
422                 /// <summary> By default QueryParser uses {@link MultiTermQuery#CONSTANT_SCORE_AUTO_REWRITE_DEFAULT}
423                 /// when creating a PrefixQuery, WildcardQuery or RangeQuery. This implementation is generally preferable because it 
424                 /// a) Runs faster b) Does not have the scarcity of terms unduly influence score 
425                 /// c) avoids any "TooManyBooleanClauses" exception.
426                 /// However, if your application really needs to use the
427                 /// old-fashioned BooleanQuery expansion rewriting and the above
428                 /// points are not relevant then use this to change
429                 /// the rewrite method.
430                 /// </summary>
431                 public virtual void  SetMultiTermRewriteMethod(MultiTermQuery.RewriteMethod method)
432                 {
433                         multiTermRewriteMethod = method;
434                 }
435                 
436                 
437                 /// <seealso cref="setMultiTermRewriteMethod">
438                 /// </seealso>
439                 public virtual MultiTermQuery.RewriteMethod GetMultiTermRewriteMethod()
440                 {
441                         return multiTermRewriteMethod;
442                 }
443                 
444                 /// <summary> Set locale used by date range parsing.</summary>
445                 public virtual void  SetLocale(System.Globalization.CultureInfo locale)
446                 {
447                         this.locale = locale;
448                 }
449                 
450                 /// <summary> Returns current locale, allowing access by subclasses.</summary>
451                 public virtual System.Globalization.CultureInfo GetLocale()
452                 {
453                         return locale;
454                 }
455                 
456                 /// <summary> Sets the default date resolution used by RangeQueries for fields for which no
457                 /// specific date resolutions has been set. Field specific resolutions can be set
458                 /// with {@link #SetDateResolution(String, DateTools.Resolution)}.
459                 /// 
460                 /// </summary>
461                 /// <param name="dateResolution">the default date resolution to set
462                 /// </param>
463                 public virtual void  SetDateResolution(DateTools.Resolution dateResolution)
464                 {
465                         this.dateResolution = dateResolution;
466                 }
467                 
468                 /// <summary> Sets the date resolution used by RangeQueries for a specific field.
469                 /// 
470                 /// </summary>
471                 /// <param name="fieldName">field for which the date resolution is to be set 
472                 /// </param>
473                 /// <param name="dateResolution">date resolution to set
474                 /// </param>
475                 public virtual void  SetDateResolution(System.String fieldName, DateTools.Resolution dateResolution)
476                 {
477                         if (fieldName == null)
478                         {
479                                 throw new System.ArgumentException("Field cannot be null.");
480                         }
481                         
482                         if (fieldToDateResolution == null)
483                         {
484                                 // lazily initialize HashMap
485                                 fieldToDateResolution = new System.Collections.Hashtable();
486                         }
487                         
488                         fieldToDateResolution[fieldName] = dateResolution;
489                 }
490                 
491                 /// <summary> Returns the date resolution that is used by RangeQueries for the given field. 
492                 /// Returns null, if no default or field specific date resolution has been set
493                 /// for the given field.
494                 /// 
495                 /// </summary>
496                 public virtual DateTools.Resolution GetDateResolution(System.String fieldName)
497                 {
498                         if (fieldName == null)
499                         {
500                                 throw new System.ArgumentException("Field cannot be null.");
501                         }
502                         
503                         if (fieldToDateResolution == null)
504                         {
505                                 // no field specific date resolutions set; return default date resolution instead
506                                 return this.dateResolution;
507                         }
508                         
509                         DateTools.Resolution resolution = (DateTools.Resolution) fieldToDateResolution[fieldName];
510                         if (resolution == null)
511                         {
512                                 // no date resolutions set for the given field; return default date resolution instead
513                                 resolution = this.dateResolution;
514                         }
515                         
516                         return resolution;
517                 }
518                 
519                 /// <summary> Sets the collator used to determine index term inclusion in ranges
520                 /// for RangeQuerys.
521                 /// <p/>
522                 /// <strong>WARNING:</strong> Setting the rangeCollator to a non-null
523                 /// collator using this method will cause every single index Term in the
524                 /// Field referenced by lowerTerm and/or upperTerm to be examined.
525                 /// Depending on the number of index Terms in this Field, the operation could
526                 /// be very slow.
527                 /// 
528                 /// </summary>
529                 /// <param name="rc"> the collator to use when constructing RangeQuerys
530                 /// </param>
531                 public virtual void  SetRangeCollator(System.Globalization.CompareInfo rc)
532                 {
533                         rangeCollator = rc;
534                 }
535                 
536                 /// <returns> the collator used to determine index term inclusion in ranges
537                 /// for RangeQuerys.
538                 /// </returns>
539                 public virtual System.Globalization.CompareInfo GetRangeCollator()
540                 {
541                         return rangeCollator;
542                 }
543                 
544                 /// <deprecated> use {@link #AddClause(List, int, int, Query)} instead.
545                 /// </deprecated>
546         [Obsolete("use AddClause(List, int, int, Query) instead.")]
547                 protected internal virtual void  AddClause(System.Collections.ArrayList clauses, int conj, int mods, Query q)
548                 {
549                         AddClause((System.Collections.IList) clauses, conj, mods, q);
550                 }
551                 
552                 protected internal virtual void  AddClause(System.Collections.IList clauses, int conj, int mods, Query q)
553                 {
554                         bool required, prohibited;
555                         
556                         // If this term is introduced by AND, make the preceding term required,
557                         // unless it's already prohibited
558                         if (clauses.Count > 0 && conj == CONJ_AND)
559                         {
560                                 BooleanClause c = (BooleanClause) clauses[clauses.Count - 1];
561                                 if (!c.IsProhibited())
562                                         c.SetOccur(BooleanClause.Occur.MUST);
563                         }
564                         
565                         if (clauses.Count > 0 && operator_Renamed == AND_OPERATOR && conj == CONJ_OR)
566                         {
567                                 // If this term is introduced by OR, make the preceding term optional,
568                                 // unless it's prohibited (that means we leave -a OR b but +a OR b-->a OR b)
569                                 // notice if the input is a OR b, first term is parsed as required; without
570                                 // this modification a OR b would parsed as +a OR b
571                                 BooleanClause c = (BooleanClause) clauses[clauses.Count - 1];
572                                 if (!c.IsProhibited())
573                                         c.SetOccur(BooleanClause.Occur.SHOULD);
574                         }
575                         
576                         // We might have been passed a null query; the term might have been
577                         // filtered away by the analyzer.
578                         if (q == null)
579                                 return ;
580                         
581                         if (operator_Renamed == OR_OPERATOR)
582                         {
583                                 // We set REQUIRED if we're introduced by AND or +; PROHIBITED if
584                                 // introduced by NOT or -; make sure not to set both.
585                                 prohibited = (mods == MOD_NOT);
586                                 required = (mods == MOD_REQ);
587                                 if (conj == CONJ_AND && !prohibited)
588                                 {
589                                         required = true;
590                                 }
591                         }
592                         else
593                         {
594                                 // We set PROHIBITED if we're introduced by NOT or -; We set REQUIRED
595                                 // if not PROHIBITED and not introduced by OR
596                                 prohibited = (mods == MOD_NOT);
597                                 required = (!prohibited && conj != CONJ_OR);
598                         }
599                         if (required && !prohibited)
600                                 clauses.Add(NewBooleanClause(q, BooleanClause.Occur.MUST));
601                         else if (!required && !prohibited)
602                                 clauses.Add(NewBooleanClause(q, BooleanClause.Occur.SHOULD));
603                         else if (!required && prohibited)
604                                 clauses.Add(NewBooleanClause(q, BooleanClause.Occur.MUST_NOT));
605                         else
606                                 throw new System.SystemException("Clause cannot be both required and prohibited");
607                 }
608                 
609                 
610                 /// <exception cref="ParseException">throw in overridden method to disallow
611                 /// </exception>
612                 public /*protected internal*/ virtual Query GetFieldQuery(System.String field, System.String queryText)
613                 {
614                         // Use the analyzer to get all the tokens, and then build a TermQuery,
615                         // PhraseQuery, or nothing based on the term count
616                         
617                         TokenStream source;
618                         try
619                         {
620                                 source = analyzer.ReusableTokenStream(field, new System.IO.StringReader(queryText));
621                                 source.Reset();
622                         }
623                         catch (System.IO.IOException e)
624                         {
625                                 source = analyzer.TokenStream(field, new System.IO.StringReader(queryText));
626                         }
627                         CachingTokenFilter buffer = new CachingTokenFilter(source);
628                         TermAttribute termAtt = null;
629                         PositionIncrementAttribute posIncrAtt = null;
630                         int numTokens = 0;
631                         
632                         bool success = false;
633                         try
634                         {
635                                 buffer.Reset();
636                                 success = true;
637                         }
638                         catch (System.IO.IOException e)
639                         {
640                                 // success==false if we hit an exception
641                         }
642                         if (success)
643                         {
644                                 if (buffer.HasAttribute(typeof(TermAttribute)))
645                                 {
646                                         termAtt = (TermAttribute) buffer.GetAttribute(typeof(TermAttribute));
647                                 }
648                                 if (buffer.HasAttribute(typeof(PositionIncrementAttribute)))
649                                 {
650                                         posIncrAtt = (PositionIncrementAttribute) buffer.GetAttribute(typeof(PositionIncrementAttribute));
651                                 }
652                         }
653                         
654                         int positionCount = 0;
655                         bool severalTokensAtSamePosition = false;
656                         
657                         bool hasMoreTokens = false;
658                         if (termAtt != null)
659                         {
660                                 try
661                                 {
662                                         hasMoreTokens = buffer.IncrementToken();
663                                         while (hasMoreTokens)
664                                         {
665                                                 numTokens++;
666                                                 int positionIncrement = (posIncrAtt != null)?posIncrAtt.GetPositionIncrement():1;
667                                                 if (positionIncrement != 0)
668                                                 {
669                                                         positionCount += positionIncrement;
670                                                 }
671                                                 else
672                                                 {
673                                                         severalTokensAtSamePosition = true;
674                                                 }
675                                                 hasMoreTokens = buffer.IncrementToken();
676                                         }
677                                 }
678                                 catch (System.IO.IOException e)
679                                 {
680                                         // ignore
681                                 }
682                         }
683                         try
684                         {
685                                 // rewind the buffer stream
686                                 buffer.Reset();
687                                 
688                                 // close original stream - all tokens buffered
689                                 source.Close();
690                         }
691                         catch (System.IO.IOException e)
692                         {
693                                 // ignore
694                         }
695                         
696                         if (numTokens == 0)
697                                 return null;
698                         else if (numTokens == 1)
699                         {
700                                 System.String term = null;
701                                 try
702                                 {
703                                         bool hasNext = buffer.IncrementToken();
704                                         System.Diagnostics.Debug.Assert(hasNext == true);
705                                         term = termAtt.Term();
706                                 }
707                                 catch (System.IO.IOException e)
708                                 {
709                                         // safe to ignore, because we know the number of tokens
710                                 }
711                                 return NewTermQuery(new Term(field, term));
712                         }
713                         else
714                         {
715                                 if (severalTokensAtSamePosition)
716                                 {
717                                         if (positionCount == 1)
718                                         {
719                                                 // no phrase query:
720                                                 BooleanQuery q = NewBooleanQuery(true);
721                                                 for (int i = 0; i < numTokens; i++)
722                                                 {
723                                                         System.String term = null;
724                                                         try
725                                                         {
726                                                                 bool hasNext = buffer.IncrementToken();
727                                                                 System.Diagnostics.Debug.Assert(hasNext == true);
728                                                                 term = termAtt.Term();
729                                                         }
730                                                         catch (System.IO.IOException e)
731                                                         {
732                                                                 // safe to ignore, because we know the number of tokens
733                                                         }
734                                                         
735                                                         Query currentQuery = NewTermQuery(new Term(field, term));
736                                                         q.Add(currentQuery, BooleanClause.Occur.SHOULD);
737                                                 }
738                                                 return q;
739                                         }
740                                         else
741                                         {
742                                                 // phrase query:
743                                                 MultiPhraseQuery mpq = NewMultiPhraseQuery();
744                                                 mpq.SetSlop(phraseSlop);
745                                                 System.Collections.ArrayList multiTerms = new System.Collections.ArrayList();
746                                                 int position = - 1;
747                                                 for (int i = 0; i < numTokens; i++)
748                                                 {
749                                                         System.String term = null;
750                                                         int positionIncrement = 1;
751                                                         try
752                                                         {
753                                                                 bool hasNext = buffer.IncrementToken();
754                                                                 System.Diagnostics.Debug.Assert(hasNext == true);
755                                                                 term = termAtt.Term();
756                                                                 if (posIncrAtt != null)
757                                                                 {
758                                                                         positionIncrement = posIncrAtt.GetPositionIncrement();
759                                                                 }
760                                                         }
761                                                         catch (System.IO.IOException e)
762                                                         {
763                                                                 // safe to ignore, because we know the number of tokens
764                                                         }
765                                                         
766                                                         if (positionIncrement > 0 && multiTerms.Count > 0)
767                                                         {
768                                                                 if (enablePositionIncrements)
769                                                                 {
770                                     mpq.Add((Term[]) multiTerms.ToArray(typeof(Term)), position);
771                                                                 }
772                                                                 else
773                                                                 {
774                                     mpq.Add((Term[]) multiTerms.ToArray(typeof(Term)));
775                                                                 }
776                                                                 multiTerms.Clear();
777                                                         }
778                                                         position += positionIncrement;
779                                                         multiTerms.Add(new Term(field, term));
780                                                 }
781                                                 if (enablePositionIncrements)
782                                                 {
783                             mpq.Add((Term[]) multiTerms.ToArray(typeof(Term)), position);
784                                                 }
785                                                 else
786                                                 {
787                             mpq.Add((Term[]) multiTerms.ToArray(typeof(Term)));
788                                                 }
789                                                 return mpq;
790                                         }
791                                 }
792                                 else
793                                 {
794                                         PhraseQuery pq = NewPhraseQuery();
795                                         pq.SetSlop(phraseSlop);
796                                         int position = - 1;
797                                         
798                                         
799                                         for (int i = 0; i < numTokens; i++)
800                                         {
801                                                 System.String term = null;
802                                                 int positionIncrement = 1;
803                                                 
804                                                 try
805                                                 {
806                                                         bool hasNext = buffer.IncrementToken();
807                                                         System.Diagnostics.Debug.Assert(hasNext == true);
808                                                         term = termAtt.Term();
809                                                         if (posIncrAtt != null)
810                                                         {
811                                                                 positionIncrement = posIncrAtt.GetPositionIncrement();
812                                                         }
813                                                 }
814                                                 catch (System.IO.IOException e)
815                                                 {
816                                                         // safe to ignore, because we know the number of tokens
817                                                 }
818                                                 
819                                                 if (enablePositionIncrements)
820                                                 {
821                                                         position += positionIncrement;
822                                                         pq.Add(new Term(field, term), position);
823                                                 }
824                                                 else
825                                                 {
826                                                         pq.Add(new Term(field, term));
827                                                 }
828                                         }
829                                         return pq;
830                                 }
831                         }
832                 }
833                 
834                 
835                 
836                 /// <summary> Base implementation delegates to {@link #GetFieldQuery(String,String)}.
837                 /// This method may be overridden, for example, to return
838                 /// a SpanNearQuery instead of a PhraseQuery.
839                 /// 
840                 /// </summary>
841                 /// <exception cref="ParseException">throw in overridden method to disallow
842                 /// </exception>
843                 protected internal virtual Query GetFieldQuery(System.String field, System.String queryText, int slop)
844                 {
845                         Query query = GetFieldQuery(field, queryText);
846                         
847                         if (query is PhraseQuery)
848                         {
849                                 ((PhraseQuery) query).SetSlop(slop);
850                         }
851                         if (query is MultiPhraseQuery)
852                         {
853                                 ((MultiPhraseQuery) query).SetSlop(slop);
854                         }
855                         
856                         return query;
857                 }
858                 
859                 
860                 /// <exception cref="ParseException">throw in overridden method to disallow
861                 /// </exception>
862                 protected internal virtual Query GetRangeQuery(System.String field, System.String part1, System.String part2, bool inclusive)
863                 {
864                         if (lowercaseExpandedTerms)
865                         {
866                                 part1 = part1.ToLower();
867                                 part2 = part2.ToLower();
868                         }
869             try
870             {
871                 System.DateTime d1;
872                 System.DateTime d2;
873
874                 try
875                 {
876                     d1 = System.DateTime.Parse(part1, locale);
877                 }
878                 catch (System.Exception)
879                 {
880                     d1 = System.DateTime.Parse(part1);
881                 }
882                 try
883                 {
884                     d2 = System.DateTime.Parse(part2, locale);
885                 }
886                 catch (System.Exception)
887                 {
888                     d2 = System.DateTime.Parse(part2);
889                 }
890
891                 if (inclusive)
892                 {
893                     // The user can only specify the date, not the time, so make sure
894                     // the time is set to the latest possible time of that date to really
895                     // include all documents:
896                     System.Globalization.Calendar cal = new System.Globalization.GregorianCalendar();
897                     System.DateTime tempDate = d2;
898                     d2 = d2.AddHours(23 - tempDate.Hour);
899                     d2 = d2.AddMinutes(59 - tempDate.Minute);
900                     d2 = d2.AddSeconds(59 - tempDate.Second);
901                     d2 = d2.AddMilliseconds(999 - tempDate.Millisecond);
902                 }
903                 DateTools.Resolution resolution = GetDateResolution(field);
904                 if (resolution == null)
905                 {
906                     // no default or field specific date resolution has been set,
907                                         // use deprecated DateField to maintain compatibility with
908                     // pre-1.9 Lucene versions.
909                     part1 = DateField.DateToString(d1);
910                     part2 = DateField.DateToString(d2);
911                 }
912                 else
913                 {
914                     part1 = DateTools.DateToString(d1, resolution);
915                     part2 = DateTools.DateToString(d2, resolution);
916                 }
917             }
918             catch (System.Exception)
919             {
920             }
921
922             return NewRangeQuery(field, part1, part2, inclusive);
923         }
924                 
925                 /// <summary> Builds a new BooleanQuery instance</summary>
926                 /// <param name="disableCoord">disable coord
927                 /// </param>
928                 /// <returns> new BooleanQuery instance
929                 /// </returns>
930                 protected internal virtual BooleanQuery NewBooleanQuery(bool disableCoord)
931                 {
932                         return new BooleanQuery(disableCoord);
933                 }
934                 
935                 /// <summary> Builds a new BooleanClause instance</summary>
936                 /// <param name="q">sub query
937                 /// </param>
938                 /// <param name="occur">how this clause should occur when matching documents
939                 /// </param>
940                 /// <returns> new BooleanClause instance
941                 /// </returns>
942                 protected internal virtual BooleanClause NewBooleanClause(Query q, BooleanClause.Occur occur)
943                 {
944                         return new BooleanClause(q, occur);
945                 }
946                 
947                 /// <summary> Builds a new TermQuery instance</summary>
948                 /// <param name="term">term
949                 /// </param>
950                 /// <returns> new TermQuery instance
951                 /// </returns>
952                 protected internal virtual Query NewTermQuery(Term term)
953                 {
954                         return new TermQuery(term);
955                 }
956                 
957                 /// <summary> Builds a new PhraseQuery instance</summary>
958                 /// <returns> new PhraseQuery instance
959                 /// </returns>
960                 protected internal virtual PhraseQuery NewPhraseQuery()
961                 {
962                         return new PhraseQuery();
963                 }
964                 
965                 /// <summary> Builds a new MultiPhraseQuery instance</summary>
966                 /// <returns> new MultiPhraseQuery instance
967                 /// </returns>
968                 protected internal virtual MultiPhraseQuery NewMultiPhraseQuery()
969                 {
970                         return new MultiPhraseQuery();
971                 }
972                 
973                 /// <summary> Builds a new PrefixQuery instance</summary>
974                 /// <param name="prefix">Prefix term
975                 /// </param>
976                 /// <returns> new PrefixQuery instance
977                 /// </returns>
978                 protected internal virtual Query NewPrefixQuery(Term prefix)
979                 {
980                         PrefixQuery query = new PrefixQuery(prefix);
981                         query.SetRewriteMethod(multiTermRewriteMethod);
982                         return query;
983                 }
984                 
985                 /// <summary> Builds a new FuzzyQuery instance</summary>
986                 /// <param name="term">Term
987                 /// </param>
988                 /// <param name="minimumSimilarity">minimum similarity
989                 /// </param>
990                 /// <param name="prefixLength">prefix length
991                 /// </param>
992                 /// <returns> new FuzzyQuery Instance
993                 /// </returns>
994                 protected internal virtual Query NewFuzzyQuery(Term term, float minimumSimilarity, int prefixLength)
995                 {
996                         // FuzzyQuery doesn't yet allow constant score rewrite
997                         return new FuzzyQuery(term, minimumSimilarity, prefixLength);
998                 }
999                 
1000                 /// <summary> Builds a new TermRangeQuery instance</summary>
1001                 /// <param name="field">Field
1002                 /// </param>
1003                 /// <param name="part1">min
1004                 /// </param>
1005                 /// <param name="part2">max
1006                 /// </param>
1007                 /// <param name="inclusive">true if range is inclusive
1008                 /// </param>
1009                 /// <returns> new TermRangeQuery instance
1010                 /// </returns>
1011                 protected internal virtual Query NewRangeQuery(System.String field, System.String part1, System.String part2, bool inclusive)
1012                 {
1013                         TermRangeQuery query = new TermRangeQuery(field, part1, part2, inclusive, inclusive, rangeCollator);
1014                         query.SetRewriteMethod(multiTermRewriteMethod);
1015                         return query;
1016                 }
1017                 
1018                 /// <summary> Builds a new MatchAllDocsQuery instance</summary>
1019                 /// <returns> new MatchAllDocsQuery instance
1020                 /// </returns>
1021                 protected internal virtual Query NewMatchAllDocsQuery()
1022                 {
1023                         return new MatchAllDocsQuery();
1024                 }
1025                 
1026                 /// <summary> Builds a new WildcardQuery instance</summary>
1027                 /// <param name="t">wildcard term
1028                 /// </param>
1029                 /// <returns> new WildcardQuery instance
1030                 /// </returns>
1031                 protected internal virtual Query NewWildcardQuery(Term t)
1032                 {
1033                         WildcardQuery query = new WildcardQuery(t);
1034                         query.SetRewriteMethod(multiTermRewriteMethod);
1035                         return query;
1036                 }
1037                 
1038                 /// <summary> Factory method for generating query, given a set of clauses.
1039                 /// By default creates a boolean query composed of clauses passed in.
1040                 /// 
1041                 /// Can be overridden by extending classes, to modify query being
1042                 /// returned.
1043                 /// 
1044                 /// </summary>
1045                 /// <param name="clauses">List that contains {@link BooleanClause} instances
1046                 /// to join.
1047                 /// 
1048                 /// </param>
1049                 /// <returns> Resulting {@link Query} object.
1050                 /// </returns>
1051                 /// <exception cref="ParseException">throw in overridden method to disallow
1052                 /// </exception>
1053                 /// <deprecated> use {@link #GetBooleanQuery(List)} instead
1054                 /// </deprecated>
1055         [Obsolete("use GetBooleanQuery(List) instead")]
1056                 protected internal virtual Query GetBooleanQuery(System.Collections.ArrayList clauses)
1057                 {
1058                         return GetBooleanQuery((System.Collections.IList) clauses, false);
1059                 }
1060                 
1061                 /// <summary> Factory method for generating query, given a set of clauses.
1062                 /// By default creates a boolean query composed of clauses passed in.
1063                 /// 
1064                 /// Can be overridden by extending classes, to modify query being
1065                 /// returned.
1066                 /// 
1067                 /// </summary>
1068                 /// <param name="clauses">List that contains {@link BooleanClause} instances
1069                 /// to join.
1070                 /// 
1071                 /// </param>
1072                 /// <returns> Resulting {@link Query} object.
1073                 /// </returns>
1074                 /// <exception cref="ParseException">throw in overridden method to disallow
1075                 /// </exception>
1076                 protected internal virtual Query GetBooleanQuery(System.Collections.IList clauses)
1077                 {
1078                         return GetBooleanQuery(clauses, false);
1079                 }
1080                 
1081                 /// <summary> Factory method for generating query, given a set of clauses.
1082                 /// By default creates a boolean query composed of clauses passed in.
1083                 /// 
1084                 /// Can be overridden by extending classes, to modify query being
1085                 /// returned.
1086                 /// 
1087                 /// </summary>
1088                 /// <param name="clauses">List that contains {@link BooleanClause} instances
1089                 /// to join.
1090                 /// </param>
1091                 /// <param name="disableCoord">true if coord scoring should be disabled.
1092                 /// 
1093                 /// </param>
1094                 /// <returns> Resulting {@link Query} object.
1095                 /// </returns>
1096                 /// <exception cref="ParseException">throw in overridden method to disallow
1097                 /// </exception>
1098                 /// <deprecated> use {@link #GetBooleanQuery(List, boolean)} instead
1099                 /// </deprecated>
1100         [Obsolete("use GetBooleanQuery(List, bool) instead")]
1101                 protected internal virtual Query GetBooleanQuery(System.Collections.ArrayList clauses, bool disableCoord)
1102                 {
1103                         return GetBooleanQuery((System.Collections.IList) clauses, disableCoord);
1104                 }
1105                 
1106                 /// <summary> Factory method for generating query, given a set of clauses.
1107                 /// By default creates a boolean query composed of clauses passed in.
1108                 /// 
1109                 /// Can be overridden by extending classes, to modify query being
1110                 /// returned.
1111                 /// 
1112                 /// </summary>
1113                 /// <param name="clauses">List that contains {@link BooleanClause} instances
1114                 /// to join.
1115                 /// </param>
1116                 /// <param name="disableCoord">true if coord scoring should be disabled.
1117                 /// 
1118                 /// </param>
1119                 /// <returns> Resulting {@link Query} object.
1120                 /// </returns>
1121                 /// <exception cref="ParseException">throw in overridden method to disallow
1122                 /// </exception>
1123                 protected internal virtual Query GetBooleanQuery(System.Collections.IList clauses, bool disableCoord)
1124                 {
1125                         if (clauses.Count == 0)
1126                         {
1127                                 return null; // all clause words were filtered away by the analyzer.
1128                         }
1129                         BooleanQuery query = NewBooleanQuery(disableCoord);
1130                         for (int i = 0; i < clauses.Count; i++)
1131                         {
1132                                 query.Add((BooleanClause) clauses[i]);
1133                         }
1134                         return query;
1135                 }
1136                 
1137                 /// <summary> Factory method for generating a query. Called when parser
1138                 /// parses an input term token that contains one or more wildcard
1139                 /// characters (? and *), but is not a prefix term token (one
1140                 /// that has just a single * character at the end)
1141                 /// <p/>
1142                 /// Depending on settings, prefix term may be lower-cased
1143                 /// automatically. It will not go through the default Analyzer,
1144                 /// however, since normal Analyzers are unlikely to work properly
1145                 /// with wildcard templates.
1146                 /// <p/>
1147                 /// Can be overridden by extending classes, to provide custom handling for
1148                 /// wildcard queries, which may be necessary due to missing analyzer calls.
1149                 /// 
1150                 /// </summary>
1151                 /// <param name="field">Name of the field query will use.
1152                 /// </param>
1153                 /// <param name="termStr">Term token that contains one or more wild card
1154                 /// characters (? or *), but is not simple prefix term
1155                 /// 
1156                 /// </param>
1157                 /// <returns> Resulting {@link Query} built for the term
1158                 /// </returns>
1159                 /// <exception cref="ParseException">throw in overridden method to disallow
1160                 /// </exception>
1161                 public /*protected internal*/ virtual Query GetWildcardQuery(System.String field, System.String termStr)
1162                 {
1163                         if ("*".Equals(field))
1164                         {
1165                                 if ("*".Equals(termStr))
1166                                         return NewMatchAllDocsQuery();
1167                         }
1168                         if (!allowLeadingWildcard && (termStr.StartsWith("*") || termStr.StartsWith("?")))
1169                                 throw new ParseException("'*' or '?' not allowed as first character in WildcardQuery");
1170                         if (lowercaseExpandedTerms)
1171                         {
1172                                 termStr = termStr.ToLower();
1173                         }
1174                         Term t = new Term(field, termStr);
1175                         return NewWildcardQuery(t);
1176                 }
1177                 
1178                 /// <summary> Factory method for generating a query (similar to
1179                 /// {@link #getWildcardQuery}). Called when parser parses an input term
1180                 /// token that uses prefix notation; that is, contains a single '*' wildcard
1181                 /// character as its last character. Since this is a special case
1182                 /// of generic wildcard term, and such a query can be optimized easily,
1183                 /// this usually results in a different query object.
1184                 /// <p/>
1185                 /// Depending on settings, a prefix term may be lower-cased
1186                 /// automatically. It will not go through the default Analyzer,
1187                 /// however, since normal Analyzers are unlikely to work properly
1188                 /// with wildcard templates.
1189                 /// <p/>
1190                 /// Can be overridden by extending classes, to provide custom handling for
1191                 /// wild card queries, which may be necessary due to missing analyzer calls.
1192                 /// 
1193                 /// </summary>
1194                 /// <param name="field">Name of the field query will use.
1195                 /// </param>
1196                 /// <param name="termStr">Term token to use for building term for the query
1197                 /// (<b>without</b> trailing '*' character!)
1198                 /// 
1199                 /// </param>
1200                 /// <returns> Resulting {@link Query} built for the term
1201                 /// </returns>
1202                 /// <exception cref="ParseException">throw in overridden method to disallow
1203                 /// </exception>
1204                 public /*protected internal*/ virtual Query GetPrefixQuery(System.String field, System.String termStr)
1205                 {
1206                         if (!allowLeadingWildcard && termStr.StartsWith("*"))
1207                                 throw new ParseException("'*' not allowed as first character in PrefixQuery");
1208                         if (lowercaseExpandedTerms)
1209                         {
1210                                 termStr = termStr.ToLower();
1211                         }
1212                         Term t = new Term(field, termStr);
1213                         return NewPrefixQuery(t);
1214                 }
1215                 
1216                 /// <summary> Factory method for generating a query (similar to
1217                 /// {@link #getWildcardQuery}). Called when parser parses
1218                 /// an input term token that has the fuzzy suffix (~) appended.
1219                 /// 
1220                 /// </summary>
1221                 /// <param name="field">Name of the field query will use.
1222                 /// </param>
1223                 /// <param name="termStr">Term token to use for building term for the query
1224                 /// 
1225                 /// </param>
1226                 /// <returns> Resulting {@link Query} built for the term
1227                 /// </returns>
1228                 /// <exception cref="ParseException">throw in overridden method to disallow
1229                 /// </exception>
1230                 public /*protected internal*/ virtual Query GetFuzzyQuery(System.String field, System.String termStr, float minSimilarity)
1231                 {
1232                         if (lowercaseExpandedTerms)
1233                         {
1234                                 termStr = termStr.ToLower();
1235                         }
1236                         Term t = new Term(field, termStr);
1237                         return NewFuzzyQuery(t, minSimilarity, fuzzyPrefixLength);
1238                 }
1239                 
1240                 /// <summary> Returns a String where the escape char has been
1241                 /// removed, or kept only once if there was a double escape.
1242                 /// 
1243                 /// Supports escaped unicode characters, e. g. translates
1244                 /// <code>\\u0041</code> to <code>A</code>.
1245                 /// 
1246                 /// </summary>
1247                 private System.String DiscardEscapeChar(System.String input)
1248                 {
1249                         // Create char array to hold unescaped char sequence
1250                         char[] output = new char[input.Length];
1251                         
1252                         // The length of the output can be less than the input
1253                         // due to discarded escape chars. This variable holds
1254                         // the actual length of the output
1255                         int length = 0;
1256                         
1257                         // We remember whether the last processed character was 
1258                         // an escape character
1259                         bool lastCharWasEscapeChar = false;
1260                         
1261                         // The multiplier the current unicode digit must be multiplied with.
1262                         // E. g. the first digit must be multiplied with 16^3, the second with 16^2...
1263                         int codePointMultiplier = 0;
1264                         
1265                         // Used to calculate the codepoint of the escaped unicode character
1266                         int codePoint = 0;
1267                         
1268                         for (int i = 0; i < input.Length; i++)
1269                         {
1270                                 char curChar = input[i];
1271                                 if (codePointMultiplier > 0)
1272                                 {
1273                                         codePoint += HexToInt(curChar) * codePointMultiplier;
1274                                         codePointMultiplier = SupportClass.Number.URShift(codePointMultiplier, 4);
1275                                         if (codePointMultiplier == 0)
1276                                         {
1277                                                 output[length++] = (char) codePoint;
1278                                                 codePoint = 0;
1279                                         }
1280                                 }
1281                                 else if (lastCharWasEscapeChar)
1282                                 {
1283                                         if (curChar == 'u')
1284                                         {
1285                                                 // found an escaped unicode character
1286                                                 codePointMultiplier = 16 * 16 * 16;
1287                                         }
1288                                         else
1289                                         {
1290                                                 // this character was escaped
1291                                                 output[length] = curChar;
1292                                                 length++;
1293                                         }
1294                                         lastCharWasEscapeChar = false;
1295                                 }
1296                                 else
1297                                 {
1298                                         if (curChar == '\\')
1299                                         {
1300                                                 lastCharWasEscapeChar = true;
1301                                         }
1302                                         else
1303                                         {
1304                                                 output[length] = curChar;
1305                                                 length++;
1306                                         }
1307                                 }
1308                         }
1309                         
1310                         if (codePointMultiplier > 0)
1311                         {
1312                                 throw new ParseException("Truncated unicode escape sequence.");
1313                         }
1314                         
1315                         if (lastCharWasEscapeChar)
1316                         {
1317                                 throw new ParseException("Term can not end with escape character.");
1318                         }
1319                         
1320                         return new System.String(output, 0, length);
1321                 }
1322                 
1323                 /// <summary>Returns the numeric value of the hexadecimal character </summary>
1324                 private static int HexToInt(char c)
1325                 {
1326                         if ('0' <= c && c <= '9')
1327                         {
1328                                 return c - '0';
1329                         }
1330                         else if ('a' <= c && c <= 'f')
1331                         {
1332                                 return c - 'a' + 10;
1333                         }
1334                         else if ('A' <= c && c <= 'F')
1335                         {
1336                                 return c - 'A' + 10;
1337                         }
1338                         else
1339                         {
1340                                 throw new ParseException("None-hex character in unicode escape sequence: " + c);
1341                         }
1342                 }
1343                 
1344                 /// <summary> Returns a String where those characters that QueryParser
1345                 /// expects to be escaped are escaped by a preceding <code>\</code>.
1346                 /// </summary>
1347                 public static System.String Escape(System.String s)
1348                 {
1349                         System.Text.StringBuilder sb = new System.Text.StringBuilder();
1350                         for (int i = 0; i < s.Length; i++)
1351                         {
1352                                 char c = s[i];
1353                                 // These characters are part of the query syntax and must be escaped
1354                                 if (c == '\\' || c == '+' || c == '-' || c == '!' || c == '(' || c == ')' || c == ':' || c == '^' || c == '[' || c == ']' || c == '\"' || c == '{' || c == '}' || c == '~' || c == '*' || c == '?' || c == '|' || c == '&')
1355                                 {
1356                                         sb.Append('\\');
1357                                 }
1358                                 sb.Append(c);
1359                         }
1360                         return sb.ToString();
1361                 }
1362                 
1363                 /// <summary> Command line tool to test QueryParser, using {@link Mono.Lucene.Net.Analysis.SimpleAnalyzer}.
1364                 /// Usage:<br/>
1365                 /// <code>java Mono.Lucene.Net.QueryParsers.QueryParser &lt;input&gt;</code>
1366                 /// </summary>
1367                 [STAThread]
1368                 public static void  Main(System.String[] args)
1369                 {
1370                         if (args.Length == 0)
1371                         {
1372                                 System.Console.Out.WriteLine("Usage: java Mono.Lucene.Net.QueryParsers.QueryParser <input>");
1373                                 System.Environment.Exit(0);
1374                         }
1375                         QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, "field", new Mono.Lucene.Net.Analysis.SimpleAnalyzer());
1376                         Query q = qp.Parse(args[0]);
1377                         System.Console.Out.WriteLine(q.ToString("field"));
1378                 }
1379                 
1380                 // *   Query  ::= ( Clause )*
1381                 // *   Clause ::= ["+", "-"] [<TERM> ":"] ( <TERM> | "(" Query ")" )
1382                 public int Conjunction()
1383                 {
1384                         int ret = CONJ_NONE;
1385                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1386                         {
1387                                 
1388                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.AND: 
1389                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.OR: 
1390                                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1391                                         {
1392                                                 
1393                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.AND: 
1394                                                         Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.AND);
1395                                                         ret = CONJ_AND;
1396                                                         break;
1397                                                 
1398                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.OR: 
1399                                                         Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.OR);
1400                                                         ret = CONJ_OR;
1401                                                         break;
1402                                                 
1403                                                 default: 
1404                                                         jj_la1[0] = jj_gen;
1405                                                         Jj_consume_token(- 1);
1406                                                         throw new ParseException();
1407                                                 
1408                                         }
1409                                         break;
1410                                 
1411                                 default: 
1412                                         jj_la1[1] = jj_gen;
1413                                         ;
1414                                         break;
1415                                 
1416                         }
1417                         {
1418                                 if (true)
1419                                         return ret;
1420                         }
1421                         throw new System.ApplicationException("Missing return statement in function");
1422                 }
1423                 
1424                 public int Modifiers()
1425                 {
1426                         int ret = MOD_NONE;
1427                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1428                         {
1429                                 
1430                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.NOT: 
1431                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.PLUS: 
1432                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.MINUS: 
1433                                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1434                                         {
1435                                                 
1436                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.PLUS: 
1437                                                         Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.PLUS);
1438                                                         ret = MOD_REQ;
1439                                                         break;
1440                                                 
1441                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.MINUS: 
1442                                                         Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.MINUS);
1443                                                         ret = MOD_NOT;
1444                                                         break;
1445                                                 
1446                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.NOT: 
1447                                                         Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.NOT);
1448                                                         ret = MOD_NOT;
1449                                                         break;
1450                                                 
1451                                                 default: 
1452                                                         jj_la1[2] = jj_gen;
1453                                                         Jj_consume_token(- 1);
1454                                                         throw new ParseException();
1455                                                 
1456                                         }
1457                                         break;
1458                                 
1459                                 default: 
1460                                         jj_la1[3] = jj_gen;
1461                                         ;
1462                                         break;
1463                                 
1464                         }
1465                         {
1466                                 if (true)
1467                                         return ret;
1468                         }
1469                         throw new System.ApplicationException("Missing return statement in function");
1470                 }
1471                 
1472                 // This makes sure that there is no garbage after the query string
1473                 public Query TopLevelQuery(System.String field)
1474                 {
1475                         Query q;
1476                         q = Query(field);
1477                         Jj_consume_token(0);
1478                         {
1479                                 if (true)
1480                                         return q;
1481                         }
1482                         throw new System.ApplicationException("Missing return statement in function");
1483                 }
1484                 
1485                 public Query Query(System.String field)
1486                 {
1487                         System.Collections.IList clauses = new System.Collections.ArrayList();
1488                         Query q, firstQuery = null;
1489                         int conj, mods;
1490                         mods = Modifiers();
1491                         q = Clause(field);
1492                         AddClause(clauses, CONJ_NONE, mods, q);
1493                         if (mods == MOD_NONE)
1494                                 firstQuery = q;
1495                         while (true)
1496                         {
1497                                 switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1498                                 {
1499                                         
1500                                         case Mono.Lucene.Net.QueryParsers.QueryParserConstants.AND: 
1501                                         case Mono.Lucene.Net.QueryParsers.QueryParserConstants.OR: 
1502                                         case Mono.Lucene.Net.QueryParsers.QueryParserConstants.NOT: 
1503                                         case Mono.Lucene.Net.QueryParsers.QueryParserConstants.PLUS: 
1504                                         case Mono.Lucene.Net.QueryParsers.QueryParserConstants.MINUS: 
1505                                         case Mono.Lucene.Net.QueryParsers.QueryParserConstants.LPAREN: 
1506                                         case Mono.Lucene.Net.QueryParsers.QueryParserConstants.STAR: 
1507                                         case Mono.Lucene.Net.QueryParsers.QueryParserConstants.QUOTED: 
1508                                         case Mono.Lucene.Net.QueryParsers.QueryParserConstants.TERM: 
1509                                         case Mono.Lucene.Net.QueryParsers.QueryParserConstants.PREFIXTERM: 
1510                                         case Mono.Lucene.Net.QueryParsers.QueryParserConstants.WILDTERM: 
1511                                         case Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_START: 
1512                                         case Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_START: 
1513                                         case Mono.Lucene.Net.QueryParsers.QueryParserConstants.NUMBER: 
1514                                                 ;
1515                                                 break;
1516                                         
1517                                         default: 
1518                                                 jj_la1[4] = jj_gen;
1519                                                 goto label_1_brk;   // {{Aroush-2.9}} this goto maybe misplaced
1520                                         
1521                                 }
1522                                 conj = Conjunction();
1523                                 mods = Modifiers();
1524                                 q = Clause(field);
1525                                 AddClause(clauses, conj, mods, q);
1526                         }
1527
1528 label_1_brk: ;  // {{Aroush-2.9}} this lable maybe misplaced
1529                         
1530                         if (clauses.Count == 1 && firstQuery != null)
1531                         {
1532                                 if (true)
1533                                         return firstQuery;
1534                         }
1535                         else
1536                         {
1537                                 {
1538                                         if (true)
1539                                                 return GetBooleanQuery(clauses);
1540                                 }
1541                         }
1542                         throw new System.ApplicationException("Missing return statement in function");
1543                 }
1544                 
1545                 public Query Clause(System.String field)
1546                 {
1547                         Query q;
1548                         Token fieldToken = null, boost = null;
1549                         if (Jj_2_1(2))
1550                         {
1551                                 switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1552                                 {
1553                                         
1554                                         case Mono.Lucene.Net.QueryParsers.QueryParserConstants.TERM: 
1555                                                 fieldToken = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.TERM);
1556                                                 Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.COLON);
1557                                                 field = DiscardEscapeChar(fieldToken.image);
1558                                                 break;
1559                                         
1560                                         case Mono.Lucene.Net.QueryParsers.QueryParserConstants.STAR: 
1561                                                 Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.STAR);
1562                                                 Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.COLON);
1563                                                 field = "*";
1564                                                 break;
1565                                         
1566                                         default: 
1567                                                 jj_la1[5] = jj_gen;
1568                                                 Jj_consume_token(- 1);
1569                                                 throw new ParseException();
1570                                         
1571                                 }
1572                         }
1573                         else
1574                         {
1575                                 ;
1576                         }
1577                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1578                         {
1579                                 
1580                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.STAR: 
1581                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.QUOTED: 
1582                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.TERM: 
1583                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.PREFIXTERM: 
1584                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.WILDTERM: 
1585                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_START: 
1586                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_START: 
1587                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.NUMBER: 
1588                                         q = Term(field);
1589                                         break;
1590                                 
1591                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.LPAREN: 
1592                                         Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.LPAREN);
1593                                         q = Query(field);
1594                                         Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.RPAREN);
1595                                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1596                                         {
1597                                                 
1598                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.CARAT: 
1599                                                         Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.CARAT);
1600                                                         boost = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.NUMBER);
1601                                                         break;
1602                                                 
1603                                                 default: 
1604                                                         jj_la1[6] = jj_gen;
1605                                                         ;
1606                                                         break;
1607                                                 
1608                                         }
1609                                         break;
1610                                 
1611                                 default: 
1612                                         jj_la1[7] = jj_gen;
1613                                         Jj_consume_token(- 1);
1614                                         throw new ParseException();
1615                                 
1616                         }
1617                         if (boost != null)
1618                         {
1619                                 float f = (float) 1.0;
1620                                 try
1621                                 {
1622                                         f = (float) SupportClass.Single.Parse(boost.image);
1623                                         q.SetBoost(f);
1624                                 }
1625                                 catch (System.Exception ignored)
1626                                 {
1627                                 }
1628                         }
1629                         {
1630                                 if (true)
1631                                         return q;
1632                         }
1633                         throw new System.ApplicationException("Missing return statement in function");
1634                 }
1635                 
1636                 public Query Term(System.String field)
1637                 {
1638                         Token term, boost = null, fuzzySlop = null, goop1, goop2;
1639                         bool prefix = false;
1640                         bool wildcard = false;
1641                         bool fuzzy = false;
1642                         Query q;
1643                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1644                         {
1645                                 
1646                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.STAR: 
1647                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.TERM: 
1648                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.PREFIXTERM: 
1649                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.WILDTERM: 
1650                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.NUMBER: 
1651                                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1652                                         {
1653                                                 
1654                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.TERM: 
1655                                                         term = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.TERM);
1656                                                         break;
1657                                                 
1658                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.STAR: 
1659                                                         term = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.STAR);
1660                                                         wildcard = true;
1661                                                         break;
1662                                                 
1663                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.PREFIXTERM: 
1664                                                         term = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.PREFIXTERM);
1665                                                         prefix = true;
1666                                                         break;
1667                                                 
1668                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.WILDTERM: 
1669                                                         term = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.WILDTERM);
1670                                                         wildcard = true;
1671                                                         break;
1672                                                 
1673                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.NUMBER: 
1674                                                         term = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.NUMBER);
1675                                                         break;
1676                                                 
1677                                                 default: 
1678                                                         jj_la1[8] = jj_gen;
1679                                                         Jj_consume_token(- 1);
1680                                                         throw new ParseException();
1681                                                 
1682                                         }
1683                                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1684                                         {
1685                                                 
1686                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.FUZZY_SLOP: 
1687                                                         fuzzySlop = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.FUZZY_SLOP);
1688                                                         fuzzy = true;
1689                                                         break;
1690                                                 
1691                                                 default: 
1692                                                         jj_la1[9] = jj_gen;
1693                                                         ;
1694                                                         break;
1695                                                 
1696                                         }
1697                                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1698                                         {
1699                                                 
1700                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.CARAT: 
1701                                                         Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.CARAT);
1702                                                         boost = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.NUMBER);
1703                                                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1704                                                         {
1705                                                                 
1706                                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.FUZZY_SLOP: 
1707                                                                         fuzzySlop = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.FUZZY_SLOP);
1708                                                                         fuzzy = true;
1709                                                                         break;
1710                                                                 
1711                                                                 default: 
1712                                                                         jj_la1[10] = jj_gen;
1713                                                                         ;
1714                                                                         break;
1715                                                                 
1716                                                         }
1717                                                         break;
1718                                                 
1719                                                 default: 
1720                                                         jj_la1[11] = jj_gen;
1721                                                         ;
1722                                                         break;
1723                                                 
1724                                         }
1725                                         System.String termImage = DiscardEscapeChar(term.image);
1726                                         if (wildcard)
1727                                         {
1728                                                 q = GetWildcardQuery(field, termImage);
1729                                         }
1730                                         else if (prefix)
1731                                         {
1732                                                 q = GetPrefixQuery(field, DiscardEscapeChar(term.image.Substring(0, (term.image.Length - 1) - (0))));
1733                                         }
1734                                         else if (fuzzy)
1735                                         {
1736                                                 float fms = fuzzyMinSim;
1737                                                 try
1738                                                 {
1739                                                         fms = (float) SupportClass.Single.Parse(fuzzySlop.image.Substring(1));
1740                                                 }
1741                                                 catch (System.Exception ignored)
1742                                                 {
1743                                                 }
1744                                                 if (fms < 0.0f || fms > 1.0f)
1745                                                 {
1746                                                         {
1747                                                                 if (true)
1748                                                                         throw new ParseException("Minimum similarity for a FuzzyQuery has to be between 0.0f and 1.0f !");
1749                                                         }
1750                                                 }
1751                                                 q = GetFuzzyQuery(field, termImage, fms);
1752                                         }
1753                                         else
1754                                         {
1755                                                 q = GetFieldQuery(field, termImage);
1756                                         }
1757                                         break;
1758                                 
1759                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_START: 
1760                                         Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_START);
1761                                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1762                                         {
1763                                                 
1764                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_GOOP: 
1765                                                         goop1 = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_GOOP);
1766                                                         break;
1767                                                 
1768                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_QUOTED: 
1769                                                         goop1 = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_QUOTED);
1770                                                         break;
1771                                                 
1772                                                 default: 
1773                                                         jj_la1[12] = jj_gen;
1774                                                         Jj_consume_token(- 1);
1775                                                         throw new ParseException();
1776                                                 
1777                                         }
1778                                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1779                                         {
1780                                                 
1781                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_TO: 
1782                                                         Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_TO);
1783                                                         break;
1784                                                 
1785                                                 default: 
1786                                                         jj_la1[13] = jj_gen;
1787                                                         ;
1788                                                         break;
1789                                                 
1790                                         }
1791                                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1792                                         {
1793                                                 
1794                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_GOOP: 
1795                                                         goop2 = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_GOOP);
1796                                                         break;
1797                                                 
1798                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_QUOTED: 
1799                                                         goop2 = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_QUOTED);
1800                                                         break;
1801                                                 
1802                                                 default: 
1803                                                         jj_la1[14] = jj_gen;
1804                                                         Jj_consume_token(- 1);
1805                                                         throw new ParseException();
1806                                                 
1807                                         }
1808                                         Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_END);
1809                                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1810                                         {
1811                                                 
1812                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.CARAT: 
1813                                                         Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.CARAT);
1814                                                         boost = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.NUMBER);
1815                                                         break;
1816                                                 
1817                                                 default: 
1818                                                         jj_la1[15] = jj_gen;
1819                                                         ;
1820                                                         break;
1821                                                 
1822                                         }
1823                                         if (goop1.kind == Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_QUOTED)
1824                                         {
1825                                                 goop1.image = goop1.image.Substring(1, (goop1.image.Length - 1) - (1));
1826                                         }
1827                                         if (goop2.kind == Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_QUOTED)
1828                                         {
1829                                                 goop2.image = goop2.image.Substring(1, (goop2.image.Length - 1) - (1));
1830                                         }
1831                                         q = GetRangeQuery(field, DiscardEscapeChar(goop1.image), DiscardEscapeChar(goop2.image), true);
1832                                         break;
1833                                 
1834                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_START: 
1835                                         Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_START);
1836                                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1837                                         {
1838                                                 
1839                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_GOOP: 
1840                                                         goop1 = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_GOOP);
1841                                                         break;
1842                                                 
1843                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_QUOTED: 
1844                                                         goop1 = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_QUOTED);
1845                                                         break;
1846                                                 
1847                                                 default: 
1848                                                         jj_la1[16] = jj_gen;
1849                                                         Jj_consume_token(- 1);
1850                                                         throw new ParseException();
1851                                                 
1852                                         }
1853                                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1854                                         {
1855                                                 
1856                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_TO: 
1857                                                         Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_TO);
1858                                                         break;
1859                                                 
1860                                                 default: 
1861                                                         jj_la1[17] = jj_gen;
1862                                                         ;
1863                                                         break;
1864                                                 
1865                                         }
1866                                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1867                                         {
1868                                                 
1869                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_GOOP: 
1870                                                         goop2 = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_GOOP);
1871                                                         break;
1872                                                 
1873                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_QUOTED: 
1874                                                         goop2 = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_QUOTED);
1875                                                         break;
1876                                                 
1877                                                 default: 
1878                                                         jj_la1[18] = jj_gen;
1879                                                         Jj_consume_token(- 1);
1880                                                         throw new ParseException();
1881                                                 
1882                                         }
1883                                         Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_END);
1884                                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1885                                         {
1886                                                 
1887                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.CARAT: 
1888                                                         Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.CARAT);
1889                                                         boost = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.NUMBER);
1890                                                         break;
1891                                                 
1892                                                 default: 
1893                                                         jj_la1[19] = jj_gen;
1894                                                         ;
1895                                                         break;
1896                                                 
1897                                         }
1898                                         if (goop1.kind == Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_QUOTED)
1899                                         {
1900                                                 goop1.image = goop1.image.Substring(1, (goop1.image.Length - 1) - (1));
1901                                         }
1902                                         if (goop2.kind == Mono.Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_QUOTED)
1903                                         {
1904                                                 goop2.image = goop2.image.Substring(1, (goop2.image.Length - 1) - (1));
1905                                         }
1906                                         
1907                                         q = GetRangeQuery(field, DiscardEscapeChar(goop1.image), DiscardEscapeChar(goop2.image), false);
1908                                         break;
1909                                 
1910                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.QUOTED: 
1911                                         term = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.QUOTED);
1912                                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1913                                         {
1914                                                 
1915                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.FUZZY_SLOP: 
1916                                                         fuzzySlop = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.FUZZY_SLOP);
1917                                                         break;
1918                                                 
1919                                                 default: 
1920                                                         jj_la1[20] = jj_gen;
1921                                                         ;
1922                                                         break;
1923                                                 
1924                                         }
1925                                         switch ((jj_ntk == - 1)?Jj_ntk():jj_ntk)
1926                                         {
1927                                                 
1928                                                 case Mono.Lucene.Net.QueryParsers.QueryParserConstants.CARAT: 
1929                                                         Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.CARAT);
1930                                                         boost = Jj_consume_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.NUMBER);
1931                                                         break;
1932                                                 
1933                                                 default: 
1934                                                         jj_la1[21] = jj_gen;
1935                                                         ;
1936                                                         break;
1937                                                 
1938                                         }
1939                                         int s = phraseSlop;
1940                                         
1941                                         if (fuzzySlop != null)
1942                                         {
1943                                                 try
1944                                                 {
1945                                                         s = (int) SupportClass.Single.Parse(fuzzySlop.image.Substring(1));
1946                                                 }
1947                                                 catch (System.Exception ignored)
1948                                                 {
1949                                                 }
1950                                         }
1951                                         q = GetFieldQuery(field, DiscardEscapeChar(term.image.Substring(1, (term.image.Length - 1) - (1))), s);
1952                                         break;
1953                                 
1954                                 default: 
1955                                         jj_la1[22] = jj_gen;
1956                                         Jj_consume_token(- 1);
1957                                         throw new ParseException();
1958                                 
1959                         }
1960                         if (boost != null)
1961                         {
1962                                 float f = (float) 1.0;
1963                                 try
1964                                 {
1965                                         f = (float) SupportClass.Single.Parse(boost.image);
1966                                 }
1967                                 catch (System.Exception ignored)
1968                                 {
1969                                         /* Should this be handled somehow? (defaults to "no boost", if
1970                                         * boost number is invalid)
1971                                         */
1972                                 }
1973                                 
1974                                 // avoid boosting null queries, such as those caused by stop words
1975                                 if (q != null)
1976                                 {
1977                                         q.SetBoost(f);
1978                                 }
1979                         }
1980                         {
1981                                 if (true)
1982                                         return q;
1983                         }
1984                         throw new System.ApplicationException("Missing return statement in function");
1985                 }
1986                 
1987                 private bool Jj_2_1(int xla)
1988                 {
1989                         jj_la = xla; jj_lastpos = jj_scanpos = token;
1990                         try
1991                         {
1992                                 return !Jj_3_1();
1993                         }
1994                         catch (LookaheadSuccess ls)
1995                         {
1996                                 return true;
1997                         }
1998                         finally
1999                         {
2000                                 Jj_save(0, xla);
2001                         }
2002                 }
2003                 
2004                 private bool Jj_3R_2()
2005                 {
2006                         if (Jj_scan_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.TERM))
2007                                 return true;
2008                         if (Jj_scan_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.COLON))
2009                                 return true;
2010                         return false;
2011                 }
2012                 
2013                 private bool Jj_3_1()
2014                 {
2015                         Token xsp;
2016                         xsp = jj_scanpos;
2017                         if (Jj_3R_2())
2018                         {
2019                                 jj_scanpos = xsp;
2020                                 if (Jj_3R_3())
2021                                         return true;
2022                         }
2023                         return false;
2024                 }
2025                 
2026                 private bool Jj_3R_3()
2027                 {
2028                         if (Jj_scan_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.STAR))
2029                                 return true;
2030                         if (Jj_scan_token(Mono.Lucene.Net.QueryParsers.QueryParserConstants.COLON))
2031                                 return true;
2032                         return false;
2033                 }
2034                 
2035                 /// <summary>Generated Token Manager. </summary>
2036                 public QueryParserTokenManager token_source;
2037                 /// <summary>Current token. </summary>
2038                 public Token token;
2039                 /// <summary>Next token. </summary>
2040                 private Token jj_nt;
2041                 private int jj_ntk;
2042                 private Token jj_scanpos, jj_lastpos;
2043                 private int jj_la;
2044                 private int jj_gen;
2045                 private int[] jj_la1 = new int[23];
2046                 private static int[] jj_la1_0;
2047                 private static int[] jj_la1_1;
2048                 private static void  Jj_la1_init_0()
2049                 {
2050                         jj_la1_0 = new int[]{0x300, 0x300, 0x1c00, 0x1c00, 0x3ed3f00, 0x90000, 0x20000, 0x3ed2000, 0x2690000, 0x100000, 0x100000, 0x20000, 0x30000000, 0x4000000, 0x30000000, 0x20000, 0x0, 0x40000000, 0x0, 0x20000, 0x100000, 0x20000, 0x3ed0000};
2051                 }
2052                 private static void  Jj_la1_init_1()
2053                 {
2054                         jj_la1_1 = new int[]{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0};
2055                 }
2056                 private JJCalls[] jj_2_rtns;
2057                 private bool jj_rescan = false;
2058                 private int jj_gc = 0;
2059                 
2060                 /// <summary>Constructor with user supplied CharStream. </summary>
2061                 protected internal QueryParser(CharStream stream)
2062                 {
2063                         InitBlock();
2064                         token_source = new QueryParserTokenManager(stream);
2065                         token = new Token();
2066                         jj_ntk = - 1;
2067                         jj_gen = 0;
2068                         for (int i = 0; i < 23; i++)
2069                                 jj_la1[i] = - 1;
2070                         for (int i = 0; i < jj_2_rtns.Length; i++)
2071                                 jj_2_rtns[i] = new JJCalls();
2072                 }
2073                 
2074                 /// <summary>Reinitialise. </summary>
2075                 public virtual void  ReInit(CharStream stream)
2076                 {
2077                         token_source.ReInit(stream);
2078                         token = new Token();
2079                         jj_ntk = - 1;
2080                         jj_gen = 0;
2081                         for (int i = 0; i < 23; i++)
2082                                 jj_la1[i] = - 1;
2083                         for (int i = 0; i < jj_2_rtns.Length; i++)
2084                                 jj_2_rtns[i] = new JJCalls();
2085                 }
2086                 
2087                 /// <summary>Constructor with generated Token Manager. </summary>
2088                 protected internal QueryParser(QueryParserTokenManager tm)
2089                 {
2090                         InitBlock();
2091                         token_source = tm;
2092                         token = new Token();
2093                         jj_ntk = - 1;
2094                         jj_gen = 0;
2095                         for (int i = 0; i < 23; i++)
2096                                 jj_la1[i] = - 1;
2097                         for (int i = 0; i < jj_2_rtns.Length; i++)
2098                                 jj_2_rtns[i] = new JJCalls();
2099                 }
2100                 
2101                 /// <summary>Reinitialise. </summary>
2102                 public virtual void  ReInit(QueryParserTokenManager tm)
2103                 {
2104                         token_source = tm;
2105                         token = new Token();
2106                         jj_ntk = - 1;
2107                         jj_gen = 0;
2108                         for (int i = 0; i < 23; i++)
2109                                 jj_la1[i] = - 1;
2110                         for (int i = 0; i < jj_2_rtns.Length; i++)
2111                                 jj_2_rtns[i] = new JJCalls();
2112                 }
2113                 
2114                 private Token Jj_consume_token(int kind)
2115                 {
2116                         Token oldToken;
2117                         if ((oldToken = token).next != null)
2118                                 token = token.next;
2119                         else
2120                                 token = token.next = token_source.GetNextToken();
2121                         jj_ntk = - 1;
2122                         if (token.kind == kind)
2123                         {
2124                                 jj_gen++;
2125                                 if (++jj_gc > 100)
2126                                 {
2127                                         jj_gc = 0;
2128                                         for (int i = 0; i < jj_2_rtns.Length; i++)
2129                                         {
2130                                                 JJCalls c = jj_2_rtns[i];
2131                                                 while (c != null)
2132                                                 {
2133                                                         if (c.gen < jj_gen)
2134                                                                 c.first = null;
2135                                                         c = c.next;
2136                                                 }
2137                                         }
2138                                 }
2139                                 return token;
2140                         }
2141                         token = oldToken;
2142                         jj_kind = kind;
2143                         throw GenerateParseException();
2144                 }
2145                 
2146                 [Serializable]
2147                 private sealed class LookaheadSuccess:System.ApplicationException
2148                 {
2149                 }
2150                 private LookaheadSuccess jj_ls;
2151                 private bool Jj_scan_token(int kind)
2152                 {
2153                         if (jj_scanpos == jj_lastpos)
2154                         {
2155                                 jj_la--;
2156                                 if (jj_scanpos.next == null)
2157                                 {
2158                                         jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.GetNextToken();
2159                                 }
2160                                 else
2161                                 {
2162                                         jj_lastpos = jj_scanpos = jj_scanpos.next;
2163                                 }
2164                         }
2165                         else
2166                         {
2167                                 jj_scanpos = jj_scanpos.next;
2168                         }
2169                         if (jj_rescan)
2170                         {
2171                                 int i = 0; Token tok = token;
2172                                 while (tok != null && tok != jj_scanpos)
2173                                 {
2174                                         i++; tok = tok.next;
2175                                 }
2176                                 if (tok != null)
2177                                         Jj_add_error_token(kind, i);
2178                         }
2179                         if (jj_scanpos.kind != kind)
2180                                 return true;
2181                         if (jj_la == 0 && jj_scanpos == jj_lastpos)
2182                                 throw jj_ls;
2183                         return false;
2184                 }
2185                 
2186                 
2187                 /// <summary>Get the next Token. </summary>
2188                 public Token GetNextToken()
2189                 {
2190                         if (token.next != null)
2191                                 token = token.next;
2192                         else
2193                                 token = token.next = token_source.GetNextToken();
2194                         jj_ntk = - 1;
2195                         jj_gen++;
2196                         return token;
2197                 }
2198                 
2199                 /// <summary>Get the specific Token. </summary>
2200                 public Token GetToken(int index)
2201                 {
2202                         Token t = token;
2203                         for (int i = 0; i < index; i++)
2204                         {
2205                                 if (t.next != null)
2206                                         t = t.next;
2207                                 else
2208                                         t = t.next = token_source.GetNextToken();
2209                         }
2210                         return t;
2211                 }
2212                 
2213                 private int Jj_ntk()
2214                 {
2215                         if ((jj_nt = token.next) == null)
2216                                 return (jj_ntk = (token.next = token_source.GetNextToken()).kind);
2217                         else
2218                                 return (jj_ntk = jj_nt.kind);
2219                 }
2220                 
2221                 private System.Collections.IList jj_expentries = new System.Collections.ArrayList();
2222                 private int[] jj_expentry;
2223                 private int jj_kind = - 1;
2224                 private int[] jj_lasttokens = new int[100];
2225                 private int jj_endpos;
2226                 
2227                 private void  Jj_add_error_token(int kind, int pos)
2228                 {
2229                         if (pos >= 100)
2230                                 return ;
2231                         if (pos == jj_endpos + 1)
2232                         {
2233                                 jj_lasttokens[jj_endpos++] = kind;
2234                         }
2235                         else if (jj_endpos != 0)
2236                         {
2237                                 jj_expentry = new int[jj_endpos];
2238                                 for (int i = 0; i < jj_endpos; i++)
2239                                 {
2240                                         jj_expentry[i] = jj_lasttokens[i];
2241                                 }
2242                                 if (pos != 0)
2243                                         jj_lasttokens[(jj_endpos = pos) - 1] = kind;
2244                         }
2245                 }
2246                 
2247                 /// <summary>Generate ParseException. </summary>
2248                 public virtual ParseException GenerateParseException()
2249                 {
2250                         jj_expentries.Clear();
2251                         bool[] la1tokens = new bool[34];
2252                         if (jj_kind >= 0)
2253                         {
2254                                 la1tokens[jj_kind] = true;
2255                                 jj_kind = - 1;
2256                         }
2257                         for (int i = 0; i < 23; i++)
2258                         {
2259                                 if (jj_la1[i] == jj_gen)
2260                                 {
2261                                         for (int j = 0; j < 32; j++)
2262                                         {
2263                                                 if ((jj_la1_0[i] & (1 << j)) != 0)
2264                                                 {
2265                                                         la1tokens[j] = true;
2266                                                 }
2267                                                 if ((jj_la1_1[i] & (1 << j)) != 0)
2268                                                 {
2269                                                         la1tokens[32 + j] = true;
2270                                                 }
2271                                         }
2272                                 }
2273                         }
2274                         for (int i = 0; i < 34; i++)
2275                         {
2276                                 if (la1tokens[i])
2277                                 {
2278                                         jj_expentry = new int[1];
2279                                         jj_expentry[0] = i;
2280                                         jj_expentries.Add(jj_expentry);
2281                                 }
2282                         }
2283                         jj_endpos = 0;
2284                         Jj_rescan_token();
2285                         Jj_add_error_token(0, 0);
2286                         int[][] exptokseq = new int[jj_expentries.Count][];
2287                         for (int i = 0; i < jj_expentries.Count; i++)
2288                         {
2289                                 exptokseq[i] = (int[]) jj_expentries[i];
2290                         }
2291                         return new ParseException(token, exptokseq, Mono.Lucene.Net.QueryParsers.QueryParserConstants.tokenImage);
2292                 }
2293                 
2294                 /// <summary>Enable tracing. </summary>
2295                 public void  Enable_tracing()
2296                 {
2297                 }
2298                 
2299                 /// <summary>Disable tracing. </summary>
2300                 public void  Disable_tracing()
2301                 {
2302                 }
2303                 
2304                 private void  Jj_rescan_token()
2305                 {
2306                         jj_rescan = true;
2307                         for (int i = 0; i < 1; i++)
2308                         {
2309                                 try
2310                                 {
2311                                         JJCalls p = jj_2_rtns[i];
2312                                         do 
2313                                         {
2314                                                 if (p.gen > jj_gen)
2315                                                 {
2316                                                         jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
2317                                                         switch (i)
2318                                                         {
2319                                                                 
2320                                                                 case 0:  Jj_3_1(); break;
2321                                                                 }
2322                                                 }
2323                                                 p = p.next;
2324                                         }
2325                                         while (p != null);
2326                                 }
2327                                 catch (LookaheadSuccess ls)
2328                                 {
2329                                 }
2330                         }
2331                         jj_rescan = false;
2332                 }
2333                 
2334                 private void  Jj_save(int index, int xla)
2335                 {
2336                         JJCalls p = jj_2_rtns[index];
2337                         while (p.gen > jj_gen)
2338                         {
2339                                 if (p.next == null)
2340                                 {
2341                                         p = p.next = new JJCalls(); break;
2342                                 }
2343                                 p = p.next;
2344                         }
2345                         p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
2346                 }
2347                 
2348                 internal sealed class JJCalls
2349                 {
2350                         internal int gen;
2351                         internal Token first;
2352                         internal int arg;
2353                         internal JJCalls next;
2354                 }
2355                 static QueryParser()
2356                 {
2357                         {
2358                                 Jj_la1_init_0();
2359                                 Jj_la1_init_1();
2360                         }
2361                 }
2362         }
2363 }