/* | |
* Licensed to the Apache Software Foundation (ASF) under one or more | |
* contributor license agreements. See the NOTICE file distributed with | |
* this work for additional information regarding copyright ownership. | |
* The ASF licenses this file to You under the Apache License, Version 2.0 | |
* (the "License"); you may not use this file except in compliance with | |
* the License. You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
/* Generated By:JavaCC: Do not edit this line. QueryParser.java */ | |
using System; | |
using Lucene.Net.Documents; | |
using Term = Lucene.Net.Index.Term; | |
using Parameter = Lucene.Net.Util.Parameter; | |
using Lucene.Net.Analysis; | |
using Lucene.Net.Search; | |
using Searchable = Lucene.Net.Search.Searchable; | |
namespace Lucene.Net.QueryParsers | |
{ | |
/// <summary> This class is generated by JavaCC. The most important method is | |
/// {@link #Parse(String)}. | |
/// | |
/// The syntax for query strings is as follows: | |
/// A Query is a series of clauses. | |
/// A clause may be prefixed by: | |
/// <ul> | |
/// <li> a plus (<code>+</code>) or a minus (<code>-</code>) sign, indicating | |
/// that the clause is required or prohibited respectively; or | |
/// <li> a term followed by a colon, indicating the field to be searched. | |
/// This enables one to construct queries which search multiple fields. | |
/// </ul> | |
/// | |
/// A clause may be either: | |
/// <ul> | |
/// <li> a term, indicating all the documents that contain this term; or | |
/// <li> a nested query, enclosed in parentheses. Note that this may be used | |
/// with a <code>+</code>/<code>-</code> prefix to require any of a set of | |
/// terms. | |
/// </ul> | |
/// | |
/// Thus, in BNF, the query grammar is: | |
/// <pre> | |
/// Query ::= ( Clause )* | |
/// Clause ::= ["+", "-"] [<TERM> ":"] ( <TERM> | "(" Query ")" ) | |
/// </pre> | |
/// | |
/// <p> | |
/// Examples of appropriately formatted queries can be found in the <a | |
/// href="http://lucene.apache.org/java/docs/queryparsersyntax.html">query syntax | |
/// documentation</a>. | |
/// </p> | |
/// | |
/// <p> | |
/// In {@link RangeQuery}s, QueryParser tries to detect date values, e.g. | |
/// <tt>date:[6/1/2005 TO 6/4/2005]</tt> produces a range query that searches | |
/// for "date" fields between 2005-06-01 and 2005-06-04. Note that the format | |
/// of the accepted input depends on {@link #SetLocale(Locale) the locale}. | |
/// By default a date is converted into a search term using the deprecated | |
/// {@link DateField} for compatibility reasons. | |
/// To use the new {@link DateTools} to convert dates, a | |
/// {@link Lucene.Net.Documents.DateTools.Resolution} has to be set. | |
/// </p> | |
/// <p> | |
/// The date resolution that shall be used for RangeQueries can be set | |
/// using {@link #SetDateResolution(DateTools.Resolution)} | |
/// or {@link #SetDateResolution(String, DateTools.Resolution)}. The former | |
/// sets the default date resolution for all fields, whereas the latter can | |
/// be used to set field specific date resolutions. Field specific date | |
/// resolutions take, if set, precedence over the default date resolution. | |
/// </p> | |
/// <p> | |
/// If you use neither {@link DateField} nor {@link DateTools} in your | |
/// index, you can create your own | |
/// query parser that inherits QueryParser and overwrites | |
/// {@link #GetRangeQuery(String, String, String, boolean)} to | |
/// use a different method for date conversion. | |
/// </p> | |
/// | |
/// <p>Note that QueryParser is <em>not</em> thread-safe.</p> | |
/// | |
/// </summary> | |
/// <author> Brian Goetz | |
/// </author> | |
/// <author> Peter Halacsy | |
/// </author> | |
/// <author> Tatu Saloranta | |
/// </author> | |
public class QueryParser : QueryParserConstants | |
{ | |
private void InitBlock() | |
{ | |
fuzzyMinSim = FuzzyQuery.defaultMinSimilarity; | |
fuzzyPrefixLength = FuzzyQuery.defaultPrefixLength; | |
jj_2_rtns = new JJCalls[1]; | |
jj_ls = new LookaheadSuccess(); | |
} | |
private const int CONJ_NONE = 0; | |
private const int CONJ_AND = 1; | |
private const int CONJ_OR = 2; | |
private const int MOD_NONE = 0; | |
private const int MOD_NOT = 10; | |
private const int MOD_REQ = 11; | |
// make it possible to call setDefaultOperator() without accessing | |
// the nested class: | |
/// <summary>Alternative form of QueryParser.Operator.AND </summary> | |
public static readonly Operator AND_OPERATOR = Operator.AND; | |
/// <summary>Alternative form of QueryParser.Operator.OR </summary> | |
public static readonly Operator OR_OPERATOR = Operator.OR; | |
/// <summary>The actual operator that parser uses to combine query terms </summary> | |
private Operator operator_Renamed = OR_OPERATOR; | |
internal bool lowercaseExpandedTerms = true; | |
internal bool useOldRangeQuery = false; | |
internal bool allowLeadingWildcard = false; | |
internal bool enablePositionIncrements = false; | |
internal Analyzer analyzer; | |
internal System.String field; | |
internal int phraseSlop = 0; | |
internal float fuzzyMinSim; | |
internal int fuzzyPrefixLength; | |
internal System.Globalization.CultureInfo locale = System.Threading.Thread.CurrentThread.CurrentCulture; | |
// the default date resolution | |
internal DateTools.Resolution dateResolution = null; | |
// maps field names to date resolutions | |
internal System.Collections.IDictionary fieldToDateResolution = null; | |
/// <summary>The default operator for parsing queries. | |
/// Use {@link QueryParser#setDefaultOperator} to change it. | |
/// </summary> | |
[Serializable] | |
public sealed class Operator : Parameter | |
{ | |
internal Operator(System.String name) : base(name) | |
{ | |
} | |
public static readonly Operator OR = new Operator("OR"); | |
public static readonly Operator AND = new Operator("AND"); | |
} | |
/// <summary>Constructs a query parser.</summary> | |
/// <param name="f"> the default field for query terms. | |
/// </param> | |
/// <param name="a"> used to find terms in the query text. | |
/// </param> | |
public QueryParser(System.String f, Analyzer a) : this(new FastCharStream(new System.IO.StringReader(""))) | |
{ | |
analyzer = a; | |
field = f; | |
} | |
/// <summary>Parses a query string, returning a {@link Lucene.Net.Search.Query}.</summary> | |
/// <param name="query"> the query string to be parsed. | |
/// </param> | |
/// <throws> ParseException if the parsing fails </throws> | |
public virtual Query Parse(System.String query) | |
{ | |
ReInit(new FastCharStream(new System.IO.StringReader(query))); | |
try | |
{ | |
// TopLevelQuery is a Query followed by the end-of-input (EOF) | |
Query res = TopLevelQuery(field); | |
return res != null ? res : new BooleanQuery(); | |
} | |
catch (ParseException tme) | |
{ | |
// rethrow to include the original query: | |
throw new ParseException("Cannot parse '" + query + "': " + tme.Message); | |
} | |
catch (TokenMgrError tme) | |
{ | |
throw new ParseException("Cannot parse '" + query + "': " + tme.Message); | |
} | |
catch (BooleanQuery.TooManyClauses tmc) | |
{ | |
throw new ParseException("Cannot parse '" + query + "': too many boolean clauses"); | |
} | |
} | |
/// <returns> Returns the analyzer. | |
/// </returns> | |
public virtual Analyzer GetAnalyzer() | |
{ | |
return analyzer; | |
} | |
/// <returns> Returns the field. | |
/// </returns> | |
public virtual System.String GetField() | |
{ | |
return field; | |
} | |
/// <summary> Get the minimal similarity for fuzzy queries.</summary> | |
public virtual float GetFuzzyMinSim() | |
{ | |
return fuzzyMinSim; | |
} | |
/// <summary> Set the minimum similarity for fuzzy queries. | |
/// Default is 0.5f. | |
/// </summary> | |
public virtual void SetFuzzyMinSim(float fuzzyMinSim) | |
{ | |
this.fuzzyMinSim = fuzzyMinSim; | |
} | |
/// <summary> Get the prefix length for fuzzy queries. </summary> | |
/// <returns> Returns the fuzzyPrefixLength. | |
/// </returns> | |
public virtual int GetFuzzyPrefixLength() | |
{ | |
return fuzzyPrefixLength; | |
} | |
/// <summary> Set the prefix length for fuzzy queries. Default is 0.</summary> | |
/// <param name="fuzzyPrefixLength">The fuzzyPrefixLength to set. | |
/// </param> | |
public virtual void SetFuzzyPrefixLength(int fuzzyPrefixLength) | |
{ | |
this.fuzzyPrefixLength = fuzzyPrefixLength; | |
} | |
/// <summary> Sets the default slop for phrases. If zero, then exact phrase matches | |
/// are required. Default value is zero. | |
/// </summary> | |
public virtual void SetPhraseSlop(int phraseSlop) | |
{ | |
this.phraseSlop = phraseSlop; | |
} | |
/// <summary> Gets the default slop for phrases.</summary> | |
public virtual int GetPhraseSlop() | |
{ | |
return phraseSlop; | |
} | |
/// <summary> Set to <code>true</code> to allow leading wildcard characters. | |
/// <p> | |
/// When set, <code>*</code> or <code>?</code> are allowed as | |
/// the first character of a PrefixQuery and WildcardQuery. | |
/// Note that this can produce very slow | |
/// queries on big indexes. | |
/// <p> | |
/// Default: false. | |
/// </summary> | |
public virtual void SetAllowLeadingWildcard(bool allowLeadingWildcard) | |
{ | |
this.allowLeadingWildcard = allowLeadingWildcard; | |
} | |
/// <seealso cref="SetAllowLeadingWildcard(boolean)"> | |
/// </seealso> | |
public virtual bool GetAllowLeadingWildcard() | |
{ | |
return allowLeadingWildcard; | |
} | |
/// <summary> Set to <code>true</code> to enable position increments in result query. | |
/// <p> | |
/// When set, result phrase and multi-phrase queries will | |
/// be aware of position increments. | |
/// Useful when e.g. a StopFilter increases the position increment of | |
/// the token that follows an omitted token. | |
/// <p> | |
/// Default: false. | |
/// </summary> | |
public virtual void SetEnablePositionIncrements(bool enable) | |
{ | |
this.enablePositionIncrements = enable; | |
} | |
/// <seealso cref="SetEnablePositionIncrements(boolean)"> | |
/// </seealso> | |
public virtual bool GetEnablePositionIncrements() | |
{ | |
return enablePositionIncrements; | |
} | |
/// <summary> Sets the boolean operator of the QueryParser. | |
/// In default mode (<code>OR_OPERATOR</code>) terms without any modifiers | |
/// are considered optional: for example <code>capital of Hungary</code> is equal to | |
/// <code>capital OR of OR Hungary</code>.<br/> | |
/// In <code>AND_OPERATOR</code> mode terms are considered to be in conjuction: the | |
/// above mentioned query is parsed as <code>capital AND of AND Hungary</code> | |
/// </summary> | |
public virtual void SetDefaultOperator(Operator op) | |
{ | |
this.operator_Renamed = op; | |
} | |
/// <summary> Gets implicit operator setting, which will be either AND_OPERATOR | |
/// or OR_OPERATOR. | |
/// </summary> | |
public virtual Operator GetDefaultOperator() | |
{ | |
return operator_Renamed; | |
} | |
/// <summary> Whether terms of wildcard, prefix, fuzzy and range queries are to be automatically | |
/// lower-cased or not. Default is <code>true</code>. | |
/// </summary> | |
public virtual void SetLowercaseExpandedTerms(bool lowercaseExpandedTerms) | |
{ | |
this.lowercaseExpandedTerms = lowercaseExpandedTerms; | |
} | |
/// <seealso cref="#SetLowercaseExpandedTerms(boolean)"> | |
/// </seealso> | |
public virtual bool GetLowercaseExpandedTerms() | |
{ | |
return lowercaseExpandedTerms; | |
} | |
/// <summary> By default QueryParser uses new ConstantScoreRangeQuery in preference to RangeQuery | |
/// for range queries. This implementation is generally preferable because it | |
/// a) Runs faster b) Does not have the scarcity of range terms unduly influence score | |
/// c) avoids any "TooManyBooleanClauses" exception. | |
/// However, if your application really needs to use the old-fashioned RangeQuery and the above | |
/// points are not required then set this option to <code>true</code> | |
/// Default is <code>false</code>. | |
/// </summary> | |
public virtual void SetUseOldRangeQuery(bool useOldRangeQuery) | |
{ | |
this.useOldRangeQuery = useOldRangeQuery; | |
} | |
/// <seealso cref="SetUseOldRangeQuery(boolean)"> | |
/// </seealso> | |
public virtual bool GetUseOldRangeQuery() | |
{ | |
return useOldRangeQuery; | |
} | |
/// <summary> Set locale used by date range parsing.</summary> | |
public virtual void SetLocale(System.Globalization.CultureInfo locale) | |
{ | |
this.locale = locale; | |
} | |
/// <summary> Returns current locale, allowing access by subclasses.</summary> | |
public virtual System.Globalization.CultureInfo GetLocale() | |
{ | |
return locale; | |
} | |
/// <summary> Sets the default date resolution used by RangeQueries for fields for which no | |
/// specific date resolutions has been set. Field specific resolutions can be set | |
/// with {@link #SetDateResolution(String, DateTools.Resolution)}. | |
/// | |
/// </summary> | |
/// <param name="dateResolution">the default date resolution to set | |
/// </param> | |
public virtual void SetDateResolution(DateTools.Resolution dateResolution) | |
{ | |
this.dateResolution = dateResolution; | |
} | |
/// <summary> Sets the date resolution used by RangeQueries for a specific field. | |
/// | |
/// </summary> | |
/// <param name="fieldName">field for which the date resolution is to be set | |
/// </param> | |
/// <param name="dateResolution">date resolution to set | |
/// </param> | |
public virtual void SetDateResolution(System.String fieldName, DateTools.Resolution dateResolution) | |
{ | |
if (fieldName == null) | |
{ | |
throw new System.ArgumentException("Field cannot be null."); | |
} | |
if (fieldToDateResolution == null) | |
{ | |
// lazily initialize HashMap | |
fieldToDateResolution = new System.Collections.Hashtable(); | |
} | |
fieldToDateResolution[fieldName] = dateResolution; | |
} | |
/// <summary> Returns the date resolution that is used by RangeQueries for the given field. | |
/// Returns null, if no default or field specific date resolution has been set | |
/// for the given field. | |
/// | |
/// </summary> | |
public virtual DateTools.Resolution GetDateResolution(System.String fieldName) | |
{ | |
if (fieldName == null) | |
{ | |
throw new System.ArgumentException("Field cannot be null."); | |
} | |
if (fieldToDateResolution == null) | |
{ | |
// no field specific date resolutions set; return default date resolution instead | |
return this.dateResolution; | |
} | |
DateTools.Resolution resolution = (DateTools.Resolution) fieldToDateResolution[fieldName]; | |
if (resolution == null) | |
{ | |
// no date resolutions set for the given field; return default date resolution instead | |
resolution = this.dateResolution; | |
} | |
return resolution; | |
} | |
public virtual void AddClause(System.Collections.ArrayList clauses, int conj, int mods, Query q) | |
{ | |
bool required, prohibited; | |
// If this term is introduced by AND, make the preceding term required, | |
// unless it's already prohibited | |
if (clauses.Count > 0 && conj == CONJ_AND) | |
{ | |
BooleanClause c = (BooleanClause) clauses[clauses.Count - 1]; | |
if (!c.IsProhibited()) | |
c.SetOccur(BooleanClause.Occur.MUST); | |
} | |
if (clauses.Count > 0 && operator_Renamed == AND_OPERATOR && conj == CONJ_OR) | |
{ | |
// If this term is introduced by OR, make the preceding term optional, | |
// unless it's prohibited (that means we leave -a OR b but +a OR b-->a OR b) | |
// notice if the input is a OR b, first term is parsed as required; without | |
// this modification a OR b would parsed as +a OR b | |
BooleanClause c = (BooleanClause) clauses[clauses.Count - 1]; | |
if (!c.IsProhibited()) | |
c.SetOccur(BooleanClause.Occur.SHOULD); | |
} | |
// We might have been passed a null query; the term might have been | |
// filtered away by the analyzer. | |
if (q == null) | |
return ; | |
if (operator_Renamed == OR_OPERATOR) | |
{ | |
// We set REQUIRED if we're introduced by AND or +; PROHIBITED if | |
// introduced by NOT or -; make sure not to set both. | |
prohibited = (mods == MOD_NOT); | |
required = (mods == MOD_REQ); | |
if (conj == CONJ_AND && !prohibited) | |
{ | |
required = true; | |
} | |
} | |
else | |
{ | |
// We set PROHIBITED if we're introduced by NOT or -; We set REQUIRED | |
// if not PROHIBITED and not introduced by OR | |
prohibited = (mods == MOD_NOT); | |
required = (!prohibited && conj != CONJ_OR); | |
} | |
if (required && !prohibited) | |
clauses.Add(new BooleanClause(q, BooleanClause.Occur.MUST)); | |
else if (!required && !prohibited) | |
clauses.Add(new BooleanClause(q, BooleanClause.Occur.SHOULD)); | |
else if (!required && prohibited) | |
clauses.Add(new BooleanClause(q, BooleanClause.Occur.MUST_NOT)); | |
else | |
throw new System.SystemException("Clause cannot be both required and prohibited"); | |
} | |
/// <exception cref=""> ParseException throw in overridden method to disallow | |
/// </exception> | |
public virtual Query GetFieldQuery(System.String field, System.String queryText) | |
{ | |
// Use the analyzer to get all the tokens, and then build a TermQuery, | |
// PhraseQuery, or nothing based on the term count | |
TokenStream source = analyzer.TokenStream(field, new System.IO.StringReader(queryText)); | |
System.Collections.ArrayList v = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); | |
Lucene.Net.Analysis.Token t; | |
int positionCount = 0; | |
bool severalTokensAtSamePosition = false; | |
while (true) | |
{ | |
try | |
{ | |
t = source.Next(); | |
} | |
catch (System.IO.IOException e) | |
{ | |
t = null; | |
} | |
if (t == null) | |
break; | |
v.Add(t); | |
if (t.GetPositionIncrement() != 0) | |
positionCount += t.GetPositionIncrement(); | |
else | |
severalTokensAtSamePosition = true; | |
} | |
try | |
{ | |
source.Close(); | |
} | |
catch (System.IO.IOException e) | |
{ | |
// ignore | |
} | |
if (v.Count == 0) | |
return null; | |
else if (v.Count == 1) | |
{ | |
t = (Lucene.Net.Analysis.Token) v[0]; | |
return new TermQuery(new Term(field, t.TermText())); | |
} | |
else | |
{ | |
if (severalTokensAtSamePosition) | |
{ | |
if (positionCount == 1) | |
{ | |
// no phrase query: | |
BooleanQuery q = new BooleanQuery(true); | |
for (int i = 0; i < v.Count; i++) | |
{ | |
t = (Lucene.Net.Analysis.Token) v[i]; | |
TermQuery currentQuery = new TermQuery(new Term(field, t.TermText())); | |
q.Add(currentQuery, BooleanClause.Occur.SHOULD); | |
} | |
return q; | |
} | |
else | |
{ | |
// phrase query: | |
MultiPhraseQuery mpq = new MultiPhraseQuery(); | |
mpq.SetSlop(phraseSlop); | |
System.Collections.ArrayList multiTerms = new System.Collections.ArrayList(); | |
int position = - 1; | |
for (int i = 0; i < v.Count; i++) | |
{ | |
t = (Lucene.Net.Analysis.Token) v[i]; | |
if (t.GetPositionIncrement() > 0 && multiTerms.Count > 0) | |
{ | |
if (enablePositionIncrements) | |
{ | |
mpq.Add((Term[])multiTerms.ToArray(typeof(Term)), position); | |
} | |
else | |
{ | |
mpq.Add((Term[])multiTerms.ToArray(typeof(Term))); | |
} | |
multiTerms.Clear(); | |
} | |
position += t.GetPositionIncrement(); | |
multiTerms.Add(new Term(field, t.TermText())); | |
} | |
if (enablePositionIncrements) | |
{ | |
mpq.Add((Term[])multiTerms.ToArray(typeof(Term)), position); | |
} | |
else | |
{ | |
mpq.Add((Term[])multiTerms.ToArray(typeof(Term))); | |
} | |
return mpq; | |
} | |
} | |
else | |
{ | |
PhraseQuery pq = new PhraseQuery(); | |
pq.SetSlop(phraseSlop); | |
int position = - 1; | |
for (int i = 0; i < v.Count; i++) | |
{ | |
t = (Lucene.Net.Analysis.Token) v[i]; | |
if (enablePositionIncrements) | |
{ | |
position += t.GetPositionIncrement(); | |
pq.Add(new Term(field, t.TermText()), position); | |
} | |
else | |
{ | |
pq.Add(new Term(field, t.TermText())); | |
} | |
} | |
return pq; | |
} | |
} | |
} | |
/// <summary> Base implementation delegates to {@link #GetFieldQuery(String,String)}. | |
/// This method may be overridden, for example, to return | |
/// a SpanNearQuery instead of a PhraseQuery. | |
/// | |
/// </summary> | |
/// <exception cref="ParseException">throw in overridden method to disallow | |
/// </exception> | |
public virtual Query GetFieldQuery(System.String field, System.String queryText, int slop) | |
{ | |
Query query = GetFieldQuery(field, queryText); | |
if (query is PhraseQuery) | |
{ | |
((PhraseQuery) query).SetSlop(slop); | |
} | |
if (query is MultiPhraseQuery) | |
{ | |
((MultiPhraseQuery) query).SetSlop(slop); | |
} | |
return query; | |
} | |
/// <exception cref="ParseException">throw in overridden method to disallow | |
/// </exception> | |
public virtual Query GetRangeQuery(System.String field, System.String part1, System.String part2, bool inclusive) | |
{ | |
if (lowercaseExpandedTerms) | |
{ | |
part1 = part1.ToLower(); | |
part2 = part2.ToLower(); | |
} | |
try | |
{ | |
System.DateTime d1; | |
System.DateTime d2; | |
try | |
{ | |
d1 = System.DateTime.Parse(part1, locale); | |
} | |
catch (System.Exception) | |
{ | |
d1 = System.DateTime.Parse(part1); | |
} | |
try | |
{ | |
d2 = System.DateTime.Parse(part2, locale); | |
} | |
catch (System.Exception) | |
{ | |
d2 = System.DateTime.Parse(part2); | |
} | |
if (inclusive) | |
{ | |
// The user can only specify the date, not the time, so make sure | |
// the time is set to the latest possible time of that date to really | |
// include all documents: | |
System.Globalization.Calendar cal = new System.Globalization.GregorianCalendar(); | |
System.DateTime tempDate = d2; | |
d2 = d2.AddHours(23 - tempDate.Hour); | |
d2 = d2.AddMinutes(59 - tempDate.Minute); | |
d2 = d2.AddSeconds(59 - tempDate.Second); | |
d2 = d2.AddMilliseconds(999 - tempDate.Millisecond); | |
} | |
DateTools.Resolution resolution = GetDateResolution(field); | |
if (resolution == null) | |
{ | |
// no default or field specific date resolution has been set, | |
// use deprecated DateField to maintain compatibilty with | |
// pre-1.9 Lucene versions. | |
part1 = DateField.DateToString(d1); | |
part2 = DateField.DateToString(d2); | |
} | |
else | |
{ | |
part1 = DateTools.DateToString(d1, resolution); | |
part2 = DateTools.DateToString(d2, resolution); | |
} | |
} | |
catch (System.Exception e) | |
{ | |
} | |
if (useOldRangeQuery) | |
{ | |
return new RangeQuery(new Term(field, part1), new Term(field, part2), inclusive); | |
} | |
else | |
{ | |
return new ConstantScoreRangeQuery(field, part1, part2, inclusive, inclusive); | |
} | |
} | |
/// <summary> Factory method for generating query, given a set of clauses. | |
/// By default creates a boolean query composed of clauses passed in. | |
/// | |
/// Can be overridden by extending classes, to modify query being | |
/// returned. | |
/// | |
/// </summary> | |
/// <param name="clauses">Vector that contains {@link BooleanClause} instances | |
/// to join. | |
/// | |
/// </param> | |
/// <returns> Resulting {@link Query} object. | |
/// </returns> | |
/// <exception cref="ParseException">throw in overridden method to disallow | |
/// </exception> | |
public virtual Query GetBooleanQuery(System.Collections.ArrayList clauses) | |
{ | |
return GetBooleanQuery(clauses, false); | |
} | |
/// <summary> Factory method for generating query, given a set of clauses. | |
/// By default creates a boolean query composed of clauses passed in. | |
/// | |
/// Can be overridden by extending classes, to modify query being | |
/// returned. | |
/// | |
/// </summary> | |
/// <param name="clauses">Vector that contains {@link BooleanClause} instances | |
/// to join. | |
/// </param> | |
/// <param name="disableCoord">true if coord scoring should be disabled. | |
/// | |
/// </param> | |
/// <returns> Resulting {@link Query} object. | |
/// </returns> | |
/// <exception cref=""> ParseException throw in overridden method to disallow | |
/// </exception> | |
public virtual Query GetBooleanQuery(System.Collections.ArrayList clauses, bool disableCoord) | |
{ | |
if (clauses.Count == 0) | |
{ | |
return null; // all clause words were filtered away by the analyzer. | |
} | |
BooleanQuery query = new BooleanQuery(disableCoord); | |
for (int i = 0; i < clauses.Count; i++) | |
{ | |
query.Add((BooleanClause) clauses[i]); | |
} | |
return query; | |
} | |
/// <summary> Factory method for generating a query. Called when parser | |
/// parses an input term token that contains one or more wildcard | |
/// characters (? and *), but is not a prefix term token (one | |
/// that has just a single * character at the end) | |
/// <p> | |
/// Depending on settings, prefix term may be lower-cased | |
/// automatically. It will not go through the default Analyzer, | |
/// however, since normal Analyzers are unlikely to work properly | |
/// with wildcard templates. | |
/// <p> | |
/// Can be overridden by extending classes, to provide custom handling for | |
/// wildcard queries, which may be necessary due to missing analyzer calls. | |
/// | |
/// </summary> | |
/// <param name="field">Name of the field query will use. | |
/// </param> | |
/// <param name="termStr">Term token that contains one or more wild card | |
/// characters (? or *), but is not simple prefix term | |
/// | |
/// </param> | |
/// <returns> Resulting {@link Query} built for the term | |
/// </returns> | |
/// <exception cref="ParseException">throw in overridden method to disallow | |
/// </exception> | |
public virtual Query GetWildcardQuery(System.String field, System.String termStr) | |
{ | |
if ("*".Equals(field)) | |
{ | |
if ("*".Equals(termStr)) | |
return new MatchAllDocsQuery(); | |
} | |
if (!allowLeadingWildcard && (termStr.StartsWith("*") || termStr.StartsWith("?"))) | |
throw new ParseException("'*' or '?' not allowed as first character in WildcardQuery"); | |
if (lowercaseExpandedTerms) | |
{ | |
termStr = termStr.ToLower(); | |
} | |
Term t = new Term(field, termStr); | |
return new WildcardQuery(t); | |
} | |
/// <summary> Factory method for generating a query (similar to | |
/// {@link #getWildcardQuery}). Called when parser parses an input term | |
/// token that uses prefix notation; that is, contains a single '*' wildcard | |
/// character as its last character. Since this is a special case | |
/// of generic wildcard term, and such a query can be optimized easily, | |
/// this usually results in a different query object. | |
/// <p> | |
/// Depending on settings, a prefix term may be lower-cased | |
/// automatically. It will not go through the default Analyzer, | |
/// however, since normal Analyzers are unlikely to work properly | |
/// with wildcard templates. | |
/// <p> | |
/// Can be overridden by extending classes, to provide custom handling for | |
/// wild card queries, which may be necessary due to missing analyzer calls. | |
/// | |
/// </summary> | |
/// <param name="field">Name of the field query will use. | |
/// </param> | |
/// <param name="termStr">Term token to use for building term for the query | |
/// (<b>without</b> trailing '*' character!) | |
/// | |
/// </param> | |
/// <returns> Resulting {@link Query} built for the term | |
/// </returns> | |
/// <exception cref="ParseException">throw in overridden method to disallow | |
/// </exception> | |
public virtual Query GetPrefixQuery(System.String field, System.String termStr) | |
{ | |
if (!allowLeadingWildcard && termStr.StartsWith("*")) | |
throw new ParseException("'*' not allowed as first character in PrefixQuery"); | |
if (lowercaseExpandedTerms) | |
{ | |
termStr = termStr.ToLower(); | |
} | |
Term t = new Term(field, termStr); | |
return new PrefixQuery(t); | |
} | |
/// <summary> Factory method for generating a query (similar to | |
/// {@link #getWildcardQuery}). Called when parser parses | |
/// an input term token that has the fuzzy suffix (~) appended. | |
/// | |
/// </summary> | |
/// <param name="field">Name of the field query will use. | |
/// </param> | |
/// <param name="termStr">Term token to use for building term for the query | |
/// | |
/// </param> | |
/// <returns> Resulting {@link Query} built for the term | |
/// </returns> | |
/// <exception cref="ParseException">throw in overridden method to disallow | |
/// </exception> | |
public virtual Query GetFuzzyQuery(System.String field, System.String termStr, float minSimilarity) | |
{ | |
if (lowercaseExpandedTerms) | |
{ | |
termStr = termStr.ToLower(); | |
} | |
Term t = new Term(field, termStr); | |
return new FuzzyQuery(t, minSimilarity, fuzzyPrefixLength); | |
} | |
/// <summary> Returns a String where the escape char has been | |
/// removed, or kept only once if there was a double escape. | |
/// | |
/// Supports escaped unicode characters, e. g. translates | |
/// <code>A</code> to <code>A</code>. | |
/// | |
/// </summary> | |
private System.String DiscardEscapeChar(System.String input) | |
{ | |
// Create char array to hold unescaped char sequence | |
char[] output = new char[input.Length]; | |
// The length of the output can be less than the input | |
// due to discarded escape chars. This variable holds | |
// the actual length of the output | |
int length = 0; | |
// We remember whether the last processed character was | |
// an escape character | |
bool lastCharWasEscapeChar = false; | |
// The multiplier the current unicode digit must be multiplied with. | |
// E. g. the first digit must be multiplied with 16^3, the second with 16^2... | |
int codePointMultiplier = 0; | |
// Used to calculate the codepoint of the escaped unicode character | |
int codePoint = 0; | |
for (int i = 0; i < input.Length; i++) | |
{ | |
char curChar = input[i]; | |
if (codePointMultiplier > 0) | |
{ | |
codePoint += HexToInt(curChar) * codePointMultiplier; | |
codePointMultiplier = SupportClass.Number.URShift(codePointMultiplier, 4); | |
if (codePointMultiplier == 0) | |
{ | |
output[length++] = (char) codePoint; | |
codePoint = 0; | |
} | |
} | |
else if (lastCharWasEscapeChar) | |
{ | |
if (curChar == 'u') | |
{ | |
// found an escaped unicode character | |
codePointMultiplier = 16 * 16 * 16; | |
} | |
else | |
{ | |
// this character was escaped | |
output[length] = curChar; | |
length++; | |
} | |
lastCharWasEscapeChar = false; | |
} | |
else | |
{ | |
if (curChar == '\\') | |
{ | |
lastCharWasEscapeChar = true; | |
} | |
else | |
{ | |
output[length] = curChar; | |
length++; | |
} | |
} | |
} | |
if (codePointMultiplier > 0) | |
{ | |
throw new ParseException("Truncated unicode escape sequence."); | |
} | |
if (lastCharWasEscapeChar) | |
{ | |
throw new ParseException("Term can not end with escape character."); | |
} | |
return new System.String(output, 0, length); | |
} | |
/// <summary>Returns the numeric value of the hexadecimal character </summary> | |
private static int HexToInt(char c) | |
{ | |
if ('0' <= c && c <= '9') | |
{ | |
return c - '0'; | |
} | |
else if ('a' <= c && c <= 'f') | |
{ | |
return c - 'a' + 10; | |
} | |
else if ('A' <= c && c <= 'F') | |
{ | |
return c - 'A' + 10; | |
} | |
else | |
{ | |
throw new ParseException("None-hex character in unicode escape sequence: " + c); | |
} | |
} | |
/// <summary> Returns a String where those characters that QueryParser | |
/// expects to be escaped are escaped by a preceding <code>\</code>. | |
/// </summary> | |
public static System.String Escape(System.String s) | |
{ | |
System.Text.StringBuilder sb = new System.Text.StringBuilder(); | |
for (int i = 0; i < s.Length; i++) | |
{ | |
char c = s[i]; | |
// These characters are part of the query syntax and must be escaped | |
if (c == '\\' || c == '+' || c == '-' || c == '!' || c == '(' || c == ')' || c == ':' || c == '^' || c == '[' || c == ']' || c == '\"' || c == '{' || c == '}' || c == '~' || c == '*' || c == '?' || c == '|' || c == '&') | |
{ | |
sb.Append('\\'); | |
} | |
sb.Append(c); | |
} | |
return sb.ToString(); | |
} | |
/// <summary> Command line tool to test QueryParser, using {@link Lucene.Net.Analysis.SimpleAnalyzer}. | |
/// Usage:<br> | |
/// <code>java Lucene.Net.QueryParsers.QueryParser <input></code> | |
/// </summary> | |
[STAThread] | |
public static void Main(System.String[] args) | |
{ | |
if (args.Length == 0) | |
{ | |
System.Console.Out.WriteLine("Usage: java Lucene.Net.QueryParsers.QueryParser <input>"); | |
System.Environment.Exit(0); | |
} | |
QueryParser qp = new QueryParser("field", new Lucene.Net.Analysis.SimpleAnalyzer()); | |
Query q = qp.Parse(args[0]); | |
System.Console.Out.WriteLine(q.ToString("field")); | |
} | |
// * Query ::= ( Clause )* | |
// * Clause ::= ["+", "-"] [<TERM> ":"] ( <TERM> | "(" Query ")" ) | |
public int Conjunction() | |
{ | |
int ret = CONJ_NONE; | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.AND: | |
case Lucene.Net.QueryParsers.QueryParserConstants.OR: | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.AND: | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.AND); | |
ret = CONJ_AND; | |
break; | |
case Lucene.Net.QueryParsers.QueryParserConstants.OR: | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.OR); | |
ret = CONJ_OR; | |
break; | |
default: | |
jj_la1[0] = jj_gen; | |
Jj_consume_token(- 1); | |
throw new ParseException(); | |
} | |
break; | |
default: | |
jj_la1[1] = jj_gen; | |
; | |
break; | |
} | |
{ | |
if (true) | |
return ret; | |
} | |
//// throw new System.ApplicationException("Missing return statement in function"); | |
} | |
public int Modifiers() | |
{ | |
int ret = MOD_NONE; | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.NOT: | |
case Lucene.Net.QueryParsers.QueryParserConstants.PLUS: | |
case Lucene.Net.QueryParsers.QueryParserConstants.MINUS: | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.PLUS: | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.PLUS); | |
ret = MOD_REQ; | |
break; | |
case Lucene.Net.QueryParsers.QueryParserConstants.MINUS: | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.MINUS); | |
ret = MOD_NOT; | |
break; | |
case Lucene.Net.QueryParsers.QueryParserConstants.NOT: | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.NOT); | |
ret = MOD_NOT; | |
break; | |
default: | |
jj_la1[2] = jj_gen; | |
Jj_consume_token(- 1); | |
throw new ParseException(); | |
} | |
break; | |
default: | |
jj_la1[3] = jj_gen; | |
; | |
break; | |
} | |
{ | |
if (true) | |
return ret; | |
} | |
//// throw new System.ApplicationException("Missing return statement in function"); | |
} | |
// This makes sure that there is no garbage after the query string | |
public Query TopLevelQuery(System.String field) | |
{ | |
Query q; | |
q = Query(field); | |
Jj_consume_token(0); | |
{ | |
if (true) | |
return q; | |
} | |
//// throw new System.ApplicationException("Missing return statement in function"); | |
} | |
public Query Query(System.String field) | |
{ | |
System.Collections.ArrayList clauses = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); | |
Query q, firstQuery = null; | |
int conj, mods; | |
mods = Modifiers(); | |
q = Clause(field); | |
AddClause(clauses, CONJ_NONE, mods, q); | |
if (mods == MOD_NONE) | |
firstQuery = q; | |
while (true) | |
{ | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.AND: | |
case Lucene.Net.QueryParsers.QueryParserConstants.OR: | |
case Lucene.Net.QueryParsers.QueryParserConstants.NOT: | |
case Lucene.Net.QueryParsers.QueryParserConstants.PLUS: | |
case Lucene.Net.QueryParsers.QueryParserConstants.MINUS: | |
case Lucene.Net.QueryParsers.QueryParserConstants.LPAREN: | |
case Lucene.Net.QueryParsers.QueryParserConstants.STAR: | |
case Lucene.Net.QueryParsers.QueryParserConstants.QUOTED: | |
case Lucene.Net.QueryParsers.QueryParserConstants.TERM: | |
case Lucene.Net.QueryParsers.QueryParserConstants.PREFIXTERM: | |
case Lucene.Net.QueryParsers.QueryParserConstants.WILDTERM: | |
case Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_START: | |
case Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_START: | |
case Lucene.Net.QueryParsers.QueryParserConstants.NUMBER: | |
; | |
break; | |
default: | |
jj_la1[4] = jj_gen; | |
goto label_1_brk; | |
} | |
conj = Conjunction(); | |
mods = Modifiers(); | |
q = Clause(field); | |
AddClause(clauses, conj, mods, q); | |
} | |
label_1_brk: ; | |
if (clauses.Count == 1 && firstQuery != null) | |
{ | |
if (true) | |
return firstQuery; | |
} | |
else | |
{ | |
{ | |
if (true) | |
return GetBooleanQuery(clauses); | |
} | |
} | |
//// throw new System.ApplicationException("Missing return statement in function"); | |
} | |
public Query Clause(System.String field) | |
{ | |
Query q; | |
Token fieldToken = null, boost = null; | |
if (Jj_2_1(2)) | |
{ | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.TERM: | |
fieldToken = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.TERM); | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.COLON); | |
field = DiscardEscapeChar(fieldToken.image); | |
break; | |
case Lucene.Net.QueryParsers.QueryParserConstants.STAR: | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.STAR); | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.COLON); | |
field = "*"; | |
break; | |
default: | |
jj_la1[5] = jj_gen; | |
Jj_consume_token(- 1); | |
throw new ParseException(); | |
} | |
} | |
else | |
{ | |
; | |
} | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.STAR: | |
case Lucene.Net.QueryParsers.QueryParserConstants.QUOTED: | |
case Lucene.Net.QueryParsers.QueryParserConstants.TERM: | |
case Lucene.Net.QueryParsers.QueryParserConstants.PREFIXTERM: | |
case Lucene.Net.QueryParsers.QueryParserConstants.WILDTERM: | |
case Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_START: | |
case Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_START: | |
case Lucene.Net.QueryParsers.QueryParserConstants.NUMBER: | |
q = Term(field); | |
break; | |
case Lucene.Net.QueryParsers.QueryParserConstants.LPAREN: | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.LPAREN); | |
q = Query(field); | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RPAREN); | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.CARAT: | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.CARAT); | |
boost = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.NUMBER); | |
break; | |
default: | |
jj_la1[6] = jj_gen; | |
; | |
break; | |
} | |
break; | |
default: | |
jj_la1[7] = jj_gen; | |
Jj_consume_token(- 1); | |
throw new ParseException(); | |
} | |
if (boost != null) | |
{ | |
float f = (float) 1.0; | |
try | |
{ | |
f = (float) SupportClass.Single.Parse(boost.image); | |
q.SetBoost(f); | |
} | |
catch (System.Exception ignored) | |
{ | |
} | |
} | |
{ | |
if (true) | |
return q; | |
} | |
//// throw new System.ApplicationException("Missing return statement in function"); | |
} | |
public Query Term(System.String field) | |
{ | |
Token term, boost = null, fuzzySlop = null, goop1, goop2; | |
bool prefix = false; | |
bool wildcard = false; | |
bool fuzzy = false; | |
bool rangein = false; | |
Query q; | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.STAR: | |
case Lucene.Net.QueryParsers.QueryParserConstants.TERM: | |
case Lucene.Net.QueryParsers.QueryParserConstants.PREFIXTERM: | |
case Lucene.Net.QueryParsers.QueryParserConstants.WILDTERM: | |
case Lucene.Net.QueryParsers.QueryParserConstants.NUMBER: | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.TERM: | |
term = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.TERM); | |
break; | |
case Lucene.Net.QueryParsers.QueryParserConstants.STAR: | |
term = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.STAR); | |
wildcard = true; | |
break; | |
case Lucene.Net.QueryParsers.QueryParserConstants.PREFIXTERM: | |
term = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.PREFIXTERM); | |
prefix = true; | |
break; | |
case Lucene.Net.QueryParsers.QueryParserConstants.WILDTERM: | |
term = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.WILDTERM); | |
wildcard = true; | |
break; | |
case Lucene.Net.QueryParsers.QueryParserConstants.NUMBER: | |
term = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.NUMBER); | |
break; | |
default: | |
jj_la1[8] = jj_gen; | |
Jj_consume_token(- 1); | |
throw new ParseException(); | |
} | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.FUZZY_SLOP: | |
fuzzySlop = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.FUZZY_SLOP); | |
fuzzy = true; | |
break; | |
default: | |
jj_la1[9] = jj_gen; | |
; | |
break; | |
} | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.CARAT: | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.CARAT); | |
boost = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.NUMBER); | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.FUZZY_SLOP: | |
fuzzySlop = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.FUZZY_SLOP); | |
fuzzy = true; | |
break; | |
default: | |
jj_la1[10] = jj_gen; | |
; | |
break; | |
} | |
break; | |
default: | |
jj_la1[11] = jj_gen; | |
; | |
break; | |
} | |
System.String termImage = DiscardEscapeChar(term.image); | |
if (wildcard) | |
{ | |
q = GetWildcardQuery(field, termImage); | |
} | |
else if (prefix) | |
{ | |
q = GetPrefixQuery(field, DiscardEscapeChar(term.image.Substring(0, (term.image.Length - 1) - (0)))); | |
} | |
else if (fuzzy) | |
{ | |
float fms = fuzzyMinSim; | |
try | |
{ | |
fms = (float) SupportClass.Single.Parse(fuzzySlop.image.Substring(1)); | |
} | |
catch (System.Exception ignored) | |
{ | |
} | |
if (fms < 0.0f || fms > 1.0f) | |
{ | |
{ | |
if (true) | |
throw new ParseException("Minimum similarity for a FuzzyQuery has to be between 0.0f and 1.0f !"); | |
} | |
} | |
q = GetFuzzyQuery(field, termImage, fms); | |
} | |
else | |
{ | |
q = GetFieldQuery(field, termImage); | |
} | |
break; | |
case Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_START: | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_START); | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_GOOP: | |
goop1 = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_GOOP); | |
break; | |
case Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_QUOTED: | |
goop1 = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_QUOTED); | |
break; | |
default: | |
jj_la1[12] = jj_gen; | |
Jj_consume_token(- 1); | |
throw new ParseException(); | |
} | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_TO: | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_TO); | |
break; | |
default: | |
jj_la1[13] = jj_gen; | |
; | |
break; | |
} | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_GOOP: | |
goop2 = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_GOOP); | |
break; | |
case Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_QUOTED: | |
goop2 = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_QUOTED); | |
break; | |
default: | |
jj_la1[14] = jj_gen; | |
Jj_consume_token(- 1); | |
throw new ParseException(); | |
} | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_END); | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.CARAT: | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.CARAT); | |
boost = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.NUMBER); | |
break; | |
default: | |
jj_la1[15] = jj_gen; | |
; | |
break; | |
} | |
if (goop1.kind == Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_QUOTED) | |
{ | |
goop1.image = goop1.image.Substring(1, (goop1.image.Length - 1) - (1)); | |
} | |
if (goop2.kind == Lucene.Net.QueryParsers.QueryParserConstants.RANGEIN_QUOTED) | |
{ | |
goop2.image = goop2.image.Substring(1, (goop2.image.Length - 1) - (1)); | |
} | |
q = GetRangeQuery(field, DiscardEscapeChar(goop1.image), DiscardEscapeChar(goop2.image), true); | |
break; | |
case Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_START: | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_START); | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_GOOP: | |
goop1 = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_GOOP); | |
break; | |
case Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_QUOTED: | |
goop1 = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_QUOTED); | |
break; | |
default: | |
jj_la1[16] = jj_gen; | |
Jj_consume_token(- 1); | |
throw new ParseException(); | |
} | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_TO: | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_TO); | |
break; | |
default: | |
jj_la1[17] = jj_gen; | |
; | |
break; | |
} | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_GOOP: | |
goop2 = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_GOOP); | |
break; | |
case Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_QUOTED: | |
goop2 = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_QUOTED); | |
break; | |
default: | |
jj_la1[18] = jj_gen; | |
Jj_consume_token(- 1); | |
throw new ParseException(); | |
} | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_END); | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.CARAT: | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.CARAT); | |
boost = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.NUMBER); | |
break; | |
default: | |
jj_la1[19] = jj_gen; | |
; | |
break; | |
} | |
if (goop1.kind == Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_QUOTED) | |
{ | |
goop1.image = goop1.image.Substring(1, (goop1.image.Length - 1) - (1)); | |
} | |
if (goop2.kind == Lucene.Net.QueryParsers.QueryParserConstants.RANGEEX_QUOTED) | |
{ | |
goop2.image = goop2.image.Substring(1, (goop2.image.Length - 1) - (1)); | |
} | |
q = GetRangeQuery(field, DiscardEscapeChar(goop1.image), DiscardEscapeChar(goop2.image), false); | |
break; | |
case Lucene.Net.QueryParsers.QueryParserConstants.QUOTED: | |
term = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.QUOTED); | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.FUZZY_SLOP: | |
fuzzySlop = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.FUZZY_SLOP); | |
break; | |
default: | |
jj_la1[20] = jj_gen; | |
; | |
break; | |
} | |
switch ((jj_ntk == - 1) ? Jj_ntk() : jj_ntk) | |
{ | |
case Lucene.Net.QueryParsers.QueryParserConstants.CARAT: | |
Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.CARAT); | |
boost = Jj_consume_token(Lucene.Net.QueryParsers.QueryParserConstants.NUMBER); | |
break; | |
default: | |
jj_la1[21] = jj_gen; | |
; | |
break; | |
} | |
int s = phraseSlop; | |
if (fuzzySlop != null) | |
{ | |
try | |
{ | |
s = (int) SupportClass.Single.Parse(fuzzySlop.image.Substring(1)); | |
} | |
catch (System.Exception ignored) | |
{ | |
} | |
} | |
q = GetFieldQuery(field, DiscardEscapeChar(term.image.Substring(1, (term.image.Length - 1) - (1))), s); | |
break; | |
default: | |
jj_la1[22] = jj_gen; | |
Jj_consume_token(- 1); | |
throw new ParseException(); | |
} | |
if (boost != null) | |
{ | |
float f = (float) 1.0; | |
try | |
{ | |
f = (float) SupportClass.Single.Parse(boost.image); | |
} | |
catch (System.Exception ignored) | |
{ | |
/* Should this be handled somehow? (defaults to "no boost", if | |
* boost number is invalid) | |
*/ | |
} | |
// avoid boosting null queries, such as those caused by stop words | |
if (q != null) | |
{ | |
q.SetBoost(f); | |
} | |
} | |
{ | |
if (true) | |
return q; | |
} | |
//// throw new System.ApplicationException("Missing return statement in function"); | |
} | |
private bool Jj_2_1(int xla) | |
{ | |
jj_la = xla; jj_lastpos = jj_scanpos = token; | |
try | |
{ | |
return !Jj_3_1(); | |
} | |
catch (LookaheadSuccess ls) | |
{ | |
return true; | |
} | |
finally | |
{ | |
Jj_save(0, xla); | |
} | |
} | |
private bool Jj_3R_2() | |
{ | |
if (Jj_scan_token(Lucene.Net.QueryParsers.QueryParserConstants.TERM)) | |
return true; | |
if (Jj_scan_token(Lucene.Net.QueryParsers.QueryParserConstants.COLON)) | |
return true; | |
return false; | |
} | |
private bool Jj_3_1() | |
{ | |
Token xsp; | |
xsp = jj_scanpos; | |
if (Jj_3R_2()) | |
{ | |
jj_scanpos = xsp; | |
if (Jj_3R_3()) | |
return true; | |
} | |
return false; | |
} | |
private bool Jj_3R_3() | |
{ | |
if (Jj_scan_token(Lucene.Net.QueryParsers.QueryParserConstants.STAR)) | |
return true; | |
if (Jj_scan_token(Lucene.Net.QueryParsers.QueryParserConstants.COLON)) | |
return true; | |
return false; | |
} | |
public QueryParserTokenManager token_source; | |
public Token token, jj_nt; | |
private int jj_ntk; | |
private Token jj_scanpos, jj_lastpos; | |
private int jj_la; | |
public bool lookingAhead = false; | |
private bool jj_semLA; | |
private int jj_gen; | |
private int[] jj_la1 = new int[23]; | |
private static uint[] jj_la1_0; | |
private static uint[] jj_la1_1; | |
private static void Jj_la1_0() | |
{ | |
jj_la1_0 = new uint[]{0x180, 0x180, 0xe00, 0xe00, 0x1f69f80, 0x48000, 0x10000, 0x1f69000, 0x1348000, 0x80000, 0x80000, 0x10000, 0x18000000, 0x2000000, 0x18000000, 0x10000, 0x80000000, 0x20000000, 0x80000000, 0x10000, 0x80000, 0x10000, 0x1f68000}; | |
} | |
private static void Jj_la1_1() | |
{ | |
jj_la1_1 = new uint[]{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0}; | |
} | |
private JJCalls[] jj_2_rtns; | |
private bool jj_rescan = false; | |
private int jj_gc = 0; | |
public QueryParser(CharStream stream) | |
{ | |
InitBlock(); | |
token_source = new QueryParserTokenManager(stream); | |
token = new Token(); | |
jj_ntk = - 1; | |
jj_gen = 0; | |
for (int i = 0; i < 23; i++) | |
jj_la1[i] = - 1; | |
for (int i = 0; i < jj_2_rtns.Length; i++) | |
jj_2_rtns[i] = new JJCalls(); | |
} | |
public virtual void ReInit(CharStream stream) | |
{ | |
token_source.ReInit(stream); | |
token = new Token(); | |
jj_ntk = - 1; | |
jj_gen = 0; | |
for (int i = 0; i < 23; i++) | |
jj_la1[i] = - 1; | |
for (int i = 0; i < jj_2_rtns.Length; i++) | |
jj_2_rtns[i] = new JJCalls(); | |
} | |
public QueryParser(QueryParserTokenManager tm) | |
{ | |
InitBlock(); | |
token_source = tm; | |
token = new Token(); | |
jj_ntk = - 1; | |
jj_gen = 0; | |
for (int i = 0; i < 23; i++) | |
jj_la1[i] = - 1; | |
for (int i = 0; i < jj_2_rtns.Length; i++) | |
jj_2_rtns[i] = new JJCalls(); | |
} | |
public virtual void ReInit(QueryParserTokenManager tm) | |
{ | |
token_source = tm; | |
token = new Token(); | |
jj_ntk = - 1; | |
jj_gen = 0; | |
for (int i = 0; i < 23; i++) | |
jj_la1[i] = - 1; | |
for (int i = 0; i < jj_2_rtns.Length; i++) | |
jj_2_rtns[i] = new JJCalls(); | |
} | |
private Token Jj_consume_token(int kind) | |
{ | |
Token oldToken; | |
if ((oldToken = token).next != null) | |
token = token.next; | |
else | |
token = token.next = token_source.GetNextToken(); | |
jj_ntk = - 1; | |
if (token.kind == kind) | |
{ | |
jj_gen++; | |
if (++jj_gc > 100) | |
{ | |
jj_gc = 0; | |
for (int i = 0; i < jj_2_rtns.Length; i++) | |
{ | |
JJCalls c = jj_2_rtns[i]; | |
while (c != null) | |
{ | |
if (c.gen < jj_gen) | |
c.first = null; | |
c = c.next; | |
} | |
} | |
} | |
return token; | |
} | |
token = oldToken; | |
jj_kind = kind; | |
throw GenerateParseException(); | |
} | |
[Serializable] | |
private sealed class LookaheadSuccess:System.ApplicationException | |
{ | |
} | |
private LookaheadSuccess jj_ls; | |
private bool Jj_scan_token(int kind) | |
{ | |
if (jj_scanpos == jj_lastpos) | |
{ | |
jj_la--; | |
if (jj_scanpos.next == null) | |
{ | |
jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.GetNextToken(); | |
} | |
else | |
{ | |
jj_lastpos = jj_scanpos = jj_scanpos.next; | |
} | |
} | |
else | |
{ | |
jj_scanpos = jj_scanpos.next; | |
} | |
if (jj_rescan) | |
{ | |
int i = 0; Token tok = token; | |
while (tok != null && tok != jj_scanpos) | |
{ | |
i++; tok = tok.next; | |
} | |
if (tok != null) | |
Jj_add_error_token(kind, i); | |
} | |
if (jj_scanpos.kind != kind) | |
return true; | |
if (jj_la == 0 && jj_scanpos == jj_lastpos) | |
throw jj_ls; | |
return false; | |
} | |
public Token GetNextToken() | |
{ | |
if (token.next != null) | |
token = token.next; | |
else | |
token = token.next = token_source.GetNextToken(); | |
jj_ntk = - 1; | |
jj_gen++; | |
return token; | |
} | |
public Token GetToken(int index) | |
{ | |
Token t = lookingAhead ? jj_scanpos : token; | |
for (int i = 0; i < index; i++) | |
{ | |
if (t.next != null) | |
t = t.next; | |
else | |
t = t.next = token_source.GetNextToken(); | |
} | |
return t; | |
} | |
private int Jj_ntk() | |
{ | |
if ((jj_nt = token.next) == null) | |
return (jj_ntk = (token.next = token_source.GetNextToken()).kind); | |
else | |
return (jj_ntk = jj_nt.kind); | |
} | |
private System.Collections.ArrayList jj_expentries = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); | |
private int[] jj_expentry; | |
private int jj_kind = - 1; | |
private int[] jj_lasttokens = new int[100]; | |
private int jj_endpos; | |
private void Jj_add_error_token(int kind, int pos) | |
{ | |
if (pos >= 100) | |
return ; | |
if (pos == jj_endpos + 1) | |
{ | |
jj_lasttokens[jj_endpos++] = kind; | |
} | |
else if (jj_endpos != 0) | |
{ | |
jj_expentry = new int[jj_endpos]; | |
for (int i = 0; i < jj_endpos; i++) | |
{ | |
jj_expentry[i] = jj_lasttokens[i]; | |
} | |
bool exists = false; | |
for (System.Collections.IEnumerator e = jj_expentries.GetEnumerator(); e.MoveNext(); ) | |
{ | |
int[] oldentry = (int[]) (e.Current); | |
if (oldentry.Length == jj_expentry.Length) | |
{ | |
exists = true; | |
for (int i = 0; i < jj_expentry.Length; i++) | |
{ | |
if (oldentry[i] != jj_expentry[i]) | |
{ | |
exists = false; | |
break; | |
} | |
} | |
if (exists) | |
break; | |
} | |
} | |
if (!exists) | |
jj_expentries.Add(jj_expentry); | |
if (pos != 0) | |
jj_lasttokens[(jj_endpos = pos) - 1] = kind; | |
} | |
} | |
public virtual ParseException GenerateParseException() | |
{ | |
jj_expentries.Clear(); | |
bool[] la1tokens = new bool[33]; | |
for (int i = 0; i < 33; i++) | |
{ | |
la1tokens[i] = false; | |
} | |
if (jj_kind >= 0) | |
{ | |
la1tokens[jj_kind] = true; | |
jj_kind = - 1; | |
} | |
for (int i = 0; i < 23; i++) | |
{ | |
if (jj_la1[i] == jj_gen) | |
{ | |
for (int j = 0; j < 32; j++) | |
{ | |
if ((jj_la1_0[i] & (1 << j)) != 0) | |
{ | |
la1tokens[j] = true; | |
} | |
if ((jj_la1_1[i] & (1 << j)) != 0) | |
{ | |
la1tokens[32 + j] = true; | |
} | |
} | |
} | |
} | |
for (int i = 0; i < 33; i++) | |
{ | |
if (la1tokens[i]) | |
{ | |
jj_expentry = new int[1]; | |
jj_expentry[0] = i; | |
jj_expentries.Add(jj_expentry); | |
} | |
} | |
jj_endpos = 0; | |
Jj_rescan_token(); | |
Jj_add_error_token(0, 0); | |
int[][] exptokseq = new int[jj_expentries.Count][]; | |
for (int i = 0; i < jj_expentries.Count; i++) | |
{ | |
exptokseq[i] = (int[]) jj_expentries[i]; | |
} | |
return new ParseException(token, exptokseq, Lucene.Net.QueryParsers.QueryParserConstants.tokenImage); | |
} | |
public void Enable_tracing() | |
{ | |
} | |
public void Disable_tracing() | |
{ | |
} | |
private void Jj_rescan_token() | |
{ | |
jj_rescan = true; | |
for (int i = 0; i < 1; i++) | |
{ | |
JJCalls p = jj_2_rtns[i]; | |
do | |
{ | |
if (p.gen > jj_gen) | |
{ | |
jj_la = p.arg; jj_lastpos = jj_scanpos = p.first; | |
switch (i) | |
{ | |
case 0: Jj_3_1(); break; | |
} | |
} | |
p = p.next; | |
} | |
while (p != null); | |
} | |
jj_rescan = false; | |
} | |
private void Jj_save(int index, int xla) | |
{ | |
JJCalls p = jj_2_rtns[index]; | |
while (p.gen > jj_gen) | |
{ | |
if (p.next == null) | |
{ | |
p = p.next = new JJCalls(); break; | |
} | |
p = p.next; | |
} | |
p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla; | |
} | |
internal sealed class JJCalls | |
{ | |
internal int gen; | |
internal Token first; | |
internal int arg; | |
internal JJCalls next; | |
} | |
static QueryParser() | |
{ | |
{ | |
Jj_la1_0(); | |
Jj_la1_1(); | |
} | |
} | |
} | |
} |