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 "Foundation/NSObjCRuntime.h" 28#import "RecognitionException.h" 29#import "TokenStream.h" 30#import "TreeNodeStream.h" 31#import "BufferedTokenStream.h" 32 33@implementation RecognitionException 34 35@synthesize input; 36@synthesize index; 37@synthesize token; 38@synthesize node; 39@synthesize c; 40@synthesize line; 41@synthesize charPositionInLine; 42@synthesize approximateLineInfo; 43 44+ (id) newException 45{ 46 return [[RecognitionException alloc] init]; 47} 48 49+ (id) newException:(id<IntStream>) anInputStream 50{ 51 return [[RecognitionException alloc] initWithStream:anInputStream]; 52} 53 54+ (id) newException:(id<IntStream>) anInputStream reason:(NSString *)aReason 55{ 56 return [[RecognitionException alloc] initWithStream:anInputStream reason:aReason]; 57} 58 59- (id) init 60{ 61 self = [super initWithName:@"Recognition Exception" reason:@"Recognition Exception" userInfo:nil]; 62 if ( self != nil ) { 63 } 64 return self; 65} 66 67- (id) initWithStream:(id<IntStream>)anInputStream reason:(NSString *)aReason 68{ 69 self = [super initWithName:NSStringFromClass([self class]) reason:aReason userInfo:nil]; 70 if ( self != nil ) { 71 [self setStream:anInputStream]; 72 index = input.index; 73 74 Class inputClass = [input class]; 75 if ([inputClass conformsToProtocol:@protocol(TokenStream)]) { 76 [self setToken:[(id<TokenStream>)input LT:1]]; 77 line = token.line; 78 charPositionInLine = token.charPositionInLine; 79 } else if ([inputClass conformsToProtocol:@protocol(CharStream)]) { 80 c = (unichar)[input LA:1]; 81 line = ((id<CharStream>)input).getLine; 82 charPositionInLine = ((id<CharStream>)input).getCharPositionInLine; 83 } else if ([inputClass conformsToProtocol:@protocol(TreeNodeStream)]) { 84 [self setNode:[(id<TreeNodeStream>)input LT:1]]; 85 line = [node line]; 86 charPositionInLine = [node charPositionInLine]; 87 } else { 88 c = (unichar)[input LA:1]; 89 } 90 } 91 return self; 92} 93 94- (id) initWithStream:(id<IntStream>)anInputStream 95{ 96 self = [super initWithName:NSStringFromClass([self class]) reason:@"Runtime Exception" userInfo:nil]; 97 if ( self != nil ) { 98 self.input = anInputStream; 99 self.index = input.index; 100 if ( [anInputStream isKindOfClass:[BufferedTokenStream class]] ) { 101 self.token = [(id<TokenStream>)anInputStream LT:1]; 102 self.line = [token line]; 103 self.charPositionInLine = [token charPositionInLine]; 104 if ( [input conformsToProtocol:objc_getProtocol("TreeNodeStream")] ) { 105 [self extractInformationFromTreeNodeStream:anInputStream]; 106 } 107 else if ( [[anInputStream class] instancesRespondToSelector:@selector(LA1:)] ) { 108 c = [anInputStream LA:1]; 109 if ( [[anInputStream class] instancesRespondToSelector:@selector(getLine)] ) 110 line = [anInputStream getLine]; 111 if ( [[anInputStream class] instancesRespondToSelector:@selector(getCharPositionInLine)] ) 112 charPositionInLine = [anInputStream getCharPositionInLine]; 113 } 114 else { 115 c = [anInputStream LA:1]; 116 } 117 } 118 } 119 return self; 120} 121 122- (id) initWithName:(NSString *)aName reason:(NSString *)aReason userInfo:(NSDictionary *)aUserInfo 123{ 124 self = [super initWithName:aName reason:aReason userInfo:aUserInfo]; 125 if ( self != nil ) { 126 } 127 return self; 128} 129 130- (void) dealloc 131{ 132#ifdef DEBUG_DEALLOC 133 NSLog( @"called dealloc in RecognitionException" ); 134#endif 135 if ( input ) [input release]; 136 if ( token ) [token release]; 137 if ( node ) [node release]; 138 [super dealloc]; 139} 140 141- (void) extractInformationFromTreeNodeStream:(id<TreeNodeStream>)anInput 142{ 143 id<TreeNodeStream> nodes = anInput; 144 node = [nodes LT:1]; 145 id<TreeAdaptor> adaptor = [nodes getTreeAdaptor]; 146 id<Token> payload = [adaptor getToken:node]; 147 if ( payload != nil ) { 148 token = payload; 149 if ( payload.line <= 0 ) { 150 // imaginary node; no line/pos info; scan backwards 151 int i = -1; 152 id priorNode = [nodes LT:i]; 153 while ( priorNode != nil ) { 154 id<Token> priorPayload = [adaptor getToken:priorNode]; 155 if ( priorPayload!=nil && priorPayload.line > 0 ) { 156 // we found the most recent real line / pos info 157 line = priorPayload.line; 158 charPositionInLine = priorPayload.charPositionInLine; 159 approximateLineInfo = YES; 160 break; 161 } 162 --i; 163 priorNode = [nodes LT:i]; 164 } 165 } 166 else { // node created from real token 167 line = payload.line; 168 charPositionInLine = payload.charPositionInLine; 169 } 170 } 171 else if ( [self.node isKindOfClass:[CommonTree class]] ) { 172 line = ((id<Tree>)node).line; 173 charPositionInLine = ((id<Tree>)node).charPositionInLine; 174 if ( [node isMemberOfClass:[CommonTree class]]) { 175 token = ((CommonTree *)node).token; 176 } 177 } 178 else { 179 NSInteger type = [adaptor getType:node]; 180 NSString *text = [adaptor getText:node]; 181 self.token = [CommonToken newToken:type Text:text]; 182 } 183} 184 185- (NSInteger) unexpectedType 186{ 187 if (token) { 188 return token.type; 189 } else if (node) { 190 return [node type]; 191 } else { 192 return c; 193 } 194} 195 196- (id<Token>)getUnexpectedToken 197{ 198 return token; 199} 200 201- (NSString *) description 202{ 203 //NSMutableString *desc = [[NSMutableString alloc] initWithString:NSStringFromClass([self class])]; 204 NSMutableString *desc = [NSMutableString stringWithString:[self className]]; 205 if (token) { 206 [desc appendFormat:@" token:%@", token]; 207 } else if (node) { 208 [desc appendFormat:@" node:%@", node]; 209 } else { 210 [desc appendFormat:@" char:%c", c]; 211 } 212 [desc appendFormat:@" line:%d position:%d", line, charPositionInLine]; 213 return desc; 214} 215 216//---------------------------------------------------------- 217// input 218//---------------------------------------------------------- 219- (id<IntStream>) getStream 220{ 221 return input; 222} 223 224- (void) setStream: (id<IntStream>) aStream 225{ 226 if ( input != aStream ) { 227 if ( input ) [input release]; 228 if ( aStream ) [aStream retain]; 229 input = aStream; 230 } 231} 232 233//---------------------------------------------------------- 234// token 235//---------------------------------------------------------- 236- (id<Token>) getToken 237{ 238 return token; 239} 240 241- (void) setToken: (id<Token>) aToken 242{ 243 if (token != aToken) { 244 if ( token ) [token release]; 245 if ( aToken ) [aToken retain]; 246 token = aToken; 247 } 248} 249 250//---------------------------------------------------------- 251// node 252//---------------------------------------------------------- 253- (id<BaseTree>) getNode 254{ 255 return node; 256} 257 258- (void) setNode: (id<BaseTree>) aNode 259{ 260 if (node != aNode) { 261 if ( node ) [node release]; 262 if ( aNode ) [aNode retain]; 263 node = aNode; 264 } 265} 266 267- (NSString *)getMessage 268{ 269 return @"Fix getMessage in RecognitionException"; 270} 271 272- (NSUInteger)charPositionInLine 273{ 274 return charPositionInLine; 275} 276 277- (void)setCharPositionInLine:(NSUInteger)aPos 278{ 279 charPositionInLine = aPos; 280} 281 282@end 283