1/* ANTLR Translator Generator 2 * Project led by Terence Parr at http://www.jGuru.com 3 * Software rights: http://www.antlr.org/license.html 4 * 5 * $Id: //depot/code/org.antlr/release/antlr-2.7.7/lib/cpp/src/TokenStreamSelector.cpp#2 $ 6 */ 7#include "antlr/TokenStreamSelector.hpp" 8#include "antlr/TokenStreamRetryException.hpp" 9 10#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE 11namespace antlr { 12#endif 13 14/** A token stream MUX (multiplexor) knows about n token streams 15 * and can multiplex them onto the same channel for use by token 16 * stream consumer like a parser. This is a way to have multiple 17 * lexers break up the same input stream for a single parser. 18 * Or, you can have multiple instances of the same lexer handle 19 * multiple input streams; this works great for includes. 20 */ 21 22TokenStreamSelector::TokenStreamSelector() 23: input(0) 24{ 25} 26 27TokenStreamSelector::~TokenStreamSelector() 28{ 29} 30 31void TokenStreamSelector::addInputStream(TokenStream* stream, const ANTLR_USE_NAMESPACE(std)string& key) 32{ 33 inputStreamNames[key] = stream; 34} 35 36TokenStream* TokenStreamSelector::getCurrentStream() const 37{ 38 return input; 39} 40 41TokenStream* TokenStreamSelector::getStream(const ANTLR_USE_NAMESPACE(std)string& sname) const 42{ 43 inputStreamNames_coll::const_iterator i = inputStreamNames.find(sname); 44 if (i == inputStreamNames.end()) { 45 throw ANTLR_USE_NAMESPACE(std)string("TokenStream ")+sname+" not found"; 46 } 47 return (*i).second; 48} 49 50RefToken TokenStreamSelector::nextToken() 51{ 52 // keep looking for a token until you don't 53 // get a retry exception 54 for (;;) { 55 try { 56 return input->nextToken(); 57 } 58 catch (TokenStreamRetryException&) { 59 // just retry "forever" 60 } 61 } 62} 63 64TokenStream* TokenStreamSelector::pop() 65{ 66 TokenStream* stream = streamStack.top(); 67 streamStack.pop(); 68 select(stream); 69 return stream; 70} 71 72void TokenStreamSelector::push(TokenStream* stream) 73{ 74 streamStack.push(input); 75 select(stream); 76} 77 78void TokenStreamSelector::push(const ANTLR_USE_NAMESPACE(std)string& sname) 79{ 80 streamStack.push(input); 81 select(sname); 82} 83 84void TokenStreamSelector::retry() 85{ 86 throw TokenStreamRetryException(); 87} 88 89/** Set the stream without pushing old stream */ 90void TokenStreamSelector::select(TokenStream* stream) 91{ 92 input = stream; 93} 94 95void TokenStreamSelector::select(const ANTLR_USE_NAMESPACE(std)string& sname) 96{ 97 inputStreamNames_coll::const_iterator i = inputStreamNames.find(sname); 98 if (i == inputStreamNames.end()) { 99 throw ANTLR_USE_NAMESPACE(std)string("TokenStream ")+sname+" not found"; 100 } 101 input = (*i).second; 102} 103 104#ifdef ANTLR_CXX_SUPPORTS_NAMESPACE 105} 106#endif 107 108