You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by sy...@apache.org on 2016/09/11 21:30:47 UTC
[16/50] [abbrv] lucenenet git commit: Ported QueryParser.Surround
namespace + tests.
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e7576a6/Lucene.Net.QueryParser/Surround/Parser/QueryParserTokenManager.cs
----------------------------------------------------------------------
diff --git a/Lucene.Net.QueryParser/Surround/Parser/QueryParserTokenManager.cs b/Lucene.Net.QueryParser/Surround/Parser/QueryParserTokenManager.cs
new file mode 100644
index 0000000..ac3d611
--- /dev/null
+++ b/Lucene.Net.QueryParser/Surround/Parser/QueryParserTokenManager.cs
@@ -0,0 +1,760 @@
+\ufeffusing System;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+
+namespace Lucene.Net.QueryParser.Surround.Parser
+{
+ /*
+ * 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.
+ */
+
+ /// <summary>
+ /// Token Manager.
+ /// </summary>
+ public class QueryParserTokenManager //: QueryParserConstants
+ {
+ private void InitBlock()
+ {
+ StreamWriter temp_writer;
+ temp_writer = new StreamWriter(Console.OpenStandardOutput(), Console.Out.Encoding);
+ temp_writer.AutoFlush = true;
+ debugStream = temp_writer;
+ }
+
+ /// <summary>Debug output. </summary>
+ public StreamWriter debugStream;
+ /// <summary>Set debug output. </summary>
+ public virtual void SetDebugStream(StreamWriter ds)
+ {
+ debugStream = ds;
+ }
+ private int JjStopStringLiteralDfa_1(int pos, long active0)
+ {
+ switch (pos)
+ {
+ default:
+ return -1;
+ }
+ }
+ private int JjStartNfa_1(int pos, long active0)
+ {
+ return JjMoveNfa_1(JjStopStringLiteralDfa_1(pos, active0), pos + 1);
+ }
+ private int JjStopAtPos(int pos, int kind)
+ {
+ jjmatchedKind = kind;
+ jjmatchedPos = pos;
+ return pos + 1;
+ }
+ private int jjMoveStringLiteralDfa0_1()
+ {
+ switch (curChar)
+ {
+ case (char)40:
+ return JjStopAtPos(0, 13);
+ case (char)41:
+ return JjStopAtPos(0, 14);
+ case (char)44:
+ return JjStopAtPos(0, 15);
+ case (char)58:
+ return JjStopAtPos(0, 16);
+ case (char)94:
+ return JjStopAtPos(0, 17);
+ default:
+ return JjMoveNfa_1(0, 0);
+ }
+ }
+ internal static readonly ulong[] jjbitVec0 = {
+ 0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
+ };
+ internal static readonly ulong[] jjbitVec2 = {
+ 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
+ };
+ private int JjMoveNfa_1(int startState, int curPos)
+ {
+ int startsAt = 0;
+ jjnewStateCnt = 38;
+ int i = 1;
+ jjstateSet[0] = startState;
+ int kind = 0x7fffffff;
+ for (; ; )
+ {
+ if (++jjround == 0x7fffffff)
+ ReInitRounds();
+ if (curChar < 64)
+ {
+ ulong l = (ulong)(1L << (int)curChar);
+ do
+ {
+ switch (jjstateSet[--i])
+ {
+ case 0:
+ if ((0x7bffe8faffffd9ffL & l) != 0L)
+ {
+ if (kind > 22)
+ kind = 22;
+ JjCheckNAddStates(0, 4);
+ }
+ else if ((0x100002600L & l) != 0L)
+ {
+ if (kind > 7)
+ kind = 7;
+ }
+ else if (curChar == 34)
+ JjCheckNAddStates(5, 7);
+ if ((0x3fc000000000000L & l) != 0L)
+ JjCheckNAddStates(8, 11);
+ else if (curChar == 49)
+ JjCheckNAddTwoStates(20, 21);
+ break;
+ case 19:
+ if ((0x3fc000000000000L & l) != 0L)
+ JjCheckNAddStates(8, 11);
+ break;
+ case 20:
+ if ((0x3ff000000000000L & l) != 0L)
+ JjCheckNAdd(17);
+ break;
+ case 21:
+ if ((0x3ff000000000000L & l) != 0L)
+ JjCheckNAdd(18);
+ break;
+ case 22:
+ if (curChar == 49)
+ JjCheckNAddTwoStates(20, 21);
+ break;
+ case 23:
+ if (curChar == 34)
+ JjCheckNAddStates(5, 7);
+ break;
+ case 24:
+ if ((0xfffffffbffffffffL & l) != (ulong)0L)
+ JjCheckNAddTwoStates(24, 25);
+ break;
+ case 25:
+ if (curChar == 34)
+ jjstateSet[jjnewStateCnt++] = 26;
+ break;
+ case 26:
+ if (curChar == 42 && kind > 18)
+ kind = 18;
+ break;
+ case 27:
+ if ((0xfffffffbffffffffL & l) != (ulong)0L)
+ JjCheckNAddStates(12, 14);
+ break;
+ case 29:
+ if (curChar == 34)
+ JjCheckNAddStates(12, 14);
+ break;
+ case 30:
+ if (curChar == 34 && kind > 19)
+ kind = 19;
+ break;
+ case 31:
+ if ((0x7bffe8faffffd9ffL & l) == 0L)
+ break;
+ if (kind > 22)
+ kind = 22;
+ JjCheckNAddStates(0, 4);
+ break;
+ case 32:
+ if ((0x7bffe8faffffd9ffL & l) != 0L)
+ JjCheckNAddTwoStates(32, 33);
+ break;
+ case 33:
+ if (curChar == 42 && kind > 20)
+ kind = 20;
+ break;
+ case 34:
+ if ((0x7bffe8faffffd9ffL & l) != 0L)
+ JjCheckNAddTwoStates(34, 35);
+ break;
+ case 35:
+ if ((0x8000040000000000L & l) == (ulong)0L)
+ break;
+ if (kind > 21)
+ kind = 21;
+ JjCheckNAddTwoStates(35, 36);
+ break;
+ case 36:
+ if ((0xfbffecfaffffd9ffL & l) == (ulong)0L)
+ break;
+ if (kind > 21)
+ kind = 21;
+ JjCheckNAdd(36);
+ break;
+ case 37:
+ if ((0x7bffe8faffffd9ffL & l) == 0L)
+ break;
+ if (kind > 22)
+ kind = 22;
+ JjCheckNAdd(37);
+ break;
+ default: break;
+ }
+ } while (i != startsAt);
+ }
+ else if (curChar < 128)
+ {
+ // NOTE: See the note in the Classic.QueryParserTokenManager.cs file.
+ // I am working under the assumption 63 is the correct value, since it
+ // made the tests pass there.
+ ulong l = (ulong)(1L << (curChar & 63));
+ //long l = 1L << (curChar & 077);
+ do
+ {
+ switch (jjstateSet[--i])
+ {
+ case 0:
+ if ((0xffffffffbfffffffL & l) != (ulong)0L)
+ {
+ if (kind > 22)
+ kind = 22;
+ JjCheckNAddStates(0, 4);
+ }
+ if ((0x400000004000L & l) != 0L)
+ {
+ if (kind > 12)
+ kind = 12;
+ }
+ else if ((0x80000000800000L & l) != 0L)
+ {
+ if (kind > 11)
+ kind = 11;
+ }
+ else if (curChar == 97)
+ jjstateSet[jjnewStateCnt++] = 9;
+ else if (curChar == 65)
+ jjstateSet[jjnewStateCnt++] = 6;
+ else if (curChar == 111)
+ jjstateSet[jjnewStateCnt++] = 3;
+ else if (curChar == 79)
+ jjstateSet[jjnewStateCnt++] = 1;
+ if (curChar == 110)
+ jjstateSet[jjnewStateCnt++] = 15;
+ else if (curChar == 78)
+ jjstateSet[jjnewStateCnt++] = 12;
+ break;
+ case 1:
+ if (curChar == 82 && kind > 8)
+ kind = 8;
+ break;
+ case 2:
+ if (curChar == 79)
+ jjstateSet[jjnewStateCnt++] = 1;
+ break;
+ case 3:
+ if (curChar == 114 && kind > 8)
+ kind = 8;
+ break;
+ case 4:
+ if (curChar == 111)
+ jjstateSet[jjnewStateCnt++] = 3;
+ break;
+ case 5:
+ if (curChar == 68 && kind > 9)
+ kind = 9;
+ break;
+ case 6:
+ if (curChar == 78)
+ jjstateSet[jjnewStateCnt++] = 5;
+ break;
+ case 7:
+ if (curChar == 65)
+ jjstateSet[jjnewStateCnt++] = 6;
+ break;
+ case 8:
+ if (curChar == 100 && kind > 9)
+ kind = 9;
+ break;
+ case 9:
+ if (curChar == 110)
+ jjstateSet[jjnewStateCnt++] = 8;
+ break;
+ case 10:
+ if (curChar == 97)
+ jjstateSet[jjnewStateCnt++] = 9;
+ break;
+ case 11:
+ if (curChar == 84 && kind > 10)
+ kind = 10;
+ break;
+ case 12:
+ if (curChar == 79)
+ jjstateSet[jjnewStateCnt++] = 11;
+ break;
+ case 13:
+ if (curChar == 78)
+ jjstateSet[jjnewStateCnt++] = 12;
+ break;
+ case 14:
+ if (curChar == 116 && kind > 10)
+ kind = 10;
+ break;
+ case 15:
+ if (curChar == 111)
+ jjstateSet[jjnewStateCnt++] = 14;
+ break;
+ case 16:
+ if (curChar == 110)
+ jjstateSet[jjnewStateCnt++] = 15;
+ break;
+ case 17:
+ if ((0x80000000800000L & l) != 0L && kind > 11)
+ kind = 11;
+ break;
+ case 18:
+ if ((0x400000004000L & l) != 0L && kind > 12)
+ kind = 12;
+ break;
+ case 24:
+ JjAddStates(15, 16);
+ break;
+ case 27:
+ if ((0xffffffffefffffffL & l) != (ulong)0L)
+ JjCheckNAddStates(12, 14);
+ break;
+ case 28:
+ if (curChar == 92)
+ jjstateSet[jjnewStateCnt++] = 29;
+ break;
+ case 29:
+ if (curChar == 92)
+ JjCheckNAddStates(12, 14);
+ break;
+ case 31:
+ if ((0xffffffffbfffffffL & l) == (ulong)0L)
+ break;
+ if (kind > 22)
+ kind = 22;
+ JjCheckNAddStates(0, 4);
+ break;
+ case 32:
+ if ((0xffffffffbfffffffL & l) != (ulong)0L)
+ JjCheckNAddTwoStates(32, 33);
+ break;
+ case 34:
+ if ((0xffffffffbfffffffL & l) != (ulong)0L)
+ JjCheckNAddTwoStates(34, 35);
+ break;
+ case 36:
+ if ((0xffffffffbfffffffL & l) == (ulong)0L)
+ break;
+ if (kind > 21)
+ kind = 21;
+ jjstateSet[jjnewStateCnt++] = 36;
+ break;
+ case 37:
+ if ((0xffffffffbfffffffL & l) == (ulong)0L)
+ break;
+ if (kind > 22)
+ kind = 22;
+ JjCheckNAdd(37);
+ break;
+ default: break;
+ }
+ } while (i != startsAt);
+ }
+ else
+ {
+ int hiByte = (int)(curChar >> 8);
+ int i1 = hiByte >> 6;
+ //long l1 = 1L << (hiByte & 077);
+ ulong l1 = (ulong)(1L << (hiByte & 63));
+ int i2 = (curChar & 0xff) >> 6;
+ //long l2 = 1L << (curChar & 077);
+ ulong l2 = (ulong)(1L << (curChar & 63));
+ do
+ {
+ switch (jjstateSet[--i])
+ {
+ case 0:
+ if (!JjCanMove_0(hiByte, i1, i2, l1, l2))
+ break;
+ if (kind > 22)
+ kind = 22;
+ JjCheckNAddStates(0, 4);
+ break;
+ case 24:
+ if (JjCanMove_0(hiByte, i1, i2, l1, l2))
+ JjAddStates(15, 16);
+ break;
+ case 27:
+ if (JjCanMove_0(hiByte, i1, i2, l1, l2))
+ JjAddStates(12, 14);
+ break;
+ case 32:
+ if (JjCanMove_0(hiByte, i1, i2, l1, l2))
+ JjCheckNAddTwoStates(32, 33);
+ break;
+ case 34:
+ if (JjCanMove_0(hiByte, i1, i2, l1, l2))
+ JjCheckNAddTwoStates(34, 35);
+ break;
+ case 36:
+ if (!JjCanMove_0(hiByte, i1, i2, l1, l2))
+ break;
+ if (kind > 21)
+ kind = 21;
+ jjstateSet[jjnewStateCnt++] = 36;
+ break;
+ case 37:
+ if (!JjCanMove_0(hiByte, i1, i2, l1, l2))
+ break;
+ if (kind > 22)
+ kind = 22;
+ JjCheckNAdd(37);
+ break;
+ default: break;
+ }
+ } while (i != startsAt);
+ }
+ if (kind != 0x7fffffff)
+ {
+ jjmatchedKind = kind;
+ jjmatchedPos = curPos;
+ kind = 0x7fffffff;
+ }
+ ++curPos;
+ if ((i = jjnewStateCnt) == (startsAt = 38 - (jjnewStateCnt = startsAt)))
+ return curPos;
+ try { curChar = input_stream.ReadChar(); }
+ catch (System.IO.IOException e) { return curPos; }
+ }
+ }
+
+ private int JjMoveStringLiteralDfa0_0()
+ {
+ return JjMoveNfa_0(0, 0);
+ }
+ private int JjMoveNfa_0(int startState, int curPos)
+ {
+ int startsAt = 0;
+ jjnewStateCnt = 3;
+ int i = 1;
+ jjstateSet[0] = startState;
+ int kind = 0x7fffffff;
+ for (; ; )
+ {
+ if (++jjround == 0x7fffffff)
+ ReInitRounds();
+ if (curChar < 64)
+ {
+ long l = 1L << curChar;
+ do
+ {
+ switch (jjstateSet[--i])
+ {
+ case 0:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 23)
+ kind = 23;
+ JjAddStates(17, 18);
+ break;
+ case 1:
+ if (curChar == 46)
+ JjCheckNAdd(2);
+ break;
+ case 2:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 23)
+ kind = 23;
+ JjCheckNAdd(2);
+ break;
+ default: break;
+ }
+ } while (i != startsAt);
+ }
+ else if (curChar < 128)
+ {
+ //long l = 1L << (curChar & 077);
+ ulong l = (ulong)(1L << (curChar & 63));
+ do
+ {
+ switch (jjstateSet[--i])
+ {
+ default: break;
+ }
+ } while (i != startsAt);
+ }
+ else
+ {
+ int hiByte = (int)(curChar >> 8);
+ int i1 = hiByte >> 6;
+ //long l1 = 1L << (hiByte & 077);
+ ulong l1 = (ulong)(1L << (hiByte & 63));
+ int i2 = (curChar & 0xff) >> 6;
+ //long l2 = 1L << (curChar & 077);
+ ulong l2 = (ulong)(1L << (curChar & 63));
+ do
+ {
+ switch (jjstateSet[--i])
+ {
+ default: break;
+ }
+ } while (i != startsAt);
+ }
+ if (kind != 0x7fffffff)
+ {
+ jjmatchedKind = kind;
+ jjmatchedPos = curPos;
+ kind = 0x7fffffff;
+ }
+ ++curPos;
+ if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
+ return curPos;
+ try { curChar = input_stream.ReadChar(); }
+ catch (System.IO.IOException e) { return curPos; }
+ }
+ }
+ internal static readonly int[] jjnextStates = {
+ 32, 33, 34, 35, 37, 24, 27, 28, 20, 17, 21, 18, 27, 28, 30, 24,
+ 25, 0, 1,
+ };
+ private static bool JjCanMove_0(int hiByte, int i1, int i2, ulong l1, ulong l2)
+ {
+ switch (hiByte)
+ {
+ case 0:
+ return ((jjbitVec2[i2] & l2) != 0L);
+ default:
+ if ((jjbitVec0[i1] & l1) != 0L)
+ return true;
+ return false;
+ }
+ }
+
+ /** Token literal values. */
+ //public static readonly string[] jjstrLiteralImages = {
+ // "", null, null, null, null, null, null, null, null, null, null, null, null,
+ // "\50", "\51", "\54", "\72", "\136", null, null, null, null, null, null
+ //};
+
+ public static readonly string[] jjstrLiteralImages = {
+ "", null, null, null, null, null, null, null, null, null, null, null, null,
+ "\x0028" /*"\50"*/, "\x0029" /*"\51"*/, "\x002C" /*"\54"*/, "\x003A" /*"\72"*/, "\x005E" /*"\136"*/, null, null, null, null, null, null
+ };
+
+ /** Lexer state names. */
+ public static readonly string[] lexStateNames = {
+ "Boost",
+ "DEFAULT"
+ };
+
+ /** Lex State array. */
+ public static readonly int[] jjnewLexState = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 1,
+ };
+ internal static readonly long[] jjtoToken = {
+ 0xffff01L,
+ };
+ internal static readonly long[] jjtoSkip = {
+ 0x80L,
+ };
+ protected ICharStream input_stream;
+ private readonly uint[] jjrounds = new uint[38];
+ private readonly int[] jjstateSet = new int[76];
+ protected internal char curChar;
+
+ /** Constructor. */
+ public QueryParserTokenManager(ICharStream stream)
+ {
+ InitBlock();
+ input_stream = stream;
+ }
+
+ /** Constructor. */
+ public QueryParserTokenManager(ICharStream stream, int lexState)
+ : this(stream)
+ {
+ SwitchTo(lexState);
+ }
+
+ /** Reinitialise parser. */
+ public void ReInit(ICharStream stream)
+ {
+ jjmatchedPos = jjnewStateCnt = 0;
+ curLexState = defaultLexState;
+ input_stream = stream;
+ ReInitRounds();
+ }
+ private void ReInitRounds()
+ {
+ int i;
+ jjround = 0x80000001;
+ for (i = 38; i-- > 0; )
+ jjrounds[i] = 0x80000000;
+ }
+
+ /** Reinitialise parser. */
+ public void ReInit(ICharStream stream, int lexState)
+ {
+ ReInit(stream);
+ SwitchTo(lexState);
+ }
+
+ /** Switch to specified lex state. */
+ public void SwitchTo(int lexState)
+ {
+ if (lexState >= 2 || lexState < 0)
+ throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
+ else
+ curLexState = lexState;
+ }
+
+ protected Token JjFillToken()
+ {
+ Token t;
+ string curTokenImage;
+ int beginLine;
+ int endLine;
+ int beginColumn;
+ int endColumn;
+ string im = jjstrLiteralImages[jjmatchedKind];
+ curTokenImage = (im == null) ? input_stream.Image : im;
+ beginLine = input_stream.BeginLine;
+ beginColumn = input_stream.BeginColumn;
+ endLine = input_stream.EndLine;
+ endColumn = input_stream.EndColumn;
+ t = Token.NewToken(jjmatchedKind, curTokenImage);
+
+ t.beginLine = beginLine;
+ t.endLine = endLine;
+ t.beginColumn = beginColumn;
+ t.endColumn = endColumn;
+
+ return t;
+ }
+
+ internal int curLexState = 1;
+ internal int defaultLexState = 1;
+ internal int jjnewStateCnt;
+ internal uint jjround;
+ internal int jjmatchedPos;
+ internal int jjmatchedKind;
+
+ /// <summary>Get the next Token.</summary>
+ [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
+ public Token GetNextToken()
+ {
+ Token matchedToken;
+ int curPos = 0;
+
+ for (; ; )
+ {
+ try
+ {
+ curChar = input_stream.BeginToken();
+ }
+ catch (System.IO.IOException e)
+ {
+ jjmatchedKind = 0;
+ matchedToken = JjFillToken();
+ return matchedToken;
+ }
+
+ switch (curLexState)
+ {
+ case 0:
+ jjmatchedKind = 0x7fffffff;
+ jjmatchedPos = 0;
+ curPos = JjMoveStringLiteralDfa0_0();
+ break;
+ case 1:
+ jjmatchedKind = 0x7fffffff;
+ jjmatchedPos = 0;
+ curPos = jjMoveStringLiteralDfa0_1();
+ break;
+ }
+ if (jjmatchedKind != 0x7fffffff)
+ {
+ if (jjmatchedPos + 1 < curPos)
+ input_stream.Backup(curPos - jjmatchedPos - 1);
+ if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
+ {
+ matchedToken = JjFillToken();
+ if (jjnewLexState[jjmatchedKind] != -1)
+ curLexState = jjnewLexState[jjmatchedKind];
+ return matchedToken;
+ }
+ else
+ {
+ if (jjnewLexState[jjmatchedKind] != -1)
+ curLexState = jjnewLexState[jjmatchedKind];
+ goto EOFLoop;
+ }
+ }
+ int error_line = input_stream.EndLine;
+ int error_column = input_stream.EndColumn;
+ string error_after = null;
+ bool EOFSeen = false;
+ try { input_stream.ReadChar(); input_stream.Backup(1); }
+ catch (System.IO.IOException e1)
+ {
+ EOFSeen = true;
+ error_after = curPos <= 1 ? "" : input_stream.Image;
+ if (curChar == '\n' || curChar == '\r')
+ {
+ error_line++;
+ error_column = 0;
+ }
+ else
+ error_column++;
+ }
+ if (!EOFSeen)
+ {
+ input_stream.Backup(1);
+ error_after = curPos <= 1 ? "" : input_stream.Image;
+ }
+ throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
+ EOFLoop: ;
+ }
+ }
+
+ private void JjCheckNAdd(int state)
+ {
+ if (jjrounds[state] != jjround)
+ {
+ jjstateSet[jjnewStateCnt++] = state;
+ jjrounds[state] = jjround;
+ }
+ }
+ private void JjAddStates(int start, int end)
+ {
+ do
+ {
+ jjstateSet[jjnewStateCnt++] = jjnextStates[start];
+ } while (start++ != end);
+ }
+ private void JjCheckNAddTwoStates(int state1, int state2)
+ {
+ JjCheckNAdd(state1);
+ JjCheckNAdd(state2);
+ }
+
+ private void JjCheckNAddStates(int start, int end)
+ {
+ do
+ {
+ JjCheckNAdd(jjnextStates[start]);
+ } while (start++ != end);
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e7576a6/Lucene.Net.QueryParser/Surround/Parser/Token.cs
----------------------------------------------------------------------
diff --git a/Lucene.Net.QueryParser/Surround/Parser/Token.cs b/Lucene.Net.QueryParser/Surround/Parser/Token.cs
new file mode 100644
index 0000000..2d9b83d
--- /dev/null
+++ b/Lucene.Net.QueryParser/Surround/Parser/Token.cs
@@ -0,0 +1,142 @@
+\ufeffusing System;
+
+namespace Lucene.Net.QueryParser.Surround.Parser
+{
+ /*
+ * 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.
+ */
+
+ /// <summary>
+ /// Describes the input token stream.
+ /// </summary>
+ [Serializable]
+ public class Token
+ {
+
+ /// <summary>
+ /// An integer that describes the kind of this token. This numbering
+ /// system is determined by JavaCCParser, and a table of these numbers is
+ /// stored in the file ...Constants.java.
+ /// </summary>
+ public int kind;
+
+ /// <summary>The line number of the first character of this Token. </summary>
+ public int beginLine;
+ /// <summary>The column number of the first character of this Token. </summary>
+ public int beginColumn;
+ /// <summary>The line number of the last character of this Token. </summary>
+ public int endLine;
+ /// <summary>The column number of the last character of this Token. </summary>
+ public int endColumn;
+
+ /// <summary>The string image of the token.</summary>
+ public string image;
+
+ /// <summary>
+ /// A reference to the next regular (non-special) token from the input
+ /// stream. If this is the last token from the input stream, or if the
+ /// token manager has not read tokens beyond this one, this field is
+ /// set to null. This is true only if this token is also a regular
+ /// token. Otherwise, see below for a description of the contents of
+ /// this field.
+ /// </summary>
+ public Token next;
+
+ /// <summary>
+ /// This field is used to access special tokens that occur prior to this
+ /// token, but after the immediately preceding regular (non-special) token.
+ /// If there are no such special tokens, this field is set to null.
+ /// When there are more than one such special token, this field refers
+ /// to the last of these special tokens, which in turn refers to the next
+ /// previous special token through its specialToken field, and so on
+ /// until the first special token (whose specialToken field is null).
+ /// The next fields of special tokens refer to other special tokens that
+ /// immediately follow it (without an intervening regular token). If there
+ /// is no such token, this field is null.
+ /// </summary>
+ public Token specialToken;
+
+ /// <summary>
+ /// An optional attribute value of the Token.
+ /// Tokens which are not used as syntactic sugar will often contain
+ /// meaningful values that will be used later on by the compiler or
+ /// interpreter. This attribute value is often different from the image.
+ /// Any subclass of Token that actually wants to return a non-null value can
+ /// override this method as appropriate.
+ /// </summary>
+ public virtual object Value
+ {
+ get { return null; }
+ }
+
+ /// <summary>
+ /// No-argument constructor
+ /// </summary>
+ public Token()
+ {
+ }
+
+ /// <summary>
+ /// Constructs a new token for the specified Image.
+ /// </summary>
+ public Token(int kind)
+ : this(kind, null)
+ {
+ }
+
+ /// <summary>
+ /// Constructs a new token for the specified Image and Kind.
+ /// </summary>
+ public Token(int kind, string image)
+ {
+ this.kind = kind;
+ this.image = image;
+ }
+
+ /// <summary>
+ /// Returns the image.
+ /// </summary>
+ public override string ToString()
+ {
+ return image;
+ }
+
+ /// <summary>
+ /// Returns a new Token object, by default. However, if you want, you
+ /// can create and return subclass objects based on the value of ofKind.
+ /// Simply add the cases to the switch for all those special cases.
+ /// For example, if you have a subclass of Token called IDToken that
+ /// you want to create if ofKind is ID, simply add something like :
+ ///
+ /// case MyParserConstants.ID : return new IDToken(ofKind, image);
+ ///
+ /// to the following switch statement. Then you can cast matchedToken
+ /// variable to the appropriate type and use sit in your lexical actions.
+ /// </summary>
+ public static Token NewToken(int ofKind, string image)
+ {
+ switch (ofKind)
+ {
+ default: return new Token(ofKind, image);
+ }
+ }
+
+ public static Token NewToken(int ofKind)
+ {
+ return NewToken(ofKind, null);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e7576a6/Lucene.Net.QueryParser/Surround/Parser/TokenMgrError.cs
----------------------------------------------------------------------
diff --git a/Lucene.Net.QueryParser/Surround/Parser/TokenMgrError.cs b/Lucene.Net.QueryParser/Surround/Parser/TokenMgrError.cs
new file mode 100644
index 0000000..2ccfc58
--- /dev/null
+++ b/Lucene.Net.QueryParser/Surround/Parser/TokenMgrError.cs
@@ -0,0 +1,170 @@
+\ufeffusing System;
+using System.Text;
+
+namespace Lucene.Net.QueryParser.Surround.Parser
+{
+ /*
+ * 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.
+ */
+
+ /// <summary>Token Manager Error. </summary>
+ [Serializable]
+ public class TokenMgrError : Exception
+ {
+ /*
+ * Ordinals for various reasons why an Error of this type can be thrown.
+ */
+
+ /// <summary> Lexical error occurred.</summary>
+ internal const int LEXICAL_ERROR = 0;
+
+ /// <summary> An attempt was made to create a second instance of a static token manager.</summary>
+ internal const int STATIC_LEXER_ERROR = 1;
+
+ /// <summary> Tried to change to an invalid lexical state.</summary>
+ internal const int INVALID_LEXICAL_STATE = 2;
+
+ /// <summary> Detected (and bailed out of) an infinite loop in the token manager.</summary>
+ internal const int LOOP_DETECTED = 3;
+
+ /// <summary> Indicates the reason why the exception is thrown. It will have
+ /// one of the above 4 values.
+ /// </summary>
+ internal int errorCode;
+
+ /// <summary>
+ /// Replaces unprintable characters by their escaped (or unicode escaped)
+ /// equivalents in the given string
+ /// </summary>
+ protected internal static string AddEscapes(string str)
+ {
+ StringBuilder retval = new StringBuilder();
+ char ch;
+ for (int i = 0; i < str.Length; i++)
+ {
+ switch (str[i])
+ {
+
+ case (char)(0):
+ continue;
+
+ case '\b':
+ retval.Append("\\b");
+ continue;
+
+ case '\t':
+ retval.Append("\\t");
+ continue;
+
+ case '\n':
+ retval.Append("\\n");
+ continue;
+
+ case '\f':
+ retval.Append("\\f");
+ continue;
+
+ case '\r':
+ retval.Append("\\r");
+ continue;
+
+ case '\"':
+ retval.Append("\\\"");
+ continue;
+
+ case '\'':
+ retval.Append("\\\'");
+ continue;
+
+ case '\\':
+ retval.Append("\\\\");
+ continue;
+
+ default:
+ if ((ch = str[i]) < 0x20 || ch > 0x7e)
+ {
+ string s = "0000" + Convert.ToString(ch, 16);
+ retval.Append("\\u" + s.Substring(s.Length - 4, (s.Length) - (s.Length - 4)));
+ }
+ else
+ {
+ retval.Append(ch);
+ }
+ continue;
+
+ }
+ }
+ return retval.ToString();
+ }
+
+ /// <summary>
+ /// Returns a detailed message for the Error when it is thrown by the
+ /// token manager to indicate a lexical error.
+ /// </summary>
+ /// <remarks>You can customize the lexical error message by modifying this method.</remarks>
+ /// <param name="EOFSeen">indicates if EOF caused the lexical error</param>
+ /// <param name="lexState">lexical state in which this error occurred</param>
+ /// <param name="errorLine">line number when the error occurred</param>
+ /// <param name="errorColumn">column number when the error occurred</param>
+ /// <param name="errorAfter">prefix that was seen before this error occurred</param>
+ /// <param name="curChar">the offending character</param>
+ /// <returns>Detailed error message</returns>
+ protected internal static string LexicalError(bool EOFSeen, int lexState, int errorLine, int errorColumn, string errorAfter, char curChar)
+ {
+ return ("Lexical error at line " +
+ errorLine + ", column " +
+ errorColumn + ". Encountered: " +
+ (EOFSeen ? "<EOF> " : ("\"" + AddEscapes(Convert.ToString(curChar)) + "\"") + " (" + (int)curChar + "), ") +
+ "after : \"" + AddEscapes(errorAfter) + "\"");
+ }
+
+ /// <summary>
+ /// You can also modify the body of this method to customize your error messages.
+ /// For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+ /// of end-users concern, so you can return something like :
+ ///
+ /// "Internal Error : Please file a bug report .... "
+ ///
+ /// from this method for such cases in the release version of your parser.
+ /// </summary>
+ public override string Message
+ {
+ get { return base.Message; }
+ }
+
+ /*
+ * Constructors of various flavors follow.
+ */
+
+ /// <summary>No arg constructor. </summary>
+ public TokenMgrError()
+ {
+ }
+
+ /// <summary>Constructor with message and reason. </summary>
+ public TokenMgrError(string message, int reason)
+ : base(message)
+ {
+ errorCode = reason;
+ }
+
+ /// <summary>Full Constructor. </summary>
+ public TokenMgrError(bool EOFSeen, int lexState, int errorLine, int errorColumn, string errorAfter, char curChar, int reason)
+ : this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason)
+ {
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e7576a6/Lucene.Net.QueryParser/Surround/Query/AndQuery.cs
----------------------------------------------------------------------
diff --git a/Lucene.Net.QueryParser/Surround/Query/AndQuery.cs b/Lucene.Net.QueryParser/Surround/Query/AndQuery.cs
new file mode 100644
index 0000000..aa00e0d
--- /dev/null
+++ b/Lucene.Net.QueryParser/Surround/Query/AndQuery.cs
@@ -0,0 +1,39 @@
+\ufeffusing Lucene.Net.Search;
+using System.Collections.Generic;
+
+namespace Lucene.Net.QueryParser.Surround.Query
+{
+ /*
+ * 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.
+ */
+
+ /// <summary>
+ /// Factory for conjunctions
+ /// </summary>
+ public class AndQuery : ComposedQuery
+ {
+ public AndQuery(IEnumerable<SrndQuery> queries, bool inf, string opName)
+ : base(queries, inf, opName)
+ {
+ }
+
+ public override Search.Query MakeLuceneQueryFieldNoBoost(string fieldName, BasicQueryFactory qf)
+ {
+ return SrndBooleanQuery.MakeBooleanQuery( /* subqueries can be individually boosted */
+ MakeLuceneSubQueriesField(fieldName, qf), BooleanClause.Occur.MUST);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e7576a6/Lucene.Net.QueryParser/Surround/Query/BasicQueryFactory.cs
----------------------------------------------------------------------
diff --git a/Lucene.Net.QueryParser/Surround/Query/BasicQueryFactory.cs b/Lucene.Net.QueryParser/Surround/Query/BasicQueryFactory.cs
new file mode 100644
index 0000000..8992746
--- /dev/null
+++ b/Lucene.Net.QueryParser/Surround/Query/BasicQueryFactory.cs
@@ -0,0 +1,110 @@
+\ufeffusing Lucene.Net.Index;
+using Lucene.Net.Search;
+using Lucene.Net.Search.Spans;
+using System.Runtime.CompilerServices;
+
+namespace Lucene.Net.QueryParser.Surround.Query
+{
+ /*
+ * 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.
+ */
+
+
+ // Create basic queries to be used during rewrite.
+ // The basic queries are TermQuery and SpanTermQuery.
+ // An exception can be thrown when too many of these are used.
+ // SpanTermQuery and TermQuery use IndexReader.termEnum(Term), which causes the buffer usage.
+
+ // Use this class to limit the buffer usage for reading terms from an index.
+ // Default is 1024, the same as the max. number of subqueries for a BooleanQuery.
+
+
+
+ /// <summary>
+ /// Factory for creating basic term queries
+ /// </summary>
+ public class BasicQueryFactory
+ {
+ public BasicQueryFactory(int maxBasicQueries)
+ {
+ this.maxBasicQueries = maxBasicQueries;
+ this.queriesMade = 0;
+ }
+
+ public BasicQueryFactory()
+ : this(1024)
+ {
+ }
+
+ private int maxBasicQueries;
+ private int queriesMade;
+
+ public int NrQueriesMade { get { return queriesMade; } }
+ public int MaxBasicQueries { get { return maxBasicQueries; } }
+
+ public override string ToString()
+ {
+ return GetType().Name
+ + "(maxBasicQueries: " + maxBasicQueries
+ + ", queriesMade: " + queriesMade
+ + ")";
+ }
+
+ private bool AtMax
+ {
+ get { return queriesMade >= maxBasicQueries; }
+ }
+
+ [MethodImpl(MethodImplOptions.Synchronized)]
+ protected virtual void CheckMax()
+ {
+ if (AtMax)
+ throw new TooManyBasicQueries(MaxBasicQueries);
+ queriesMade++;
+ }
+
+ public TermQuery NewTermQuery(Term term)
+ {
+ CheckMax();
+ return new TermQuery(term);
+ }
+
+ public SpanTermQuery NewSpanTermQuery(Term term)
+ {
+ CheckMax();
+ return new SpanTermQuery(term);
+ }
+
+ public override int GetHashCode()
+ {
+ return GetType().GetHashCode() ^ (AtMax ? 7 : 31 * 32);
+ }
+
+ /// <summary>
+ /// Two BasicQueryFactory's are equal when they generate
+ /// the same types of basic queries, or both cannot generate queries anymore.
+ /// </summary>
+ /// <param name="obj"></param>
+ /// <returns></returns>
+ public override bool Equals(object obj)
+ {
+ if (!(obj is BasicQueryFactory))
+ return false;
+ BasicQueryFactory other = (BasicQueryFactory)obj;
+ return AtMax == other.AtMax;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e7576a6/Lucene.Net.QueryParser/Surround/Query/ComposedQuery.cs
----------------------------------------------------------------------
diff --git a/Lucene.Net.QueryParser/Surround/Query/ComposedQuery.cs b/Lucene.Net.QueryParser/Surround/Query/ComposedQuery.cs
new file mode 100644
index 0000000..d421ad6
--- /dev/null
+++ b/Lucene.Net.QueryParser/Surround/Query/ComposedQuery.cs
@@ -0,0 +1,144 @@
+\ufeffusing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.QueryParser.Surround.Query
+{
+ /*
+ * 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.
+ */
+
+ /// <summary>
+ /// Base class for composite queries (such as AND/OR/NOT)
+ /// </summary>
+ public abstract class ComposedQuery : SrndQuery
+ {
+ public ComposedQuery(IEnumerable<SrndQuery> qs, bool operatorInfix, string opName)
+ {
+ Recompose(qs);
+ this.operatorInfix = operatorInfix;
+ this.opName = opName;
+ }
+
+ protected virtual void Recompose(IEnumerable<SrndQuery> queries)
+ {
+ if (queries.Count() < 2) throw new InvalidOperationException("Too few subqueries");
+ this.queries = new List<SrndQuery>(queries);
+ }
+
+ protected string opName;
+ public virtual string OperatorName { get { return opName; } }
+
+ protected IList<SrndQuery> queries;
+
+ public virtual IEnumerator<SrndQuery> GetSubQueriesEnumerator()
+ {
+ return queries.GetEnumerator();
+ }
+
+ public virtual int NrSubQueries { get { return queries.Count; } }
+
+ public virtual SrndQuery GetSubQuery(int qn) { return queries[qn]; }
+
+ private bool operatorInfix;
+ public virtual bool IsOperatorInfix { get { return operatorInfix; } } /* else prefix operator */
+
+ public IEnumerable<Search.Query> MakeLuceneSubQueriesField(string fn, BasicQueryFactory qf)
+ {
+ List<Search.Query> luceneSubQueries = new List<Search.Query>();
+ IEnumerator<SrndQuery> sqi = GetSubQueriesEnumerator();
+ while (sqi.MoveNext())
+ {
+ luceneSubQueries.Add((sqi.Current).MakeLuceneQueryField(fn, qf));
+ }
+ return luceneSubQueries;
+ }
+
+ public override string ToString()
+ {
+ StringBuilder r = new StringBuilder();
+ if (IsOperatorInfix)
+ {
+ InfixToString(r);
+ }
+ else
+ {
+ PrefixToString(r);
+ }
+ WeightToString(r);
+ return r.ToString();
+ }
+
+ // Override for different spacing
+ protected virtual string PrefixSeparator { get { return ", "; } }
+ protected virtual string BracketOpen { get { return "("; } }
+ protected virtual string BracketClose { get { return ")"; } }
+
+ protected virtual void InfixToString(StringBuilder r)
+ {
+ /* Brackets are possibly redundant in the result. */
+ IEnumerator<SrndQuery> sqi = GetSubQueriesEnumerator();
+ r.Append(BracketOpen);
+ if (sqi.MoveNext())
+ {
+ r.Append(sqi.Current.ToString());
+ while (sqi.MoveNext())
+ {
+ r.Append(" ");
+ r.Append(OperatorName); /* infix operator */
+ r.Append(" ");
+ r.Append(sqi.Current.ToString());
+ }
+ }
+ r.Append(BracketClose);
+ }
+
+ protected virtual void PrefixToString(StringBuilder r)
+ {
+ IEnumerator<SrndQuery> sqi = GetSubQueriesEnumerator();
+ r.Append(OperatorName); /* prefix operator */
+ r.Append(BracketOpen);
+ if (sqi.MoveNext())
+ {
+ r.Append(sqi.Current.ToString());
+ while (sqi.MoveNext())
+ {
+ r.Append(PrefixSeparator);
+ r.Append(sqi.Current.ToString());
+ }
+ }
+ r.Append(BracketClose);
+ }
+
+ public override bool IsFieldsSubQueryAcceptable
+ {
+ get
+ {
+ /* at least one subquery should be acceptable */
+ IEnumerator<SrndQuery> sqi = GetSubQueriesEnumerator();
+ while (sqi.MoveNext())
+ {
+ if ((sqi.Current).IsFieldsSubQueryAcceptable)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e7576a6/Lucene.Net.QueryParser/Surround/Query/DistanceQuery.cs
----------------------------------------------------------------------
diff --git a/Lucene.Net.QueryParser/Surround/Query/DistanceQuery.cs b/Lucene.Net.QueryParser/Surround/Query/DistanceQuery.cs
new file mode 100644
index 0000000..1ca7a01
--- /dev/null
+++ b/Lucene.Net.QueryParser/Surround/Query/DistanceQuery.cs
@@ -0,0 +1,117 @@
+\ufeffusing Lucene.Net.Index;
+using Lucene.Net.Search.Spans;
+using System;
+using System.Collections.Generic;
+
+namespace Lucene.Net.QueryParser.Surround.Query
+{
+ /*
+ * 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.
+ */
+
+ /// <summary>
+ /// Factory for NEAR queries
+ /// </summary>
+ public class DistanceQuery : ComposedQuery, IDistanceSubQuery
+ {
+ public DistanceQuery(
+ IEnumerable<SrndQuery> queries,
+ bool infix,
+ int opDistance,
+ string opName,
+ bool ordered)
+ : base(queries, infix, opName)
+ {
+ this.opDistance = opDistance; /* the distance indicated in the operator */
+ this.ordered = ordered;
+ }
+
+ private int opDistance;
+ public virtual int OpDistance { get { return opDistance; } }
+
+ private bool ordered;
+ public virtual bool QueriesOrdered { get { return ordered; } }
+
+
+ public virtual string DistanceSubQueryNotAllowed()
+ {
+ var sqi = GetSubQueriesEnumerator();
+ while (sqi.MoveNext())
+ {
+ var dsq = sqi.Current as IDistanceSubQuery;
+ if (dsq != null)
+ {
+ string m = dsq.DistanceSubQueryNotAllowed();
+ if (m != null)
+ {
+ return m;
+ }
+ }
+ else
+ {
+ return "Operator " + OperatorName + " does not allow subquery " + dsq.ToString();
+ }
+ }
+ return null; /* subqueries acceptable */
+ }
+
+ public virtual void AddSpanQueries(SpanNearClauseFactory sncf)
+ {
+ Search.Query snq = GetSpanNearQuery(sncf.IndexReader,
+ sncf.FieldName,
+ Weight,
+ sncf.BasicQueryFactory);
+ sncf.AddSpanQuery(snq);
+ }
+
+ public Search.Query GetSpanNearQuery(
+ IndexReader reader,
+ String fieldName,
+ float boost,
+ BasicQueryFactory qf)
+ {
+ SpanQuery[] spanClauses = new SpanQuery[NrSubQueries];
+ var sqi = GetSubQueriesEnumerator();
+ int qi = 0;
+ while (sqi.MoveNext())
+ {
+ SpanNearClauseFactory sncf = new SpanNearClauseFactory(reader, fieldName, qf);
+
+ ((IDistanceSubQuery)sqi.Current).AddSpanQueries(sncf);
+ if (sncf.Count == 0)
+ { /* distance operator requires all sub queries */
+ while (sqi.MoveNext())
+ { /* produce evt. error messages but ignore results */
+ ((IDistanceSubQuery)sqi.Current).AddSpanQueries(sncf);
+ sncf.Clear();
+ }
+ return SrndQuery.TheEmptyLcnQuery;
+ }
+
+ spanClauses[qi] = sncf.MakeSpanClause();
+ qi++;
+ }
+ SpanNearQuery r = new SpanNearQuery(spanClauses, OpDistance - 1, QueriesOrdered);
+ r.Boost = boost;
+ return r;
+ }
+
+ public override Search.Query MakeLuceneQueryFieldNoBoost(string fieldName, BasicQueryFactory qf)
+ {
+ return new DistanceRewriteQuery(this, fieldName, qf);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e7576a6/Lucene.Net.QueryParser/Surround/Query/DistanceRewriteQuery.cs
----------------------------------------------------------------------
diff --git a/Lucene.Net.QueryParser/Surround/Query/DistanceRewriteQuery.cs b/Lucene.Net.QueryParser/Surround/Query/DistanceRewriteQuery.cs
new file mode 100644
index 0000000..3d3a108
--- /dev/null
+++ b/Lucene.Net.QueryParser/Surround/Query/DistanceRewriteQuery.cs
@@ -0,0 +1,35 @@
+\ufeffnamespace Lucene.Net.QueryParser.Surround.Query
+{
+ /*
+ * 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.
+ */
+
+ internal class DistanceRewriteQuery : RewriteQuery<DistanceQuery>
+ {
+ public DistanceRewriteQuery(
+ DistanceQuery srndQuery,
+ string fieldName,
+ BasicQueryFactory qf)
+ : base(srndQuery, fieldName, qf)
+ {
+ }
+
+ public override Search.Query Rewrite(Index.IndexReader reader)
+ {
+ return srndQuery.GetSpanNearQuery(reader, fieldName, Boost, qf);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e7576a6/Lucene.Net.QueryParser/Surround/Query/DistanceSubQuery.cs
----------------------------------------------------------------------
diff --git a/Lucene.Net.QueryParser/Surround/Query/DistanceSubQuery.cs b/Lucene.Net.QueryParser/Surround/Query/DistanceSubQuery.cs
new file mode 100644
index 0000000..639f9e0
--- /dev/null
+++ b/Lucene.Net.QueryParser/Surround/Query/DistanceSubQuery.cs
@@ -0,0 +1,36 @@
+\ufeffnamespace Lucene.Net.QueryParser.Surround.Query
+{
+ /*
+ * 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.
+ */
+
+ /// <summary>
+ /// Interface for queries that can be nested as subqueries
+ /// into a span near.
+ /// </summary>
+ public interface IDistanceSubQuery
+ {
+ /// <summary>
+ /// When distanceSubQueryNotAllowed() returns non null, the reason why the subquery
+ /// is not allowed as a distance subquery is returned.
+ /// <br>When distanceSubQueryNotAllowed() returns null addSpanNearQueries() can be used
+ /// in the creation of the span near clause for the subquery.
+ /// </summary>
+ string DistanceSubQueryNotAllowed();
+
+ void AddSpanQueries(SpanNearClauseFactory sncf);
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e7576a6/Lucene.Net.QueryParser/Surround/Query/FieldsQuery.cs
----------------------------------------------------------------------
diff --git a/Lucene.Net.QueryParser/Surround/Query/FieldsQuery.cs b/Lucene.Net.QueryParser/Surround/Query/FieldsQuery.cs
new file mode 100644
index 0000000..912bf36
--- /dev/null
+++ b/Lucene.Net.QueryParser/Surround/Query/FieldsQuery.cs
@@ -0,0 +1,105 @@
+\ufeffusing System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Lucene.Net.QueryParser.Surround.Query
+{
+ /*
+ * 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.
+ */
+
+ /// <summary>
+ /// Forms an OR query of the provided query across multiple fields.
+ /// </summary>
+ public class FieldsQuery : SrndQuery /* mostly untested */
+ {
+ private SrndQuery q;
+ private IEnumerable<string> fieldNames;
+ private readonly char fieldOp;
+ private readonly string OrOperatorName = "OR"; /* for expanded queries, not normally visible */
+
+ public FieldsQuery(SrndQuery q, IEnumerable<string> fieldNames, char fieldOp)
+ {
+ this.q = q;
+ this.fieldNames = new List<string>(fieldNames);
+ this.fieldOp = fieldOp;
+ }
+
+ public FieldsQuery(SrndQuery q, string fieldName, char fieldOp)
+ {
+ this.q = q;
+ var fieldNameList = new List<string>();
+ fieldNameList.Add(fieldName);
+ this.fieldNames = fieldNameList;
+ this.fieldOp = fieldOp;
+ }
+
+ public override bool IsFieldsSubQueryAcceptable
+ {
+ get { return false; }
+ }
+
+ public Search.Query MakeLuceneQueryNoBoost(BasicQueryFactory qf)
+ {
+ if (fieldNames.Count() == 1)
+ { /* single field name: no new queries needed */
+ return q.MakeLuceneQueryFieldNoBoost(fieldNames.FirstOrDefault(), qf);
+ }
+ else
+ { /* OR query over the fields */
+ List<SrndQuery> queries = new List<SrndQuery>();
+ foreach (var fieldName in fieldNames)
+ {
+ var qc = (SrndQuery)q.Clone();
+ queries.Add(new FieldsQuery(qc, fieldName, fieldOp));
+ }
+ OrQuery oq = new OrQuery(queries,
+ true /* infix OR for field names */,
+ OrOperatorName);
+ // System.out.println(getClass().toString() + ", fields expanded: " + oq.toString()); /* needs testing */
+ return oq.MakeLuceneQueryField(null, qf);
+ }
+ }
+
+ public override Search.Query MakeLuceneQueryFieldNoBoost(string fieldName, BasicQueryFactory qf)
+ {
+ return MakeLuceneQueryNoBoost(qf); /* use this.fieldNames instead of fieldName */
+ }
+
+ public virtual IEnumerable<string> FieldNames { get { return fieldNames; } }
+
+ public virtual char FieldOperator { get { return fieldOp; } }
+
+ public override string ToString()
+ {
+ StringBuilder r = new StringBuilder();
+ r.Append("(");
+ FieldNamesToString(r);
+ r.Append(q.ToString());
+ r.Append(")");
+ return r.ToString();
+ }
+
+ protected virtual void FieldNamesToString(StringBuilder r)
+ {
+ foreach (var fieldName in FieldNames)
+ {
+ r.Append(fieldName);
+ r.Append(FieldOperator);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e7576a6/Lucene.Net.QueryParser/Surround/Query/NotQuery.cs
----------------------------------------------------------------------
diff --git a/Lucene.Net.QueryParser/Surround/Query/NotQuery.cs b/Lucene.Net.QueryParser/Surround/Query/NotQuery.cs
new file mode 100644
index 0000000..30d40a8
--- /dev/null
+++ b/Lucene.Net.QueryParser/Surround/Query/NotQuery.cs
@@ -0,0 +1,48 @@
+\ufeffusing Lucene.Net.Search;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Lucene.Net.QueryParser.Surround.Query
+{
+ /*
+ * 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.
+ */
+
+ /// <summary>
+ /// Factory for prohibited clauses
+ /// </summary>
+ public class NotQuery : ComposedQuery
+ {
+ public NotQuery(IEnumerable<SrndQuery> queries, string opName)
+ : base(queries, true /* infix */, opName)
+ {
+ }
+
+ public override Search.Query MakeLuceneQueryFieldNoBoost(string fieldName, BasicQueryFactory qf)
+ {
+ var luceneSubQueries = MakeLuceneSubQueriesField(fieldName, qf);
+ BooleanQuery bq = new BooleanQuery();
+ bq.Add(luceneSubQueries.FirstOrDefault(), BooleanClause.Occur.MUST);
+ SrndBooleanQuery.AddQueriesToBoolean(bq,
+ // FIXME: do not allow weights on prohibited subqueries.
+ //luceneSubQueries.subList(1, luceneSubQueries.size()),
+ luceneSubQueries.Skip(1).ToList(),
+ // later subqueries: not required, prohibited
+ BooleanClause.Occur.MUST_NOT);
+ return bq;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e7576a6/Lucene.Net.QueryParser/Surround/Query/OrQuery.cs
----------------------------------------------------------------------
diff --git a/Lucene.Net.QueryParser/Surround/Query/OrQuery.cs b/Lucene.Net.QueryParser/Surround/Query/OrQuery.cs
new file mode 100644
index 0000000..f7d0036
--- /dev/null
+++ b/Lucene.Net.QueryParser/Surround/Query/OrQuery.cs
@@ -0,0 +1,71 @@
+\ufeffusing Lucene.Net.Search;
+using System.Collections.Generic;
+
+namespace Lucene.Net.QueryParser.Surround.Query
+{
+ /*
+ * 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.
+ */
+
+ /// <summary>
+ /// Factory for disjunctions
+ /// </summary>
+ public class OrQuery : ComposedQuery, IDistanceSubQuery
+ {
+ public OrQuery(IEnumerable<SrndQuery> queries, bool infix, string opName)
+ : base(queries, infix, opName)
+ {
+ }
+
+ public override Search.Query MakeLuceneQueryFieldNoBoost(string fieldName, BasicQueryFactory qf)
+ {
+ return SrndBooleanQuery.MakeBooleanQuery(
+ /* subqueries can be individually boosted */
+ MakeLuceneSubQueriesField(fieldName, qf), BooleanClause.Occur.SHOULD);
+ }
+
+ public virtual string DistanceSubQueryNotAllowed()
+ {
+ var sqi = GetSubQueriesEnumerator();
+ while (sqi.MoveNext())
+ {
+ SrndQuery leq = sqi.Current;
+ if (leq is IDistanceSubQuery)
+ {
+ string m = ((IDistanceSubQuery)leq).DistanceSubQueryNotAllowed();
+ if (m != null)
+ {
+ return m;
+ }
+ }
+ else
+ {
+ return "subquery not allowed: " + leq.ToString();
+ }
+ }
+ return null;
+ }
+
+ public virtual void AddSpanQueries(SpanNearClauseFactory sncf)
+ {
+ var sqi = GetSubQueriesEnumerator();
+ while (sqi.MoveNext())
+ {
+ ((IDistanceSubQuery)sqi.Current).AddSpanQueries(sncf);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e7576a6/Lucene.Net.QueryParser/Surround/Query/RewriteQuery.cs
----------------------------------------------------------------------
diff --git a/Lucene.Net.QueryParser/Surround/Query/RewriteQuery.cs b/Lucene.Net.QueryParser/Surround/Query/RewriteQuery.cs
new file mode 100644
index 0000000..030923f
--- /dev/null
+++ b/Lucene.Net.QueryParser/Surround/Query/RewriteQuery.cs
@@ -0,0 +1,85 @@
+\ufeffusing Lucene.Net.Index;
+using System;
+
+namespace Lucene.Net.QueryParser.Surround.Query
+{
+ /*
+ * 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.
+ */
+
+ public abstract class RewriteQuery<SQ> : Search.Query
+ {
+ protected readonly SQ srndQuery;
+ protected readonly string fieldName;
+ protected readonly BasicQueryFactory qf;
+
+ public RewriteQuery(
+ SQ srndQuery,
+ String fieldName,
+ BasicQueryFactory qf)
+ {
+ this.srndQuery = srndQuery;
+ this.fieldName = fieldName;
+ this.qf = qf;
+ }
+
+ public abstract override Search.Query Rewrite(IndexReader reader);
+
+ public override string ToString()
+ {
+ return ToString(null);
+ }
+
+ public override string ToString(string field)
+ {
+ return GetType().Name
+ + (field == null ? "" : "(unused: " + field + ")")
+ + "(" + fieldName
+ + ", " + srndQuery.ToString()
+ + ", " + qf.ToString()
+ + ")";
+ }
+
+ public override int GetHashCode()
+ {
+ return GetType().GetHashCode()
+ ^ fieldName.GetHashCode()
+ ^ qf.GetHashCode()
+ ^ srndQuery.GetHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj == null)
+ return false;
+ if (!GetType().Equals(obj.GetType()))
+ return false;
+ RewriteQuery<SQ> other = (RewriteQuery<SQ>)obj;
+ return fieldName.Equals(other.fieldName)
+ && qf.Equals(other.qf)
+ && srndQuery.Equals(other.srndQuery);
+ }
+
+ /// <summary>
+ /// Not supported by this query.
+ /// </summary>
+ /// <exception cref="NotSupportedException">throws NotSupportedException always: clone is not supported.</exception>
+ public override object Clone()
+ {
+ throw new NotSupportedException();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e7576a6/Lucene.Net.QueryParser/Surround/Query/SimpleTerm.cs
----------------------------------------------------------------------
diff --git a/Lucene.Net.QueryParser/Surround/Query/SimpleTerm.cs b/Lucene.Net.QueryParser/Surround/Query/SimpleTerm.cs
new file mode 100644
index 0000000..5e39e03
--- /dev/null
+++ b/Lucene.Net.QueryParser/Surround/Query/SimpleTerm.cs
@@ -0,0 +1,118 @@
+\ufeffusing Lucene.Net.Index;
+using System;
+using System.Text;
+
+namespace Lucene.Net.QueryParser.Surround.Query
+{
+ /*
+ * 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.
+ */
+
+ /// <summary>
+ /// Base class for queries that expand to sets of simple terms.
+ /// </summary>
+ public abstract class SimpleTerm : SrndQuery, IDistanceSubQuery, IComparable<SimpleTerm>
+ {
+ public SimpleTerm(bool q)
+ {
+ quoted = q;
+ }
+
+ private bool quoted;
+ internal bool IsQuoted { get { return quoted; } }
+
+ public virtual string Quote { get { return "\""; }}
+ public virtual string FieldOperator { get { return "/"; } }
+
+ public abstract string ToStringUnquoted();
+
+ [Obsolete("deprecated (March 2011) Not normally used, to be removed from Lucene 4.0. This class implementing Comparable is to be removed at the same time.")]
+ public int CompareTo(SimpleTerm ost)
+ {
+ /* for ordering terms and prefixes before using an index, not used */
+ return this.ToStringUnquoted().CompareTo(ost.ToStringUnquoted());
+ }
+
+ protected virtual void SuffixToString(StringBuilder r) { } /* override for prefix query */
+
+
+ public override string ToString()
+ {
+ StringBuilder r = new StringBuilder();
+ if (IsQuoted)
+ {
+ r.Append(Quote);
+ }
+ r.Append(ToStringUnquoted());
+ if (IsQuoted)
+ {
+ r.Append(Quote);
+ }
+ SuffixToString(r);
+ WeightToString(r);
+ return r.ToString();
+ }
+
+ public abstract void VisitMatchingTerms(
+ IndexReader reader,
+ string fieldName,
+ IMatchingTermVisitor mtv);
+
+ /// <summary>
+ /// Callback to visit each matching term during "rewrite"
+ /// in <see cref="M:VisitMatchingTerm(Term)"/>
+ /// </summary>
+ public interface IMatchingTermVisitor
+ {
+ void VisitMatchingTerm(Term t);
+ }
+
+ public string DistanceSubQueryNotAllowed()
+ {
+ return null;
+ }
+
+ public void AddSpanQueries(SpanNearClauseFactory sncf)
+ {
+ VisitMatchingTerms(
+ sncf.IndexReader,
+ sncf.FieldName,
+ new AddSpanQueriesMatchingTermVisitor(sncf, Weight));
+ }
+
+ internal class AddSpanQueriesMatchingTermVisitor : IMatchingTermVisitor
+ {
+ private readonly SpanNearClauseFactory sncf;
+ private readonly float weight;
+
+ public AddSpanQueriesMatchingTermVisitor(SpanNearClauseFactory sncf, float weight)
+ {
+ this.sncf = sncf;
+ this.weight = weight;
+ }
+
+ public void VisitMatchingTerm(Term term)
+ {
+ sncf.AddTermWeighted(term, weight);
+ }
+ }
+
+ public override Search.Query MakeLuceneQueryFieldNoBoost(string fieldName, BasicQueryFactory qf)
+ {
+ return new SimpleTermRewriteQuery(this, fieldName, qf);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/1e7576a6/Lucene.Net.QueryParser/Surround/Query/SimpleTermRewriteQuery.cs
----------------------------------------------------------------------
diff --git a/Lucene.Net.QueryParser/Surround/Query/SimpleTermRewriteQuery.cs b/Lucene.Net.QueryParser/Surround/Query/SimpleTermRewriteQuery.cs
new file mode 100644
index 0000000..6502d6c
--- /dev/null
+++ b/Lucene.Net.QueryParser/Surround/Query/SimpleTermRewriteQuery.cs
@@ -0,0 +1,64 @@
+\ufeffusing Lucene.Net.Index;
+using Lucene.Net.Search;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Lucene.Net.QueryParser.Surround.Query
+{
+ /*
+ * 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.
+ */
+
+ internal class SimpleTermRewriteQuery : RewriteQuery<SimpleTerm>
+ {
+ public SimpleTermRewriteQuery(
+ SimpleTerm srndQuery,
+ string fieldName,
+ BasicQueryFactory qf)
+ : base(srndQuery, fieldName, qf)
+ {
+ }
+
+ public override Search.Query Rewrite(IndexReader reader)
+ {
+ var luceneSubQueries = new List<Search.Query>();
+ srndQuery.VisitMatchingTerms(reader, fieldName,
+ new SimpleTermRewriteMatchingTermVisitor(luceneSubQueries, qf));
+ return (luceneSubQueries.Count == 0) ? SrndQuery.TheEmptyLcnQuery
+ : (luceneSubQueries.Count == 1) ? luceneSubQueries.First()
+ : SrndBooleanQuery.MakeBooleanQuery(
+ /* luceneSubQueries all have default weight */
+ luceneSubQueries, BooleanClause.Occur.SHOULD); /* OR the subquery terms */
+ }
+
+ internal class SimpleTermRewriteMatchingTermVisitor : SimpleTerm.IMatchingTermVisitor
+ {
+ private readonly IList<Search.Query> luceneSubQueries;
+ private readonly BasicQueryFactory qf;
+
+ public SimpleTermRewriteMatchingTermVisitor(IList<Search.Query> luceneSubQueries, BasicQueryFactory qf)
+ {
+ this.luceneSubQueries = luceneSubQueries;
+ this.qf = qf;
+ }
+
+ public void VisitMatchingTerm(Term term)
+ {
+ luceneSubQueries.Add(qf.NewTermQuery(term));
+ }
+ }
+ }
+}