1// 2// ANTLRCommonErrorNode.m 3// ANTLR 4// 5// [The "BSD licence"] 6// Copyright (c) 2010 Alan Condit 7// All rights reserved. 8// 9// Redistribution and use in source and binary forms, with or without 10// modification, are permitted provided that the following conditions 11// are met: 12// 1. Redistributions of source code must retain the above copyright 13// notice, this list of conditions and the following disclaimer. 14// 2. Redistributions in binary form must reproduce the above copyright 15// notice, this list of conditions and the following disclaimer in the 16// documentation and/or other materials provided with the distribution. 17// 3. The name of the author may not be used to endorse or promote products 18// derived from this software without specific prior written permission. 19// 20// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31#import "ANTLRCommonErrorNode.h" 32#import "ANTLRMissingTokenException.h" 33#import "ANTLRNoViableAltException.h" 34#import "ANTLRTreeNodeStream.h" 35#import "ANTLRUnwantedTokenException.h" 36 37@implementation ANTLRCommonErrorNode 38 39+ (id) newANTLRCommonErrorNode:(id<ANTLRTokenStream>)anInput 40 From:(id<ANTLRToken>)aStartToken 41 To:(id<ANTLRToken>)aStopToken 42 Exception:(ANTLRRecognitionException *) e 43{ 44 return [[ANTLRCommonErrorNode alloc] initWithInput:anInput From:aStartToken To:aStopToken Exception:e]; 45} 46 47- (id) init 48{ 49 self = [super init]; 50 if ( self != nil ) { 51 } 52 return self; 53} 54 55- (id) initWithInput:(id<ANTLRTokenStream>)anInput 56 From:(id<ANTLRToken>)aStartToken 57 To:(id<ANTLRToken>)aStopToken 58 Exception:(ANTLRRecognitionException *) e 59{ 60 self = [super init]; 61 if ( self != nil ) { 62 //System.out.println("aStartToken: "+aStartToken+", aStopToken: "+aStopToken); 63 if ( aStopToken == nil || 64 ([aStopToken getTokenIndex] < [aStartToken getTokenIndex] && 65 aStopToken.type != ANTLRTokenTypeEOF) ) 66 { 67 // sometimes resync does not consume a token (when LT(1) is 68 // in follow set. So, aStopToken will be 1 to left to aStartToken. adjust. 69 // Also handle case where aStartToken is the first token and no token 70 // is consumed during recovery; LT(-1) will return null. 71 aStopToken = aStartToken; 72 } 73 input = anInput; 74 if ( input ) [input retain]; 75 startToken = aStartToken; 76 if ( startToken ) [startToken retain]; 77 stopToken = aStopToken; 78 if ( stopToken ) [stopToken retain]; 79 trappedException = e; 80 if ( trappedException ) [trappedException retain]; 81 } 82 return self; 83} 84 85- (void)dealloc 86{ 87#ifdef DEBUG_DEALLOC 88 NSLog( @"called dealloc in ANTLRCommonErrorNode" ); 89#endif 90 if ( input ) [input release]; 91 if ( startToken ) [startToken release]; 92 if ( stopToken ) [stopToken release]; 93 if ( trappedException ) [trappedException release]; 94 [super dealloc]; 95} 96 97- (BOOL) isNil 98{ 99 return NO; 100} 101 102- (NSInteger)type 103{ 104 return ANTLRTokenTypeInvalid; 105} 106 107- (NSString *)text 108{ 109 NSString *badText = nil; 110 if ( [startToken isKindOfClass:[self class]] ) { 111 int i = [(id<ANTLRToken>)startToken getTokenIndex]; 112 int j = [(id<ANTLRToken>)stopToken getTokenIndex]; 113 if ( stopToken.type == ANTLRTokenTypeEOF ) { 114 j = [(id<ANTLRTokenStream>)input size]; 115 } 116 badText = [(id<ANTLRTokenStream>)input toStringFromStart:i ToEnd:j]; 117 } 118 else if ( [startToken isKindOfClass:[self class]] ) { 119 badText = [(id<ANTLRTreeNodeStream>)input toStringFromNode:startToken ToNode:stopToken]; 120 } 121 else { 122 // people should subclass if they alter the tree type so this 123 // next one is for sure correct. 124 badText = @"<unknown>"; 125 } 126 return badText; 127} 128 129- (NSString *)toString 130{ 131 NSString *aString; 132 if ( [trappedException isKindOfClass:[ANTLRMissingTokenException class]] ) { 133 aString = [NSString stringWithFormat:@"<missing type: %@ >", 134 [(ANTLRMissingTokenException *)trappedException getMissingType]]; 135 return aString; 136 } 137 else if ( [trappedException isKindOfClass:[ANTLRUnwantedTokenException class]] ) { 138 aString = [NSString stringWithFormat:@"<extraneous: %@, resync=%@>", 139 [trappedException getUnexpectedToken], 140 [self text]]; 141 return aString; 142 } 143 else if ( [trappedException isKindOfClass:[ANTLRMismatchedTokenException class]] ) { 144 aString = [NSString stringWithFormat:@"<mismatched token: %@, resync=%@>", trappedException.token, [self text]]; 145 return aString; 146 } 147 else if ( [trappedException isKindOfClass:[ANTLRNoViableAltException class]] ) { 148 aString = [NSString stringWithFormat:@"<unexpected: %@, resync=%@>", trappedException.token, [self text]]; 149 return aString; 150 } 151 aString = [NSString stringWithFormat:@"<error: %@>",[self text]]; 152 return aString; 153} 154 155@synthesize input; 156@synthesize startToken; 157@synthesize stopToken; 158@synthesize trappedException; 159@end 160