Home | History | Annotate | Download | only in Framework
      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