1// 2// LookaheadStream.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 "LookaheadStream.h" 33#import "ANTLRError.h" 34#import "RecognitionException.h" 35#import "CommonToken.h" 36#import "RuntimeException.h" 37 38@implementation LookaheadStream 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 = [[CommonToken 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:@"UnsupportedOperationException" 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 [NoSuchElementException 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