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