1 // 2 // ANTLRLookaheadStream.m 3 // ANTLR 4 // 5 // Created by Ian Michell on 26/04/2010. 6 // [The "BSD licence"] 7 // Copyright (c) 2010 Ian Michell 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 32 #import "ANTLRLookaheadStream.h" 33 #import "ANTLRError.h" 34 #import "ANTLRRecognitionException.h" 35 #import "ANTLRCommonToken.h" 36 #import "ANTLRRuntimeException.h" 37 38 @implementation ANTLRLookaheadStream 39 40 @synthesize eof; 41 @synthesize index; 42 @synthesize eofElementIndex; 43 @synthesize lastMarker; 44 @synthesize markDepth; 45 @synthesize prevElement; 46 47 -(id) init 48 { 49 self = [super init]; 50 if ( self != nil ) { 51 eof = [[ANTLRCommonToken eofToken] retain]; 52 eofElementIndex = UNITIALIZED_EOF_ELEMENT_INDEX; 53 markDepth = 0; 54 index = 0; 55 } 56 return self; 57 } 58 59 -(id) initWithEOF:(id)obj 60 { 61 if ((self = [super init]) != nil) { 62 self.eof = obj; 63 if ( self.eof ) [self.eof retain]; 64 } 65 return self; 66 } 67 68 - (void) reset 69 { 70 [super reset]; 71 index = 0; 72 p = 0; 73 prevElement = nil; 74 eofElementIndex = UNITIALIZED_EOF_ELEMENT_INDEX; 75 } 76 77 -(id) nextElement 78 { 79 // [self doesNotRecognizeSelector:_cmd]; 80 return nil; 81 } 82 83 - (id) remove 84 { 85 id obj = [self objectAtIndex:0]; 86 p++; 87 // have we hit end of buffer and not backtracking? 88 if ( p == [data count] && markDepth==0 ) { 89 // if so, it's an opportunity to start filling at index 0 again 90 [self clear]; // size goes to 0, but retains memory 91 } 92 [obj release]; 93 return obj; 94 } 95 96 -(void) consume 97 { 98 [self sync:1]; 99 prevElement = [self remove]; 100 index++; 101 } 102 103 -(void) sync:(NSInteger) need 104 { 105 NSInteger n = (p + need - 1) - [data count] + 1; 106 if ( n > 0 ) { 107 [self fill:n]; 108 } 109 } 110 111 -(void) fill:(NSInteger) n 112 { 113 id obj; 114 for (NSInteger i = 1; i <= n; i++) { 115 obj = [self nextElement]; 116 if ( obj == eof ) { 117 [data addObject:self.eof]; 118 eofElementIndex = [data count] - 1; 119 } 120 else { 121 [data addObject:obj]; 122 } 123 } 124 } 125 126 -(NSUInteger) count 127 { 128 @throw [NSException exceptionWithName:@"ANTLRUnsupportedOperationException" reason:@"Streams have no defined size" userInfo:nil]; 129 } 130 131 -(id) LT:(NSInteger) k 132 { 133 if (k == 0) { 134 return nil; 135 } 136 if (k < 0) { 137 return [self LB:-k]; 138 } 139 if ((p + k - 1) >= eofElementIndex) { 140 return self.eof; 141 } 142 [self sync:k]; 143 return [self objectAtIndex:(k - 1)]; 144 } 145 146 -(id) LB:(NSInteger) k 147 { 148 if (k == 1) { 149 return prevElement; 150 } 151 @throw [ANTLRNoSuchElementException newException:@"can't look backwards more than one token in this stream"]; 152 } 153 154 -(id) getCurrentSymbol 155 { 156 return [self LT:1]; 157 } 158 159 -(NSInteger) mark 160 { 161 markDepth++; 162 lastMarker = p; 163 return lastMarker; 164 } 165 166 -(void) release:(NSInteger) marker 167 { 168 // no resources to release 169 } 170 171 -(void) rewind:(NSInteger) marker 172 { 173 markDepth--; 174 [self seek:marker]; 175 // if (marker == 0) [self reset]; 176 } 177 178 -(void) rewind 179 { 180 [self seek:lastMarker]; 181 // if (lastMarker == 0) [self reset]; 182 } 183 184 -(void) seek:(NSInteger) anIndex 185 { 186 p = anIndex; 187 } 188 189 - (id) getEof 190 { 191 return eof; 192 } 193 194 - (void) setEof:(id) anID 195 { 196 eof = anID; 197 } 198 199 - (NSInteger) getEofElementIndex 200 { 201 return eofElementIndex; 202 } 203 204 - (void) setEofElementIndex:(NSInteger) anInt 205 { 206 eofElementIndex = anInt; 207 } 208 209 - (NSInteger) getLastMarker 210 { 211 return lastMarker; 212 } 213 214 - (void) setLastMarker:(NSInteger) anInt 215 { 216 lastMarker = anInt; 217 } 218 219 - (NSInteger) getMarkDepthlastMarker 220 { 221 return markDepth; 222 } 223 224 - (void) setMarkDepth:(NSInteger) anInt 225 { 226 markDepth = anInt; 227 } 228 229 @end 230