PageRenderTime 104ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/projects/antlr-3.4/runtime/ObjC/Framework/ANTLRTokenRewriteStream.m

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Objective C | 692 lines | 474 code | 98 blank | 120 comment | 96 complexity | 22f3b7278198220fd336fe4d32a3d8f7 MD5 | raw file
  1. //
  2. // ANTLRTokenRewriteStream.m
  3. // ANTLR
  4. //
  5. // Created by Alan Condit on 6/19/10.
  6. // [The "BSD licence"]
  7. // Copyright (c) 2010 Alan Condit
  8. // All rights reserved.
  9. //
  10. // Redistribution and use in source and binary forms, with or without
  11. // modification, are permitted provided that the following conditions
  12. // are met:
  13. // 1. Redistributions of source code must retain the above copyright
  14. // notice, this list of conditions and the following disclaimer.
  15. // 2. Redistributions in binary form must reproduce the above copyright
  16. // notice, this list of conditions and the following disclaimer in the
  17. // documentation and/or other materials provided with the distribution.
  18. // 3. The name of the author may not be used to endorse or promote products
  19. // derived from this software without specific prior written permission.
  20. //
  21. // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  22. // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  23. // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  24. // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  25. // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  26. // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  30. // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. #import "ANTLRTokenRewriteStream.h"
  32. #import "ANTLRRuntimeException.h"
  33. static NSString *DEFAULT_PROGRAM_NAME = @"default";
  34. static NSInteger PROGRAM_INIT_SIZE = 100;
  35. static NSInteger MIN_TOKEN_INDEX = 0;
  36. extern NSInteger debug;
  37. // Define the rewrite operation hierarchy
  38. @implementation ANTLRRewriteOperation
  39. @synthesize instructionIndex;
  40. @synthesize rwIndex;
  41. @synthesize text;
  42. + (ANTLRRewriteOperation *) newANTLRRewriteOperation:(NSInteger)anIndex Text:(NSString *)theText
  43. {
  44. return [[ANTLRRewriteOperation alloc] initWithIndex:anIndex Text:theText];
  45. }
  46. - (id) initWithIndex:(NSInteger)anIndex Text:(NSString *)theText
  47. {
  48. if ((self = [super init]) != nil) {
  49. rwIndex = anIndex;
  50. text = theText;
  51. }
  52. return self;
  53. }
  54. /** Execute the rewrite operation by possibly adding to the buffer.
  55. * Return the rwIndex of the next token to operate on.
  56. */
  57. - (NSInteger) execute:(NSString *)buf
  58. {
  59. return rwIndex;
  60. }
  61. - (NSString *)toString
  62. {
  63. NSString *opName = [self className];
  64. int $index = [self indexOf:'$' inString:opName];
  65. opName = [opName substringWithRange:NSMakeRange($index+1, [opName length])];
  66. return [NSString stringWithFormat:@"<%@%d:\"%@\">", opName, rwIndex, opName];
  67. }
  68. - (NSInteger) indexOf:(char)aChar inString:(NSString *)aString
  69. {
  70. char indexedChar;
  71. for( int i = 0; i < [aString length]; i++ ) {
  72. indexedChar = [aString characterAtIndex:i];
  73. if (indexedChar == aChar) {
  74. return i;
  75. }
  76. }
  77. return -1;
  78. }
  79. @end
  80. @implementation ANTLRInsertBeforeOp
  81. + (ANTLRInsertBeforeOp *) newANTLRInsertBeforeOp:(NSInteger) anIndex Text:(NSString *)theText
  82. {
  83. return [[ANTLRInsertBeforeOp alloc] initWithIndex:anIndex Text:theText];
  84. }
  85. - (id) initWithIndex:(NSInteger)anIndex Text:(NSString *)theText
  86. {
  87. if ((self = [super initWithIndex:anIndex Text:theText]) != nil) {
  88. rwIndex = anIndex;
  89. text = theText;
  90. }
  91. return self;
  92. }
  93. - (NSInteger) execute:(NSMutableString *)buf
  94. {
  95. [buf appendString:text];
  96. if ( ((ANTLRCommonToken *)[tokens objectAtIndex:rwIndex]).type != ANTLRTokenTypeEOF ) {
  97. [buf appendString:[[tokens objectAtIndex:rwIndex] text]];
  98. }
  99. return rwIndex+1;
  100. }
  101. @end
  102. /** I'm going to try replacing range from x..y with (y-x)+1 ANTLRReplaceOp
  103. * instructions.
  104. */
  105. @implementation ANTLRReplaceOp
  106. @synthesize lastIndex;
  107. + (ANTLRReplaceOp *) newANTLRReplaceOp:(NSInteger)from ToIndex:(NSInteger)to Text:(NSString*)theText
  108. {
  109. return [[ANTLRReplaceOp alloc] initWithIndex:from ToIndex:to Text:theText];
  110. }
  111. - (id) initWithIndex:(NSInteger)from ToIndex:(NSInteger)to Text:(NSString *)theText
  112. {
  113. if ((self = [super initWithIndex:from Text:theText]) != nil) {
  114. lastIndex = to;
  115. }
  116. return self;
  117. }
  118. - (NSInteger) execute:(NSMutableString *)buf
  119. {
  120. if ( text!=nil ) {
  121. [buf appendString:text];
  122. }
  123. return lastIndex+1;
  124. }
  125. - (NSString *)toString
  126. {
  127. return [NSString stringWithFormat:@"<ANTLRReplaceOp@ %d..%d :>%@\n", rwIndex, lastIndex, text];
  128. }
  129. @end
  130. @implementation ANTLRDeleteOp
  131. + (ANTLRDeleteOp *) newANTLRDeleteOp:(NSInteger)from ToIndex:(NSInteger)to
  132. {
  133. // super(from To:to, null);
  134. return [[ANTLRDeleteOp alloc] initWithIndex:from ToIndex:to];
  135. }
  136. - (id) initWithIndex:(NSInteger)from ToIndex:(NSInteger)to
  137. {
  138. if ((self = [super initWithIndex:from ToIndex:to Text:nil]) != nil) {
  139. lastIndex = to;
  140. }
  141. return self;
  142. }
  143. - (NSString *)toString
  144. {
  145. return [NSString stringWithFormat:@"<DeleteOp@ %d..%d\n", rwIndex, lastIndex];
  146. }
  147. @end
  148. @implementation ANTLRTokenRewriteStream
  149. @synthesize programs;
  150. @synthesize lastRewriteTokenIndexes;
  151. + (ANTLRTokenRewriteStream *)newANTLRTokenRewriteStream
  152. {
  153. return [[ANTLRTokenRewriteStream alloc] init];
  154. }
  155. + (ANTLRTokenRewriteStream *)newANTLRTokenRewriteStream:(id<ANTLRTokenSource>) aTokenSource
  156. {
  157. return [[ANTLRTokenRewriteStream alloc] initWithTokenSource:aTokenSource];
  158. }
  159. + (ANTLRTokenRewriteStream *)newANTLRTokenRewriteStream:(id<ANTLRTokenSource>) aTokenSource Channel:(NSInteger)aChannel
  160. {
  161. return [[ANTLRTokenRewriteStream alloc] initWithTokenSource:aTokenSource Channel:aChannel];
  162. }
  163. - (id) init
  164. {
  165. if ((self = [super init]) != nil) {
  166. programs = [ANTLRHashMap newANTLRHashMap];
  167. [programs addObject:[ANTLRMapElement newANTLRMapElementWithName:DEFAULT_PROGRAM_NAME Node:[ANTLRHashMap newANTLRHashMapWithLen:PROGRAM_INIT_SIZE]]];
  168. lastRewriteTokenIndexes = [ANTLRHashMap newANTLRHashMap];
  169. }
  170. return self;
  171. }
  172. - (id)initWithTokenSource:(id<ANTLRTokenSource>)aTokenSource
  173. {
  174. if ((self = [super init]) != nil) {
  175. programs = [ANTLRHashMap newANTLRHashMap];
  176. [programs addObject:[ANTLRMapElement newANTLRMapElementWithName:DEFAULT_PROGRAM_NAME Node:[ANTLRHashMap newANTLRHashMapWithLen:PROGRAM_INIT_SIZE]]];
  177. lastRewriteTokenIndexes = [ANTLRHashMap newANTLRHashMap];
  178. tokenSource = aTokenSource;
  179. }
  180. return self;
  181. }
  182. - (id)initWithTokenSource:(id<ANTLRTokenSource>)aTokenSource Channel:(NSInteger)aChannel
  183. {
  184. if ((self = [super init]) != nil) {
  185. programs = [ANTLRHashMap newANTLRHashMap];
  186. [programs addObject:[ANTLRMapElement newANTLRMapElementWithName:DEFAULT_PROGRAM_NAME Node:[ANTLRHashMap newANTLRHashMapWithLen:PROGRAM_INIT_SIZE]]];
  187. lastRewriteTokenIndexes = [ANTLRHashMap newANTLRHashMap];
  188. tokenSource = aTokenSource;
  189. channel = aChannel;
  190. }
  191. return self;
  192. }
  193. - (ANTLRHashMap *)getPrograms
  194. {
  195. return programs;
  196. }
  197. - (void)setPrograms:(ANTLRHashMap *)aProgList
  198. {
  199. programs = aProgList;
  200. }
  201. - (void) rollback:(NSInteger)instructionIndex
  202. {
  203. [self rollback:DEFAULT_PROGRAM_NAME Index:instructionIndex];
  204. }
  205. /** Rollback the instruction stream for a program so that
  206. * the indicated instruction (via instructionIndex) is no
  207. * longer in the stream. UNTESTED!
  208. */
  209. - (void) rollback:(NSString *)programName Index:(NSInteger)anInstructionIndex
  210. {
  211. id object;
  212. ANTLRHashMap *is;
  213. // AMutableArray *is = [programs get(programName)];
  214. is = [self getPrograms];
  215. object = [is getName:programName];
  216. if ( is != nil ) {
  217. #pragma warning this has to be fixed
  218. [programs insertObject:programName atIndex:anInstructionIndex];
  219. }
  220. }
  221. - (void) deleteProgram
  222. {
  223. [self deleteProgram:DEFAULT_PROGRAM_NAME];
  224. }
  225. /** Reset the program so that no instructions exist */
  226. - (void) deleteProgram:(NSString *)programName
  227. {
  228. [self rollback:programName Index:MIN_TOKEN_INDEX];
  229. }
  230. - (void) insertAfterToken:(id<ANTLRToken>)t Text:(NSString *)theText
  231. {
  232. [self insertAfterProgNam:DEFAULT_PROGRAM_NAME Index:[t getTokenIndex] Text:theText];
  233. }
  234. - (void) insertAfterIndex:(NSInteger)anIndex Text:(NSString *)theText
  235. {
  236. [self insertAfterProgNam:DEFAULT_PROGRAM_NAME Index:(NSInteger)anIndex Text:(NSString *)theText];
  237. }
  238. - (void) insertAfterProgNam:(NSString *)programName Index:(NSInteger)anIndex Text:(NSString *)theText
  239. {
  240. // to insert after, just insert before next rwIndex (even if past end)
  241. [self insertBeforeProgName:programName Index:anIndex+1 Text:theText];
  242. //addToSortedRewriteList(programName, new InsertAfterOp(rwIndex,text));
  243. }
  244. - (void) insertBeforeToken:(id<ANTLRToken>)t Text:(NSString *)theText
  245. {
  246. [self insertBeforeProgName:DEFAULT_PROGRAM_NAME Index:[t getTokenIndex] Text:theText];
  247. }
  248. - (void) insertBeforeIndex:(NSInteger)anIndex Text:(NSString *)theText
  249. {
  250. [self insertBeforeProgName:DEFAULT_PROGRAM_NAME Index:anIndex Text:theText];
  251. }
  252. - (void) insertBeforeProgName:(NSString *)programName Index:(NSInteger)rwIndex Text:(NSString *)theText
  253. {
  254. //addToSortedRewriteList(programName, new ANTLRInsertBeforeOp(rwIndex,text));
  255. ANTLRRewriteOperation *op = [ANTLRInsertBeforeOp newANTLRInsertBeforeOp:rwIndex Text:theText];
  256. ANTLRHashMap *rewrites = [self getProgram:programName];
  257. op.instructionIndex = [rewrites count];
  258. [rewrites addObject:op];
  259. }
  260. - (void) replaceFromIndex:(NSInteger)anIndex Text:(NSString *)theText
  261. {
  262. [self replaceProgNam:DEFAULT_PROGRAM_NAME FromIndex:anIndex ToIndex:anIndex Text:theText];
  263. }
  264. - (void) replaceFromIndex:(NSInteger)from ToIndex:(NSInteger)to Text:(NSString *)theText
  265. {
  266. [self replaceProgNam:DEFAULT_PROGRAM_NAME FromIndex:from ToIndex:to Text:theText];
  267. }
  268. - (void) replaceFromToken:(id<ANTLRToken>)anIndexT Text:(NSString *)theText
  269. {
  270. [self replaceProgNam:DEFAULT_PROGRAM_NAME FromIndex:[anIndexT getTokenIndex] ToIndex:[anIndexT getTokenIndex] Text:theText];
  271. }
  272. - (void) replaceFromToken:(id<ANTLRToken>)from ToToken:(id<ANTLRToken>)to Text:(NSString *)theText
  273. {
  274. [self replaceProgNam:DEFAULT_PROGRAM_NAME FromIndex:[from getTokenIndex] ToIndex:[to getTokenIndex] Text:theText];
  275. }
  276. - (void) replaceProgNam:(NSString *)programName Token:(id<ANTLRToken>)from Token:(id<ANTLRToken>)to Text:(NSString *)theText
  277. {
  278. [self replaceProgNam:programName FromIndex:[from getTokenIndex] ToIndex:[to getTokenIndex] Text:theText];
  279. }
  280. - (void) replaceProgNam:(NSString *)programName FromIndex:(NSInteger)from ToIndex:(NSInteger)to Text:(NSString *)theText
  281. {
  282. if ( from > to || from < 0 || to < 0 || to >= [tokens count] ) {
  283. @throw [ANTLRIllegalArgumentException newException:[NSString stringWithFormat:@"replace: range invalid: %d..%d size=%d\n", from, to, [tokens count]]];
  284. }
  285. ANTLRRewriteOperation *op = [ANTLRReplaceOp newANTLRReplaceOp:from ToIndex:to Text:theText];
  286. ANTLRHashMap *rewrites = (ANTLRHashMap *)[lastRewriteTokenIndexes getName:programName];
  287. op.instructionIndex = [rewrites count];
  288. [rewrites addObject:op];
  289. }
  290. - (void) delete:(NSInteger)anIndex
  291. {
  292. [self delete:DEFAULT_PROGRAM_NAME FromIndex:(NSInteger)anIndex ToIndex:(NSInteger)anIndex];
  293. }
  294. - (void) delete:(NSInteger)from ToIndex:(NSInteger)to
  295. {
  296. [self delete:DEFAULT_PROGRAM_NAME FromIndex:from ToIndex:to];
  297. }
  298. - (void) deleteToken:(id<ANTLRToken>)anIndexT
  299. {
  300. [self delete:DEFAULT_PROGRAM_NAME FromIndex:[anIndexT getTokenIndex] ToIndex:[anIndexT getTokenIndex]];
  301. }
  302. - (void) deleteFromToken:(id<ANTLRToken>)from ToToken:(id<ANTLRToken>)to
  303. {
  304. [self delete:DEFAULT_PROGRAM_NAME FromIndex:[from getTokenIndex] ToIndex:[to getTokenIndex]];
  305. }
  306. - (void) delete:(NSString *)programName FromToken:(id<ANTLRToken>)from ToToken:(id<ANTLRToken>)to
  307. {
  308. [self replaceProgNam:programName FromIndex:[from getTokenIndex] ToIndex:[to getTokenIndex] Text:nil];
  309. }
  310. - (void) delete:(NSString *)programName FromIndex:(NSInteger)from ToIndex:(NSInteger)to
  311. {
  312. [self replaceProgNam:programName FromIndex:from ToIndex:to Text:nil];
  313. }
  314. - (NSInteger)getLastRewriteTokenIndex
  315. {
  316. return [self getLastRewriteTokenIndex:DEFAULT_PROGRAM_NAME];
  317. }
  318. - (NSInteger)getLastRewriteTokenIndex:(NSString *)programName
  319. {
  320. #pragma warning fix this to look up the hashed name
  321. NSInteger anInt = -1;
  322. ANTLRMapElement *node = [lastRewriteTokenIndexes lookup:programName Scope:0];
  323. if ( node != nil ) {
  324. anInt = [lastRewriteTokenIndexes hash:programName];
  325. }
  326. return anInt;
  327. }
  328. - (void)setLastRewriteTokenIndex:(NSString *)programName Index:(NSInteger)anInt
  329. {
  330. [lastRewriteTokenIndexes insertObject:programName atIndex:anInt];
  331. }
  332. -(ANTLRHashMap *) getProgram:(NSString *)name
  333. {
  334. ANTLRHashMap *is = (ANTLRHashMap *)[programs getName:name];
  335. if ( is == nil ) {
  336. is = [self initializeProgram:name];
  337. }
  338. return is;
  339. }
  340. -(ANTLRHashMap *) initializeProgram:(NSString *)name
  341. {
  342. ANTLRHashMap *is = [ANTLRHashMap newANTLRHashMapWithLen:PROGRAM_INIT_SIZE];
  343. [is putName:name Node:nil];
  344. return is;
  345. }
  346. - (NSString *)toOriginalString
  347. {
  348. [super fill];
  349. return [self toOriginalString:MIN_TOKEN_INDEX End:[tokens count]-1];
  350. }
  351. - (NSString *)toOriginalString:(NSInteger)start End:(NSInteger)end
  352. {
  353. NSMutableString *buf = [NSMutableString stringWithCapacity:100];
  354. for (int i = start; i >= MIN_TOKEN_INDEX && i <= end && i< [tokens count]; i++) {
  355. if ( [[lastRewriteTokenIndexes objectAtIndex:i] type] != ANTLRTokenTypeEOF )
  356. [buf appendString:[[tokens objectAtIndex:i] text]];
  357. }
  358. return [NSString stringWithString:buf];
  359. }
  360. - (NSString *)toString
  361. {
  362. [super fill];
  363. return [self toStringFromStart:MIN_TOKEN_INDEX ToEnd:[tokens count]-1];
  364. }
  365. - (NSString *)toString:(NSString *)programName
  366. {
  367. [super fill];
  368. return [self toString:programName FromStart:MIN_TOKEN_INDEX ToEnd:[[programs objectAtIndex:MIN_TOKEN_INDEX] count]-1];
  369. }
  370. - (NSString *)toStringFromStart:(NSInteger)start ToEnd:(NSInteger)end
  371. {
  372. return [self toString:DEFAULT_PROGRAM_NAME FromStart:start ToEnd:end];
  373. }
  374. - (NSString *)toString:(NSString *)programName FromStart:(NSInteger)start ToEnd:(NSInteger)end
  375. {
  376. ANTLRHashMap *rewrites = (ANTLRHashMap *)[programs getName:programName];
  377. // ensure start/end are in range
  378. if ( end > [tokens count]-1 ) end = [tokens count]-1;
  379. if ( start < 0 )
  380. start = 0;
  381. if ( rewrites == nil || [rewrites count] == 0 ) {
  382. return [self toOriginalString:start End:end]; // no instructions to execute
  383. }
  384. NSMutableString *buf = [NSMutableString stringWithCapacity:100];
  385. // First, optimize instruction stream
  386. ANTLRHashMap *indexToOp = [self reduceToSingleOperationPerIndex:rewrites];
  387. // Walk buffer, executing instructions and emitting tokens
  388. int i = start;
  389. while ( i <= end && i < [tokens count] ) {
  390. ANTLRRewriteOperation *op = (ANTLRRewriteOperation *)[indexToOp objectAtIndex:i];
  391. [indexToOp setObject:nil atIndex:i]; // remove so any left have rwIndex size-1
  392. id<ANTLRToken>t = (id<ANTLRToken>) [tokens objectAtIndex:i];
  393. if ( op == nil ) {
  394. // no operation at that rwIndex, just dump token
  395. if ( t.type != ANTLRTokenTypeEOF )
  396. [buf appendString:t.text];
  397. i++; // move to next token
  398. }
  399. else {
  400. i = [op execute:buf]; // execute operation and skip
  401. }
  402. }
  403. // include stuff after end if it's last rwIndex in buffer
  404. // So, if they did an insertAfter(lastValidIndex, "foo"), include
  405. // foo if end==lastValidIndex.
  406. //if ( end == [tokens size]-1 ) {
  407. if ( end == [tokens count]-1 ) {
  408. // Scan any remaining operations after last token
  409. // should be included (they will be inserts).
  410. int i2 = 0;
  411. while ( i2 < [indexToOp count] - 1 ) {
  412. ANTLRRewriteOperation *op = [indexToOp objectAtIndex:i2];
  413. if ( op.rwIndex >= [tokens count]-1 ) {
  414. [buf appendString:op.text];
  415. }
  416. }
  417. }
  418. return [NSString stringWithString:buf];
  419. }
  420. /** We need to combine operations and report invalid operations (like
  421. * overlapping replaces that are not completed nested). Inserts to
  422. * same rwIndex need to be combined etc... Here are the cases:
  423. *
  424. * I.i.u I.j.v leave alone, nonoverlapping
  425. * I.i.u I.i.v combine: Iivu
  426. *
  427. * R.i-j.u R.x-y.v | i-j in x-y delete first R
  428. * R.i-j.u R.i-j.v delete first R
  429. * R.i-j.u R.x-y.v | x-y in i-j ERROR
  430. * R.i-j.u R.x-y.v | boundaries overlap ERROR
  431. *
  432. * I.i.u R.x-y.v | i in x-y delete I
  433. * I.i.u R.x-y.v | i not in x-y leave alone, nonoverlapping
  434. * R.x-y.v I.i.u | i in x-y ERROR
  435. * R.x-y.v I.x.u R.x-y.uv (combine, delete I)
  436. * R.x-y.v I.i.u | i not in x-y leave alone, nonoverlapping
  437. *
  438. * I.i.u = insert u before op @ rwIndex i
  439. * R.x-y.u = replace x-y indexed tokens with u
  440. *
  441. * First we need to examine replaces. For any replace op:
  442. *
  443. * 1. wipe out any insertions before op within that range.
  444. * 2. Drop any replace op before that is contained completely within
  445. * that range.
  446. * 3. Throw exception upon boundary overlap with any previous replace.
  447. *
  448. * Then we can deal with inserts:
  449. *
  450. * 1. for any inserts to same rwIndex, combine even if not adjacent.
  451. * 2. for any prior replace with same left boundary, combine this
  452. * insert with replace and delete this replace.
  453. * 3. throw exception if rwIndex in same range as previous replace
  454. *
  455. * Don't actually delete; make op null in list. Easier to walk list.
  456. * Later we can throw as we add to rwIndex -> op map.
  457. *
  458. * Note that I.2 R.2-2 will wipe out I.2 even though, technically, the
  459. * inserted stuff would be before the replace range. But, if you
  460. * add tokens in front of a method body '{' and then delete the method
  461. * body, I think the stuff before the '{' you added should disappear too.
  462. *
  463. * Return a map from token rwIndex to operation.
  464. */
  465. - (ANTLRHashMap *)reduceToSingleOperationPerIndex:(ANTLRHashMap *)rewrites
  466. {
  467. //System.out.println("rewrites="+rewrites);
  468. if (debug > 1) NSLog(@"rewrites=%@\n", [rewrites getName:DEFAULT_PROGRAM_NAME]);
  469. // WALK REPLACES
  470. for (int i = 0; i < [rewrites count]; i++) {
  471. ANTLRRewriteOperation *op = (ANTLRRewriteOperation *)[rewrites objectAtIndex:i];
  472. if ( op==nil )
  473. continue;
  474. if ( !([[op class] isKindOfClass:[ANTLRReplaceOp class]]) )
  475. continue;
  476. ANTLRReplaceOp *rop = (ANTLRReplaceOp *)[rewrites objectAtIndex:i];
  477. // Wipe prior inserts within range
  478. //List inserts = getKindOfOps(rewrites, ANTLRInsertBeforeOp.class, i);
  479. ANTLRHashMap *inserts = [self getKindOfOps:rewrites KindOfClass:[ANTLRInsertBeforeOp class] Index:i];
  480. for (int j = 0; j < [inserts size]; j++) {
  481. ANTLRInsertBeforeOp *iop = (ANTLRInsertBeforeOp *)[inserts objectAtIndex:j];
  482. if ( iop.rwIndex >= rop.rwIndex && iop.rwIndex <= rop.lastIndex ) {
  483. // delete insert as it's a no-op.
  484. [rewrites insertObject:nil atIndex:iop.instructionIndex];
  485. }
  486. }
  487. // Drop any prior replaces contained within
  488. ANTLRHashMap *prevReplaces = [self getKindOfOps:rewrites KindOfClass:[ANTLRReplaceOp class] Index:i];
  489. for (int j = 0; j < [prevReplaces count]; j++) {
  490. ANTLRReplaceOp *prevRop = (ANTLRReplaceOp *) [prevReplaces objectAtIndex:j];
  491. if ( prevRop.rwIndex>=rop.rwIndex && prevRop.lastIndex <= rop.lastIndex ) {
  492. // delete replace as it's a no-op.
  493. [rewrites setObject:nil atIndex:prevRop.instructionIndex];
  494. continue;
  495. }
  496. // throw exception unless disjoint or identical
  497. BOOL disjoint = prevRop.lastIndex<rop.rwIndex || prevRop.rwIndex > rop.lastIndex;
  498. BOOL same = prevRop.rwIndex==rop.rwIndex && prevRop.lastIndex==rop.lastIndex;
  499. if ( !disjoint && !same ) {
  500. @throw [ANTLRIllegalArgumentException newException:
  501. [NSString stringWithFormat:@"replace op boundaries of %@, overlap with previous %@\n", rop, prevRop]];
  502. }
  503. }
  504. }
  505. // WALK INSERTS
  506. for (int i = 0; i < [rewrites count]; i++) {
  507. ANTLRRewriteOperation *op = (ANTLRRewriteOperation *)[rewrites objectAtIndex:i];
  508. if ( op == nil )
  509. continue;
  510. if ( !([[op class] isKindOfClass:[ANTLRInsertBeforeOp class]]) )
  511. continue;
  512. ANTLRInsertBeforeOp *iop = (ANTLRInsertBeforeOp *)[rewrites objectAtIndex:i];
  513. // combine current insert with prior if any at same rwIndex
  514. ANTLRHashMap *prevInserts = (ANTLRHashMap *)[self getKindOfOps:rewrites KindOfClass:[ANTLRInsertBeforeOp class] Index:i];
  515. for (int j = 0; j < [prevInserts count]; j++) {
  516. ANTLRInsertBeforeOp *prevIop = (ANTLRInsertBeforeOp *) [prevInserts objectAtIndex:j];
  517. if ( prevIop.rwIndex == iop.rwIndex ) { // combine objects
  518. // convert to strings...we're in process of toString'ing
  519. // whole token buffer so no lazy eval issue with any templates
  520. iop.text = [self catOpText:iop.text PrevText:prevIop.text];
  521. // delete redundant prior insert
  522. [rewrites setObject:nil atIndex:prevIop.instructionIndex];
  523. }
  524. }
  525. // look for replaces where iop.rwIndex is in range; error
  526. ANTLRHashMap *prevReplaces = (ANTLRHashMap *)[self getKindOfOps:rewrites KindOfClass:[ANTLRReplaceOp class] Index:i];
  527. for (int j = 0; j < [prevReplaces count]; j++) {
  528. ANTLRReplaceOp *rop = (ANTLRReplaceOp *) [prevReplaces objectAtIndex:j];
  529. if ( iop.rwIndex == rop.rwIndex ) {
  530. rop.text = [self catOpText:iop.text PrevText:rop.text];
  531. [rewrites setObject:nil atIndex:i]; // delete current insert
  532. continue;
  533. }
  534. if ( iop.rwIndex >= rop.rwIndex && iop.rwIndex <= rop.lastIndex ) {
  535. @throw [ANTLRIllegalArgumentException newException:[NSString stringWithFormat:@"insert op %d within boundaries of previous %d", iop, rop]];
  536. }
  537. }
  538. }
  539. // System.out.println("rewrites after="+rewrites);
  540. ANTLRHashMap *m = [ANTLRHashMap newANTLRHashMapWithLen:15];
  541. for (int i = 0; i < [rewrites count]; i++) {
  542. ANTLRRewriteOperation *op = (ANTLRRewriteOperation *)[rewrites objectAtIndex:i];
  543. if ( op == nil )
  544. continue; // ignore deleted ops
  545. if ( [m objectAtIndex:op.rwIndex] != nil ) {
  546. @throw [ANTLRRuntimeException newException:@"should only be one op per rwIndex\n"];
  547. }
  548. //[m put(new Integer(op.rwIndex), op);
  549. [m setObject:op atIndex:op.rwIndex];
  550. }
  551. //System.out.println("rwIndex to op: "+m);
  552. if (debug > 1) NSLog(@"rwIndex to op %d\n", (NSInteger)m);
  553. return m;
  554. }
  555. - (NSString *)catOpText:(id)a PrevText:(id)b
  556. {
  557. NSString *x = @"";
  558. NSString *y = @"";
  559. if ( a != nil )
  560. x = [a toString];
  561. if ( b != nil )
  562. y = [b toString];
  563. return [NSString stringWithFormat:@"%@%@",x, y];
  564. }
  565. - (ANTLRHashMap *)getKindOfOps:(ANTLRHashMap *)rewrites KindOfClass:(Class)kind
  566. {
  567. return [self getKindOfOps:rewrites KindOfClass:kind Index:[rewrites count]];
  568. }
  569. /** Get all operations before an rwIndex of a particular kind */
  570. - (ANTLRHashMap *)getKindOfOps:(ANTLRHashMap *)rewrites KindOfClass:(Class)kind Index:(NSInteger)before
  571. {
  572. ANTLRHashMap *ops = [ANTLRHashMap newANTLRHashMapWithLen:15];
  573. for (int i = 0; i < before && i < [rewrites count]; i++) {
  574. ANTLRRewriteOperation *op = (ANTLRRewriteOperation *)[rewrites objectAtIndex:i];
  575. if ( op == nil )
  576. continue; // ignore deleted
  577. if ( [op isKindOfClass:(Class)kind] )
  578. [ops addObject:op];
  579. }
  580. return ops;
  581. }
  582. - (NSMutableString *)toDebugString
  583. {
  584. return [self toDebugStringFromStart:MIN_TOKEN_INDEX ToEnd:[tokens count]-1];
  585. }
  586. - (NSMutableString *)toDebugStringFromStart:(NSInteger)start ToEnd:(NSInteger)end
  587. {
  588. NSMutableString *buf = [NSMutableString stringWithCapacity:100];
  589. for (int i = start; i >= MIN_TOKEN_INDEX && i <= end && i < [tokens count]; i++) {
  590. [buf appendString:[[tokens objectAtIndex:i] text]];
  591. }
  592. return [NSString stringWithString:buf];
  593. }
  594. @end