1 // [The "BSD licence"] 2 // Copyright (c) 2006-2007 Kay Roepke 2010 Alan Condit 3 // All rights reserved. 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions 7 // are met: 8 // 1. Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // 2. Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // 3. The name of the author may not be used to endorse or promote products 14 // derived from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 27 #import "ANTLRCommonTreeNodeStream.h" 28 #import "ANTLRTokenStream.h" 29 #import "ANTLRIntStream.h" 30 #import "ANTLRCharStream.h" 31 #import "AMutableArray.h" 32 #import "ANTLRCommonTreeAdaptor.h" 33 34 #ifndef DEBUG_DEALLOC 35 #define DEBUG_DEALLOC 36 #endif 37 38 @implementation ANTLRCommonTreeNodeStream 39 40 @synthesize root; 41 @synthesize tokens; 42 @synthesize adaptor; 43 @synthesize level; 44 45 + (ANTLRCommonTreeNodeStream *) newANTLRCommonTreeNodeStream:(ANTLRCommonTree *)theTree 46 { 47 return [[ANTLRCommonTreeNodeStream alloc] initWithTree:theTree]; 48 } 49 50 + (ANTLRCommonTreeNodeStream *) newANTLRCommonTreeNodeStream:(id<ANTLRTreeAdaptor>)anAdaptor Tree:(ANTLRCommonTree *)theTree 51 { 52 return [[ANTLRCommonTreeNodeStream alloc] initWithTreeAdaptor:anAdaptor Tree:theTree]; 53 } 54 55 - (id) initWithTree:(ANTLRCommonTree *)theTree 56 { 57 if ((self = [super init]) != nil ) { 58 adaptor = [[ANTLRCommonTreeAdaptor newTreeAdaptor] retain]; 59 root = [theTree retain]; 60 navigationNodeEOF = [[adaptor createTree:ANTLRTokenTypeEOF Text:@"EOF"] retain]; // set EOF 61 it = [[ANTLRTreeIterator newANTRLTreeIteratorWithAdaptor:adaptor andTree:root] retain]; 62 calls = [[ANTLRIntArray newArrayWithLen:INITIAL_CALL_STACK_SIZE] retain]; 63 /** Tree (nil A B C) trees like flat A B C streams */ 64 hasNilRoot = NO; 65 level = 0; 66 } 67 return self; 68 } 69 70 - (id) initWithTreeAdaptor:(id<ANTLRTreeAdaptor>)anAdaptor Tree:(ANTLRCommonTree *)theTree 71 { 72 if ((self = [super init]) != nil ) { 73 adaptor = [anAdaptor retain]; 74 root = [theTree retain]; 75 navigationNodeEOF = [[adaptor createTree:ANTLRTokenTypeEOF Text:@"EOF"] retain]; // set EOF 76 // it = [root objectEnumerator]; 77 it = [[ANTLRTreeIterator newANTRLTreeIteratorWithAdaptor:adaptor andTree:root] retain]; 78 calls = [[ANTLRIntArray newArrayWithLen:INITIAL_CALL_STACK_SIZE] retain]; 79 /** Tree (nil A B C) trees like flat A B C streams */ 80 hasNilRoot = NO; 81 level = 0; 82 } 83 // eof = [self isEOF]; // make sure tree iterator returns the EOF we want 84 return self; 85 } 86 87 - (void)dealloc 88 { 89 #ifdef DEBUG_DEALLOC 90 NSLog( @"called dealloc in ANTLRCommonTreeNodeStream" ); 91 #endif 92 if ( root ) [root release]; 93 if ( tokens ) [tokens release]; 94 if ( adaptor ) [adaptor release]; 95 if ( it ) [it release]; 96 if ( calls ) [calls release]; 97 [super dealloc]; 98 } 99 100 - (void) reset 101 { 102 [super reset]; 103 [it reset]; 104 hasNilRoot = false; 105 level = 0; 106 if ( calls != nil ) 107 [calls reset]; // [calls clear]; // in Java 108 } 109 110 /** Pull elements from tree iterator. Track tree level 0..max_level. 111 * If nil rooted tree, don't give initial nil and DOWN nor final UP. 112 */ 113 - (id) nextElement 114 { 115 id t = [it nextObject]; 116 //System.out.println("pulled "+adaptor.getType(t)); 117 if ( t == [it up] ) { 118 level--; 119 if ( level==0 && hasNilRoot ) return [it nextObject]; // don't give last UP; get EOF 120 } 121 else if ( t == [it down] ) 122 level++; 123 if ( level == 0 && [adaptor isNil:t] ) { // if nil root, scarf nil, DOWN 124 hasNilRoot = true; 125 t = [it nextObject]; // t is now DOWN, so get first real node next 126 level++; 127 t = [it nextObject]; 128 } 129 return t; 130 } 131 132 - (BOOL) isEOF:(id<ANTLRBaseTree>) aTree 133 { 134 return [adaptor getType:(ANTLRCommonTree *)aTree] == ANTLRTokenTypeEOF; 135 } 136 137 - (void) setUniqueNavigationNodes:(BOOL) uniqueNavigationNodes 138 { 139 } 140 141 - (id) getTreeSource 142 { 143 return root; 144 } 145 146 - (NSString *) getSourceName 147 { 148 return [[self getTokenStream] getSourceName]; 149 } 150 151 - (id<ANTLRTokenStream>) getTokenStream 152 { 153 return tokens; 154 } 155 156 - (void) setTokenStream:(id<ANTLRTokenStream>)theTokens 157 { 158 if ( tokens != theTokens ) { 159 if ( tokens ) [tokens release]; 160 [theTokens retain]; 161 } 162 tokens = theTokens; 163 } 164 165 - (ANTLRCommonTreeAdaptor *) getTreeAdaptor 166 { 167 return adaptor; 168 } 169 170 - (void) setTreeAdaptor:(ANTLRCommonTreeAdaptor *) anAdaptor 171 { 172 if ( adaptor != anAdaptor ) { 173 if ( adaptor ) [adaptor release]; 174 [anAdaptor retain]; 175 } 176 adaptor = anAdaptor; 177 } 178 179 - (ANTLRCommonTree *)getNode:(NSInteger) i 180 { 181 @throw [ANTLRRuntimeException newException:@"Absolute node indexes are meaningless in an unbuffered stream"]; 182 return nil; 183 } 184 185 - (NSInteger) LA:(NSInteger) i 186 { 187 return [adaptor getType:[self LT:i]]; 188 } 189 190 /** Make stream jump to a new location, saving old location. 191 * Switch back with pop(). 192 */ 193 - (void) push:(NSInteger) anIndex 194 { 195 if ( calls == nil ) { 196 calls = [[ANTLRIntArray newArrayWithLen:INITIAL_CALL_STACK_SIZE] retain]; 197 } 198 [calls push:p]; // save current anIndex 199 [self seek:anIndex]; 200 } 201 202 /** Seek back to previous anIndex saved during last push() call. 203 * Return top of stack (return anIndex). 204 */ 205 - (NSInteger) pop 206 { 207 int ret = [calls pop]; 208 [self seek:ret]; 209 return ret; 210 } 211 212 // TREE REWRITE INTERFACE 213 214 - (void) replaceChildren:(id) parent From:(NSInteger)startChildIndex To:(NSInteger)stopChildIndex With:(id) aTree 215 { 216 if ( parent != nil ) { 217 [adaptor replaceChildren:parent From:startChildIndex To:stopChildIndex With:aTree]; 218 } 219 } 220 221 - (NSString *) toStringFromNode:(id<ANTLRBaseTree>)startNode ToNode:(id<ANTLRBaseTree>)stopNode 222 { 223 // we'll have to walk from start to stop in tree; we're not keeping 224 // a complete node stream buffer 225 return @"n/a"; 226 } 227 228 /** For debugging; destructive: moves tree iterator to end. */ 229 - (NSString *) toTokenTypeString 230 { 231 [self reset]; 232 NSMutableString *buf = [NSMutableString stringWithCapacity:5]; 233 id obj = [self LT:1]; 234 NSInteger type = [adaptor getType:obj]; 235 while ( type != ANTLRTokenTypeEOF ) { 236 [buf appendString:@" "]; 237 [buf appendString:[NSString stringWithFormat:@"%d", type]]; 238 [self consume]; 239 obj = [self LT:1]; 240 type = [adaptor getType:obj]; 241 } 242 return buf; 243 } 244 245 @synthesize it; 246 @synthesize calls; 247 @synthesize hasNilRoot; 248 @end 249 250