Split token into read-only and writable portions. added release method. moved the methods around that get input streams and token streams between interfaces. simplify the character stream interface by moving the gas line and get characterization methods to the lexer.

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 9039]
This commit is contained in:
parrt 2011-09-03 17:36:14 -08:00
parent 5c6f35abef
commit 783f1bc38f
24 changed files with 189 additions and 148 deletions

View File

@ -129,7 +129,7 @@ public class BufferedTokenStream implements TokenStream {
/** add n elements to buffer */ /** add n elements to buffer */
protected void fetch(int n) { protected void fetch(int n) {
for (int i=1; i<=n; i++) { for (int i=1; i<=n; i++) {
Token t = tokenSource.nextToken(); WritableToken t = (WritableToken)tokenSource.nextToken();
// System.out.println("adding "+t+" at index "+tokens.size()); // System.out.println("adding "+t+" at index "+tokens.size());
t.setTokenIndex(tokens.size()); t.setTokenIndex(tokens.size());
tokens.add(t); tokens.add(t);

View File

@ -37,22 +37,4 @@ public interface CharStream extends IntStream {
* use this on streams that don't support it. * use this on streams that don't support it.
*/ */
public String substring(int start, int stop); public String substring(int start, int stop);
/** Get the ith character of lookahead. This is the same usually as
* LA(i). This will be used for labels in the generated
* lexer code. I'd prefer to return a char here type-wise, but it's
* probably better to be 32-bit clean and be consistent with LA.
*/
public int LT(int i);
/** ANTLR tracks the line information automatically */
int getLine();
/** Because this stream can rewind, we need to be able to reset the line */
void setLine(int line);
void setCharPositionInLine(int pos);
/** The index of the character relative to the beginning of the line 0..n-1 */
int getCharPositionInLine();
} }

View File

@ -30,17 +30,19 @@ package org.antlr.v4.runtime;
import java.io.Serializable; import java.io.Serializable;
public class CommonToken implements Token, Serializable { public class CommonToken implements WritableToken, Serializable {
protected int type; protected int type;
protected int line; protected int line;
protected int charPositionInLine = -1; // set to invalid position protected int charPositionInLine = -1; // set to invalid position
protected int channel=DEFAULT_CHANNEL; protected int channel=DEFAULT_CHANNEL;
protected transient CharStream input; protected TokenSource source;
// TODO: rm protected transient CharStream input;
/** We need to be able to change the text once in a while. If /** We need to be able to change the text once in a while. If
* this is non-null, then getText should return this. Note that * this is non-null, then getText should return this. Note that
* start/stop are not affected by changing this. * start/stop are not affected by changing this.
*/ */
// TODO: can store these in map in token stream rather than as field here
protected String text; protected String text;
/** What token number is this from 0..n-1 tokens; < 0 implies invalid index */ /** What token number is this from 0..n-1 tokens; < 0 implies invalid index */
@ -56,14 +58,14 @@ public class CommonToken implements Token, Serializable {
this.type = type; this.type = type;
} }
public CommonToken(CharStream input, int type, int channel, int start, int stop) { public CommonToken(TokenSource source, int type, int channel, int start, int stop) {
this.input = input; this.source = source;
this.type = type; this.type = type;
this.channel = channel; this.channel = channel;
this.start = start; this.start = start;
this.stop = stop; this.stop = stop;
this.line = input.getLine(); this.line = source.getLine();
this.charPositionInLine = input.getCharPositionInLine(); this.charPositionInLine = source.getCharPositionInLine();
} }
public CommonToken(int type, String text) { public CommonToken(int type, String text) {
@ -79,7 +81,7 @@ public class CommonToken implements Token, Serializable {
index = oldToken.getTokenIndex(); index = oldToken.getTokenIndex();
charPositionInLine = oldToken.getCharPositionInLine(); charPositionInLine = oldToken.getCharPositionInLine();
channel = oldToken.getChannel(); channel = oldToken.getChannel();
input = oldToken.getInputStream(); source = oldToken.getTokenSource();
if ( oldToken instanceof CommonToken ) { if ( oldToken instanceof CommonToken ) {
start = ((CommonToken)oldToken).start; start = ((CommonToken)oldToken).start;
stop = ((CommonToken)oldToken).stop; stop = ((CommonToken)oldToken).stop;
@ -98,6 +100,7 @@ public class CommonToken implements Token, Serializable {
if ( text!=null ) { if ( text!=null ) {
return text; return text;
} }
CharStream input = getTokenSource().getInputStream();
if ( input==null ) { if ( input==null ) {
return null; return null;
} }
@ -167,12 +170,12 @@ public class CommonToken implements Token, Serializable {
this.index = index; this.index = index;
} }
public CharStream getInputStream() { public TokenSource getTokenSource() {
return input; return source;
} }
public void setInputStream(CharStream input) { public CharStream getInputStream() {
this.input = input; return source.getInputStream();
} }
public String toString() { public String toString() {

View File

@ -31,9 +31,8 @@ package org.antlr.v4.runtime;
/** A simple stream of integers used when all I care about is the char /** A simple stream of integers used when all I care about is the char
* or token type sequence (such as interpretation). * or token type sequence (such as interpretation).
* *
* TODO: Notes from Oli: index, seek, LA, LT, consume, getSourceName needed
* Do like Java IO and have new BufferedStream(new TokenStream) rather than * Do like Java IO and have new BufferedStream(new TokenStream) rather than
* using inheritance. line/col go into lexer * using inheritance?
*/ */
public interface IntStream { public interface IntStream {
void consume(); void consume();
@ -46,13 +45,17 @@ public interface IntStream {
int LA(int i); int LA(int i);
/** Tell the stream to start buffering if it hasn't already. Return /** Tell the stream to start buffering if it hasn't already. Return
* current input position, index(). seek(mark()) should not * a marker, usually current input position, index().
* affect the input cursor. * Calling release(mark()) should not affect the input cursor.
* Can seek to any index between where we were when mark() was called
* and current index() until we release this marker.
*/ */
int mark(); int mark();
/** Reset the stream so that next call to index() would return index arg. */ /** Release requirement that stream holds tokens from marked location
void rewind(int index); * to current index().
*/
void release(int marker);
/** Return the current input symbol index 0..n where n indicates the /** Return the current input symbol index 0..n where n indicates the
* last symbol has been read. The index is the symbol about to be * last symbol has been read. The index is the symbol about to be
@ -61,21 +64,16 @@ public interface IntStream {
int index(); int index();
/** Set the input cursor to the position indicated by index. This is /** Set the input cursor to the position indicated by index. This is
* normally used to seek ahead in the input stream. No buffering is * normally used to rewind the input stream but can move forward as well.
* required to do this unless you know your stream will use seek to * It's up to the stream implementation to make sure that tokens are
* move backwards such as when backtracking. * buffered as necessary to make seek land on a valid token.
* * Or, they should avoid moving the input cursor.
* This is different from rewind in its multi-directional
* requirement and in that its argument is strictly an input cursor (index).
* *
* For char streams, seeking forward must update the stream state such * For char streams, seeking forward must update the stream state such
* as line number. For seeking backwards, you will be presumably * as line number. For seeking backwards, you will be presumably
* backtracking using the mark/rewind mechanism that restores state and * backtracking using the mark/rewind mechanism that restores state and
* so this method does not need to update state when seeking backwards. * so this method does not need to update state when seeking backwards.
* *
* Currently, this method is only used for efficient backtracking using
* memoization, but in the future it may be used for incremental parsing.
*
* The index is 0..n-1. A seek to position i means that LA(1) will * The index is 0..n-1. A seek to position i means that LA(1) will
* return the ith symbol. So, seeking to 0 means LA(1) will return the * return the ith symbol. So, seeking to 0 means LA(1) will return the
* first element in the stream. * first element in the stream.

View File

@ -115,13 +115,13 @@ public abstract class Lexer extends Recognizer<LexerATNSimulator>
token = null; token = null;
channel = Token.DEFAULT_CHANNEL; channel = Token.DEFAULT_CHANNEL;
tokenStartCharIndex = input.index(); tokenStartCharIndex = input.index();
tokenStartCharPositionInLine = input.getCharPositionInLine(); tokenStartCharPositionInLine = _interp.getCharPositionInLine();
tokenStartLine = input.getLine(); tokenStartLine = _interp.getLine();
text = null; text = null;
do { do {
type = Token.INVALID_TYPE; type = Token.INVALID_TYPE;
if ( input.LA(1)==CharStream.EOF ) { if ( input.LA(1)==CharStream.EOF ) {
Token eof = new CommonToken(input,Token.EOF, WritableToken eof = new CommonToken(this,Token.EOF,
Token.DEFAULT_CHANNEL, Token.DEFAULT_CHANNEL,
input.index(),input.index()); input.index(),input.index());
eof.setLine(getLine()); eof.setLine(getLine());
@ -182,14 +182,14 @@ public abstract class Lexer extends Recognizer<LexerATNSimulator>
this.input = input; this.input = input;
} }
public CharStream getCharStream() {
return ((CharStream)input);
}
public String getSourceName() { public String getSourceName() {
return input.getSourceName(); return input.getSourceName();
} }
public CharStream getInputStream() {
return input;
}
/** Currently does not support multiple emits per nextToken invocation /** Currently does not support multiple emits per nextToken invocation
* for efficiency reasons. Subclass and override this method and * for efficiency reasons. Subclass and override this method and
* nextToken (to push tokens into a list and pull from that list rather * nextToken (to push tokens into a list and pull from that list rather
@ -210,7 +210,7 @@ public abstract class Lexer extends Recognizer<LexerATNSimulator>
* Parser or TreeParser.getMissingSymbol(). * Parser or TreeParser.getMissingSymbol().
*/ */
public Token emit() { public Token emit() {
Token t = new CommonToken(((CharStream)input), type, WritableToken t = new CommonToken(this, type,
channel, tokenStartCharIndex, channel, tokenStartCharIndex,
getCharIndex()-1); getCharIndex()-1);
t.setLine(tokenStartLine); t.setLine(tokenStartLine);
@ -221,11 +221,11 @@ public abstract class Lexer extends Recognizer<LexerATNSimulator>
} }
public int getLine() { public int getLine() {
return ((CharStream)input).getLine(); return _interp.getLine();
} }
public int getCharPositionInLine() { public int getCharPositionInLine() {
return ((CharStream)input).getCharPositionInLine(); return _interp.getCharPositionInLine();
} }
/** What is the index of the current character of lookahead? */ /** What is the index of the current character of lookahead? */
@ -338,6 +338,7 @@ public abstract class Lexer extends Recognizer<LexerATNSimulator>
public void recover(RecognitionException re) { public void recover(RecognitionException re) {
//System.out.println("consuming char "+(char)input.LA(1)+" during recovery"); //System.out.println("consuming char "+(char)input.LA(1)+" during recovery");
//re.printStackTrace(); //re.printStackTrace();
// TODO: Do we lose character or line position information?
input.consume(); input.consume();
} }
} }

View File

@ -55,8 +55,8 @@ public class LexerRecognitionExeption extends RuntimeException {
this.lexer = lexer; this.lexer = lexer;
this.index = input.index(); this.index = input.index();
this.c = input.LA(1); this.c = input.LA(1);
this.line = input.getLine(); this.line = lexer.getLine();
this.charPositionInLine = input.getCharPositionInLine(); this.charPositionInLine = lexer.getCharPositionInLine();
} }
} }

View File

@ -67,7 +67,7 @@ public class Parser extends BaseRecognizer {
t.line = current.getLine(); t.line = current.getLine();
t.charPositionInLine = current.getCharPositionInLine(); t.charPositionInLine = current.getCharPositionInLine();
t.channel = Token.DEFAULT_CHANNEL; t.channel = Token.DEFAULT_CHANNEL;
t.input = current.getInputStream(); t.source = current.getTokenSource();
return t; return t;
} }

View File

@ -129,11 +129,6 @@ public class RecognitionException extends RuntimeException {
if ( input instanceof TreeNodeStream) { if ( input instanceof TreeNodeStream) {
//extractInformationFromTreeNodeStream(input); //extractInformationFromTreeNodeStream(input);
} }
else if ( input instanceof CharStream) {
this.c = input.LA(1);
this.line = ((CharStream)input).getLine();
this.charPositionInLine = ((CharStream)input).getCharPositionInLine();
}
else { else {
this.c = input.LA(1); this.c = input.LA(1);
} }

View File

@ -29,6 +29,10 @@
package org.antlr.v4.runtime; package org.antlr.v4.runtime;
/** A token has properties: text, type, line, character position in the line
* (so we can ignore tabs), token channel, index, and source from which
* we obtained this token.
*/
public interface Token { public interface Token {
public static final int INVALID_TYPE = 0; public static final int INVALID_TYPE = 0;
public static final Token INVALID_TOKEN = new CommonToken(INVALID_TYPE); public static final Token INVALID_TOKEN = new CommonToken(INVALID_TYPE);
@ -36,6 +40,7 @@ public interface Token {
/** imaginary tree navigation type; traverse "get child" link */ /** imaginary tree navigation type; traverse "get child" link */
public static final int DOWN = 1; public static final int DOWN = 1;
/** imaginary tree navigation type; finish with a child list */ /** imaginary tree navigation type; finish with a child list */
public static final int UP = 2; public static final int UP = 2;
@ -55,32 +60,34 @@ public interface Token {
public static final int HIDDEN_CHANNEL = 99; public static final int HIDDEN_CHANNEL = 99;
/** Get the text of the token */ /** Get the text of the token */
public String getText(); String getText();
public void setText(String text);
public int getType(); /** Get the token type of the token */
public void setType(int ttype); int getType();
/** The line number on which this token was matched; line=1..n */
public int getLine();
public void setLine(int line);
/** The index of the first character relative to the beginning of the line 0..n-1 */ /** The line number on which the 1st character of this token was matched,
public int getCharPositionInLine(); * line=1..n
public void setCharPositionInLine(int pos); */
int getLine();
public int getChannel(); /** The index of the first character of this token relative to the
public void setChannel(int channel); * beginning of the line at which it occurs, 0..n-1
*/
int getCharPositionInLine();
/** Return the channel this token. Each token can arrive at the parser
* on a different channel, but the parser only "tunes" to a single channel.
* The parser ignores everything not on DEFAULT_CHANNEL.
*/
int getChannel();
/** An index from 0..n-1 of the token object in the input stream. /** An index from 0..n-1 of the token object in the input stream.
* This must be valid in order to use the ANTLRWorks debugger. * This must be valid in order to use the ANTLRWorks debugger.
*/ */
public int getTokenIndex(); int getTokenIndex();
public void setTokenIndex(int index);
/** From what character stream was this token created? You don't have to /** Where does this token come from? You can get the
* implement but it's nice to know where a Token comes from if you have * character input stream from the token source.
* include files etc... on the input.
*/ */
public CharStream getInputStream(); TokenSource getTokenSource();
public void setInputStream(CharStream input);
} }

View File

@ -48,6 +48,16 @@ public interface TokenSource {
*/ */
public Token nextToken(); public Token nextToken();
public int getLine();
public int getCharPositionInLine();
/** From what character stream was this token created? You don't have to
* implement but it's nice to know where a Token comes from if you have
* include files etc... on the input.
*/
public CharStream getInputStream();
/** Where are you getting tokens from? normally the implication will simply /** Where are you getting tokens from? normally the implication will simply
* ask lexers input stream. * ask lexers input stream.
*/ */

View File

@ -41,6 +41,12 @@ public class LexerATNSimulator extends ATNSimulator {
protected Lexer recog; protected Lexer recog;
/** line number 1..n within the input */
protected int line = 1;
/** The index of the character relative to the beginning of the line 0..n-1 */
protected int charPositionInLine = 0;
protected DFA[] dfa; protected DFA[] dfa;
protected int mode = Lexer.DEFAULT_MODE; protected int mode = Lexer.DEFAULT_MODE;
@ -87,6 +93,9 @@ public class LexerATNSimulator extends ATNSimulator {
(char)input.LA(1)); (char)input.LA(1));
//System.out.println("DFA start of execDFA: "+dfa[mode].toLexerString()); //System.out.println("DFA start of execDFA: "+dfa[mode].toLexerString());
int prevAcceptMarker = -1; int prevAcceptMarker = -1;
int prevAcceptIndex = -1;
int prevAcceptLine = 0;
int prevAcceptCharPos = -1;
DFAState prevAcceptState = null; DFAState prevAcceptState = null;
DFAState s = s0; DFAState s = s0;
int startIndex = input.index(); int startIndex = input.index();
@ -99,7 +108,10 @@ public class LexerATNSimulator extends ATNSimulator {
if ( dfa_debug ) System.out.println("accept; predict "+s.prediction+ if ( dfa_debug ) System.out.println("accept; predict "+s.prediction+
" in state "+s.stateNumber); " in state "+s.stateNumber);
prevAcceptState = s; prevAcceptState = s;
prevAcceptMarker = input.index(); prevAcceptMarker = input.mark();
prevAcceptIndex = input.index();
prevAcceptLine = line;
prevAcceptCharPos = charPositionInLine;
// keep going unless we're at EOF; check if something else could match // keep going unless we're at EOF; check if something else could match
if ( t==CharStream.EOF ) break; if ( t==CharStream.EOF ) break;
} }
@ -134,7 +146,7 @@ public class LexerATNSimulator extends ATNSimulator {
DFAState target = s.edges[t]; DFAState target = s.edges[t];
if ( target == ERROR ) break; if ( target == ERROR ) break;
s = target; s = target;
input.consume(); consume(input, t);
t = input.LA(1); t = input.LA(1);
} }
if ( prevAcceptState==null ) { if ( prevAcceptState==null ) {
@ -150,7 +162,10 @@ public class LexerATNSimulator extends ATNSimulator {
} }
if ( actionIndex>=0 ) recog.action(null, prevAcceptState.ruleIndex, actionIndex); if ( actionIndex>=0 ) recog.action(null, prevAcceptState.ruleIndex, actionIndex);
} }
input.seek(prevAcceptMarker); input.release(prevAcceptMarker);
input.seek(prevAcceptIndex);
line = prevAcceptLine;
charPositionInLine = prevAcceptCharPos;
return prevAcceptState.prediction; return prevAcceptState.prediction;
} }
@ -223,7 +238,7 @@ public class LexerATNSimulator extends ATNSimulator {
break; break;
} }
input.consume(); consume(input, t);
addDFAEdge(closure, t, reach); addDFAEdge(closure, t, reach);
t = input.LA(1); t = input.LA(1);
@ -464,6 +479,28 @@ public class LexerATNSimulator extends ATNSimulator {
return dfa[mode]; return dfa[mode];
} }
public int getLine() {
return line;
}
public int getCharPositionInLine() {
return charPositionInLine;
}
public void consume(CharStream input, int curChar) {
//System.out.println("prev p="+p+", c="+(char)data[p]);
charPositionInLine++;
if ( curChar=='\n' ) {
/*
System.out.println("newline char found on line: "+line+
"@ pos="+charPositionInLine);
*/
line++;
charPositionInLine=0;
}
input.consume();
}
public String getTokenName(int t) { public String getTokenName(int t) {
if ( t==-1 ) return "EOF"; if ( t==-1 ) return "EOF";
//if ( atn.g!=null ) return atn.g.getTokenDisplayName(t); //if ( atn.g!=null ) return atn.g.getTokenDisplayName(t);

View File

@ -28,8 +28,7 @@
package org.antlr.v4.runtime.debug; package org.antlr.v4.runtime.debug;
import org.antlr.v4.runtime.RecognitionException; import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.Token;
/** A blank listener that does nothing; useful for real classes so /** A blank listener that does nothing; useful for real classes so
* they don't have to have lots of blank methods and are less * they don't have to have lots of blank methods and are less
@ -48,7 +47,7 @@ public class BlankDebugEventListener implements DebugEventListener {
public void consumeHiddenToken(Token token) {} public void consumeHiddenToken(Token token) {}
public void LT(int i, Token t) {} public void LT(int i, Token t) {}
public void mark(int i) {} public void mark(int i) {}
public void rewind(int i) {} public void release(int i) {}
public void seek(int i) {} public void seek(int i) {}
public void recognitionException(RecognitionException e) {} public void recognitionException(RecognitionException e) {}
public void beginResync() {} public void beginResync() {}

View File

@ -27,11 +27,9 @@
*/ */
package org.antlr.v4.runtime.debug; package org.antlr.v4.runtime.debug;
import org.antlr.v4.runtime.RecognitionException; import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.Token;
import java.util.ArrayList; import java.util.*;
import java.util.List;
/** Broadcast debug events to multiple listeners. Lets you debug and still /** Broadcast debug events to multiple listeners. Lets you debug and still
* use the event mechanism to build parse trees etc... Not thread-safe. * use the event mechanism to build parse trees etc... Not thread-safe.
@ -158,10 +156,10 @@ public class DebugEventHub implements DebugEventListener {
} }
} }
public void rewind(int index) { public void release(int marker) {
for (int i = 0; i < listeners.size(); i++) { for (int i = 0; i < listeners.size(); i++) {
DebugEventListener listener = (DebugEventListener)listeners.get(i); DebugEventListener listener = (DebugEventListener)listeners.get(i);
listener.rewind(index); listener.release(marker);
} }
} }

View File

@ -28,8 +28,7 @@
package org.antlr.v4.runtime.debug; package org.antlr.v4.runtime.debug;
import org.antlr.v4.runtime.RecognitionException; import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.Token;
/** All debugging events that a recognizer can trigger. /** All debugging events that a recognizer can trigger.
* *
@ -91,7 +90,7 @@ public interface DebugEventListener {
/** After an arbitrarily long lookahead, this informs the /** After an arbitrarily long lookahead, this informs the
* debugger that stream should be rewound to the position index. * debugger that stream should be rewound to the position index.
*/ */
public void rewind(int index); public void release(int marker);
/** Set the input cursor to the position indicated by index. */ /** Set the input cursor to the position indicated by index. */
public void seek(int index); public void seek(int index);

View File

@ -27,8 +27,7 @@
*/ */
package org.antlr.v4.runtime.debug; package org.antlr.v4.runtime.debug;
import org.antlr.v4.runtime.RecognitionException; import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.Token;
/** A simple event repeater (proxy) that delegates all functionality to the /** A simple event repeater (proxy) that delegates all functionality to the
* listener sent into the ctor. Useful if you want to listen in on a few * listener sent into the ctor. Useful if you want to listen in on a few
@ -58,7 +57,7 @@ public class DebugEventRepeater implements DebugEventListener {
public void consumeHiddenToken(Token token) { listener.consumeHiddenToken(token); } public void consumeHiddenToken(Token token) { listener.consumeHiddenToken(token); }
public void LT(int i, Token t) { listener.LT(i, t); } public void LT(int i, Token t) { listener.LT(i, t); }
public void mark(int i) { listener.mark(i); } public void mark(int i) { listener.mark(i); }
public void rewind(int i) { listener.rewind(i); } public void release(int i) { listener.release(i); }
public void seek(int i) { listener.seek(i); } public void seek(int i) { listener.seek(i); }
public void recognitionException(RecognitionException e) { listener.recognitionException(e); } public void recognitionException(RecognitionException e) { listener.recognitionException(e); }
public void beginResync() { listener.beginResync(); } public void beginResync() { listener.beginResync(); }

View File

@ -27,14 +27,11 @@
*/ */
package org.antlr.v4.runtime.debug; package org.antlr.v4.runtime.debug;
import org.antlr.v4.runtime.BaseRecognizer; import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.TreeAdaptor; import org.antlr.v4.runtime.tree.TreeAdaptor;
import java.io.*; import java.io.*;
import java.net.ServerSocket; import java.net.*;
import java.net.Socket;
/** A proxy debug event listener that forwards events over a socket to /** A proxy debug event listener that forwards events over a socket to
* a debugger (or any other listener) using a simple text-based protocol; * a debugger (or any other listener) using a simple text-based protocol;
@ -165,7 +162,7 @@ public class DebugEventSocketProxy extends BlankDebugEventListener {
transmit("mark\t"+i); transmit("mark\t"+i);
} }
public void rewind(int i) { public void release(int i) {
transmit("rewind\t"+i); transmit("rewind\t"+i);
} }

View File

@ -27,9 +27,7 @@
*/ */
package org.antlr.v4.runtime.debug; package org.antlr.v4.runtime.debug;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.TokenSource;
import org.antlr.v4.runtime.TokenStream;
public class DebugTokenStream implements TokenStream { public class DebugTokenStream implements TokenStream {
protected DebugEventListener dbg; protected DebugEventListener dbg;
@ -111,9 +109,9 @@ public class DebugTokenStream implements TokenStream {
return input.range(); return input.range();
} }
public void rewind(int index) { public void release(int index) {
dbg.rewind(index); dbg.release(index);
input.seek(index); input.release(index);
} }
public void seek(int index) { public void seek(int index) {

View File

@ -28,8 +28,7 @@
package org.antlr.v4.runtime.debug; package org.antlr.v4.runtime.debug;
import org.antlr.v4.runtime.TokenStream; import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.tree.TreeAdaptor; import org.antlr.v4.runtime.tree.*;
import org.antlr.v4.runtime.tree.TreeNodeStream;
/** Debug any tree node stream. The constructor accepts the stream /** Debug any tree node stream. The constructor accepts the stream
* and a debug listener. As node stream calls come in, debug events * and a debug listener. As node stream calls come in, debug events
@ -95,9 +94,9 @@ public class DebugTreeNodeStream implements TreeNodeStream {
return lastMarker; return lastMarker;
} }
public void rewind(int marker) { public void release(int marker) {
dbg.rewind(marker); dbg.release(marker);
input.rewind(marker); input.release(marker);
} }
public int index() { public int index() {

View File

@ -27,15 +27,11 @@
*/ */
package org.antlr.v4.runtime.debug; package org.antlr.v4.runtime.debug;
import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.RecognitionException; import org.antlr.v4.runtime.tree.*;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.BaseTree;
import org.antlr.v4.runtime.tree.Tree;
import java.io.*; import java.io.*;
import java.net.ConnectException; import java.net.*;
import java.net.Socket;
import java.util.StringTokenizer; import java.util.StringTokenizer;
public class RemoteDebugEventSocketListener implements Runnable { public class RemoteDebugEventSocketListener implements Runnable {
@ -110,11 +106,9 @@ public class RemoteDebugEventSocketListener implements Runnable {
public void setTokenIndex(int index) { public void setTokenIndex(int index) {
this.index = index; this.index = index;
} }
public CharStream getInputStream() { public TokenSource getTokenSource() {
return null; return null;
} }
public void setInputStream(CharStream input) {
}
public String toString() { public String toString() {
String channelStr = ""; String channelStr = "";
if ( channel!= Token.DEFAULT_CHANNEL ) { if ( channel!= Token.DEFAULT_CHANNEL ) {

View File

@ -195,19 +195,19 @@ public abstract class BaseTreeAdaptor implements TreeAdaptor {
} }
public Object create(int tokenType, Token fromToken) { public Object create(int tokenType, Token fromToken) {
fromToken = createToken(fromToken); WritableToken tok = createToken(fromToken);
//((ClassicToken)fromToken).setType(tokenType); //((ClassicToken)fromToken).setType(tokenType);
fromToken.setType(tokenType); tok.setType(tokenType);
Tree t = (Tree)create(fromToken); Tree t = (Tree)create(tok);
return t; return t;
} }
public Object create(int tokenType, Token fromToken, String text) { public Object create(int tokenType, Token fromToken, String text) {
if (fromToken == null) return create(tokenType, text); if (fromToken == null) return create(tokenType, text);
fromToken = createToken(fromToken); WritableToken tok = createToken(fromToken);
fromToken.setType(tokenType); tok.setType(tokenType);
fromToken.setText(text); tok.setText(text);
Tree t = (Tree)create(fromToken); Tree t = (Tree)create(tok);
return t; return t;
} }
@ -273,7 +273,7 @@ public abstract class BaseTreeAdaptor implements TreeAdaptor {
* If you care what the token payload objects' type is, you should * If you care what the token payload objects' type is, you should
* override this method and any other createToken variant. * override this method and any other createToken variant.
*/ */
public abstract Token createToken(int tokenType, String text); public abstract WritableToken createToken(int tokenType, String text);
/** Tell me how to create a token for use with imaginary token nodes. /** Tell me how to create a token for use with imaginary token nodes.
* For example, there is probably no input symbol associated with imaginary * For example, there is probably no input symbol associated with imaginary
@ -289,6 +289,6 @@ public abstract class BaseTreeAdaptor implements TreeAdaptor {
* If you care what the token payload objects' type is, you should * If you care what the token payload objects' type is, you should
* override this method and any other createToken variant. * override this method and any other createToken variant.
*/ */
public abstract Token createToken(Token fromToken); public abstract WritableToken createToken(Token fromToken);
} }

View File

@ -66,7 +66,7 @@ public class CommonTreeAdaptor extends BaseTreeAdaptor {
* override this method and any other createToken variant. * override this method and any other createToken variant.
*/ */
@Override @Override
public Token createToken(int tokenType, String text) { public WritableToken createToken(int tokenType, String text) {
return new CommonToken(tokenType, text); return new CommonToken(tokenType, text);
} }
@ -85,7 +85,7 @@ public class CommonTreeAdaptor extends BaseTreeAdaptor {
* override this method and any other createToken variant. * override this method and any other createToken variant.
*/ */
@Override @Override
public Token createToken(Token fromToken) { public WritableToken createToken(Token fromToken) {
return new CommonToken(fromToken); return new CommonToken(fromToken);
} }

View File

@ -55,13 +55,26 @@ public class LexerInterpreter implements TokenSource {
public String getSourceName() { return g.name; } public String getSourceName() { return g.name; }
public int getCharPositionInLine() {
return 0;
}
public int getLine() {
return 0;
}
public CharStream getInputStream() {
return null;
}
public Token nextToken() { public Token nextToken() {
// TODO: Deal with off channel tokens
int start = input.index(); int start = input.index();
int tokenStartCharPositionInLine = interp.getCharPositionInLine();
int tokenStartLine = interp.getLine();
int ttype = interp.match(input, Lexer.DEFAULT_MODE); int ttype = interp.match(input, Lexer.DEFAULT_MODE);
int stop = input.index()-1; int stop = input.index()-1;
int tokenStartCharPositionInLine = input.getCharPositionInLine(); WritableToken t = new CommonToken(this, ttype, Token.DEFAULT_CHANNEL, start, stop);
int tokenStartLine = input.getLine();
Token t = new CommonToken(input, ttype, Token.DEFAULT_CHANNEL, start, stop);
t.setLine(tokenStartLine); t.setLine(tokenStartLine);
t.setCharPositionInLine(tokenStartCharPositionInLine); t.setCharPositionInLine(tokenStartCharPositionInLine);
return t; return t;

View File

@ -837,7 +837,10 @@ public abstract class BaseTest {
Set<Integer> hide = new HashSet<Integer>(); Set<Integer> hide = new HashSet<Integer>();
protected void sync(int i) { protected void sync(int i) {
super.sync(i); super.sync(i);
if ( hide.contains(get(i).getType()) ) get(i).setChannel(Token.HIDDEN_CHANNEL); Token t = get(i);
if ( hide.contains(t.getType()) ) {
((WritableToken)t).setChannel(Token.HIDDEN_CHANNEL);
}
} }
public void setTokenTypeChannel(int ttype, int channel) { public void setTokenTypeChannel(int ttype, int channel) {
hide.add(ttype); hide.add(ttype);

View File

@ -177,7 +177,7 @@ public class TestCommonTokenStream extends BaseTest {
TokenSource lexer = // simulate input " x =34 ;\n" TokenSource lexer = // simulate input " x =34 ;\n"
new TokenSource() { new TokenSource() {
int i = 0; int i = 0;
Token[] tokens = { WritableToken[] tokens = {
new CommonToken(1," "), new CommonToken(1," "),
new CommonToken(1,"x"), new CommonToken(1,"x"),
new CommonToken(1," "), new CommonToken(1," "),
@ -200,6 +200,15 @@ public class TestCommonTokenStream extends BaseTest {
return tokens[i++]; return tokens[i++];
} }
public String getSourceName() { return "test"; } public String getSourceName() { return "test"; }
public int getCharPositionInLine() {
return 0;
}
public int getLine() {
return 0;
}
public CharStream getInputStream() {
return null;
}
}; };
CommonTokenStream tokens = new CommonTokenStream(lexer); CommonTokenStream tokens = new CommonTokenStream(lexer);