package antlr;
/* ANTLR Translator Generator
* Project led by Terence Parr at http://www.cs.usfca.edu
* Software rights: http://www.antlr.org/license.html
*
* $Id: //depot/code/org.antlr/release/antlr-2.7.7/antlr/TokenStreamSelector.java#2 $
*/
import java.util.Hashtable;
import antlr.ASdebug.ASDebugStream;
import antlr.ASdebug.IASDebugStream;
import antlr.ASdebug.TokenOffsetInfo;
import antlr.collections.Stack;
import antlr.collections.impl.LList;
/** A token stream MUX (multiplexor) knows about n token streams
* and can multiplex them onto the same channel for use by token
* stream consumer like a parser. This is a way to have multiple
* lexers break up the same input stream for a single parser.
* Or, you can have multiple instances of the same lexer handle
* multiple input streams; this works great for includes.
*/
public class TokenStreamSelector implements TokenStream, IASDebugStream {
/** The set of inputs to the MUX */
protected HashtableinputStreamNames;
/** The currently-selected token stream input */
protected TokenStreaminput;
/** Used to track stack of input streams */
protected StackstreamStack = new LList();
public TokenStreamSelector() {
super();
inputStreamNames = new Hashtable();
}
public void addInputStream(TokenStreamstream, Stringkey) {
inputStreamNames.put(key, stream);
}
/** Return the stream from tokens are being pulled at
* the moment.
*/
public TokenStreamgetCurrentStream() {
return input;
}
public TokenStreamgetStream(Stringsname) {
TokenStreamstream = (TokenStream)inputStreamNames.get(sname);
if (stream == null) {
throw new IllegalArgumentException("TokenStream " + sname + " not found");
}
return stream;
}
public TokennextToken() throws TokenStreamException {
// return input.nextToken();
// keep looking for a token until you don't
// get a retry exception.
for (; ;) {
try {
return input.nextToken();
}
catch (TokenStreamRetryExceptionr) {
// just retry "forever"
}
}
}
public TokenStreampop() {
TokenStreamstream = (TokenStream)streamStack.pop();
select(stream);
return stream;
}
public void push(TokenStreamstream) {
streamStack.push(input); // save current stream
select(stream);
}
public void push(Stringsname) {
streamStack.push(input);
select(sname);
}
/** Abort recognition of current Token and try again.
* A stream can push a new stream (for include files
* for example, and then retry(), which will cause
* the current stream to abort back to this.nextToken().
* this.nextToken() then asks for a token from the
* current stream, which is the new "substream."
*/
public void retry() throws TokenStreamRetryException {
throw new TokenStreamRetryException();
}
/** Set the stream without pushing old stream */
public void select(TokenStreamstream) {
input = stream;
}
public void select(Stringsname) throws IllegalArgumentException {
input = getStream(sname);
}
public StringgetEntireText()
{
return ASDebugStream.getEntireText(this.input);
}
public TokenOffsetInfogetOffsetInfo(Tokentoken)
{
return ASDebugStream.getOffsetInfo(this.input, token);
}
}