| 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 |  | } |