1 // 2 // ANTLRTreePatternParser.m 3 // ANTLR 4 // 5 // Created by Alan Condit on 6/18/10. 6 // [The "BSD licence"] 7 // Copyright (c) 2010 Alan Condit 8 // All rights reserved. 9 // 10 // Redistribution and use in source and binary forms, with or without 11 // modification, are permitted provided that the following conditions 12 // are met: 13 // 1. Redistributions of source code must retain the above copyright 14 // notice, this list of conditions and the following disclaimer. 15 // 2. Redistributions in binary form must reproduce the above copyright 16 // notice, this list of conditions and the following disclaimer in the 17 // documentation and/or other materials provided with the distribution. 18 // 3. The name of the author may not be used to endorse or promote products 19 // derived from this software without specific prior written permission. 20 // 21 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 32 #import "ANTLRTreePatternParser.h" 33 #import "ANTLRTreePatternLexer.h" 34 35 @implementation ANTLRTreePatternParser 36 37 + (ANTLRTreePatternParser *)newANTLRTreePatternParser:(ANTLRTreePatternLexer *)aTokenizer 38 Wizard:(ANTLRTreeWizard *)aWizard 39 Adaptor:(id<ANTLRTreeAdaptor>)anAdaptor 40 { 41 return [[ANTLRTreePatternParser alloc] initWithTokenizer:aTokenizer Wizard:aWizard Adaptor:anAdaptor]; 42 } 43 44 - (id) init 45 { 46 if ((self = [super init]) != nil) { 47 //tokenizer = aTokenizer; 48 //wizard = aWizard; 49 //adaptor = anAdaptor; 50 //ttype = [tokenizer nextToken]; // kickstart 51 } 52 return self; 53 } 54 55 - (id) initWithTokenizer:(ANTLRTreePatternLexer *)aTokenizer 56 Wizard:(ANTLRTreeWizard *)aWizard 57 Adaptor:(id<ANTLRTreeAdaptor>)anAdaptor 58 { 59 if ((self = [super init]) != nil) { 60 adaptor = anAdaptor; 61 if ( adaptor ) [adaptor retain]; 62 tokenizer = aTokenizer; 63 if ( tokenizer ) [tokenizer retain]; 64 wizard = aWizard; 65 if ( wizard ) [wizard retain]; 66 ttype = [aTokenizer nextToken]; // kickstart 67 } 68 return self; 69 } 70 71 - (void) dealloc 72 { 73 #ifdef DEBUG_DEALLOC 74 NSLog( @"called dealloc in ANTLRTreePatternParser" ); 75 #endif 76 if ( adaptor ) [adaptor release]; 77 if ( tokenizer ) [tokenizer release]; 78 if ( wizard ) [wizard release]; 79 [super dealloc]; 80 } 81 82 - (id<ANTLRBaseTree>)pattern 83 { 84 if ( ttype==ANTLRLexerTokenTypeBEGIN ) { 85 return [self parseTree]; 86 } 87 else if ( ttype==ANTLRLexerTokenTypeID ) { 88 id<ANTLRBaseTree> node = [self parseNode]; 89 if ( ttype==ANTLRLexerTokenTypeEOF ) { 90 return node; 91 } 92 return nil; // extra junk on end 93 } 94 return nil; 95 } 96 97 - (id<ANTLRBaseTree>) parseTree 98 { 99 if ( ttype != ANTLRLexerTokenTypeBEGIN ) { 100 @throw [ANTLRRuntimeException newException:@"no BEGIN"]; 101 } 102 ttype = [tokenizer nextToken]; 103 id<ANTLRBaseTree> root = [self parseNode]; 104 if ( root==nil ) { 105 return nil; 106 } 107 while ( ttype==ANTLRLexerTokenTypeBEGIN || 108 ttype==ANTLRLexerTokenTypeID || 109 ttype==ANTLRLexerTokenTypePERCENT || 110 ttype==ANTLRLexerTokenTypeDOT ) 111 { 112 if ( ttype==ANTLRLexerTokenTypeBEGIN ) { 113 id<ANTLRBaseTree> subtree = [self parseTree]; 114 [adaptor addChild:subtree toTree:root]; 115 } 116 else { 117 id<ANTLRBaseTree> child = [self parseNode]; 118 if ( child == nil ) { 119 return nil; 120 } 121 [adaptor addChild:child toTree:root]; 122 } 123 } 124 if ( ttype != ANTLRLexerTokenTypeEND ) { 125 @throw [ANTLRRuntimeException newException:@"no END"]; 126 } 127 ttype = [tokenizer nextToken]; 128 return root; 129 } 130 131 - (id<ANTLRBaseTree>) parseNode 132 { 133 // "%label:" prefix 134 NSString *label = nil; 135 ANTLRTreePattern *node; 136 if ( ttype == ANTLRLexerTokenTypePERCENT ) { 137 ttype = [tokenizer nextToken]; 138 if ( ttype != ANTLRLexerTokenTypeID ) { 139 return nil; 140 } 141 label = [tokenizer toString]; 142 ttype = [tokenizer nextToken]; 143 if ( ttype != ANTLRLexerTokenTypeCOLON ) { 144 return nil; 145 } 146 ttype = [tokenizer nextToken]; // move to ID following colon 147 } 148 149 // Wildcard? 150 if ( ttype == ANTLRLexerTokenTypeDOT ) { 151 ttype = [tokenizer nextToken]; 152 id<ANTLRToken> wildcardPayload = [ANTLRCommonToken newToken:0 Text:@"."]; 153 node = [ANTLRWildcardTreePattern newANTLRWildcardTreePattern:wildcardPayload]; 154 if ( label != nil ) { 155 node.label = label; 156 } 157 return node; 158 } 159 160 // "ID" or "ID[arg]" 161 if ( ttype != ANTLRLexerTokenTypeID ) { 162 return nil; 163 } 164 NSString *tokenName = [tokenizer toString]; 165 ttype = [tokenizer nextToken]; 166 if ( [tokenName isEqualToString:@"nil"] ) { 167 return [adaptor emptyNode]; 168 } 169 NSString *text = tokenName; 170 // check for arg 171 NSString *arg = nil; 172 if ( ttype == ANTLRLexerTokenTypeARG ) { 173 arg = [tokenizer toString]; 174 text = arg; 175 ttype = [tokenizer nextToken]; 176 } 177 178 // create node 179 int treeNodeType = [wizard getTokenType:tokenName]; 180 if ( treeNodeType==ANTLRTokenTypeInvalid ) { 181 return nil; 182 } 183 node = [adaptor createTree:treeNodeType Text:text]; 184 if ( label!=nil && [node class] == [ANTLRTreePattern class] ) { 185 ((ANTLRTreePattern *)node).label = label; 186 } 187 if ( arg!=nil && [node class] == [ANTLRTreePattern class] ) { 188 ((ANTLRTreePattern *)node).hasTextArg = YES; 189 } 190 return node; 191 } 192 193 @synthesize tokenizer; 194 @synthesize ttype; 195 @synthesize wizard; 196 @synthesize adaptor; 197 @end 198