ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-3.0/src/antlr/TokenStreamRewriteEngine.cpp
Revision: 2482
Committed: Fri Dec 2 22:37:31 2005 UTC (18 years, 7 months ago) by gezelter
File size: 5549 byte(s)
Log Message:
Spurious semicolon removal

File Contents

# User Rev Content
1 tim 2469 #include <string>
2     #include <list>
3     #include <vector>
4     #include <map>
5     #include <utility>
6     #include <iostream>
7     #include <iterator>
8     #include <sstream>
9     #include <cassert>
10    
11     #include <antlr/config.hpp>
12    
13     #include <antlr/TokenStream.hpp>
14     #include <antlr/TokenWithIndex.hpp>
15     #include <antlr/BitSet.hpp>
16     #include <antlr/TokenStreamRewriteEngine.hpp>
17    
18     #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
19     namespace antlr {
20     #endif
21    
22     const char* TokenStreamRewriteEngine::DEFAULT_PROGRAM_NAME = "default";
23    
24     namespace {
25    
26     struct compareOperationIndex {
27     typedef TokenStreamRewriteEngine::RewriteOperation RewriteOperation;
28     bool operator() ( const RewriteOperation* a, const RewriteOperation* b ) const
29     {
30     return a->getIndex() < b->getIndex();
31     }
32     };
33     struct dumpTokenWithIndex {
34     dumpTokenWithIndex( ANTLR_USE_NAMESPACE(std)ostream& o ) : out(o) {}
35     void operator() ( const RefTokenWithIndex& t ) {
36     out << "[txt='" << t->getText() << "' tp=" << t->getType() << " idx=" << t->getIndex() << "]\n";
37     }
38     ANTLR_USE_NAMESPACE(std)ostream& out;
39     };
40 gezelter 2482 }
41 tim 2469
42     TokenStreamRewriteEngine::TokenStreamRewriteEngine(TokenStream& upstream)
43     : stream(upstream)
44     , index(MIN_TOKEN_INDEX)
45     , tokens()
46     , programs()
47     , discardMask()
48     {
49     }
50    
51     TokenStreamRewriteEngine::TokenStreamRewriteEngine(TokenStream& upstream, size_t initialSize )
52     : stream(upstream)
53     , index(MIN_TOKEN_INDEX)
54     , tokens(initialSize)
55     , programs()
56     , discardMask()
57     {
58     }
59    
60     RefToken TokenStreamRewriteEngine::nextToken( void )
61     {
62     RefTokenWithIndex t;
63     // suck tokens until end of stream or we find a non-discarded token
64     do {
65     t = RefTokenWithIndex(stream.nextToken());
66     if ( t )
67     {
68     t->setIndex(index); // what is t's index in list?
69     if ( t->getType() != Token::EOF_TYPE ) {
70     tokens.push_back(t); // track all tokens except EOF
71     }
72     index++; // move to next position
73     }
74     } while ( t && discardMask.member(t->getType()) );
75     return RefToken(t);
76     }
77    
78     void TokenStreamRewriteEngine::rollback( const std::string& programName,
79     size_t instructionIndex )
80     {
81     program_map::iterator rewrite = programs.find(programName);
82     if( rewrite != programs.end() )
83     {
84     operation_list& prog = rewrite->second;
85     operation_list::iterator
86     j = prog.begin(),
87     end = prog.end();
88    
89     std::advance(j,instructionIndex);
90     if( j != end )
91     prog.erase(j, end);
92     }
93     }
94    
95     void TokenStreamRewriteEngine::originalToStream( std::ostream& out,
96     size_t start,
97     size_t end ) const
98     {
99     token_list::const_iterator s = tokens.begin();
100     std::advance( s, start );
101     token_list::const_iterator e = s;
102     std::advance( e, end-start );
103     std::for_each( s, e, tokenToStream(out) );
104     }
105    
106     void TokenStreamRewriteEngine::toStream( std::ostream& out,
107     const std::string& programName,
108     size_t firstToken,
109     size_t lastToken ) const
110     {
111     if( tokens.size() == 0 )
112     return;
113    
114     program_map::const_iterator rewriter = programs.find(programName);
115    
116     if ( rewriter == programs.end() )
117     return;
118    
119     // get the prog and some iterators in it...
120     const operation_list& prog = rewriter->second;
121     operation_list::const_iterator
122     rewriteOpIndex = prog.begin(),
123     rewriteOpEnd = prog.end();
124    
125     size_t tokenCursor = firstToken;
126     // make sure we don't run out of the tokens we have...
127     if( lastToken > (tokens.size() - 1) )
128     lastToken = tokens.size() - 1;
129    
130     while ( tokenCursor <= lastToken )
131     {
132     // std::cout << "tokenCursor = " << tokenCursor << " first prog index = " << (*rewriteOpIndex)->getIndex() << std::endl;
133    
134     if( rewriteOpIndex != rewriteOpEnd )
135     {
136     size_t up_to_here = std::min(lastToken,(*rewriteOpIndex)->getIndex());
137     while( tokenCursor < up_to_here )
138     out << tokens[tokenCursor++]->getText();
139     }
140     while ( rewriteOpIndex != rewriteOpEnd &&
141     tokenCursor == (*rewriteOpIndex)->getIndex() &&
142     tokenCursor <= lastToken )
143     {
144     tokenCursor = (*rewriteOpIndex)->execute(out);
145     ++rewriteOpIndex;
146     }
147     if( tokenCursor <= lastToken )
148     out << tokens[tokenCursor++]->getText();
149     }
150     // std::cout << "Handling tail operations # left = " << std::distance(rewriteOpIndex,rewriteOpEnd) << std::endl;
151     // now see if there are operations (append) beyond last token index
152     std::for_each( rewriteOpIndex, rewriteOpEnd, executeOperation(out) );
153     rewriteOpIndex = rewriteOpEnd;
154     }
155    
156     void TokenStreamRewriteEngine::toDebugStream( std::ostream& out,
157     size_t start,
158     size_t end ) const
159     {
160     token_list::const_iterator s = tokens.begin();
161     std::advance( s, start );
162     token_list::const_iterator e = s;
163     std::advance( e, end-start );
164     std::for_each( s, e, dumpTokenWithIndex(out) );
165     }
166    
167     void TokenStreamRewriteEngine::addToSortedRewriteList( const std::string& programName,
168     RewriteOperation* op )
169     {
170     program_map::iterator rewrites = programs.find(programName);
171     // check if we got the program already..
172     if ( rewrites == programs.end() )
173     {
174     // no prog make a new one...
175     operation_list ops;
176     ops.push_back(op);
177     programs.insert(std::make_pair(programName,ops));
178     return;
179     }
180     operation_list& prog = rewrites->second;
181    
182     if( prog.empty() )
183     {
184     prog.push_back(op);
185     return;
186     }
187    
188     operation_list::iterator i, end = prog.end();
189     i = end;
190     --i;
191     // if at or beyond last op's index, just append
192     if ( op->getIndex() >= (*i)->getIndex() ) {
193     prog.push_back(op); // append to list of operations
194     return;
195     }
196     i = prog.begin();
197    
198     if( i != end )
199     {
200     operation_list::iterator pos = std::upper_bound( i, end, op, compareOperationIndex() );
201     prog.insert(pos,op);
202     }
203     else
204     prog.push_back(op);
205     }
206    
207     #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE
208     }
209     #endif