[1] | 1 | package antlr; |
---|
| 2 | |
---|
| 3 | /* ANTLR Translator Generator |
---|
| 4 | * Project led by Terence Parr at http://www.cs.usfca.edu |
---|
| 5 | * Software rights: http://www.antlr.org/license.html |
---|
| 6 | * |
---|
| 7 | * $Id: //depot/code/org.antlr/release/antlr-2.7.7/antlr/TokenStreamSelector.java#2 $ |
---|
| 8 | */ |
---|
| 9 | |
---|
| 10 | import java.util.Hashtable; |
---|
| 11 | |
---|
| 12 | import antlr.ASdebug.ASDebugStream; |
---|
| 13 | import antlr.ASdebug.IASDebugStream; |
---|
| 14 | import antlr.ASdebug.TokenOffsetInfo; |
---|
| 15 | import antlr.collections.Stack; |
---|
| 16 | import antlr.collections.impl.LList; |
---|
| 17 | |
---|
| 18 | /** A token stream MUX (multiplexor) knows about n token streams |
---|
| 19 | * and can multiplex them onto the same channel for use by token |
---|
| 20 | * stream consumer like a parser. This is a way to have multiple |
---|
| 21 | * lexers break up the same input stream for a single parser. |
---|
| 22 | * Or, you can have multiple instances of the same lexer handle |
---|
| 23 | * multiple input streams; this works great for includes. |
---|
| 24 | */ |
---|
| 25 | public class TokenStreamSelector implements TokenStream, IASDebugStream { |
---|
| 26 | /** The set of inputs to the MUX */ |
---|
| 27 | protected Hashtable inputStreamNames; |
---|
| 28 | |
---|
| 29 | /** The currently-selected token stream input */ |
---|
| 30 | protected TokenStream input; |
---|
| 31 | |
---|
| 32 | /** Used to track stack of input streams */ |
---|
| 33 | protected Stack streamStack = new LList(); |
---|
| 34 | |
---|
| 35 | public TokenStreamSelector() { |
---|
| 36 | super(); |
---|
| 37 | inputStreamNames = new Hashtable(); |
---|
| 38 | } |
---|
| 39 | |
---|
| 40 | public void addInputStream(TokenStream stream, String key) { |
---|
| 41 | inputStreamNames.put(key, stream); |
---|
| 42 | } |
---|
| 43 | |
---|
| 44 | /** Return the stream from tokens are being pulled at |
---|
| 45 | * the moment. |
---|
| 46 | */ |
---|
| 47 | public TokenStream getCurrentStream() { |
---|
| 48 | return input; |
---|
| 49 | } |
---|
| 50 | |
---|
| 51 | public TokenStream getStream(String sname) { |
---|
| 52 | TokenStream stream = (TokenStream)inputStreamNames.get(sname); |
---|
| 53 | if (stream == null) { |
---|
| 54 | throw new IllegalArgumentException("TokenStream " + sname + " not found"); |
---|
| 55 | } |
---|
| 56 | return stream; |
---|
| 57 | } |
---|
| 58 | |
---|
| 59 | public Token nextToken() throws TokenStreamException { |
---|
| 60 | // return input.nextToken(); |
---|
| 61 | // keep looking for a token until you don't |
---|
| 62 | // get a retry exception. |
---|
| 63 | for (; ;) { |
---|
| 64 | try { |
---|
| 65 | return input.nextToken(); |
---|
| 66 | } |
---|
| 67 | catch (TokenStreamRetryException r) { |
---|
| 68 | // just retry "forever" |
---|
| 69 | } |
---|
| 70 | } |
---|
| 71 | } |
---|
| 72 | |
---|
| 73 | public TokenStream pop() { |
---|
| 74 | TokenStream stream = (TokenStream)streamStack.pop(); |
---|
| 75 | select(stream); |
---|
| 76 | return stream; |
---|
| 77 | } |
---|
| 78 | |
---|
| 79 | public void push(TokenStream stream) { |
---|
| 80 | streamStack.push(input); // save current stream |
---|
| 81 | select(stream); |
---|
| 82 | } |
---|
| 83 | |
---|
| 84 | public void push(String sname) { |
---|
| 85 | streamStack.push(input); |
---|
| 86 | select(sname); |
---|
| 87 | } |
---|
| 88 | |
---|
| 89 | /** Abort recognition of current Token and try again. |
---|
| 90 | * A stream can push a new stream (for include files |
---|
| 91 | * for example, and then retry(), which will cause |
---|
| 92 | * the current stream to abort back to this.nextToken(). |
---|
| 93 | * this.nextToken() then asks for a token from the |
---|
| 94 | * current stream, which is the new "substream." |
---|
| 95 | */ |
---|
| 96 | public void retry() throws TokenStreamRetryException { |
---|
| 97 | throw new TokenStreamRetryException(); |
---|
| 98 | } |
---|
| 99 | |
---|
| 100 | /** Set the stream without pushing old stream */ |
---|
| 101 | public void select(TokenStream stream) { |
---|
| 102 | input = stream; |
---|
| 103 | } |
---|
| 104 | |
---|
| 105 | public void select(String sname) throws IllegalArgumentException { |
---|
| 106 | input = getStream(sname); |
---|
| 107 | } |
---|
| 108 | |
---|
| 109 | public String getEntireText() |
---|
| 110 | { |
---|
| 111 | return ASDebugStream.getEntireText(this.input); |
---|
| 112 | } |
---|
| 113 | |
---|
| 114 | public TokenOffsetInfo getOffsetInfo(Token token) |
---|
| 115 | { |
---|
| 116 | return ASDebugStream.getOffsetInfo(this.input, token); |
---|
| 117 | } |
---|
| 118 | } |
---|