Lucene.Net  3.0.3
Lucene.Net is a .NET port of the Java Lucene Indexing Library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties
QueryParser.cs
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18 */
19 
20 /* Generated By:JavaCC: Do not edit this line. QueryParser.java */
21 
22 using System;
23 using System.Collections.Generic;
24 using System.Diagnostics;
25 using System.Globalization;
26 using System.IO;
27 using System.Text;
28 using Lucene.Net.Analysis;
29 using Lucene.Net.Analysis.Tokenattributes;
30 using Lucene.Net.Search;
31 using Lucene.Net.Support;
32 using Lucene.Net.Util;
33 using Analyzer = Lucene.Net.Analysis.Analyzer;
34 using CachingTokenFilter = Lucene.Net.Analysis.CachingTokenFilter;
35 using TokenStream = Lucene.Net.Analysis.TokenStream;
36 using DateField = Lucene.Net.Documents.DateField;
37 using DateTools = Lucene.Net.Documents.DateTools;
38 using Term = Lucene.Net.Index.Term;
39 using BooleanClause = Lucene.Net.Search.BooleanClause;
40 using BooleanQuery = Lucene.Net.Search.BooleanQuery;
41 using FuzzyQuery = Lucene.Net.Search.FuzzyQuery;
42 using MatchAllDocsQuery = Lucene.Net.Search.MatchAllDocsQuery;
43 using MultiPhraseQuery = Lucene.Net.Search.MultiPhraseQuery;
44 using MultiTermQuery = Lucene.Net.Search.MultiTermQuery;
45 using PhraseQuery = Lucene.Net.Search.PhraseQuery;
46 using PrefixQuery = Lucene.Net.Search.PrefixQuery;
47 using Query = Lucene.Net.Search.Query;
48 using Single = Lucene.Net.Support.Single;
49 using TermQuery = Lucene.Net.Search.TermQuery;
50 using TermRangeQuery = Lucene.Net.Search.TermRangeQuery;
51 using WildcardQuery = Lucene.Net.Search.WildcardQuery;
52 using Version = Lucene.Net.Util.Version;
53 
54 namespace Lucene.Net.QueryParsers
55 {
131  {
132 
133  private static int CONJ_NONE = 0;
134  private static int CONJ_AND = 1;
135  private static int CONJ_OR = 2;
136 
137  private static int MOD_NONE = 0;
138  private static int MOD_NOT = 10;
139  private static int MOD_REQ = 11;
140 
141  // make it possible to call setDefaultOperator() without accessing
142  // the nested class:
144  public static Operator AND_OPERATOR = Operator.AND;
145 
147  public static Operator OR_OPERATOR = Operator.OR;
148 
150  private Operator operator_Renamed = OR_OPERATOR;
151 
152  private bool lowercaseExpandedTerms = true;
153  private RewriteMethod multiTermRewriteMethod = MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT;
154  private bool allowLeadingWildcard = false;
155  private bool enablePositionIncrements = true;
156 
157  // LUCENENET-423 - DateRange differences with Java and .NET
158  private bool _useJavaStyleDateRangeParsing = false;
159 
160  private Analyzer analyzer;
161  private String field;
162  private int phraseSlop = 0;
163  private float fuzzyMinSim = FuzzyQuery.defaultMinSimilarity;
164  private int fuzzyPrefixLength = FuzzyQuery.defaultPrefixLength;
165  private System.Globalization.CultureInfo locale = System.Globalization.CultureInfo.CurrentCulture;
166 
167  // the default date resolution
168  private DateTools.Resolution dateResolution = null;
169  // maps field names to date resolutions
170  private IDictionary<String, DateTools.Resolution> fieldToDateResolution = null;
171 
172  // The collator to use when determining range inclusion,
173  // for use when constructing RangeQuerys.
174  private System.Globalization.CompareInfo rangeCollator = null;
175 
176  /* The default operator_Renamed for parsing queries.
177  * Use {@link QueryParser#setDefaultOperator} to change it.
178  */
179 
180  public enum Operator
181  {
182  OR,
183  AND
184  }
185 
186  /* Constructs a query parser.
187  * @param matchVersion Lucene version to match. See <a href="#version">above</a>)
188  * @param f the default field for query terms.
189  * @param a used to find terms in the query text.
190  */
191 
192  public QueryParser(Version matchVersion, String f, Analyzer a)
193  : this(new FastCharStream(new StringReader("")))
194  {
195  analyzer = a;
196  field = f;
197  if (matchVersion.OnOrAfter(Version.LUCENE_29))
198  {
199  enablePositionIncrements = true;
200  }
201  else
202  {
203  enablePositionIncrements = false;
204  }
205 
206  // LUCENENET-423 - DateRange differences with Java and .NET
207  if (matchVersion.OnOrAfter(Version.LUCENE_30))
208  {
209  _useJavaStyleDateRangeParsing = true;
210  }
211  }
212 
217  public virtual Query Parse(String query)
218  {
219  ReInit(new FastCharStream(new StringReader(query)));
220  try
221  {
222  // TopLevelQuery is a Query followed by the end-of-input (EOF)
223  Query res = TopLevelQuery(field);
224  return res ?? NewBooleanQuery(false);
225  }
226  catch (ParseException tme)
227  {
228  // rethrow to include the original query:
229  throw new ParseException("Cannot parse '" + query + "': " + tme.Message, tme);
230  }
231  catch (TokenMgrError tme)
232  {
233  throw new ParseException("Cannot parse '" + query + "': " + tme.Message, tme);
234  }
235  catch (BooleanQuery.TooManyClauses tmc)
236  {
237  throw new ParseException("Cannot parse '" + query + "': too many bool clauses", tmc);
238  }
239  }
240 
242  public virtual Analyzer Analyzer
243  {
244  get { return analyzer; }
245  }
246 
248  public virtual string Field
249  {
250  get { return field; }
251  }
252 
257  public virtual float FuzzyMinSim
258  {
259  get { return fuzzyMinSim; }
260  set { this.fuzzyMinSim = value; }
261  }
262 
265  public virtual int FuzzyPrefixLength
266  {
267  get { return fuzzyPrefixLength; }
268  set { this.fuzzyPrefixLength = value; }
269  }
270 
274  public virtual int PhraseSlop
275  {
276  set { this.phraseSlop = value; }
277  get { return phraseSlop; }
278  }
279 
289  public virtual bool AllowLeadingWildcard
290  {
291  set { this.allowLeadingWildcard = value; }
292  get { return allowLeadingWildcard; }
293  }
294 
304  public virtual bool EnablePositionIncrements
305  {
306  set { this.enablePositionIncrements = value; }
307  get { return enablePositionIncrements; }
308  }
309 
317  public virtual Operator DefaultOperator
318  {
319  set { this.operator_Renamed = value; }
320  get { return operator_Renamed; }
321  }
322 
326  public virtual bool LowercaseExpandedTerms
327  {
328  set { this.lowercaseExpandedTerms = value; }
329  get { return lowercaseExpandedTerms; }
330  }
331 
332 
342  public virtual RewriteMethod MultiTermRewriteMethod
343  {
344  set { multiTermRewriteMethod = value; }
345  get { return multiTermRewriteMethod; }
346  }
347 
349  public virtual CultureInfo Locale
350  {
351  set { this.locale = value; }
352  get { return locale; }
353  }
354 
362  public virtual void SetDateResolution(DateTools.Resolution dateResolution)
363  {
364  this.dateResolution = dateResolution;
365  }
366 
374  public virtual void SetDateResolution(String fieldName, DateTools.Resolution dateResolution)
375  {
376  if (fieldName == null)
377  {
378  throw new ArgumentException("Field cannot be null.");
379  }
380 
381  if (fieldToDateResolution == null)
382  {
383  // lazily initialize HashMap
384  fieldToDateResolution = new HashMap<String, DateTools.Resolution>();
385  }
386 
387  fieldToDateResolution.Add(fieldName, dateResolution);
388  }
389 
394  public virtual DateTools.Resolution getDateResolution(String fieldName)
395  {
396  if (fieldName == null)
397  {
398  throw new ArgumentException("Field cannot be null.");
399  }
400 
401  if (fieldToDateResolution == null)
402  {
403  // no field specific date resolutions set; return default date resolution instead
404  return this.dateResolution;
405  }
406 
407  DateTools.Resolution resolution = fieldToDateResolution[fieldName];
408  if (resolution == null)
409  {
410  // no date resolutions set for the given field; return default date resolution instead
411  resolution = this.dateResolution;
412  }
413 
414  return resolution;
415  }
416 
428  public virtual CompareInfo RangeCollator
429  {
430  set { rangeCollator = value; }
431  get { return rangeCollator; }
432  }
433 
434  protected internal virtual void AddClause(List<BooleanClause> clauses, int conj, int mods, Query q)
435  {
436  bool required, prohibited;
437 
438  // If this term is introduced by AND, make the preceding term required,
439  // unless it's already prohibited
440  if (clauses.Count > 0 && conj == CONJ_AND)
441  {
442  BooleanClause c = clauses[clauses.Count - 1];
443  if (!c.IsProhibited)
444  c.Occur = Occur.MUST;
445  }
446 
447  if (clauses.Count > 0 && operator_Renamed == AND_OPERATOR && conj == CONJ_OR)
448  {
449  // If this term is introduced by OR, make the preceding term optional,
450  // unless it's prohibited (that means we leave -a OR b but +a OR b-->a OR b)
451  // notice if the input is a OR b, first term is parsed as required; without
452  // this modification a OR b would parsed as +a OR b
453  BooleanClause c = clauses[clauses.Count - 1];
454  if (!c.IsProhibited)
455  c.Occur = Occur.SHOULD;
456  }
457 
458  // We might have been passed a null query; the term might have been
459  // filtered away by the analyzer.
460  if (q == null)
461  return;
462 
463  if (operator_Renamed == OR_OPERATOR)
464  {
465  // We set REQUIRED if we're introduced by AND or +; PROHIBITED if
466  // introduced by NOT or -; make sure not to set both.
467  prohibited = (mods == MOD_NOT);
468  required = (mods == MOD_REQ);
469  if (conj == CONJ_AND && !prohibited)
470  {
471  required = true;
472  }
473  }
474  else
475  {
476  // We set PROHIBITED if we're introduced by NOT or -; We set REQUIRED
477  // if not PROHIBITED and not introduced by OR
478  prohibited = (mods == MOD_NOT);
479  required = (!prohibited && conj != CONJ_OR);
480  }
481  if (required && !prohibited)
482  clauses.Add(NewBooleanClause(q, Occur.MUST));
483  else if (!required && !prohibited)
484  clauses.Add(NewBooleanClause(q, Occur.SHOULD));
485  else if (!required && prohibited)
486  clauses.Add(NewBooleanClause(q, Occur.MUST_NOT));
487  else
488  throw new SystemException("Clause cannot be both required and prohibited");
489  }
490 
491 
494  protected internal virtual Query GetFieldQuery(String field, String queryText)
495  {
496  // Use the analyzer to get all the tokens, and then build a TermQuery,
497  // PhraseQuery, or nothing based on the term count
498 
499  TokenStream source;
500  try
501  {
502  source = analyzer.ReusableTokenStream(field, new StringReader(queryText));
503  source.Reset();
504  }
505  catch (IOException)
506  {
507  source = analyzer.TokenStream(field, new StringReader(queryText));
508  }
509  CachingTokenFilter buffer = new CachingTokenFilter(source);
510  ITermAttribute termAtt = null;
511  IPositionIncrementAttribute posIncrAtt = null;
512  int numTokens = 0;
513 
514  bool success = false;
515  try
516  {
517  buffer.Reset();
518  success = true;
519  }
520  catch (IOException)
521  {
522  // success==false if we hit an exception
523  }
524  if (success)
525  {
526  if (buffer.HasAttribute<ITermAttribute>())
527  {
528  termAtt = buffer.GetAttribute<ITermAttribute>();
529  }
530  if (buffer.HasAttribute<IPositionIncrementAttribute>())
531  {
532  posIncrAtt = buffer.GetAttribute<IPositionIncrementAttribute>();
533  }
534  }
535 
536  int positionCount = 0;
537  bool severalTokensAtSamePosition = false;
538 
539  bool hasMoreTokens = false;
540  if (termAtt != null)
541  {
542  try
543  {
544  hasMoreTokens = buffer.IncrementToken();
545  while (hasMoreTokens)
546  {
547  numTokens++;
548  int positionIncrement = (posIncrAtt != null) ? posIncrAtt.PositionIncrement : 1;
549  if (positionIncrement != 0)
550  {
551  positionCount += positionIncrement;
552  }
553  else
554  {
555  severalTokensAtSamePosition = true;
556  }
557  hasMoreTokens = buffer.IncrementToken();
558  }
559  }
560  catch (IOException)
561  {
562  // ignore
563  }
564  }
565  try
566  {
567  // rewind the buffer stream
568  buffer.Reset();
569 
570  // close original stream - all tokens buffered
571  source.Close();
572  }
573  catch (IOException)
574  {
575  // ignore
576  }
577 
578  if (numTokens == 0)
579  return null;
580  else if (numTokens == 1)
581  {
582  String term = null;
583  try
584  {
585  bool hasNext = buffer.IncrementToken();
586  Debug.Assert(hasNext);
587  term = termAtt.Term;
588  }
589  catch (IOException)
590  {
591  // safe to ignore, because we know the number of tokens
592  }
593  return NewTermQuery(new Term(field, term));
594  }
595  else
596  {
597  if (severalTokensAtSamePosition)
598  {
599  if (positionCount == 1)
600  {
601  // no phrase query:
602  BooleanQuery q = NewBooleanQuery(true);
603  for (int i = 0; i < numTokens; i++)
604  {
605  String term = null;
606  try
607  {
608  bool hasNext = buffer.IncrementToken();
609  Debug.Assert(hasNext);
610  term = termAtt.Term;
611  }
612  catch (IOException)
613  {
614  // safe to ignore, because we know the number of tokens
615  }
616 
617  Query currentQuery = NewTermQuery(
618  new Term(field, term));
619  q.Add(currentQuery, Occur.SHOULD);
620  }
621  return q;
622  }
623  else
624  {
625  // phrase query:
626  MultiPhraseQuery mpq = NewMultiPhraseQuery();
627  mpq.Slop = phraseSlop;
628  List<Term> multiTerms = new List<Term>();
629  int position = -1;
630  for (int i = 0; i < numTokens; i++)
631  {
632  String term = null;
633  int positionIncrement = 1;
634  try
635  {
636  bool hasNext = buffer.IncrementToken();
637  Debug.Assert(hasNext == true);
638  term = termAtt.Term;
639  if (posIncrAtt != null)
640  {
641  positionIncrement = posIncrAtt.PositionIncrement;
642  }
643  }
644  catch (IOException)
645  {
646  // safe to ignore, because we know the number of tokens
647  }
648 
649  if (positionIncrement > 0 && multiTerms.Count > 0)
650  {
651  if (enablePositionIncrements)
652  {
653  mpq.Add(multiTerms.ToArray(), position);
654  }
655  else
656  {
657  mpq.Add(multiTerms.ToArray());
658  }
659  multiTerms.Clear();
660  }
661  position += positionIncrement;
662  multiTerms.Add(new Term(field, term));
663  }
664  if (enablePositionIncrements)
665  {
666  mpq.Add(multiTerms.ToArray(), position);
667  }
668  else
669  {
670  mpq.Add(multiTerms.ToArray());
671  }
672  return mpq;
673  }
674  }
675  else
676  {
677  PhraseQuery pq = NewPhraseQuery();
678  pq.Slop = phraseSlop;
679  int position = -1;
680 
681 
682  for (int i = 0; i < numTokens; i++)
683  {
684  String term = null;
685  int positionIncrement = 1;
686 
687  try
688  {
689  bool hasNext = buffer.IncrementToken();
690  Debug.Assert(hasNext == true);
691  term = termAtt.Term;
692  if (posIncrAtt != null)
693  {
694  positionIncrement = posIncrAtt.PositionIncrement;
695  }
696  }
697  catch (IOException)
698  {
699  // safe to ignore, because we know the number of tokens
700  }
701 
702  if (enablePositionIncrements)
703  {
704  position += positionIncrement;
705  pq.Add(new Term(field, term), position);
706  }
707  else
708  {
709  pq.Add(new Term(field, term));
710  }
711  }
712  return pq;
713  }
714  }
715  }
716 
717 
725  protected internal virtual Query GetFieldQuery(String field, String queryText, int slop)
726  {
727  Query query = GetFieldQuery(field, queryText);
728 
729  if (query is PhraseQuery)
730  {
731  ((PhraseQuery)query).Slop = slop;
732  }
733  if (query is MultiPhraseQuery)
734  {
735  ((MultiPhraseQuery)query).Slop = slop;
736  }
737 
738  return query;
739  }
740 
743  protected internal virtual Query GetRangeQuery(String field,
744  String part1,
745  String part2,
746  bool inclusive)
747  {
748  if (lowercaseExpandedTerms)
749  {
750  part1 = part1.ToLower();
751  part2 = part2.ToLower();
752  }
753 
754  try
755  {
756  DateTime d1, d2;
757  if (_useJavaStyleDateRangeParsing)
758  {
759  // TODO: This doesn't emulate java perfectly.
760  // Java allows parsing of the string up to the end of the pattern
761  // and then ignores everything else. .NET will throw an exception,
762  // so this will fail in those cases, though the code below is clear
763  // that users can only specify the date, not the time.
764  var shortFormat = locale.DateTimeFormat.ShortDatePattern;
765  d1 = DateTime.ParseExact(part1, shortFormat, locale);
766  d2 = DateTime.ParseExact(part2, shortFormat, locale);
767  }
768  else
769  {
770  d1 = DateTime.Parse(part1, locale);
771  d2 = DateTime.Parse(part2, locale);
772  }
773 
774  if (inclusive)
775  {
776  // The user can only specify the date, not the time, so make sure
777  // the time is set to the latest possible time of that date to really
778  // include all documents:
779  var cal = locale.Calendar;
780  d2 = cal.AddHours(d2, 23);
781  d2 = cal.AddMinutes(d2, 59);
782  d2 = cal.AddSeconds(d2, 59);
783  d2 = cal.AddMilliseconds(d2, 999);
784  }
785  DateTools.Resolution resolution = getDateResolution(field);
786  if (resolution == null)
787  {
788  // no default or field specific date resolution has been set,
789  // use deprecated DateField to maintain compatibility with
790  // pre-1.9 Lucene versions.
791  part1 = DateField.DateToString(d1);
792  part2 = DateField.DateToString(d2);
793  }
794  else
795  {
796  part1 = DateTools.DateToString(d1, resolution);
797  part2 = DateTools.DateToString(d2, resolution);
798  }
799  }
800  catch (Exception)
801  {
802  }
803 
804  return NewRangeQuery(field, part1, part2, inclusive);
805  }
806 
812  protected internal virtual BooleanQuery NewBooleanQuery(bool disableCoord)
813  {
814  return new BooleanQuery(disableCoord);
815  }
816 
824  protected internal virtual BooleanClause NewBooleanClause(Query q, Occur occur)
825  {
826  return new BooleanClause(q, occur);
827  }
828 
834  protected internal virtual Query NewTermQuery(Term term)
835  {
836  return new TermQuery(term);
837  }
838 
842  protected internal virtual PhraseQuery NewPhraseQuery()
843  {
844  return new PhraseQuery();
845  }
846 
850  protected internal virtual MultiPhraseQuery NewMultiPhraseQuery()
851  {
852  return new MultiPhraseQuery();
853  }
854 
860  protected internal virtual Query NewPrefixQuery(Term prefix)
861  {
862  return new PrefixQuery(prefix) { RewriteMethod = multiTermRewriteMethod };
863  }
864 
874  protected internal virtual Query NewFuzzyQuery(Term term, float minimumSimilarity, int prefixLength)
875  {
876  // FuzzyQuery doesn't yet allow constant score rewrite
877  return new FuzzyQuery(term, minimumSimilarity, prefixLength);
878  }
879 
891  protected internal virtual Query NewRangeQuery(String field, String part1, String part2, bool inclusive)
892  {
893  return new TermRangeQuery(field, part1, part2, inclusive, inclusive, rangeCollator) { RewriteMethod = multiTermRewriteMethod };
894  }
895 
899  protected internal virtual Query NewMatchAllDocsQuery()
900  {
901  return new MatchAllDocsQuery();
902  }
903 
909  protected internal virtual Query NewWildcardQuery(Term t)
910  {
911  return new WildcardQuery(t) { RewriteMethod = multiTermRewriteMethod };
912  }
913 
929  protected internal virtual Query GetBooleanQuery(IList<BooleanClause> clauses)
930  {
931  return GetBooleanQuery(clauses, false);
932  }
933 
951  protected internal virtual Query GetBooleanQuery(IList<BooleanClause> clauses, bool disableCoord)
952  {
953  if (clauses.Count == 0)
954  {
955  return null; // all clause words were filtered away by the analyzer.
956  }
957  BooleanQuery query = NewBooleanQuery(disableCoord);
958  foreach (var clause in clauses)
959  {
960  query.Add(clause);
961  }
962  return query;
963  }
964 
989  protected internal virtual Query GetWildcardQuery(String field, String termStr)
990  {
991  if ("*".Equals(field))
992  {
993  if ("*".Equals(termStr)) return NewMatchAllDocsQuery();
994  }
995  if (!allowLeadingWildcard && (termStr.StartsWith("*") || termStr.StartsWith("?")))
996  throw new ParseException("'*' or '?' not allowed as first character in WildcardQuery");
997  if (lowercaseExpandedTerms)
998  {
999  termStr = termStr.ToLower();
1000  }
1001  Term t = new Term(field, termStr);
1002  return NewWildcardQuery(t);
1003  }
1004 
1031  protected internal virtual Query GetPrefixQuery(String field, String termStr)
1032  {
1033  if (!allowLeadingWildcard && termStr.StartsWith("*"))
1034  throw new ParseException("'*' not allowed as first character in PrefixQuery");
1035  if (lowercaseExpandedTerms)
1036  {
1037  termStr = termStr.ToLower();
1038  }
1039  Term t = new Term(field, termStr);
1040  return NewPrefixQuery(t);
1041  }
1042 
1057  protected internal virtual Query GetFuzzyQuery(String field, String termStr, float minSimilarity)
1058  {
1059  if (lowercaseExpandedTerms)
1060  {
1061  termStr = termStr.ToLower();
1062  }
1063  Term t = new Term(field, termStr);
1064  return NewFuzzyQuery(t, minSimilarity, fuzzyPrefixLength);
1065  }
1066 
1067 
1075  private String DiscardEscapeChar(String input)
1076  {
1077  // Create char array to hold unescaped char sequence
1078  char[] output = new char[input.Length];
1079 
1080  // The Length of the output can be less than the input
1081  // due to discarded escape chars. This variable holds
1082  // the actual Length of the output
1083  int Length = 0;
1084 
1085  // We remember whether the last processed character was
1086  // an escape character
1087  bool lastCharWasEscapeChar = false;
1088 
1089  // The multiplier the current unicode digit must be multiplied with.
1090  // E. g. the first digit must be multiplied with 16^3, the second with 16^2...
1091  int codePointMultiplier = 0;
1092 
1093  // Used to calculate the codepoint of the escaped unicode character
1094  int codePoint = 0;
1095 
1096  for (int i = 0; i < input.Length; i++)
1097  {
1098  char curChar = input[i];
1099  if (codePointMultiplier > 0)
1100  {
1101  codePoint += HexToInt(curChar) * codePointMultiplier;
1102  codePointMultiplier = Number.URShift(codePointMultiplier, 4);
1103  if (codePointMultiplier == 0)
1104  {
1105  output[Length++] = (char)codePoint;
1106  codePoint = 0;
1107  }
1108  }
1109  else if (lastCharWasEscapeChar)
1110  {
1111  if (curChar == 'u')
1112  {
1113  // found an escaped unicode character
1114  codePointMultiplier = 16 * 16 * 16;
1115  }
1116  else
1117  {
1118  // this character was escaped
1119  output[Length] = curChar;
1120  Length++;
1121  }
1122  lastCharWasEscapeChar = false;
1123  }
1124  else
1125  {
1126  if (curChar == '\\')
1127  {
1128  lastCharWasEscapeChar = true;
1129  }
1130  else
1131  {
1132  output[Length] = curChar;
1133  Length++;
1134  }
1135  }
1136  }
1137 
1138  if (codePointMultiplier > 0)
1139  {
1140  throw new ParseException("Truncated unicode escape sequence.");
1141  }
1142 
1143  if (lastCharWasEscapeChar)
1144  {
1145  throw new ParseException("Term can not end with escape character.");
1146  }
1147 
1148  return new String(output, 0, Length);
1149  }
1150 
1152  private static int HexToInt(char c)
1153  {
1154  if ('0' <= c && c <= '9')
1155  {
1156  return c - '0';
1157  }
1158  else if ('a' <= c && c <= 'f')
1159  {
1160  return c - 'a' + 10;
1161  }
1162  else if ('A' <= c && c <= 'F')
1163  {
1164  return c - 'A' + 10;
1165  }
1166  else
1167  {
1168  throw new ParseException("None-hex character in unicode escape sequence: " + c);
1169  }
1170  }
1171 
1175  public static String Escape(String s)
1176  {
1177  StringBuilder sb = new StringBuilder();
1178  for (int i = 0; i < s.Length; i++)
1179  {
1180  char c = s[i];
1181  // These characters are part of the query syntax and must be escaped
1182  if (c == '\\' || c == '+' || c == '-' || c == '!' || c == '(' || c == ')' || c == ':'
1183  || c == '^' || c == '[' || c == ']' || c == '\"' || c == '{' || c == '}' || c == '~'
1184  || c == '*' || c == '?' || c == '|' || c == '&')
1185  {
1186  sb.Append('\\');
1187  }
1188  sb.Append(c);
1189  }
1190  return sb.ToString();
1191  }
1192 
1197  [STAThread]
1198  public static void Main(String[] args)
1199  {
1200  if (args.Length == 0)
1201  {
1202  Console.WriteLine("Usage: java org.apache.lucene.queryParser.QueryParser <input>");
1203  Environment.Exit(0);
1204  }
1205  QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, "field", new SimpleAnalyzer());
1206  Query q = qp.Parse(args[0]);
1207  Console.WriteLine(q.ToString("field"));
1208  }
1209 
1210  // * Query ::= ( Clause )*
1211  // * Clause ::= ["+", "-"] [<TermToken> ":"] ( <TermToken> | "(" Query ")" )
1212  public int Conjunction()
1213  {
1214  int ret = CONJ_NONE;
1215  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1216  {
1217  case AndToken:
1218  case OrToken:
1219  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1220  {
1221  case AndToken:
1222  Jj_consume_token(AndToken);
1223  ret = CONJ_AND;
1224  break;
1225  case OrToken:
1226  Jj_consume_token(OrToken);
1227  ret = CONJ_OR;
1228  break;
1229  default:
1230  jj_la1[0] = jj_gen;
1231  Jj_consume_token(-1);
1232  throw new ParseException();
1233  }
1234  break;
1235  default:
1236  jj_la1[1] = jj_gen;
1237  break;
1238  }
1239  {
1240  if (true) return ret;
1241  }
1242  throw new ApplicationException("Missing return statement in function");
1243  }
1244 
1245  public int Modifiers()
1246  {
1247  int ret = MOD_NONE;
1248  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1249  {
1250  case NotToken:
1251  case PlusToken:
1252  case MinusToken:
1253  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1254  {
1255  case PlusToken:
1256  Jj_consume_token(PlusToken);
1257  ret = MOD_REQ;
1258  break;
1259  case MinusToken:
1260  Jj_consume_token(MinusToken);
1261  ret = MOD_NOT;
1262  break;
1263  case NotToken:
1264  Jj_consume_token(NotToken);
1265  ret = MOD_NOT;
1266  break;
1267  default:
1268  jj_la1[2] = jj_gen;
1269  Jj_consume_token(-1);
1270  throw new ParseException();
1271  }
1272  break;
1273  default:
1274  jj_la1[3] = jj_gen;
1275  break;
1276  }
1277  {
1278  if (true) return ret;
1279  }
1280  throw new Exception("Missing return statement in function");
1281  }
1282 
1283  // This makes sure that there is no garbage after the query string
1284  public Query TopLevelQuery(String field)
1285  {
1286  Query q;
1287  q = Query(field);
1288  Jj_consume_token(0);
1289  {
1290  if (true) return q;
1291  }
1292  throw new Exception("Missing return statement in function");
1293  }
1294 
1295  public Query Query(String field)
1296  {
1297  List<BooleanClause> clauses = new List<BooleanClause>();
1298  Query q, firstQuery = null;
1299  int conj, mods;
1300  mods = Modifiers();
1301  q = Clause(field);
1302  AddClause(clauses, CONJ_NONE, mods, q);
1303  if (mods == MOD_NONE)
1304  firstQuery = q;
1305  while (true)
1306  {
1307  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1308  {
1309  case AndToken:
1310  case OrToken:
1311  case NotToken:
1312  case PlusToken:
1313  case MinusToken:
1314  case LParanToken:
1315  case StarToken:
1316  case QuotedToken:
1317  case TermToken:
1318  case PrefixTermToken:
1319  case WildTermToken:
1320  case RangeInStartToken:
1321  case RangeExStartToken:
1322  case NumberToken:
1323  break;
1324  default:
1325  jj_la1[4] = jj_gen;
1326  goto label_1;
1327  }
1328 
1329  conj = Conjunction();
1330  mods = Modifiers();
1331  q = Clause(field);
1332  AddClause(clauses, conj, mods, q);
1333  }
1334 
1335  label_1:
1336 
1337  if (clauses.Count == 1 && firstQuery != null)
1338  {
1339  if (true) return firstQuery;
1340  }
1341 
1342  return GetBooleanQuery(clauses);
1343  }
1344 
1345  public Query Clause(String field)
1346  {
1347  Query q;
1348  Token fieldToken = null, boost = null;
1349  if (Jj_2_1(2))
1350  {
1351  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1352  {
1353  case TermToken:
1354  fieldToken = Jj_consume_token(TermToken);
1355  Jj_consume_token(ColonToken);
1356  field = DiscardEscapeChar(fieldToken.image);
1357  break;
1358  case StarToken:
1359  Jj_consume_token(StarToken);
1360  Jj_consume_token(ColonToken);
1361  field = "*";
1362  break;
1363  default:
1364  jj_la1[5] = jj_gen;
1365  Jj_consume_token(-1);
1366  throw new ParseException();
1367  }
1368  }
1369  else
1370  {
1371  ;
1372  }
1373  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1374  {
1375  case StarToken:
1376  case QuotedToken:
1377  case TermToken:
1378  case PrefixTermToken:
1379  case WildTermToken:
1380  case RangeInStartToken:
1381  case RangeExStartToken:
1382  case NumberToken:
1383  q = Term(field);
1384  break;
1385  case LParanToken:
1386  Jj_consume_token(LParanToken);
1387  q = Query(field);
1388  Jj_consume_token(RParenToken);
1389  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1390  {
1391  case CaratToken:
1392  Jj_consume_token(CaratToken);
1393  boost = Jj_consume_token(NumberToken);
1394  break;
1395  default:
1396  jj_la1[6] = jj_gen;
1397  break;
1398  }
1399  break;
1400  default:
1401  jj_la1[7] = jj_gen;
1402  Jj_consume_token(-1);
1403  throw new ParseException();
1404  }
1405  if (boost != null)
1406  {
1407  try
1408  {
1409  float f = Single.Parse(boost.image);
1410  q.Boost = f;
1411  }
1412  catch (Exception)
1413  {
1414  }
1415  }
1416  {
1417  if (true) return q;
1418  }
1419  throw new Exception("Missing return statement in function");
1420  }
1421 
1422  public Query Term(String field)
1423  {
1424  Token term, boost = null, fuzzySlop = null, goop1, goop2;
1425  bool prefix = false;
1426  bool wildcard = false;
1427  bool fuzzy = false;
1428  Query q;
1429  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1430  {
1431  case StarToken:
1432  case TermToken:
1433  case PrefixTermToken:
1434  case WildTermToken:
1435  case NumberToken:
1436  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1437  {
1438  case TermToken:
1439  term = Jj_consume_token(TermToken);
1440  break;
1441  case StarToken:
1442  term = Jj_consume_token(StarToken);
1443  wildcard = true;
1444  break;
1445  case PrefixTermToken:
1446  term = Jj_consume_token(PrefixTermToken);
1447  prefix = true;
1448  break;
1449  case WildTermToken:
1450  term = Jj_consume_token(WildTermToken);
1451  wildcard = true;
1452  break;
1453  case NumberToken:
1454  term = Jj_consume_token(NumberToken);
1455  break;
1456  default:
1457  jj_la1[8] = jj_gen;
1458  Jj_consume_token(-1);
1459  throw new ParseException();
1460  }
1461  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1462  {
1463  case FuzzySlopToken:
1464  fuzzySlop = Jj_consume_token(FuzzySlopToken);
1465  fuzzy = true;
1466  break;
1467  default:
1468  jj_la1[9] = jj_gen;
1469  break;
1470  }
1471  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1472  {
1473  case CaratToken:
1474  Jj_consume_token(CaratToken);
1475  boost = Jj_consume_token(NumberToken);
1476  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1477  {
1478  case FuzzySlopToken:
1479  fuzzySlop = Jj_consume_token(FuzzySlopToken);
1480  fuzzy = true;
1481  break;
1482  default:
1483  jj_la1[10] = jj_gen;
1484  break;
1485  }
1486  break;
1487  default:
1488  jj_la1[11] = jj_gen;
1489  break;
1490  }
1491  String termImage = DiscardEscapeChar(term.image);
1492  if (wildcard)
1493  {
1494  q = GetWildcardQuery(field, termImage);
1495  }
1496  else if (prefix)
1497  {
1498  q = GetPrefixQuery(field,
1499  DiscardEscapeChar(term.image.Substring(0, (term.image.Length - 1) - (0))));
1500  }
1501  else if (fuzzy)
1502  {
1503  float fms = fuzzyMinSim;
1504  try
1505  {
1506  fms = Single.Parse(fuzzySlop.image.Substring(1));
1507  }
1508  catch (Exception)
1509  {
1510  }
1511  if (fms < 0.0f || fms > 1.0f)
1512  {
1513  {
1514  if (true)
1515  throw new ParseException(
1516  "Minimum similarity for a FuzzyQuery has to be between 0.0f and 1.0f !");
1517  }
1518  }
1519  q = GetFuzzyQuery(field, termImage, fms);
1520  }
1521  else
1522  {
1523  q = GetFieldQuery(field, termImage);
1524  }
1525  break;
1526  case RangeInStartToken:
1527  Jj_consume_token(RangeInStartToken);
1528  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1529  {
1530  case RangeInGoopToken:
1531  goop1 = Jj_consume_token(RangeInGoopToken);
1532  break;
1533  case RangeInQuotedToken:
1534  goop1 = Jj_consume_token(RangeInQuotedToken);
1535  break;
1536  default:
1537  jj_la1[12] = jj_gen;
1538  Jj_consume_token(-1);
1539  throw new ParseException();
1540  }
1541  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1542  {
1543  case RangeInToToken:
1544  Jj_consume_token(RangeInToToken);
1545  break;
1546  default:
1547  jj_la1[13] = jj_gen;
1548  break;
1549  }
1550  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1551  {
1552  case RangeInGoopToken:
1553  goop2 = Jj_consume_token(RangeInGoopToken);
1554  break;
1555  case RangeInQuotedToken:
1556  goop2 = Jj_consume_token(RangeInQuotedToken);
1557  break;
1558  default:
1559  jj_la1[14] = jj_gen;
1560  Jj_consume_token(-1);
1561  throw new ParseException();
1562  }
1563  Jj_consume_token(RangeInEndToken);
1564  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1565  {
1566  case CaratToken:
1567  Jj_consume_token(CaratToken);
1568  boost = Jj_consume_token(NumberToken);
1569  break;
1570  default:
1571  jj_la1[15] = jj_gen;
1572  break;
1573  }
1574  if (goop1.kind == RangeInQuotedToken)
1575  {
1576  goop1.image = goop1.image.Substring(1, (goop1.image.Length - 1) - (1));
1577  }
1578  if (goop2.kind == RangeInQuotedToken)
1579  {
1580  goop2.image = goop2.image.Substring(1, (goop2.image.Length - 1) - (1));
1581  }
1582  q = GetRangeQuery(field, DiscardEscapeChar(goop1.image), DiscardEscapeChar(goop2.image), true);
1583  break;
1584  case RangeExStartToken:
1585  Jj_consume_token(RangeExStartToken);
1586  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1587  {
1588  case RangeExGoopToken:
1589  goop1 = Jj_consume_token(RangeExGoopToken);
1590  break;
1591  case RangeExQuotedToken:
1592  goop1 = Jj_consume_token(RangeExQuotedToken);
1593  break;
1594  default:
1595  jj_la1[16] = jj_gen;
1596  Jj_consume_token(-1);
1597  throw new ParseException();
1598  }
1599  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1600  {
1601  case RangeExToToken:
1602  Jj_consume_token(RangeExToToken);
1603  break;
1604  default:
1605  jj_la1[17] = jj_gen;
1606  break;
1607  }
1608  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1609  {
1610  case RangeExGoopToken:
1611  goop2 = Jj_consume_token(RangeExGoopToken);
1612  break;
1613  case RangeExQuotedToken:
1614  goop2 = Jj_consume_token(RangeExQuotedToken);
1615  break;
1616  default:
1617  jj_la1[18] = jj_gen;
1618  Jj_consume_token(-1);
1619  throw new ParseException();
1620  }
1621  Jj_consume_token(RangeExEndToken);
1622  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1623  {
1624  case CaratToken:
1625  Jj_consume_token(CaratToken);
1626  boost = Jj_consume_token(NumberToken);
1627  break;
1628  default:
1629  jj_la1[19] = jj_gen;
1630  break;
1631  }
1632  if (goop1.kind == RangeExQuotedToken)
1633  {
1634  goop1.image = goop1.image.Substring(1, (goop1.image.Length - 1) - (1));
1635  }
1636  if (goop2.kind == RangeExQuotedToken)
1637  {
1638  goop2.image = goop2.image.Substring(1, (goop2.image.Length - 1) - (1));
1639  }
1640 
1641  q = GetRangeQuery(field, DiscardEscapeChar(goop1.image), DiscardEscapeChar(goop2.image), false);
1642  break;
1643  case QuotedToken:
1644  term = Jj_consume_token(QuotedToken);
1645  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1646  {
1647  case FuzzySlopToken:
1648  fuzzySlop = Jj_consume_token(FuzzySlopToken);
1649  break;
1650  default:
1651  jj_la1[20] = jj_gen;
1652  break;
1653  }
1654  switch ((jj_ntk == -1) ? Jj_ntk() : jj_ntk)
1655  {
1656  case CaratToken:
1657  Jj_consume_token(CaratToken);
1658  boost = Jj_consume_token(NumberToken);
1659  break;
1660  default:
1661  jj_la1[21] = jj_gen;
1662  break;
1663  }
1664  int s = phraseSlop;
1665 
1666  if (fuzzySlop != null)
1667  {
1668  try
1669  {
1670  s = (int)Single.Parse(fuzzySlop.image.Substring(1));
1671  }
1672  catch (Exception)
1673  {
1674  }
1675  }
1676  q = GetFieldQuery(field, DiscardEscapeChar(term.image.Substring(1, (term.image.Length - 1) - (1))),
1677  s);
1678  break;
1679  default:
1680  jj_la1[22] = jj_gen;
1681  Jj_consume_token(-1);
1682  throw new ParseException();
1683  }
1684  if (boost != null)
1685  {
1686  float f = (float)1.0;
1687  try
1688  {
1689  f = Single.Parse(boost.image);
1690  }
1691  catch (Exception)
1692  {
1693  /* Should this be handled somehow? (defaults to "no boost", if
1694  * boost number is invalid)
1695  */
1696  }
1697 
1698  // avoid boosting null queries, such as those caused by stop words
1699  if (q != null)
1700  {
1701  q.Boost = f;
1702  }
1703  }
1704  {
1705  if (true) return q;
1706  }
1707  throw new Exception("Missing return statement in function");
1708  }
1709 
1710  private bool Jj_2_1(int xla)
1711  {
1712  jj_la = xla;
1713  jj_lastpos = jj_scanpos = token;
1714  try
1715  {
1716  return !Jj_3_1();
1717  }
1718  catch (LookaheadSuccess)
1719  {
1720  return true;
1721  }
1722  finally
1723  {
1724  Jj_save(0, xla);
1725  }
1726  }
1727 
1728  private bool Jj_3R_2()
1729  {
1730  if (jj_scan_token(TermToken)) return true;
1731  if (jj_scan_token(ColonToken)) return true;
1732  return false;
1733  }
1734 
1735  private bool Jj_3_1()
1736  {
1737  Token xsp;
1738  xsp = jj_scanpos;
1739  if (Jj_3R_2())
1740  {
1741  jj_scanpos = xsp;
1742  if (Jj_3R_3()) return true;
1743  }
1744  return false;
1745  }
1746 
1747  private bool Jj_3R_3()
1748  {
1749  if (jj_scan_token(StarToken)) return true;
1750  if (jj_scan_token(ColonToken)) return true;
1751  return false;
1752  }
1753 
1754  /* Generated Token Manager. */
1756  /* Current token. */
1757  public Token token;
1758  /* Next token. */
1759  public Token jj_nt;
1760  private int jj_ntk;
1761  private Token jj_scanpos, jj_lastpos;
1762  private int jj_la;
1763  private int jj_gen;
1764  private int[] jj_la1 = new int[23];
1765  private static int[] jj_la1_0;
1766  private static int[] jj_la1_1;
1767 
1768  private static void Jj_la1_init_0()
1769  {
1770  jj_la1_0 = new int[]
1771  {
1772  0x300, 0x300, 0x1c00, 0x1c00, 0x3ed3f00, 0x90000, 0x20000, 0x3ed2000, 0x2690000, 0x100000,
1773  0x100000, 0x20000, 0x30000000, 0x4000000, 0x30000000, 0x20000, 0x0, 0x40000000, 0x0, 0x20000
1774  , 0x100000, 0x20000, 0x3ed0000,
1775  };
1776  }
1777 
1778  private static void Jj_la1_init_1()
1779  {
1780  jj_la1_1 = new int[]
1781  {
1782  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0,
1783  0x3, 0x0, 0x0, 0x0, 0x0,
1784  };
1785  }
1786 
1787  private JJCalls[] jj_2_rtns = new JJCalls[1];
1788  private bool jj_rescan = false;
1789  private int jj_gc = 0;
1790 
1792  protected internal QueryParser(ICharStream stream)
1793  {
1794  token_source = new QueryParserTokenManager(stream);
1795  token = new Token();
1796  jj_ntk = -1;
1797  jj_gen = 0;
1798  for (int i = 0; i < 23; i++) jj_la1[i] = -1;
1799  for (int i = 0; i < jj_2_rtns.Length; i++) jj_2_rtns[i] = new JJCalls();
1800  }
1801 
1803  public void ReInit(ICharStream stream)
1804  {
1805  token_source.ReInit(stream);
1806  token = new Token();
1807  jj_ntk = -1;
1808  jj_gen = 0;
1809  for (int i = 0; i < 23; i++) jj_la1[i] = -1;
1810  for (int i = 0; i < jj_2_rtns.Length; i++) jj_2_rtns[i] = new JJCalls();
1811  }
1812 
1815  {
1816  token_source = tm;
1817  token = new Token();
1818  jj_ntk = -1;
1819  jj_gen = 0;
1820  for (int i = 0; i < 23; i++) jj_la1[i] = -1;
1821  for (int i = 0; i < jj_2_rtns.Length; i++) jj_2_rtns[i] = new JJCalls();
1822  }
1823 
1825  public void ReInit(QueryParserTokenManager tm)
1826  {
1827  token_source = tm;
1828  token = new Token();
1829  jj_ntk = -1;
1830  jj_gen = 0;
1831  for (int i = 0; i < 23; i++) jj_la1[i] = -1;
1832  for (int i = 0; i < jj_2_rtns.Length; i++) jj_2_rtns[i] = new JJCalls();
1833  }
1834 
1835  private Token Jj_consume_token(int kind)
1836  {
1837  Token oldToken;
1838  if ((oldToken = token).next != null) token = token.next;
1839  else token = token.next = token_source.GetNextToken();
1840  jj_ntk = -1;
1841  if (token.kind == kind)
1842  {
1843  jj_gen++;
1844  if (++jj_gc > 100)
1845  {
1846  jj_gc = 0;
1847  for (int i = 0; i < jj_2_rtns.Length; i++)
1848  {
1849  JJCalls c = jj_2_rtns[i];
1850  while (c != null)
1851  {
1852  if (c.gen < jj_gen) c.first = null;
1853  c = c.next;
1854  }
1855  }
1856  }
1857  return token;
1858  }
1859  token = oldToken;
1860  jj_kind = kind;
1861  throw GenerateParseException();
1862  }
1863 
1864  [Serializable]
1865  private sealed class LookaheadSuccess : System.Exception
1866  {
1867  }
1868 
1869  private LookaheadSuccess jj_ls = new LookaheadSuccess();
1870  private bool jj_scan_token(int kind)
1871  {
1872  if (jj_scanpos == jj_lastpos)
1873  {
1874  jj_la--;
1875  if (jj_scanpos.next == null)
1876  {
1877  jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.GetNextToken();
1878  }
1879  else
1880  {
1881  jj_lastpos = jj_scanpos = jj_scanpos.next;
1882  }
1883  }
1884  else
1885  {
1886  jj_scanpos = jj_scanpos.next;
1887  }
1888  if (jj_rescan)
1889  {
1890  int i = 0;
1891  Token tok = token;
1892  while (tok != null && tok != jj_scanpos)
1893  {
1894  i++;
1895  tok = tok.next;
1896  }
1897  if (tok != null) Jj_add_error_token(kind, i);
1898  }
1899  if (jj_scanpos.kind != kind) return true;
1900  if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
1901  return false;
1902  }
1903 
1905  public Token GetNextToken()
1906  {
1907  if (token.next != null) token = token.next;
1908  else token = token.next = token_source.GetNextToken();
1909  jj_ntk = -1;
1910  jj_gen++;
1911  return token;
1912  }
1913 
1915  public Token getToken(int index)
1916  {
1917  Token t = token;
1918  for (int i = 0; i < index; i++)
1919  {
1920  if (t.next != null) t = t.next;
1921  else t = t.next = token_source.GetNextToken();
1922  }
1923  return t;
1924  }
1925 
1926  private int Jj_ntk()
1927  {
1928  if ((jj_nt = token.next) == null)
1929  return (jj_ntk = (token.next = token_source.GetNextToken()).kind);
1930  else
1931  return (jj_ntk = jj_nt.kind);
1932  }
1933 
1934  private List<int[]> jj_expentries = new List<int[]>();
1935  private int[] jj_expentry;
1936  private int jj_kind = -1;
1937  private int[] jj_lasttokens = new int[100];
1938  private int jj_endpos;
1939 
1940  private void Jj_add_error_token(int kind, int pos)
1941  {
1942  if (pos >= 100) return;
1943  if (pos == jj_endpos + 1)
1944  {
1945  jj_lasttokens[jj_endpos++] = kind;
1946  }
1947  else if (jj_endpos != 0)
1948  {
1949  jj_expentry = new int[jj_endpos];
1950  for (int i = 0; i < jj_endpos; i++)
1951  {
1952  jj_expentry[i] = jj_lasttokens[i];
1953  }
1954 
1955  foreach (var oldentry in jj_expentries)
1956  {
1957  if (oldentry.Length == jj_expentry.Length)
1958  {
1959  for (int i = 0; i < jj_expentry.Length; i++)
1960  {
1961  if (oldentry[i] != jj_expentry[i])
1962  {
1963  continue;
1964  }
1965  }
1966  jj_expentries.Add(jj_expentry);
1967  break;
1968  }
1969  }
1970  if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
1971  }
1972  }
1973 
1975  public virtual ParseException GenerateParseException()
1976  {
1977  jj_expentries.Clear();
1978  bool[] la1tokens = new bool[34];
1979  if (jj_kind >= 0)
1980  {
1981  la1tokens[jj_kind] = true;
1982  jj_kind = -1;
1983  }
1984  for (int i = 0; i < 23; i++)
1985  {
1986  if (jj_la1[i] == jj_gen)
1987  {
1988  for (int j = 0; j < 32; j++)
1989  {
1990  if ((jj_la1_0[i] & (1 << j)) != 0)
1991  {
1992  la1tokens[j] = true;
1993  }
1994  if ((jj_la1_1[i] & (1 << j)) != 0)
1995  {
1996  la1tokens[32 + j] = true;
1997  }
1998  }
1999  }
2000  }
2001  for (int i = 0; i < 34; i++)
2002  {
2003  if (la1tokens[i])
2004  {
2005  jj_expentry = new int[1];
2006  jj_expentry[0] = i;
2007  jj_expentries.Add(jj_expentry);
2008  }
2009  }
2010  jj_endpos = 0;
2011  Jj_rescan_token();
2012  Jj_add_error_token(0, 0);
2013  int[][] exptokseq = new int[jj_expentries.Count][];
2014  for (int i = 0; i < jj_expentries.Count; i++)
2015  {
2016  exptokseq[i] = jj_expentries[i];
2017  }
2018  return new ParseException(token, exptokseq, tokenImage);
2019  }
2020 
2022  public void Enable_tracing()
2023  {
2024  }
2025 
2027  public void Disable_tracing()
2028  {
2029  }
2030 
2031  private void Jj_rescan_token()
2032  {
2033  jj_rescan = true;
2034  for (int i = 0; i < 1; i++)
2035  {
2036  try
2037  {
2038  JJCalls p = jj_2_rtns[i];
2039  do
2040  {
2041  if (p.gen > jj_gen)
2042  {
2043  jj_la = p.arg;
2044  jj_lastpos = jj_scanpos = p.first;
2045  switch (i)
2046  {
2047  case 0:
2048  Jj_3_1();
2049  break;
2050  }
2051  }
2052  p = p.next;
2053  } while (p != null);
2054  }
2055  catch (LookaheadSuccess)
2056  {
2057  }
2058  }
2059  jj_rescan = false;
2060  }
2061 
2062  private void Jj_save(int index, int xla)
2063  {
2064  JJCalls p = jj_2_rtns[index];
2065  while (p.gen > jj_gen)
2066  {
2067  if (p.next == null)
2068  {
2069  p = p.next = new JJCalls();
2070  break;
2071  }
2072  p = p.next;
2073  }
2074  p.gen = jj_gen + xla - jj_la;
2075  p.first = token;
2076  p.arg = xla;
2077  }
2078 
2079  internal sealed class JJCalls
2080  {
2081  internal int gen;
2082  internal Token first;
2083  internal int arg;
2084  internal JJCalls next;
2085  }
2086 
2087  static QueryParser()
2088  {
2089  {
2090  Jj_la1_init_0();
2091  Jj_la1_init_1();
2092  }
2093  }
2094  }
2095 }