]>
Commit | Line | Data |
---|---|---|
427c49bc A |
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 | |
11 | namespace 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 | ||
22 | TokenStreamSelector::TokenStreamSelector() | |
23 | : input(0) | |
24 | { | |
25 | } | |
26 | ||
27 | TokenStreamSelector::~TokenStreamSelector() | |
28 | { | |
29 | } | |
30 | ||
31 | void TokenStreamSelector::addInputStream(TokenStream* stream, const ANTLR_USE_NAMESPACE(std)string& key) | |
32 | { | |
33 | inputStreamNames[key] = stream; | |
34 | } | |
35 | ||
36 | TokenStream* TokenStreamSelector::getCurrentStream() const | |
37 | { | |
38 | return input; | |
39 | } | |
40 | ||
41 | TokenStream* 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 | ||
50 | RefToken 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 | ||
64 | TokenStream* TokenStreamSelector::pop() | |
65 | { | |
66 | TokenStream* stream = streamStack.top(); | |
67 | streamStack.pop(); | |
68 | select(stream); | |
69 | return stream; | |
70 | } | |
71 | ||
72 | void TokenStreamSelector::push(TokenStream* stream) | |
73 | { | |
74 | streamStack.push(input); | |
75 | select(stream); | |
76 | } | |
77 | ||
78 | void TokenStreamSelector::push(const ANTLR_USE_NAMESPACE(std)string& sname) | |
79 | { | |
80 | streamStack.push(input); | |
81 | select(sname); | |
82 | } | |
83 | ||
84 | void TokenStreamSelector::retry() | |
85 | { | |
86 | throw TokenStreamRetryException(); | |
87 | } | |
88 | ||
89 | /** Set the stream without pushing old stream */ | |
90 | void TokenStreamSelector::select(TokenStream* stream) | |
91 | { | |
92 | input = stream; | |
93 | } | |
94 | ||
95 | void 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 |