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