1*16467b97STreehugger Robot// 2*16467b97STreehugger Robot// LookaheadStream.m 3*16467b97STreehugger Robot// ANTLR 4*16467b97STreehugger Robot// 5*16467b97STreehugger Robot// Created by Ian Michell on 26/04/2010. 6*16467b97STreehugger Robot// [The "BSD licence"] 7*16467b97STreehugger Robot// Copyright (c) 2010 Ian Michell 2010 Alan Condit 8*16467b97STreehugger Robot// All rights reserved. 9*16467b97STreehugger Robot// 10*16467b97STreehugger Robot// Redistribution and use in source and binary forms, with or without 11*16467b97STreehugger Robot// modification, are permitted provided that the following conditions 12*16467b97STreehugger Robot// are met: 13*16467b97STreehugger Robot// 1. Redistributions of source code must retain the above copyright 14*16467b97STreehugger Robot// notice, this list of conditions and the following disclaimer. 15*16467b97STreehugger Robot// 2. Redistributions in binary form must reproduce the above copyright 16*16467b97STreehugger Robot// notice, this list of conditions and the following disclaimer in the 17*16467b97STreehugger Robot// documentation and/or other materials provided with the distribution. 18*16467b97STreehugger Robot// 3. The name of the author may not be used to endorse or promote products 19*16467b97STreehugger Robot// derived from this software without specific prior written permission. 20*16467b97STreehugger Robot// 21*16467b97STreehugger Robot// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22*16467b97STreehugger Robot// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23*16467b97STreehugger Robot// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24*16467b97STreehugger Robot// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25*16467b97STreehugger Robot// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26*16467b97STreehugger Robot// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27*16467b97STreehugger Robot// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28*16467b97STreehugger Robot// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29*16467b97STreehugger Robot// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30*16467b97STreehugger Robot// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31*16467b97STreehugger Robot 32*16467b97STreehugger Robot#import "LookaheadStream.h" 33*16467b97STreehugger Robot#import "ANTLRError.h" 34*16467b97STreehugger Robot#import "RecognitionException.h" 35*16467b97STreehugger Robot#import "CommonToken.h" 36*16467b97STreehugger Robot#import "RuntimeException.h" 37*16467b97STreehugger Robot 38*16467b97STreehugger Robot@implementation LookaheadStream 39*16467b97STreehugger Robot 40*16467b97STreehugger Robot@synthesize eof; 41*16467b97STreehugger Robot@synthesize index; 42*16467b97STreehugger Robot@synthesize eofElementIndex; 43*16467b97STreehugger Robot@synthesize lastMarker; 44*16467b97STreehugger Robot@synthesize markDepth; 45*16467b97STreehugger Robot@synthesize prevElement; 46*16467b97STreehugger Robot 47*16467b97STreehugger Robot-(id) init 48*16467b97STreehugger Robot{ 49*16467b97STreehugger Robot self = [super init]; 50*16467b97STreehugger Robot if ( self != nil ) { 51*16467b97STreehugger Robot eof = [[CommonToken eofToken] retain]; 52*16467b97STreehugger Robot eofElementIndex = UNITIALIZED_EOF_ELEMENT_INDEX; 53*16467b97STreehugger Robot markDepth = 0; 54*16467b97STreehugger Robot index = 0; 55*16467b97STreehugger Robot } 56*16467b97STreehugger Robot return self; 57*16467b97STreehugger Robot} 58*16467b97STreehugger Robot 59*16467b97STreehugger Robot-(id) initWithEOF:(id)obj 60*16467b97STreehugger Robot{ 61*16467b97STreehugger Robot if ((self = [super init]) != nil) { 62*16467b97STreehugger Robot self.eof = obj; 63*16467b97STreehugger Robot if ( self.eof ) [self.eof retain]; 64*16467b97STreehugger Robot } 65*16467b97STreehugger Robot return self; 66*16467b97STreehugger Robot} 67*16467b97STreehugger Robot 68*16467b97STreehugger Robot- (void) reset 69*16467b97STreehugger Robot{ 70*16467b97STreehugger Robot [super reset]; 71*16467b97STreehugger Robot index = 0; 72*16467b97STreehugger Robot p = 0; 73*16467b97STreehugger Robot prevElement = nil; 74*16467b97STreehugger Robot eofElementIndex = UNITIALIZED_EOF_ELEMENT_INDEX; 75*16467b97STreehugger Robot} 76*16467b97STreehugger Robot 77*16467b97STreehugger Robot-(id) nextElement 78*16467b97STreehugger Robot{ 79*16467b97STreehugger Robot// [self doesNotRecognizeSelector:_cmd]; 80*16467b97STreehugger Robot return nil; 81*16467b97STreehugger Robot} 82*16467b97STreehugger Robot 83*16467b97STreehugger Robot- (id) remove 84*16467b97STreehugger Robot{ 85*16467b97STreehugger Robot id obj = [self objectAtIndex:0]; 86*16467b97STreehugger Robot p++; 87*16467b97STreehugger Robot // have we hit end of buffer and not backtracking? 88*16467b97STreehugger Robot if ( p == [data count] && markDepth==0 ) { 89*16467b97STreehugger Robot // if so, it's an opportunity to start filling at index 0 again 90*16467b97STreehugger Robot [self clear]; // size goes to 0, but retains memory 91*16467b97STreehugger Robot } 92*16467b97STreehugger Robot [obj release]; 93*16467b97STreehugger Robot return obj; 94*16467b97STreehugger Robot} 95*16467b97STreehugger Robot 96*16467b97STreehugger Robot-(void) consume 97*16467b97STreehugger Robot{ 98*16467b97STreehugger Robot [self sync:1]; 99*16467b97STreehugger Robot prevElement = [self remove]; 100*16467b97STreehugger Robot index++; 101*16467b97STreehugger Robot} 102*16467b97STreehugger Robot 103*16467b97STreehugger Robot-(void) sync:(NSInteger) need 104*16467b97STreehugger Robot{ 105*16467b97STreehugger Robot NSInteger n = (p + need - 1) - [data count] + 1; 106*16467b97STreehugger Robot if ( n > 0 ) { 107*16467b97STreehugger Robot [self fill:n]; 108*16467b97STreehugger Robot } 109*16467b97STreehugger Robot} 110*16467b97STreehugger Robot 111*16467b97STreehugger Robot-(void) fill:(NSInteger) n 112*16467b97STreehugger Robot{ 113*16467b97STreehugger Robot id obj; 114*16467b97STreehugger Robot for (NSInteger i = 1; i <= n; i++) { 115*16467b97STreehugger Robot obj = [self nextElement]; 116*16467b97STreehugger Robot if ( obj == eof ) { 117*16467b97STreehugger Robot [data addObject:self.eof]; 118*16467b97STreehugger Robot eofElementIndex = [data count] - 1; 119*16467b97STreehugger Robot } 120*16467b97STreehugger Robot else { 121*16467b97STreehugger Robot [data addObject:obj]; 122*16467b97STreehugger Robot } 123*16467b97STreehugger Robot } 124*16467b97STreehugger Robot} 125*16467b97STreehugger Robot 126*16467b97STreehugger Robot-(NSUInteger) count 127*16467b97STreehugger Robot{ 128*16467b97STreehugger Robot @throw [NSException exceptionWithName:@"UnsupportedOperationException" reason:@"Streams have no defined size" userInfo:nil]; 129*16467b97STreehugger Robot} 130*16467b97STreehugger Robot 131*16467b97STreehugger Robot-(id) LT:(NSInteger) k 132*16467b97STreehugger Robot{ 133*16467b97STreehugger Robot if (k == 0) { 134*16467b97STreehugger Robot return nil; 135*16467b97STreehugger Robot } 136*16467b97STreehugger Robot if (k < 0) { 137*16467b97STreehugger Robot return [self LB:-k]; 138*16467b97STreehugger Robot } 139*16467b97STreehugger Robot if ((p + k - 1) >= eofElementIndex) { 140*16467b97STreehugger Robot return self.eof; 141*16467b97STreehugger Robot } 142*16467b97STreehugger Robot [self sync:k]; 143*16467b97STreehugger Robot return [self objectAtIndex:(k - 1)]; 144*16467b97STreehugger Robot} 145*16467b97STreehugger Robot 146*16467b97STreehugger Robot-(id) LB:(NSInteger) k 147*16467b97STreehugger Robot{ 148*16467b97STreehugger Robot if (k == 1) { 149*16467b97STreehugger Robot return prevElement; 150*16467b97STreehugger Robot } 151*16467b97STreehugger Robot @throw [NoSuchElementException newException:@"can't look backwards more than one token in this stream"]; 152*16467b97STreehugger Robot} 153*16467b97STreehugger Robot 154*16467b97STreehugger Robot-(id) getCurrentSymbol 155*16467b97STreehugger Robot{ 156*16467b97STreehugger Robot return [self LT:1]; 157*16467b97STreehugger Robot} 158*16467b97STreehugger Robot 159*16467b97STreehugger Robot-(NSInteger) mark 160*16467b97STreehugger Robot{ 161*16467b97STreehugger Robot markDepth++; 162*16467b97STreehugger Robot lastMarker = p; 163*16467b97STreehugger Robot return lastMarker; 164*16467b97STreehugger Robot} 165*16467b97STreehugger Robot 166*16467b97STreehugger Robot-(void) release:(NSInteger) marker 167*16467b97STreehugger Robot{ 168*16467b97STreehugger Robot // no resources to release 169*16467b97STreehugger Robot} 170*16467b97STreehugger Robot 171*16467b97STreehugger Robot-(void) rewind:(NSInteger) marker 172*16467b97STreehugger Robot{ 173*16467b97STreehugger Robot markDepth--; 174*16467b97STreehugger Robot [self seek:marker]; 175*16467b97STreehugger Robot// if (marker == 0) [self reset]; 176*16467b97STreehugger Robot} 177*16467b97STreehugger Robot 178*16467b97STreehugger Robot-(void) rewind 179*16467b97STreehugger Robot{ 180*16467b97STreehugger Robot [self seek:lastMarker]; 181*16467b97STreehugger Robot// if (lastMarker == 0) [self reset]; 182*16467b97STreehugger Robot} 183*16467b97STreehugger Robot 184*16467b97STreehugger Robot-(void) seek:(NSInteger) anIndex 185*16467b97STreehugger Robot{ 186*16467b97STreehugger Robot p = anIndex; 187*16467b97STreehugger Robot} 188*16467b97STreehugger Robot 189*16467b97STreehugger Robot- (id) getEof 190*16467b97STreehugger Robot{ 191*16467b97STreehugger Robot return eof; 192*16467b97STreehugger Robot} 193*16467b97STreehugger Robot 194*16467b97STreehugger Robot- (void) setEof:(id) anID 195*16467b97STreehugger Robot{ 196*16467b97STreehugger Robot eof = anID; 197*16467b97STreehugger Robot} 198*16467b97STreehugger Robot 199*16467b97STreehugger Robot- (NSInteger) getEofElementIndex 200*16467b97STreehugger Robot{ 201*16467b97STreehugger Robot return eofElementIndex; 202*16467b97STreehugger Robot} 203*16467b97STreehugger Robot 204*16467b97STreehugger Robot- (void) setEofElementIndex:(NSInteger) anInt 205*16467b97STreehugger Robot{ 206*16467b97STreehugger Robot eofElementIndex = anInt; 207*16467b97STreehugger Robot} 208*16467b97STreehugger Robot 209*16467b97STreehugger Robot- (NSInteger) getLastMarker 210*16467b97STreehugger Robot{ 211*16467b97STreehugger Robot return lastMarker; 212*16467b97STreehugger Robot} 213*16467b97STreehugger Robot 214*16467b97STreehugger Robot- (void) setLastMarker:(NSInteger) anInt 215*16467b97STreehugger Robot{ 216*16467b97STreehugger Robot lastMarker = anInt; 217*16467b97STreehugger Robot} 218*16467b97STreehugger Robot 219*16467b97STreehugger Robot- (NSInteger) getMarkDepthlastMarker 220*16467b97STreehugger Robot{ 221*16467b97STreehugger Robot return markDepth; 222*16467b97STreehugger Robot} 223*16467b97STreehugger Robot 224*16467b97STreehugger Robot- (void) setMarkDepth:(NSInteger) anInt 225*16467b97STreehugger Robot{ 226*16467b97STreehugger Robot markDepth = anInt; 227*16467b97STreehugger Robot} 228*16467b97STreehugger Robot 229*16467b97STreehugger Robot@end 230