Home | History | Annotate | Download | only in Antlr.Runtime.Tree
      1 /*
      2  * [The "BSD licence"]
      3  * Copyright (c) 2005-2008 Terence Parr
      4  * All rights reserved.
      5  *
      6  * Conversion to C#:
      7  * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc.
      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 
     33 namespace Antlr.Runtime.Tree {
     34 
     35     /** <summary>
     36      *  A TreeAdaptor that works with any Tree implementation.  It provides
     37      *  really just factory methods; all the work is done by BaseTreeAdaptor.
     38      *  If you would like to have different tokens created than ClassicToken
     39      *  objects, you need to override this and then set the parser tree adaptor to
     40      *  use your subclass.
     41      *  </summary>
     42      *
     43      *  <remarks>
     44      *  To get your parser to build nodes of a different type, override
     45      *  create(Token), errorNode(), and to be safe, YourTreeClass.dupNode().
     46      *  dupNode is called to duplicate nodes during rewrite operations.
     47      *  </remarks>
     48      */
     49     public class CommonTreeAdaptor : BaseTreeAdaptor {
     50         /** <summary>
     51          *  Duplicate a node.  This is part of the factory;
     52          *  override if you want another kind of node to be built.
     53          *  </summary>
     54          *
     55          *  <remarks>
     56          *  I could use reflection to prevent having to override this
     57          *  but reflection is slow.
     58          *  </remarks>
     59          */
     60         public override object DupNode(object t) {
     61             if (t == null)
     62                 return null;
     63 
     64             return ((ITree)t).DupNode();
     65         }
     66 
     67         public override object Create(IToken payload) {
     68             return new CommonTree(payload);
     69         }
     70 
     71         /** <summary>
     72          *  Tell me how to create a token for use with imaginary token nodes.
     73          *  For example, there is probably no input symbol associated with imaginary
     74          *  token DECL, but you need to create it as a payload or whatever for
     75          *  the DECL node as in ^(DECL type ID).
     76          *  </summary>
     77          *
     78          *  <remarks>
     79          *  If you care what the token payload objects' type is, you should
     80          *  override this method and any other createToken variant.
     81          *  </remarks>
     82          */
     83         public override IToken CreateToken(int tokenType, string text) {
     84             return new CommonToken(tokenType, text);
     85         }
     86 
     87         /** <summary>
     88          *  Tell me how to create a token for use with imaginary token nodes.
     89          *  For example, there is probably no input symbol associated with imaginary
     90          *  token DECL, but you need to create it as a payload or whatever for
     91          *  the DECL node as in ^(DECL type ID).
     92          *  </summary>
     93          *
     94          *  <remarks>
     95          *  This is a variant of createToken where the new token is derived from
     96          *  an actual real input token.  Typically this is for converting '{'
     97          *  tokens to BLOCK etc...  You'll see
     98          *
     99          *    r : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ;
    100          *
    101          *  If you care what the token payload objects' type is, you should
    102          *  override this method and any other createToken variant.
    103          *  </remarks>
    104          */
    105         public override IToken CreateToken(IToken fromToken) {
    106             return new CommonToken(fromToken);
    107         }
    108 
    109         /** <summary>
    110          *  Track start/stop token for subtree root created for a rule.
    111          *  Only works with Tree nodes.  For rules that match nothing,
    112          *  seems like this will yield start=i and stop=i-1 in a nil node.
    113          *  Might be useful info so I'll not force to be i..i.
    114          *  </summary>
    115          */
    116         public override void SetTokenBoundaries(object t, IToken startToken, IToken stopToken) {
    117             if (t == null)
    118                 return;
    119 
    120             int start = 0;
    121             int stop = 0;
    122 
    123             if (startToken != null)
    124                 start = startToken.TokenIndex;
    125 
    126             if (stopToken != null)
    127                 stop = stopToken.TokenIndex;
    128 
    129             ((ITree)t).TokenStartIndex = start;
    130             ((ITree)t).TokenStopIndex = stop;
    131         }
    132 
    133         public override int GetTokenStartIndex(object t) {
    134             if (t == null)
    135                 return -1;
    136 
    137             return ((ITree)t).TokenStartIndex;
    138         }
    139 
    140         public override int GetTokenStopIndex(object t) {
    141             if (t == null)
    142                 return -1;
    143 
    144             return ((ITree)t).TokenStopIndex;
    145         }
    146 
    147         public override string GetText(object t) {
    148             if (t == null)
    149                 return null;
    150 
    151             return ((ITree)t).Text;
    152         }
    153 
    154         public override int GetType(object t) {
    155             if (t == null)
    156                 return TokenTypes.Invalid;
    157 
    158             return ((ITree)t).Type;
    159         }
    160 
    161         /** <summary>
    162          *  What is the Token associated with this node?  If
    163          *  you are not using CommonTree, then you must
    164          *  override this in your own adaptor.
    165          *  </summary>
    166          */
    167         public override IToken GetToken(object t) {
    168             if (t is CommonTree) {
    169                 return ((CommonTree)t).Token;
    170             }
    171             return null; // no idea what to do
    172         }
    173 
    174         public override object GetChild(object t, int i) {
    175             if (t == null)
    176                 return null;
    177 
    178             return ((ITree)t).GetChild(i);
    179         }
    180 
    181         public override int GetChildCount(object t) {
    182             if (t == null)
    183                 return 0;
    184 
    185             return ((ITree)t).ChildCount;
    186         }
    187 
    188         public override object GetParent(object t) {
    189             if (t == null)
    190                 return null;
    191 
    192             return ((ITree)t).Parent;
    193         }
    194 
    195         public override void SetParent(object t, object parent) {
    196             if (t != null)
    197                 ((ITree)t).Parent = (ITree)parent;
    198         }
    199 
    200         public override int GetChildIndex(object t) {
    201             if (t == null)
    202                 return 0;
    203 
    204             return ((ITree)t).ChildIndex;
    205         }
    206 
    207         public override void SetChildIndex(object t, int index) {
    208             if (t != null)
    209                 ((ITree)t).ChildIndex = index;
    210         }
    211 
    212         public override void ReplaceChildren(object parent, int startChildIndex, int stopChildIndex, object t) {
    213             if (parent != null) {
    214                 ((ITree)parent).ReplaceChildren(startChildIndex, stopChildIndex, t);
    215             }
    216         }
    217     }
    218 }
    219