Home | History | Annotate | Download | only in Framework
      1 // [The "BSD licence"]
      2 // Copyright (c) 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 "ANTLRBufferedTokenStream.h"
     28 #import "ANTLRTokenSource.h"
     29 #import "ANTLRCommonTreeAdaptor.h"
     30 #import "ANTLRRuntimeException.h"
     31 
     32 extern NSInteger debug;
     33 
     34 @implementation ANTLRBufferedTokenStream
     35 
     36 @synthesize tokenSource;
     37 @synthesize tokens;
     38 @synthesize lastMarker;
     39 @synthesize index;
     40 @synthesize range;
     41 
     42 + (ANTLRBufferedTokenStream *) newANTLRBufferedTokenStream
     43 {
     44     return [[ANTLRBufferedTokenStream alloc] init];
     45 }
     46 
     47 + (ANTLRBufferedTokenStream *) newANTLRBufferedTokenStreamWith:(id<ANTLRTokenSource>)aSource
     48 {
     49     return [[ANTLRBufferedTokenStream alloc] initWithTokenSource:aSource];
     50 }
     51 
     52 - (ANTLRBufferedTokenStream *) init
     53 {
     54 	if ((self = [super init]) != nil)
     55 	{
     56         tokenSource = nil;
     57         tokens = [[AMutableArray arrayWithCapacity:1000] retain];
     58         index = -1;
     59         range = -1;
     60 	}
     61 	return self;
     62 }
     63 
     64 -(id) initWithTokenSource:(id<ANTLRTokenSource>)aSource
     65 {
     66 	if ((self = [super init]) != nil)
     67 	{
     68         tokenSource = [aSource retain];
     69         tokens = [[AMutableArray arrayWithCapacity:1000] retain];
     70         index = -1;
     71         range = -1;
     72 	}
     73 	return self;
     74 }
     75 
     76 - (id) copyWithZone:(NSZone *)aZone
     77 {
     78     ANTLRBufferedTokenStream *copy;
     79     
     80     copy = [[[self class] allocWithZone:aZone] init];
     81     copy.tokenSource = self.tokenSource;
     82     if ( self.tokens )
     83         copy.tokens = [tokens copyWithZone:aZone];
     84     copy.lastMarker = self.lastMarker;
     85     copy.index = self.index;
     86     copy.range = self.range;
     87     return copy;
     88 }
     89 
     90 - (void)dealloc
     91 {
     92 #ifdef DEBUG_DEALLOC
     93     NSLog( @"called dealloc in ANTLRBufferedTokenStream" );
     94 #endif
     95     if ( tokens ) [tokens release];
     96     if ( tokenSource ) [tokenSource release];
     97 	[super dealloc];
     98 }
     99 
    100 - (NSUInteger)line
    101 {
    102     return ((ANTLRCommonToken *)[tokens objectAtIndex:index]).line;
    103 }
    104 
    105 - (NSUInteger)charPositionInLine
    106 {
    107     return ((ANTLRCommonToken *)[tokens objectAtIndex:index]).charPositionInLine;
    108 }
    109 
    110 - (id<ANTLRTokenSource>) getTokenSource
    111 {
    112     return tokenSource;
    113 }
    114 
    115 - (NSInteger) getRange
    116 {
    117     return range;
    118 }
    119 
    120 - (void) setRange:(NSInteger)anInt
    121 {
    122     range = anInt;
    123 }
    124 
    125 - (NSInteger) mark
    126 {
    127     if ( index == -1 ) {
    128         [self setup];
    129 //        [self fill];
    130     }
    131     lastMarker = self.index;
    132     return lastMarker;
    133 }
    134 
    135 - (void) release:(NSInteger) marker
    136 {
    137     // no resources to release
    138 }
    139 
    140 - (void) rewind:(NSInteger) marker
    141 {
    142     [self seek:marker];
    143 }
    144 
    145 - (void) rewind
    146 {
    147     [self seek:lastMarker];
    148 }
    149 
    150 - (void) reset
    151 {
    152     index = 0;
    153     lastMarker = 0;
    154 }
    155 
    156 - (void) seek:(NSInteger) anIndex
    157 {
    158     index = anIndex;
    159 }
    160 
    161 - (NSInteger) size
    162 {
    163     return [tokens count];
    164 }
    165 
    166 /** Move the input pointer to the next incoming token.  The stream
    167  *  must become active with LT(1) available.  consume() simply
    168  *  moves the input pointer so that LT(1) points at the next
    169  *  input symbol. Consume at least one token.
    170  *
    171  *  Walk past any token not on the channel the parser is listening to.
    172  */
    173 - (void) consume
    174 {
    175     if ( index == -1 ) {
    176         [self setup];
    177 //        [self fill];
    178     }
    179     index++;
    180     [self sync:index];
    181 }
    182 
    183 /** Make sure index i in tokens has a token. */
    184 - (void) sync:(NSInteger) i
    185 {
    186     // how many more elements we need?
    187     NSInteger n = (i - [tokens count]) + 1;
    188     if (debug > 1) NSLog(@"[self sync:%d] needs %d\n", i, n);
    189     if ( n > 0 )
    190         [self fetch:n];
    191 }
    192 
    193 /** add n elements to buffer */
    194 - (void) fetch:(NSInteger)n
    195 {
    196     for (NSInteger i=1; i <= n; i++) {
    197         id<ANTLRToken> t = [tokenSource nextToken];
    198         [t setTokenIndex:[tokens count]];
    199         if (debug > 1) NSLog(@"adding %@ at index %d\n", [t text], [tokens count]);
    200         [tokens addObject:t];
    201         if ( t.type == ANTLRTokenTypeEOF )
    202             break;
    203     }
    204 }
    205 
    206 - (id<ANTLRToken>) getToken:(NSInteger) i
    207 {
    208     if ( i < 0 || i >= [tokens count] ) {
    209         @throw [ANTLRNoSuchElementException newException:[NSString stringWithFormat:@"token index %d out of range 0..%d", i, [tokens count]-1]];
    210     }
    211     return [tokens objectAtIndex:i];
    212 }
    213 
    214 /** Get all tokens from start..stop inclusively */
    215 - (AMutableArray *)getFrom:(NSInteger)startIndex To:(NSInteger)stopIndex
    216 {
    217     if ( startIndex < 0 || stopIndex < 0 )
    218         return nil;
    219     if ( index == -1 ) {
    220         [self setup];
    221 //        [self fill];
    222     }
    223     AMutableArray *subset = [AMutableArray arrayWithCapacity:5];
    224     if ( stopIndex >= [tokens count] )
    225         stopIndex = [tokens count]-1;
    226     for (NSInteger i = startIndex; i <= stopIndex; i++) {
    227         id<ANTLRToken>t = [tokens objectAtIndex:i];
    228         if ( t.type == ANTLRTokenTypeEOF )
    229             break;
    230         [subset addObject:t];
    231     }
    232     return subset;
    233 }
    234 
    235 - (NSInteger) LA:(NSInteger)i
    236 {
    237     return [[self LT:i] type];
    238 }
    239 
    240 - (id<ANTLRToken>) LB:(NSInteger)k
    241 {
    242     if ( (index - k) < 0 )
    243         return nil;
    244     return [tokens objectAtIndex:(index-k)];
    245 }
    246 
    247 - (id<ANTLRToken>) LT:(NSInteger)k
    248 {
    249     if ( index == -1 ) {
    250         [self setup];
    251 //        [self fill];
    252     }
    253     if ( k == 0 )
    254         return nil;
    255     if ( k < 0 )
    256         return [self LB:-k];
    257     
    258     NSInteger i = index + k - 1;
    259     [self sync:i];
    260     if ( i >= [tokens count] ) { // return EOF token
    261                                 // EOF must be last token
    262         return [tokens objectAtIndex:([tokens count]-1)];
    263     }
    264     if ( i > range )
    265         range = i; 		
    266     return [tokens objectAtIndex:i];
    267 }
    268 
    269 - (void) setup
    270 {
    271     [self sync:0];
    272     index = 0;
    273 }
    274 
    275 /** Reset this token stream by setting its token source. */
    276 - (void) setTokenSource:(id<ANTLRTokenSource>) aTokenSource
    277 {
    278     tokenSource = aTokenSource;
    279     if ( [tokens count] )
    280         [tokens removeAllObjects];
    281     index = -1;
    282 }
    283 
    284 - (AMutableArray *)getTokens
    285 {
    286     return tokens;
    287 }
    288 
    289 - (AMutableArray *)getTokensFrom:(NSInteger) startIndex To:(NSInteger) stopIndex
    290 {
    291     return [self getTokensFrom:startIndex To:stopIndex With:(ANTLRBitSet *)nil];
    292 }
    293 
    294 /** Given a start and stop index, return a List of all tokens in
    295  *  the token type BitSet.  Return null if no tokens were found.  This
    296  *  method looks at both on and off channel tokens.
    297  */
    298 - (AMutableArray *)getTokensFrom:(NSInteger)startIndex To:(NSInteger)stopIndex With:(ANTLRBitSet *)types
    299 {
    300     if ( index == -1 ) {
    301         [self setup];
    302 //        [self fill];
    303     }
    304     if ( stopIndex >= [tokens count] )
    305         stopIndex = [tokens count]-1;
    306     if ( startIndex < 0 )
    307         startIndex = 0;
    308     if ( startIndex > stopIndex )
    309         return nil;
    310     
    311     // list = tokens[start:stop]:{Token t, t.getType() in types}
    312     AMutableArray *filteredTokens = [AMutableArray arrayWithCapacity:5];
    313     for (NSInteger i = startIndex; i <= stopIndex; i++) {
    314         id<ANTLRToken>t = [tokens objectAtIndex:i];
    315         if ( types == nil || [types member:t.type] ) {
    316             [filteredTokens addObject:t];
    317         }
    318     }
    319     if ( [filteredTokens count] == 0 ) {
    320         filteredTokens = nil;
    321     }
    322     return filteredTokens;
    323 }
    324 
    325 - (AMutableArray *)getTokensFrom:(NSInteger)startIndex To:(NSInteger)stopIndex WithType:(NSInteger)ttype
    326 {
    327     return [self getTokensFrom:startIndex To:stopIndex With:[ANTLRBitSet of:ttype]];
    328 }
    329 
    330 - (AMutableArray *)getTokensFrom:(NSInteger)startIndex To:(NSInteger)stopIndex WithList:(AMutableArray *)types
    331 {
    332     return [self getTokensFrom:startIndex To:stopIndex With:[ANTLRBitSet newANTLRBitSetWithArray:types]];
    333 }
    334             
    335 - (NSString *)getSourceName
    336 {
    337     return [tokenSource getSourceName];
    338 }
    339 
    340 /** Grab *all* tokens from stream and return string */
    341 - (NSString *) toString
    342 {
    343     if ( index == -1 ) {
    344         [self setup];
    345     }
    346     [self fill];
    347     return [self toStringFromStart:0 ToEnd:[tokens count]-1];
    348 }
    349 
    350 - (NSString *) toStringFromStart:(NSInteger)startIdx ToEnd:(NSInteger)stopIdx
    351 {
    352     if ( startIdx < 0 || stopIdx < 0 )
    353         return nil;
    354     if ( index == -1 ) {
    355         [self setup];
    356     }
    357     if ( stopIdx >= [tokens count] )
    358         stopIdx = [tokens count]-1;
    359     NSMutableString *buf = [NSMutableString stringWithCapacity:5];
    360     for (NSInteger i = startIdx; i <= stopIdx; i++) {
    361         id<ANTLRToken>t = [tokens objectAtIndex:i];
    362         if ( t.type == ANTLRTokenTypeEOF )
    363             break;
    364         [buf appendString:[t text]];
    365     }
    366     return buf;
    367 }
    368 
    369 - (NSString *) toStringFromToken:(id<ANTLRToken>)startToken ToToken:(id<ANTLRToken>)stopToken
    370 {
    371     if ( startToken != nil && stopToken != nil ) {
    372         return [self toStringFromStart:[startToken getTokenIndex] ToEnd:[stopToken getTokenIndex]];
    373     }
    374     return nil;
    375 }
    376 
    377 /** Get all tokens from lexer until EOF */
    378 - (void) fill
    379 {
    380     if ( index == -1 ) [self setup];
    381     if ( [((ANTLRCommonToken *)[tokens objectAtIndex:index]) type] == ANTLRTokenTypeEOF )
    382         return;
    383     
    384     NSInteger i = index+1;
    385     [self sync:i];
    386     while ( [((ANTLRCommonToken *)[tokens objectAtIndex:i]) type] != ANTLRTokenTypeEOF ) {
    387         i++;
    388         [self sync:i];
    389     }
    390 }
    391 
    392 @end
    393