1// [The "BSD licence"]
2// Copyright (c) 2006-2007 Kay Roepke 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 "CommonTreeAdaptor.h"
28
29@implementation CommonTreeAdaptor
30
31+ (CommonTree *) newEmptyTree;
32{
33    return [CommonTree newTree];
34}
35
36+ (CommonTreeAdaptor *)newTreeAdaptor
37{
38    return[[CommonTreeAdaptor alloc] init];
39}
40
41- (id) init
42{
43    self = [super init];
44    if (self) {
45    }
46    return self;
47}
48
49/** Duplicate a node.  This is part of the factory;
50 *	override if you want another kind of node to be built.
51 *
52 *  I could use reflection to prevent having to override this
53 *  but reflection is slow.
54 */
55- (id) dupNode:(id<BaseTree>)t
56{
57    if ( t==nil )
58        return nil;
59    return [CommonTree newTree:t];
60}
61
62/** Tell me how to create a token for use with imaginary token nodes.
63 *  For example, there is probably no input symbol associated with imaginary
64 *  token DECL, but you need to create it as a payload or whatever for
65 *  the DECL node as in ^(DECL type ID).
66 *
67 *  This is a variant of createToken where the new token is derived from
68 *  an actual real input token.  Typically this is for converting '{'
69 *  tokens to BLOCK etc...  You'll see
70 *
71 *    r : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ;
72 *
73 *  If you care what the token payload objects' type is, you should
74 *  override this method and any other createToken variant.
75 */
76- (CommonTree *) create:(CommonToken *)aToken
77{
78    return [CommonTree newTreeWithToken:aToken];
79}
80
81/** Tell me how to create a token for use with imaginary token nodes.
82 *  For example, there is probably no input symbol associated with imaginary
83 *  token DECL, but you need to create it as a payload or whatever for
84 *  the DECL node as in ^(DECL type ID).
85 *
86 *  If you care what the token payload objects' type is, you should
87 *  override this method and any other createToken variant.
88 */
89- (CommonTree *)createTree:(NSInteger)tokenType Text:(NSString *)text
90{
91    return [CommonTree newTreeWithTokenType:tokenType Text:text];
92}
93
94- (id<Token>)createToken:(NSInteger)tokenType Text:(NSString *)text
95{
96    id<Token> fromToken = [CommonToken newToken:tokenType Text:text];
97    return fromToken;
98}
99
100- (id<Token>)createToken:(id<Token>)fromToken
101{
102    return [CommonToken newTokenWithToken:(CommonToken *)fromToken];
103}
104
105/** Track start/stop token for subtree root created for a rule.
106 *  Only works with Tree nodes.  For rules that match nothing,
107 *  seems like this will yield start=i and stop=i-1 in a nil node.
108 *  Might be useful info so I'll not force to be i..i.
109 */
110- (void) setTokenBoundaries:(id<BaseTree>)aTree From:(id<Token>)startToken To:(id<Token>)stopToken
111{
112    if ( aTree == nil )
113        return;
114    int startTokIdx = 0;
115    int stopTokIdx = 0;
116    if ( startToken != nil )
117        startTokIdx = [startToken getTokenIndex];
118    if ( stopToken != nil )
119        stopTokIdx = [stopToken getTokenIndex];
120    [(id<BaseTree>)aTree setTokenStartIndex:startTokIdx];
121    [(id<BaseTree>)aTree setTokenStopIndex:stopTokIdx];
122}
123
124- (NSInteger)getTokenStartIndex:(id<BaseTree>) t
125{
126    if ( t == nil )
127        return -1;
128    return [(id<BaseTree>)t getTokenStartIndex];
129}
130
131- (NSInteger)getTokenStopIndex:(id<BaseTree>) t
132{
133    if ( t == nil )
134        return -1;
135    return [(id<BaseTree>)t getTokenStopIndex];
136}
137
138- (NSString *)getText:(CommonTree *)t
139{
140    if ( t == nil )
141        return nil;
142    return t.token.text;
143}
144
145- (void)setText:(id<BaseTree>)t Text:(NSString *)text
146{
147    if ( t == nil )
148        return;
149}
150
151- (NSInteger)getType:(CommonTree *)t
152{
153    if ( t==nil )
154        return TokenTypeInvalid;
155    return t.token.type;
156}
157
158- (void) setType:(id<BaseTree>)t Type:(NSInteger)tokenType
159{
160    if ( t==nil )
161        return;
162}
163
164/** What is the Token associated with this node?  If
165 *  you are not using CommonTree, then you must
166 *  override this in your own adaptor.
167 */
168- (id<Token>) getToken:(CommonTree *) t
169{
170    if ( [t isKindOfClass:[CommonTree class]] ) {
171        return t.token;
172    }
173    return nil; // no idea what to do
174}
175
176- (id<BaseTree>) getChild:(id<BaseTree>)t At:(NSInteger)i
177{
178    if ( t == nil )
179        return nil;
180    return [(id<BaseTree>)t getChild:i];
181}
182
183- (void) setChild:(id<BaseTree>)t At:(NSInteger)i Child:(id<BaseTree>)child
184{
185    if ( t == nil )
186        return;
187    [(id<BaseTree>)t setChild:i With:child];
188}
189
190- (id) deleteChild:(id<BaseTree>)t Index:(NSInteger)anIndex
191{
192    return [t deleteChild:anIndex];
193}
194
195- (NSInteger) getChildCount:(id<BaseTree>) t
196{
197    if ( t == nil )
198        return 0;
199    return [(id<BaseTree>) t getChildCount];
200}
201
202- (id<BaseTree>) getParent:(id<BaseTree>) t
203{
204    if ( t == nil )
205        return nil;
206    return (id<BaseTree>)[t getParent];
207}
208
209- (void) setParent:(id<BaseTree>)t With:(id<BaseTree>) parent
210{
211    if ( t != nil )
212        [(id<BaseTree>) t setParent:(id<BaseTree>)parent];
213}
214
215- (NSInteger) getChildIndex:(id<BaseTree>) t
216{
217    if ( t == nil )
218        return 0;
219    return [(id<BaseTree>) t getChildIndex];
220}
221
222- (void) setChildIndex:(id<BaseTree>)t With:(NSInteger)anIndex
223{
224    if ( t!=nil )
225        [(id<BaseTree>)t setChildIndex:anIndex];
226}
227
228- (void) replaceChildren:(id<BaseTree>)parent From:(NSInteger)startChildIndex To:(NSInteger)stopChildIndex With:(id<BaseTree>)t
229{
230    if ( parent != nil ) {
231        [(id<BaseTree>)parent replaceChildrenFrom:startChildIndex To:stopChildIndex With:t];
232    }
233}
234
235- (id) copyWithZone:(NSZone *)aZone
236{
237    return [[[self class] allocWithZone:aZone] init];
238}
239
240@end
241