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