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