001: package persistence.antlr;
002:
003: /* ANTLR Translator Generator
004: * Project led by Terence Parr at http://www.jGuru.com
005: * Software rights: http://www.antlr.org/license.html
006: *
007: */
008:
009: import java.util.Hashtable;
010:
011: import persistence.antlr.collections.impl.LList;
012: import persistence.antlr.collections.Stack;
013:
014: import java.io.IOException;
015:
016: /** A token stream MUX (multiplexor) knows about n token streams
017: * and can multiplex them onto the same channel for use by token
018: * stream consumer like a parser. This is a way to have multiple
019: * lexers break up the same input stream for a single parser.
020: * Or, you can have multiple instances of the same lexer handle
021: * multiple input streams; this works great for includes.
022: */
023: public class TokenStreamSelector implements TokenStream {
024: /** The set of inputs to the MUX */
025: protected Hashtable inputStreamNames;
026:
027: /** The currently-selected token stream input */
028: protected TokenStream input;
029:
030: /** Used to track stack of input streams */
031: protected Stack streamStack = new LList();
032:
033: public TokenStreamSelector() {
034: super ();
035: inputStreamNames = new Hashtable();
036: }
037:
038: public void addInputStream(TokenStream stream, String key) {
039: inputStreamNames.put(key, stream);
040: }
041:
042: /** Return the stream from tokens are being pulled at
043: * the moment.
044: */
045: public TokenStream getCurrentStream() {
046: return input;
047: }
048:
049: public TokenStream getStream(String sname) {
050: TokenStream stream = (TokenStream) inputStreamNames.get(sname);
051: if (stream == null) {
052: throw new IllegalArgumentException("TokenStream " + sname
053: + " not found");
054: }
055: return stream;
056: }
057:
058: public Token nextToken() throws TokenStreamException {
059: // return input.nextToken();
060: // keep looking for a token until you don't
061: // get a retry exception.
062: for (;;) {
063: try {
064: return input.nextToken();
065: } catch (TokenStreamRetryException r) {
066: // just retry "forever"
067: }
068: }
069: }
070:
071: public TokenStream pop() {
072: TokenStream stream = (TokenStream) streamStack.pop();
073: select(stream);
074: return stream;
075: }
076:
077: public void push(TokenStream stream) {
078: streamStack.push(input); // save current stream
079: select(stream);
080: }
081:
082: public void push(String sname) {
083: streamStack.push(input);
084: select(sname);
085: }
086:
087: /** Abort recognition of current Token and try again.
088: * A stream can push a new stream (for include files
089: * for example, and then retry(), which will cause
090: * the current stream to abort back to this.nextToken().
091: * this.nextToken() then asks for a token from the
092: * current stream, which is the new "substream."
093: */
094: public void retry() throws TokenStreamRetryException {
095: throw new TokenStreamRetryException();
096: }
097:
098: /** Set the stream without pushing old stream */
099: public void select(TokenStream stream) {
100: input = stream;
101: }
102:
103: public void select(String sname) throws IllegalArgumentException {
104: input = getStream(sname);
105: }
106: }
|