From 2fce2b0f2d03e62c33e8cd2ff6c0ac5aa3e5f916 Mon Sep 17 00:00:00 2001 From: sharwell Date: Thu, 17 Nov 2011 16:02:58 -0800 Subject: [PATCH] v4: Fix mark/seek/release for LookaheadStream LookaheadStream.LB can see back to the earliest mark Specify @Override [git-p4: depot-paths = "//depot/code/antlr4/main/": change = 9334] --- .../v4/runtime/misc/LookaheadStream.java | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/runtime/Java/src/org/antlr/v4/runtime/misc/LookaheadStream.java b/runtime/Java/src/org/antlr/v4/runtime/misc/LookaheadStream.java index b7c6e95a4..8178f2fec 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/misc/LookaheadStream.java +++ b/runtime/Java/src/org/antlr/v4/runtime/misc/LookaheadStream.java @@ -50,12 +50,10 @@ public abstract class LookaheadStream extends FastQueue { */ public T eof = null; - /** Track the last mark() call result value for use in rewind(). */ - protected int lastMarker; - /** tracks how deep mark() calls are nested */ protected int markDepth = 0; + @Override public void reset() { super.reset(); currentElementIndex = 0; @@ -73,6 +71,7 @@ public abstract class LookaheadStream extends FastQueue { /** Get and remove first element in queue; override FastQueue.remove(); * it's the same, just checks for backtracking. */ + @Override public T remove() { T o = elementAt(0); p++; @@ -87,7 +86,10 @@ public abstract class LookaheadStream extends FastQueue { /** Make sure we have at least one element to remove, even if EOF */ public void consume() { syncAhead(1); - prevElement = remove(); + T element = remove(); + if (markDepth == 0) { + prevElement = element; + } currentElementIndex++; } @@ -110,6 +112,7 @@ public abstract class LookaheadStream extends FastQueue { } /** Size of entire stream is unknown; we only know buffer size from FastQueue */ + @Override public int size() { throw new UnsupportedOperationException("streams are of unknown size"); } public T LT(int k) { @@ -127,34 +130,37 @@ public abstract class LookaheadStream extends FastQueue { public int mark() { markDepth++; - lastMarker = p; // track where we are in buffer not absolute token index - return lastMarker; + return markDepth; } public void release(int marker) { // no resources to release } - public void rewind(int marker) { - markDepth--; - seek(marker); // assume marker is top - // release(marker); // waste of call; it does nothing in this class - } - - public void rewind() { - seek(lastMarker); // rewind but do not release marker - } - /** Seek to a 0-indexed position within data buffer. Can't handle * case where you seek beyond end of existing buffer. Normally used * to seek backwards in the buffer. Does not force loading of nodes. * Doesn't see to absolute position in input stream since this stream * is unbuffered. Seeks only into our moving window of elements. */ - public void seek(int index) { p = index; } + public void seek(int index) { + int bufferStartIndex = currentElementIndex - p; + if (index < bufferStartIndex || index > currentElementIndex) { + throw new UnsupportedOperationException("Cannot seek to the specified index."); + } + + currentElementIndex = index; + p = index - bufferStartIndex; + } protected T LB(int k) { - if ( k==1 ) return prevElement; + int bufferIndex = p - k; + if (bufferIndex == -1) { + return prevElement; + } else if (bufferIndex >= 0 && bufferIndex < data.size()) { + return data.get(bufferIndex); + } + throw new NoSuchElementException("can't look backwards more than one token in this stream"); } }