| 27 | 
  | 
#endif | 
| 28 | 
  | 
 | 
| 29 | 
  | 
/** This token stream tracks the *entire* token stream coming from | 
| 30 | 
< | 
 *  a lexer, but does not pass on the whitespace (or whatever else | 
| 31 | 
< | 
 *  you want to discard) to the parser. | 
| 30 | 
> | 
 *       a lexer, but does not pass on the whitespace (or whatever else | 
| 31 | 
> | 
 *       you want to discard) to the parser. | 
| 32 | 
  | 
 * | 
| 33 | 
< | 
 *  This class can then be asked for the ith token in the input stream. | 
| 34 | 
< | 
 *  Useful for dumping out the input stream exactly after doing some | 
| 35 | 
< | 
 *  augmentation or other manipulations.  Tokens are index from 0..n-1 | 
| 33 | 
> | 
 *       This class can then be asked for the ith token in the input stream. | 
| 34 | 
> | 
 *       Useful for dumping out the input stream exactly after doing some | 
| 35 | 
> | 
 *       augmentation or other manipulations.   Tokens are index from 0..n-1 | 
| 36 | 
  | 
 * | 
| 37 | 
< | 
 *  You can insert stuff, replace, and delete chunks.  Note that the | 
| 38 | 
< | 
 *  operations are done lazily--only if you convert the buffer to a | 
| 39 | 
< | 
 *  String.  This is very efficient because you are not moving data around | 
| 40 | 
< | 
 *  all the time.  As the buffer of tokens is converted to strings, the | 
| 41 | 
< | 
 *  toString() method(s) check to see if there is an operation at the | 
| 42 | 
< | 
 *  current index.  If so, the operation is done and then normal String | 
| 43 | 
< | 
 *  rendering continues on the buffer.  This is like having multiple Turing | 
| 44 | 
< | 
 *  machine instruction streams (programs) operating on a single input tape. :) | 
| 37 | 
> | 
 *       You can insert stuff, replace, and delete chunks.       Note that the | 
| 38 | 
> | 
 *       operations are done lazily--only if you convert the buffer to a | 
| 39 | 
> | 
 *       String.         This is very efficient because you are not moving data around | 
| 40 | 
> | 
 *       all the time.   As the buffer of tokens is converted to strings, the | 
| 41 | 
> | 
 *       toString() method(s) check to see if there is an operation at the | 
| 42 | 
> | 
 *       current index.  If so, the operation is done and then normal String | 
| 43 | 
> | 
 *       rendering continues on the buffer.      This is like having multiple Turing | 
| 44 | 
> | 
 *       machine instruction streams (programs) operating on a single input tape. :) | 
| 45 | 
  | 
 * | 
| 46 | 
< | 
 *  Since the operations are done lazily at toString-time, operations do not | 
| 47 | 
< | 
 *  screw up the token index values.  That is, an insert operation at token | 
| 48 | 
< | 
 *  index i does not change the index values for tokens i+1..n-1. | 
| 46 | 
> | 
 *       Since the operations are done lazily at toString-time, operations do not | 
| 47 | 
> | 
 *       screw up the token index values.  That is, an insert operation at token | 
| 48 | 
> | 
 *       index i does not change the index values for tokens i+1..n-1. | 
| 49 | 
  | 
 * | 
| 50 | 
< | 
 *  Because operations never actually alter the buffer, you may always get | 
| 51 | 
< | 
 *  the original token stream back without undoing anything.  Since | 
| 52 | 
< | 
 *  the instructions are queued up, you can easily simulate transactions and | 
| 53 | 
< | 
 *  roll back any changes if there is an error just by removing instructions. | 
| 54 | 
< | 
 *  For example, | 
| 50 | 
> | 
 *       Because operations never actually alter the buffer, you may always get | 
| 51 | 
> | 
 *       the original token stream back without undoing anything.  Since | 
| 52 | 
> | 
 *       the instructions are queued up, you can easily simulate transactions and | 
| 53 | 
> | 
 *       roll back any changes if there is an error just by removing instructions. | 
| 54 | 
> | 
 *       For example, | 
| 55 | 
  | 
 * | 
| 56 | 
< | 
 *              TokenStreamRewriteEngine rewriteEngine = | 
| 57 | 
< | 
 *                      new TokenStreamRewriteEngine(lexer); | 
| 58 | 
< | 
 *      JavaRecognizer parser = new JavaRecognizer(rewriteEngine); | 
| 59 | 
< | 
 *      ... | 
| 60 | 
< | 
 *      rewriteEngine.insertAfter("pass1", t, "foobar");} | 
| 61 | 
< | 
 *              rewriteEngine.insertAfter("pass2", u, "start");} | 
| 62 | 
< | 
 *              System.out.println(rewriteEngine.toString("pass1")); | 
| 63 | 
< | 
 *              System.out.println(rewriteEngine.toString("pass2")); | 
| 64 | 
< | 
 * | 
| 65 | 
< | 
 *  You can also have multiple "instruction streams" and get multiple | 
| 66 | 
< | 
 *  rewrites from a single pass over the input.  Just name the instruction | 
| 67 | 
< | 
 *  streams and use that name again when printing the buffer.  This could be | 
| 68 | 
< | 
 *  useful for generating a C file and also its header file--all from the | 
| 69 | 
< | 
 *  same buffer. | 
| 56 | 
> | 
 *                      TokenStreamRewriteEngine rewriteEngine = | 
| 57 | 
> | 
 *                              new TokenStreamRewriteEngine(lexer); | 
| 58 | 
> | 
 *                JavaRecognizer parser = new JavaRecognizer(rewriteEngine); | 
| 59 | 
> | 
 *                ... | 
| 60 | 
> | 
 *                rewriteEngine.insertAfter("pass1", t, "foobar");} | 
| 61 | 
> | 
 *                      rewriteEngine.insertAfter("pass2", u, "start");} | 
| 62 | 
> | 
 *                      System.out.println(rewriteEngine.toString("pass1")); | 
| 63 | 
> | 
 *                      System.out.println(rewriteEngine.toString("pass2")); | 
| 64 | 
  | 
 * | 
| 65 | 
< | 
 *  If you don't use named rewrite streams, a "default" stream is used. | 
| 65 | 
> | 
 *       You can also have multiple "instruction streams" and get multiple | 
| 66 | 
> | 
 *       rewrites from a single pass over the input.     Just name the instruction | 
| 67 | 
> | 
 *       streams and use that name again when printing the buffer.      This could be | 
| 68 | 
> | 
 *       useful for generating a C file and also its header file--all from the | 
| 69 | 
> | 
 *       same buffer. | 
| 70 | 
  | 
 * | 
| 71 | 
< | 
 *  Terence Parr, parrt@cs.usfca.edu | 
| 72 | 
< | 
 *  University of San Francisco | 
| 73 | 
< | 
 *  February 2004 | 
| 71 | 
> | 
 *       If you don't use named rewrite streams, a "default" stream is used. | 
| 72 | 
> | 
 * | 
| 73 | 
> | 
 *       Terence Parr, parrt@cs.usfca.edu | 
| 74 | 
> | 
 *       University of San Francisco | 
| 75 | 
> | 
 *       February 2004 | 
| 76 | 
  | 
 */ | 
| 77 | 
  | 
class TokenStreamRewriteEngine : public TokenStream | 
| 78 | 
  | 
{ | 
| 79 | 
  | 
public: | 
| 80 | 
  | 
        typedef ANTLR_USE_NAMESPACE(std)vector<antlr::RefTokenWithIndex> token_list; | 
| 81 | 
– | 
 | 
| 82 | 
– | 
        static const size_t MIN_TOKEN_INDEX = 0; | 
| 81 | 
  | 
        static const char* DEFAULT_PROGRAM_NAME; | 
| 82 | 
< | 
        static const int PROGRAM_INIT_SIZE = 100; | 
| 82 | 
> | 
#ifndef NO_STATIC_CONSTS | 
| 83 | 
> | 
        static const size_t MIN_TOKEN_INDEX; | 
| 84 | 
> | 
        static const int PROGRAM_INIT_SIZE; | 
| 85 | 
> | 
#else | 
| 86 | 
> | 
        enum { | 
| 87 | 
> | 
                MIN_TOKEN_INDEX = 0, | 
| 88 | 
> | 
                PROGRAM_INIT_SIZE = 100 | 
| 89 | 
> | 
        }; | 
| 90 | 
> | 
#endif | 
| 91 | 
  | 
 | 
| 92 | 
  | 
        struct tokenToStream { | 
| 93 | 
  | 
                tokenToStream( ANTLR_USE_NAMESPACE(std)ostream& o ) : out(o) {} | 
| 108 | 
  | 
                { | 
| 109 | 
  | 
                } | 
| 110 | 
  | 
                /** Execute the rewrite operation by possibly adding to the buffer. | 
| 111 | 
< | 
                 *  Return the index of the next token to operate on. | 
| 111 | 
> | 
                 *       Return the index of the next token to operate on. | 
| 112 | 
  | 
                 */ | 
| 113 | 
  | 
                virtual size_t execute( ANTLR_USE_NAMESPACE(std)ostream& /* out */ ) { | 
| 114 | 
  | 
                        return index; | 
| 197 | 
  | 
        } | 
| 198 | 
  | 
 | 
| 199 | 
  | 
        /** Rollback the instruction stream for a program so that | 
| 200 | 
< | 
         *  the indicated instruction (via instructionIndex) is no | 
| 201 | 
< | 
         *  longer in the stream.  UNTESTED! | 
| 200 | 
> | 
         *       the indicated instruction (via instructionIndex) is no | 
| 201 | 
> | 
         *       longer in the stream.  UNTESTED! | 
| 202 | 
  | 
         */ | 
| 203 | 
  | 
        void rollback(const ANTLR_USE_NAMESPACE(std)string& programName, | 
| 204 | 
  | 
                                          size_t instructionIndex ); | 
| 230 | 
  | 
        } | 
| 231 | 
  | 
 | 
| 232 | 
  | 
        void insertAfter( const ANTLR_USE_NAMESPACE(std)string& programName, | 
| 233 | 
< | 
                                                   size_t index, | 
| 233 | 
> | 
                                                        size_t index, | 
| 234 | 
  | 
                                                        const ANTLR_USE_NAMESPACE(std)string& text ) | 
| 235 | 
  | 
        { | 
| 236 | 
  | 
                // to insert after, just insert before next index (even if past end) | 
| 353 | 
  | 
                                                                  size_t start, size_t end ) const; | 
| 354 | 
  | 
 | 
| 355 | 
  | 
        void toStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const { | 
| 356 | 
< | 
                return toStream( out, MIN_TOKEN_INDEX, getTokenStreamSize()); | 
| 356 | 
> | 
                toStream( out, MIN_TOKEN_INDEX, getTokenStreamSize()); | 
| 357 | 
  | 
        } | 
| 358 | 
  | 
 | 
| 359 | 
  | 
        void toStream( ANTLR_USE_NAMESPACE(std)ostream& out, | 
| 360 | 
  | 
                                                const ANTLR_USE_NAMESPACE(std)string& programName ) const | 
| 361 | 
  | 
        { | 
| 362 | 
< | 
                return toStream( out, programName, MIN_TOKEN_INDEX, getTokenStreamSize()); | 
| 362 | 
> | 
                toStream( out, programName, MIN_TOKEN_INDEX, getTokenStreamSize()); | 
| 363 | 
  | 
        } | 
| 364 | 
  | 
 | 
| 365 | 
  | 
        void toStream( ANTLR_USE_NAMESPACE(std)ostream& out, | 
| 366 | 
  | 
                                                size_t start, size_t end ) const | 
| 367 | 
  | 
        { | 
| 368 | 
< | 
                return toStream(out, DEFAULT_PROGRAM_NAME, start, end); | 
| 368 | 
> | 
                toStream(out, DEFAULT_PROGRAM_NAME, start, end); | 
| 369 | 
  | 
        } | 
| 370 | 
  | 
 | 
| 371 | 
  | 
        void toStream( ANTLR_USE_NAMESPACE(std)ostream& out, | 
| 373 | 
  | 
                                                size_t firstToken, size_t lastToken ) const; | 
| 374 | 
  | 
 | 
| 375 | 
  | 
        void toDebugStream( ANTLR_USE_NAMESPACE(std)ostream& out ) const { | 
| 376 | 
< | 
                return toDebugStream( out, MIN_TOKEN_INDEX, getTokenStreamSize()); | 
| 376 | 
> | 
                toDebugStream( out, MIN_TOKEN_INDEX, getTokenStreamSize()); | 
| 377 | 
  | 
        } | 
| 378 | 
  | 
 | 
| 379 | 
  | 
        void toDebugStream( ANTLR_USE_NAMESPACE(std)ostream& out, | 
| 405 | 
  | 
 | 
| 406 | 
  | 
protected: | 
| 407 | 
  | 
        /** If op.index > lastRewriteTokenIndexes, just add to the end. | 
| 408 | 
< | 
         *  Otherwise, do linear */ | 
| 408 | 
> | 
         *       Otherwise, do linear */ | 
| 409 | 
  | 
        void addToSortedRewriteList(RewriteOperation* op) { | 
| 410 | 
  | 
                addToSortedRewriteList(DEFAULT_PROGRAM_NAME, op); | 
| 411 | 
  | 
        } |