ANTLR Support Libraries 2.7.1+
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines
antlr/TokenStreamRewriteEngine.hpp
Go to the documentation of this file.
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