ANTLR Support Libraries 2.7.1+
|
00001 #ifndef INC_TokenStreamRewriteEngine_hpp__ 00002 #define INC_TokenStreamRewriteEngine_hpp__ 00003 00004 /* ANTLR Translator Generator 00005 * Project led by Terence Parr at http://www.jGuru.com 00006 * Software rights: http://www.antlr.org/license.html 00007 */ 00008 00009 #include <string> 00010 #include <list> 00011 #include <vector> 00012 #include <map> 00013 #include <utility> 00014 #include <iostream> 00015 #include <iterator> 00016 #include <cassert> 00017 #include <algorithm> 00018 00019 #include <antlr/config.hpp> 00020 00021 #include <antlr/TokenStream.hpp> 00022 #include <antlr/TokenWithIndex.hpp> 00023 #include <antlr/BitSet.hpp> 00024 00025 #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE 00026 namespace antlr { 00027 #endif 00028 00077 class TokenStreamRewriteEngine : public TokenStream 00078 { 00079 public: 00080 typedef ANTLR_USE_NAMESPACE(std)vector<antlr::RefTokenWithIndex> token_list; 00081 static const char* DEFAULT_PROGRAM_NAME; 00082 #ifndef NO_STATIC_CONSTS 00083 static const size_t MIN_TOKEN_INDEX; 00084 static const int PROGRAM_INIT_SIZE; 00085 #else 00086 enum { 00087 MIN_TOKEN_INDEX = 0, 00088 PROGRAM_INIT_SIZE = 100 00089 }; 00090 #endif 00091 00092 struct tokenToStream { 00093 tokenToStream( ANTLR_USE_NAMESPACE(std)ostream& o ) : out(o) {} 00094 template <typename T> void operator() ( const T& t ) { 00095 out << t->getText(); 00096 } 00097 ANTLR_USE_NAMESPACE(std)ostream& out; 00098 }; 00099 00100 class RewriteOperation { 00101 protected: 00102 RewriteOperation( size_t idx, const ANTLR_USE_NAMESPACE(std)string& txt ) 00103 : index(idx), text(txt) 00104 { 00105 } 00106 public: 00107 virtual ~RewriteOperation() 00108 { 00109 } 00113 virtual size_t execute( ANTLR_USE_NAMESPACE(std)ostream& /* out */ ) { 00114 return index; 00115 } 00116 virtual size_t getIndex() const { 00117 return index; 00118 } 00119 virtual const char* type() const { 00120 return "RewriteOperation"; 00121 } 00122 protected: 00123 size_t index; 00124 ANTLR_USE_NAMESPACE(std)string text; 00125 }; 00126 00127 struct executeOperation { 00128 ANTLR_USE_NAMESPACE(std)ostream& out; 00129 executeOperation( ANTLR_USE_NAMESPACE(std)ostream& s ) : out(s) {} 00130 void operator () ( RewriteOperation* t ) { 00131 t->execute(out); 00132 } 00133 }; 00134 00136 typedef ANTLR_USE_NAMESPACE(std)list<RewriteOperation*> operation_list; 00138 typedef ANTLR_USE_NAMESPACE(std)map<ANTLR_USE_NAMESPACE(std)string,operation_list> program_map; 00139 00140 class InsertBeforeOp : public RewriteOperation 00141 { 00142 public: 00143 InsertBeforeOp( size_t index, const ANTLR_USE_NAMESPACE(std)string& text ) 00144 : RewriteOperation(index, text) 00145 { 00146 } 00147 virtual ~InsertBeforeOp() {} 00148 virtual size_t execute( ANTLR_USE_NAMESPACE(std)ostream& out ) 00149 { 00150 out << text; 00151 return index; 00152 } 00153 virtual const char* type() const { 00154 return "InsertBeforeOp"; 00155 } 00156 }; 00157 00158 class ReplaceOp : public RewriteOperation 00159 { 00160 public: 00161 ReplaceOp(size_t from, size_t to, ANTLR_USE_NAMESPACE(std)string text) 00162 : RewriteOperation(from,text) 00163 , lastIndex(to) 00164 { 00165 } 00166 virtual ~ReplaceOp() {} 00167 virtual size_t execute( ANTLR_USE_NAMESPACE(std)ostream& out ) { 00168 out << text; 00169 return lastIndex+1; 00170 } 00171 virtual const char* type() const { 00172 return "ReplaceOp"; 00173 } 00174 protected: 00175 size_t lastIndex; 00176 }; 00177 00178 class DeleteOp : public ReplaceOp { 00179 public: 00180 DeleteOp(size_t from, size_t to) 00181 : ReplaceOp(from,to,"") 00182 { 00183 } 00184 virtual const char* type() const { 00185 return "DeleteOp"; 00186 } 00187 }; 00188 00189 TokenStreamRewriteEngine(TokenStream& upstream); 00190 00191 TokenStreamRewriteEngine(TokenStream& upstream, size_t initialSize); 00192 00193 RefToken nextToken( void ); 00194 00195 void rollback(size_t instructionIndex) { 00196 rollback(DEFAULT_PROGRAM_NAME, instructionIndex); 00197 } 00198 00203 void rollback(const ANTLR_USE_NAMESPACE(std)string& programName, 00204 size_t instructionIndex ); 00205 00206 void deleteProgram() { 00207 deleteProgram(DEFAULT_PROGRAM_NAME); 00208 } 00209 00211 void deleteProgram(const ANTLR_USE_NAMESPACE(std)string& programName) { 00212 rollback(programName, MIN_TOKEN_INDEX); 00213 } 00214 00215 void insertAfter( RefTokenWithIndex t, 00216 const ANTLR_USE_NAMESPACE(std)string& text ) 00217 { 00218 insertAfter(DEFAULT_PROGRAM_NAME, t, text); 00219 } 00220 00221 void insertAfter(size_t index, const ANTLR_USE_NAMESPACE(std)string& text) { 00222 insertAfter(DEFAULT_PROGRAM_NAME, index, text); 00223 } 00224 00225 void insertAfter( const ANTLR_USE_NAMESPACE(std)string& programName, 00226 RefTokenWithIndex t, 00227 const ANTLR_USE_NAMESPACE(std)string& text ) 00228 { 00229 insertAfter(programName, t->getIndex(), text); 00230 } 00231 00232 void insertAfter( const ANTLR_USE_NAMESPACE(std)string& programName, 00233 size_t index, 00234 const ANTLR_USE_NAMESPACE(std)string& text ) 00235 { 00236 // to insert after, just insert before next index (even if past end) 00237 insertBefore(programName,index+1, text); 00238 } 00239 00240 void insertBefore( RefTokenWithIndex t, 00241 const ANTLR_USE_NAMESPACE(std)string& text ) 00242 { 00243 // std::cout << "insertBefore index " << t->getIndex() << " " << text << std::endl; 00244 insertBefore(DEFAULT_PROGRAM_NAME, t, text); 00245 } 00246 00247 void insertBefore(size_t index, const ANTLR_USE_NAMESPACE(std)string& text) { 00248 insertBefore(DEFAULT_PROGRAM_NAME, index, text); 00249 } 00250 00251 void insertBefore( const ANTLR_USE_NAMESPACE(std)string& programName, 00252 RefTokenWithIndex t, 00253 const ANTLR_USE_NAMESPACE(std)string& text ) 00254 { 00255 insertBefore(programName, t->getIndex(), text); 00256 } 00257 00258 void insertBefore( const ANTLR_USE_NAMESPACE(std)string& programName, 00259 size_t index, 00260 const ANTLR_USE_NAMESPACE(std)string& text ) 00261 { 00262 addToSortedRewriteList(programName, new InsertBeforeOp(index,text)); 00263 } 00264 00265 void replace(size_t index, const ANTLR_USE_NAMESPACE(std)string& text) 00266 { 00267 replace(DEFAULT_PROGRAM_NAME, index, index, text); 00268 } 00269 00270 void replace( size_t from, size_t to, 00271 const ANTLR_USE_NAMESPACE(std)string& text) 00272 { 00273 replace(DEFAULT_PROGRAM_NAME, from, to, text); 00274 } 00275 00276 void replace( RefTokenWithIndex indexT, 00277 const ANTLR_USE_NAMESPACE(std)string& text ) 00278 { 00279 replace(DEFAULT_PROGRAM_NAME, indexT->getIndex(), indexT->getIndex(), text); 00280 } 00281 00282 void replace( RefTokenWithIndex from, 00283 RefTokenWithIndex to, 00284 const ANTLR_USE_NAMESPACE(std)string& text ) 00285 { 00286 replace(DEFAULT_PROGRAM_NAME, from, to, text); 00287 } 00288 00289 void replace(const ANTLR_USE_NAMESPACE(std)string& programName, 00290 size_t from, size_t to, 00291 const ANTLR_USE_NAMESPACE(std)string& text ) 00292 { 00293 addToSortedRewriteList(programName,new ReplaceOp(from, to, text)); 00294 } 00295 00296 void replace( const ANTLR_USE_NAMESPACE(std)string& programName, 00297 RefTokenWithIndex from, 00298 RefTokenWithIndex to, 00299 const ANTLR_USE_NAMESPACE(std)string& text ) 00300 { 00301 replace(programName, 00302 from->getIndex(), 00303 to->getIndex(), 00304 text); 00305 } 00306 00307 void remove(size_t index) { 00308 remove(DEFAULT_PROGRAM_NAME, index, index); 00309 } 00310 00311 void remove(size_t from, size_t to) { 00312 remove(DEFAULT_PROGRAM_NAME, from, to); 00313 } 00314 00315 void remove(RefTokenWithIndex indexT) { 00316 remove(DEFAULT_PROGRAM_NAME, indexT, indexT); 00317 } 00318 00319 void remove(RefTokenWithIndex from, RefTokenWithIndex to) { 00320 remove(DEFAULT_PROGRAM_NAME, from, to); 00321 } 00322 00323 void remove( const ANTLR_USE_NAMESPACE(std)string& programName, 00324 size_t from, size_t to) 00325 { 00326 replace(programName,from,to,""); 00327 } 00328 00329 void remove( const ANTLR_USE_NAMESPACE(std)string& programName, 00330 RefTokenWithIndex from, RefTokenWithIndex to ) 00331 { 00332 replace(programName,from,to,""); 00333 } 00334 00335 void discard(int ttype) { 00336 discardMask.add(ttype); 00337 } 00338 00339 RefToken getToken( size_t i ) 00340 { 00341 return RefToken(tokens.at(i)); 00342 } 00343 00344 size_t getTokenStreamSize() const { 00345 return tokens.size(); 00346 } 00347 00348 void originalToStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const { 00349 ANTLR_USE_NAMESPACE(std)for_each( tokens.begin(), tokens.end(), tokenToStream(out) ); 00350 } 00351 00352 void originalToStream( ANTLR_USE_NAMESPACE(std)ostream& out, 00353 size_t start, size_t end ) const; 00354 00355 void toStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const { 00356 toStream( out, MIN_TOKEN_INDEX, getTokenStreamSize()); 00357 } 00358 00359 void toStream( ANTLR_USE_NAMESPACE(std)ostream& out, 00360 const ANTLR_USE_NAMESPACE(std)string& programName ) const 00361 { 00362 toStream( out, programName, MIN_TOKEN_INDEX, getTokenStreamSize()); 00363 } 00364 00365 void toStream( ANTLR_USE_NAMESPACE(std)ostream& out, 00366 size_t start, size_t end ) const 00367 { 00368 toStream(out, DEFAULT_PROGRAM_NAME, start, end); 00369 } 00370 00371 void toStream( ANTLR_USE_NAMESPACE(std)ostream& out, 00372 const ANTLR_USE_NAMESPACE(std)string& programName, 00373 size_t firstToken, size_t lastToken ) const; 00374 00375 void toDebugStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const { 00376 toDebugStream( out, MIN_TOKEN_INDEX, getTokenStreamSize()); 00377 } 00378 00379 void toDebugStream( ANTLR_USE_NAMESPACE(std)ostream& out, 00380 size_t start, size_t end ) const; 00381 00382 size_t getLastRewriteTokenIndex() const { 00383 return getLastRewriteTokenIndex(DEFAULT_PROGRAM_NAME); 00384 } 00385 00390 size_t getLastRewriteTokenIndex(const ANTLR_USE_NAMESPACE(std)string& programName) const { 00391 program_map::const_iterator rewrites = programs.find(programName); 00392 00393 if( rewrites == programs.end() ) 00394 return 0; 00395 00396 const operation_list& prog = rewrites->second; 00397 if( !prog.empty() ) 00398 { 00399 operation_list::const_iterator last = prog.end(); 00400 --last; 00401 return (*last)->getIndex(); 00402 } 00403 return 0; 00404 } 00405 00406 protected: 00409 void addToSortedRewriteList(RewriteOperation* op) { 00410 addToSortedRewriteList(DEFAULT_PROGRAM_NAME, op); 00411 } 00412 00413 void addToSortedRewriteList( const ANTLR_USE_NAMESPACE(std)string& programName, 00414 RewriteOperation* op ); 00415 00416 protected: 00418 TokenStream& stream; 00420 size_t index; 00421 00423 token_list tokens; 00424 00429 program_map programs; 00430 00432 BitSet discardMask; 00433 }; 00434 00435 #ifdef ANTLR_CXX_SUPPORTS_NAMESPACE 00436 } 00437 #endif 00438 00439 #endif