| // |
| // ANTLRTreePatternParser.m |
| // ANTLR |
| // |
| // Created by Alan Condit on 6/18/10. |
| // [The "BSD licence"] |
| // Copyright (c) 2010 Alan Condit |
| // All rights reserved. |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions |
| // are met: |
| // 1. Redistributions of source code must retain the above copyright |
| // notice, this list of conditions and the following disclaimer. |
| // 2. Redistributions in binary form must reproduce the above copyright |
| // notice, this list of conditions and the following disclaimer in the |
| // documentation and/or other materials provided with the distribution. |
| // 3. The name of the author may not be used to endorse or promote products |
| // derived from this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
| // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
| // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| #import "ANTLRTreePatternParser.h" |
| #import "ANTLRTreePatternLexer.h" |
| |
| @implementation ANTLRTreePatternParser |
| |
| + (ANTLRTreePatternParser *)newANTLRTreePatternParser:(ANTLRTreePatternLexer *)aTokenizer |
| Wizard:(ANTLRTreeWizard *)aWizard |
| Adaptor:(id<ANTLRTreeAdaptor>)anAdaptor |
| { |
| return [[ANTLRTreePatternParser alloc] initWithTokenizer:aTokenizer Wizard:aWizard Adaptor:anAdaptor]; |
| } |
| |
| - (id) init |
| { |
| if ((self = [super init]) != nil) { |
| //tokenizer = aTokenizer; |
| //wizard = aWizard; |
| //adaptor = anAdaptor; |
| //ttype = [tokenizer nextToken]; // kickstart |
| } |
| return self; |
| } |
| |
| - (id) initWithTokenizer:(ANTLRTreePatternLexer *)aTokenizer |
| Wizard:(ANTLRTreeWizard *)aWizard |
| Adaptor:(id<ANTLRTreeAdaptor>)anAdaptor |
| { |
| if ((self = [super init]) != nil) { |
| adaptor = anAdaptor; |
| if ( adaptor ) [adaptor retain]; |
| tokenizer = aTokenizer; |
| if ( tokenizer ) [tokenizer retain]; |
| wizard = aWizard; |
| if ( wizard ) [wizard retain]; |
| ttype = [aTokenizer nextToken]; // kickstart |
| } |
| return self; |
| } |
| |
| - (void) dealloc |
| { |
| #ifdef DEBUG_DEALLOC |
| NSLog( @"called dealloc in ANTLRTreePatternParser" ); |
| #endif |
| if ( adaptor ) [adaptor release]; |
| if ( tokenizer ) [tokenizer release]; |
| if ( wizard ) [wizard release]; |
| [super dealloc]; |
| } |
| |
| - (id<ANTLRBaseTree>)pattern |
| { |
| if ( ttype==ANTLRLexerTokenTypeBEGIN ) { |
| return [self parseTree]; |
| } |
| else if ( ttype==ANTLRLexerTokenTypeID ) { |
| id<ANTLRBaseTree> node = [self parseNode]; |
| if ( ttype==ANTLRLexerTokenTypeEOF ) { |
| return node; |
| } |
| return nil; // extra junk on end |
| } |
| return nil; |
| } |
| |
| - (id<ANTLRBaseTree>) parseTree |
| { |
| if ( ttype != ANTLRLexerTokenTypeBEGIN ) { |
| @throw [ANTLRRuntimeException newException:@"no BEGIN"]; |
| } |
| ttype = [tokenizer nextToken]; |
| id<ANTLRBaseTree> root = [self parseNode]; |
| if ( root==nil ) { |
| return nil; |
| } |
| while ( ttype==ANTLRLexerTokenTypeBEGIN || |
| ttype==ANTLRLexerTokenTypeID || |
| ttype==ANTLRLexerTokenTypePERCENT || |
| ttype==ANTLRLexerTokenTypeDOT ) |
| { |
| if ( ttype==ANTLRLexerTokenTypeBEGIN ) { |
| id<ANTLRBaseTree> subtree = [self parseTree]; |
| [adaptor addChild:subtree toTree:root]; |
| } |
| else { |
| id<ANTLRBaseTree> child = [self parseNode]; |
| if ( child == nil ) { |
| return nil; |
| } |
| [adaptor addChild:child toTree:root]; |
| } |
| } |
| if ( ttype != ANTLRLexerTokenTypeEND ) { |
| @throw [ANTLRRuntimeException newException:@"no END"]; |
| } |
| ttype = [tokenizer nextToken]; |
| return root; |
| } |
| |
| - (id<ANTLRBaseTree>) parseNode |
| { |
| // "%label:" prefix |
| NSString *label = nil; |
| ANTLRTreePattern *node; |
| if ( ttype == ANTLRLexerTokenTypePERCENT ) { |
| ttype = [tokenizer nextToken]; |
| if ( ttype != ANTLRLexerTokenTypeID ) { |
| return nil; |
| } |
| label = [tokenizer toString]; |
| ttype = [tokenizer nextToken]; |
| if ( ttype != ANTLRLexerTokenTypeCOLON ) { |
| return nil; |
| } |
| ttype = [tokenizer nextToken]; // move to ID following colon |
| } |
| |
| // Wildcard? |
| if ( ttype == ANTLRLexerTokenTypeDOT ) { |
| ttype = [tokenizer nextToken]; |
| id<ANTLRToken> wildcardPayload = [ANTLRCommonToken newToken:0 Text:@"."]; |
| node = [ANTLRWildcardTreePattern newANTLRWildcardTreePattern:wildcardPayload]; |
| if ( label != nil ) { |
| node.label = label; |
| } |
| return node; |
| } |
| |
| // "ID" or "ID[arg]" |
| if ( ttype != ANTLRLexerTokenTypeID ) { |
| return nil; |
| } |
| NSString *tokenName = [tokenizer toString]; |
| ttype = [tokenizer nextToken]; |
| if ( [tokenName isEqualToString:@"nil"] ) { |
| return [adaptor emptyNode]; |
| } |
| NSString *text = tokenName; |
| // check for arg |
| NSString *arg = nil; |
| if ( ttype == ANTLRLexerTokenTypeARG ) { |
| arg = [tokenizer toString]; |
| text = arg; |
| ttype = [tokenizer nextToken]; |
| } |
| |
| // create node |
| int treeNodeType = [wizard getTokenType:tokenName]; |
| if ( treeNodeType==ANTLRTokenTypeInvalid ) { |
| return nil; |
| } |
| node = [adaptor createTree:treeNodeType Text:text]; |
| if ( label!=nil && [node class] == [ANTLRTreePattern class] ) { |
| ((ANTLRTreePattern *)node).label = label; |
| } |
| if ( arg!=nil && [node class] == [ANTLRTreePattern class] ) { |
| ((ANTLRTreePattern *)node).hasTextArg = YES; |
| } |
| return node; |
| } |
| |
| @synthesize tokenizer; |
| @synthesize ttype; |
| @synthesize wizard; |
| @synthesize adaptor; |
| @end |