00001 #ifndef INC_TokenStreamRewriteEngine_hpp__
00002 #define INC_TokenStreamRewriteEngine_hpp__
00003
00004
00005
00006
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& ) {
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
00237 insertBefore(programName,index+1, text);
00238 }
00239
00240 void insertBefore( RefTokenWithIndex t,
00241 const ANTLR_USE_NAMESPACE(std)string& text )
00242 {
00243
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