Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Patch for QueryParser to avoid throwing lots of exceptions that slows down the debugger #131

Open
wants to merge 1 commit into
base: 3.0.3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 30 additions & 28 deletions src/core/QueryParser/CharStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public interface ICharStream
/// implementing this interface. Can throw any java.io.IOException.
/// </summary>
char ReadChar();
char ReadChar(ref bool? systemIoException);

/// <summary> Returns the column position of the character last read.</summary>
/// <deprecated>
Expand Down Expand Up @@ -82,17 +83,18 @@ public interface ICharStream
int BeginLine { get; }

/// <summary> Backs up the input stream by amount steps. Lexer calls this method if it
/// had already read some characters, but could not use them to match a
/// (longer) token. So, they will be used again as the prefix of the next
/// token and it is the implemetation's responsibility to do this right.
/// </summary>
void Backup(int amount);
/// had already read some characters, but could not use them to match a
/// (longer) token. So, they will be used again as the prefix of the next
/// token and it is the implemetation's responsibility to do this right.
/// </summary>
void Backup(int amount);

/// <summary> Returns the next character that marks the beginning of the next token.
/// All characters must remain in the buffer between two successive calls
/// to this method to implement backup correctly.
/// </summary>
char BeginToken();
/// <summary> Returns the next character that marks the beginning of the next token.
/// All characters must remain in the buffer between two successive calls
/// to this method to implement backup correctly.
/// </summary>
char BeginToken();
char BeginToken(ref bool? systemIoException);

/// <summary> Returns a string made up of characters from the marked token beginning
/// to the current buffer position. Implementations have the choice of returning
Expand All @@ -102,23 +104,23 @@ public interface ICharStream
string Image { get; }

/// <summary> Returns an array of characters that make up the suffix of length 'len' for
/// the currently matched token. This is used to build up the matched string
/// for use in actions in the case of MORE. A simple and inefficient
/// implementation of this is as follows :
///
/// {
/// String t = GetImage();
/// return t.substring(t.length() - len, t.length()).toCharArray();
/// }
/// </summary>
char[] GetSuffix(int len);
/// <summary> The lexer calls this function to indicate that it is done with the stream
/// and hence implementations can free any resources held by this class.
/// Again, the body of this function can be just empty and it will not
/// affect the lexer's operation.
/// </summary>
void Done();
/// the currently matched token. This is used to build up the matched string
/// for use in actions in the case of MORE. A simple and inefficient
/// implementation of this is as follows :
///
/// {
/// String t = GetImage();
/// return t.substring(t.length() - len, t.length()).toCharArray();
/// }
/// </summary>
char[] GetSuffix(int len);
/// <summary> The lexer calls this function to indicate that it is done with the stream
/// and hence implementations can free any resources held by this class.
/// Again, the body of this function can be just empty and it will not
/// affect the lexer's operation.
/// </summary>
void Done();
}
/* JavaCC - OriginalChecksum=32a89423891f765dde472f7ef0e3ef7b (do not edit this line) */
}
}
106 changes: 73 additions & 33 deletions src/core/QueryParser/FastCharStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,35 @@ public FastCharStream(System.IO.TextReader r)

public char ReadChar()
{
bool? systemIoException = null;
if (bufferPosition >= bufferLength)
Refill();
{
Refill(ref systemIoException);
}
return buffer[bufferPosition++];
}

public char ReadChar(ref bool? systemIoException)
{
if (bufferPosition >= bufferLength)
{
Refill(ref systemIoException);
// If using this Nullable as System.IO.IOException signal and is signaled.
if (systemIoException.HasValue && systemIoException.Value == true)
{
return '\0';
}
}
return buffer[bufferPosition++];
}

private void Refill()
// You may ask to be signaled of a System.IO.IOException through the systemIoException parameter.
// Set it to false if you are interested, it will be set to true to signal a System.IO.IOException.
// Set it to null if you are not interested.
// This is used to avoid having a lot of System.IO.IOExceptions thrown while running the code under a debugger.
// Having a lot of exceptions thrown under a debugger causes the code to execute a lot more slowly.
// So use this if you are experimenting a lot of slow parsing at runtime under a debugger.
private void Refill(ref bool? systemIoException)
{
int newPosition = bufferLength - tokenStart;

Expand Down Expand Up @@ -86,7 +109,18 @@ private void Refill()

int charsRead = input.Read(buffer, newPosition, buffer.Length - newPosition);
if (charsRead <= 0)
throw new System.IO.IOException("read past eof");
{
// If interested in using this Nullable to signal a System.IO.IOException
if (systemIoException.HasValue)
{
systemIoException = true;
return;
}
else
{
throw new System.IO.IOException("read past eof");
}
}
else
bufferLength += charsRead;
}
Expand All @@ -96,18 +130,24 @@ public char BeginToken()
tokenStart = bufferPosition;
return ReadChar();
}

public char BeginToken(ref bool? systemIoException)
{
tokenStart = bufferPosition;
return ReadChar(ref systemIoException);
}

public void Backup(int amount)
{
bufferPosition -= amount;
}

public string Image
{
get { return new System.String(buffer, tokenStart, bufferPosition - tokenStart); }
}
public string Image
{
get { return new System.String(buffer, tokenStart, bufferPosition - tokenStart); }
}

public char[] GetSuffix(int len)
public char[] GetSuffix(int len)
{
char[] value_Renamed = new char[len];
Array.Copy(buffer, bufferPosition - len, value_Renamed, 0, len);
Expand All @@ -126,34 +166,34 @@ public void Done()
}
}

public int Column
{
get { return bufferStart + bufferPosition; }
}
public int Column
{
get { return bufferStart + bufferPosition; }
}

public int Line
{
get { return 1; }
}
public int Line
{
get { return 1; }
}

public int EndColumn
{
get { return bufferStart + bufferPosition; }
}
public int EndColumn
{
get { return bufferStart + bufferPosition; }
}

public int EndLine
{
get { return 1; }
}
public int EndLine
{
get { return 1; }
}

public int BeginColumn
{
get { return bufferStart + tokenStart; }
}
public int BeginColumn
{
get { return bufferStart + tokenStart; }
}

public int BeginLine
{
get { return 1; }
}
public int BeginLine
{
get { return 1; }
}
}
}
}
88 changes: 42 additions & 46 deletions src/core/QueryParser/QueryParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1708,46 +1708,45 @@ public Query Term(String field)
}

private bool Jj_2_1(int xla)
{
{
bool lookaheadSuccess = false;
jj_la = xla;
jj_lastpos = jj_scanpos = token;
try
{
return !Jj_3_1();
}
catch (LookaheadSuccess)
{
return true;
return !Jj_3_1(out lookaheadSuccess);
}
finally
{
Jj_save(0, xla);
}
}

private bool Jj_3R_2()
{
if (jj_scan_token(TermToken)) return true;
if (jj_scan_token(ColonToken)) return true;
private bool Jj_3R_2(out bool lookaheadSuccess)
{
if (jj_scan_token(TermToken, out lookaheadSuccess)) return true;
if (lookaheadSuccess) return false;
if (jj_scan_token(ColonToken, out lookaheadSuccess)) return true;
return false;
}

private bool Jj_3_1()
private bool Jj_3_1(out bool lookaheadSuccess)
{
Token xsp;
xsp = jj_scanpos;
if (Jj_3R_2())
if (Jj_3R_2(out lookaheadSuccess))
{
jj_scanpos = xsp;
if (Jj_3R_3()) return true;
if (Jj_3R_3(out lookaheadSuccess)) return true;
}
return false;
}

private bool Jj_3R_3()
{
if (jj_scan_token(StarToken)) return true;
if (jj_scan_token(ColonToken)) return true;
private bool Jj_3R_3(out bool lookaheadSuccess)
{
if (jj_scan_token(StarToken, out lookaheadSuccess)) return true;
if (lookaheadSuccess) return false;
if (jj_scan_token(ColonToken, out lookaheadSuccess)) return true;
return false;
}

Expand Down Expand Up @@ -1861,14 +1860,9 @@ private Token Jj_consume_token(int kind)
throw GenerateParseException();
}

[Serializable]
private sealed class LookaheadSuccess : System.Exception
{
}

private LookaheadSuccess jj_ls = new LookaheadSuccess();
private bool jj_scan_token(int kind)
{
private bool jj_scan_token(int kind, out bool lookaheadSuccess)
{
lookaheadSuccess = false;
if (jj_scanpos == jj_lastpos)
{
jj_la--;
Expand Down Expand Up @@ -1896,8 +1890,8 @@ private bool jj_scan_token(int kind)
}
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;
if (jj_scanpos.kind != kind) return true;
if (jj_la == 0 && jj_scanpos == jj_lastpos) lookaheadSuccess = true;
return false;
}

Expand Down Expand Up @@ -2029,32 +2023,34 @@ public void Disable_tracing()
}

private void Jj_rescan_token()
{
{
bool lookaheadSuccess = false;
jj_rescan = true;
for (int i = 0; i < 1; i++)
{
try
JJCalls p = jj_2_rtns[i];
do
{
JJCalls p = jj_2_rtns[i];
do
if (p.gen > jj_gen)
{
if (p.gen > jj_gen)
jj_la = p.arg;
jj_lastpos = jj_scanpos = p.first;
switch (i)
{
jj_la = p.arg;
jj_lastpos = jj_scanpos = p.first;
switch (i)
{
case 0:
Jj_3_1();
break;
}
case 0:
Jj_3_1(out lookaheadSuccess);
if (lookaheadSuccess)
{
goto Jj_rescan_token_after_while_label;
}
break;
}
p = p.next;
} while (p != null);
}
catch (LookaheadSuccess)
{
}
}
p = p.next;
} while (p != null);
Jj_rescan_token_after_while_label:
lookaheadSuccess = false;
}
jj_rescan = false;
}
Expand Down
11 changes: 9 additions & 2 deletions src/core/QueryParser/QueryParserTokenManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1341,9 +1341,16 @@ public virtual Token GetNextToken()

for (; ; )
{
bool? systemIoException = false;
try
{
curChar = input_stream.BeginToken();
curChar = input_stream.BeginToken(ref systemIoException);
if (systemIoException != null && systemIoException.HasValue && systemIoException.Value == true)
{
jjmatchedKind = 0;
matchedToken = JjFillToken();
return matchedToken;
}
}
catch (System.IO.IOException)
{
Expand Down Expand Up @@ -1459,4 +1466,4 @@ private void JjCheckNAddStates(int start, int end)
while (start++ != end);
}
}
}
}