Home | History | Annotate | Download | only in Tree
      1 /*
      2  * [The "BSD licence"]
      3  * Copyright (c) 2011 Terence Parr
      4  * All rights reserved.
      5  *
      6  * Conversion to C#:
      7  * Copyright (c) 2011 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     using ArgumentNullException = System.ArgumentNullException;
     36 
     37     /** <summary>
     38      *  A tree node that is wrapper for a Token object.  After 3.0 release
     39      *  while building tree rewrite stuff, it became clear that computing
     40      *  parent and child index is very difficult and cumbersome.  Better to
     41      *  spend the space in every tree node.  If you don't want these extra
     42      *  fields, it's easy to cut them out in your own BaseTree subclass.
     43      *  </summary>
     44      */
     45     [System.Serializable]
     46     public class CommonTree : BaseTree
     47     {
     48         /** <summary>A single token is the payload</summary> */
     49         private IToken _token;
     50 
     51         /** <summary>
     52          *  What token indexes bracket all tokens associated with this node
     53          *  and below?
     54          *  </summary>
     55          */
     56         protected int startIndex = -1;
     57         protected int stopIndex = -1;
     58 
     59         /** <summary>Who is the parent node of this node; if null, implies node is root</summary> */
     60         CommonTree parent;
     61 
     62         /** <summary>What index is this node in the child list? Range: 0..n-1</summary> */
     63         int childIndex = -1;
     64 
     65         public CommonTree()
     66         {
     67         }
     68 
     69         public CommonTree( CommonTree node )
     70             : base( node )
     71         {
     72             if (node == null)
     73                 throw new ArgumentNullException("node");
     74 
     75             this.Token = node.Token;
     76             this.startIndex = node.startIndex;
     77             this.stopIndex = node.stopIndex;
     78         }
     79 
     80         public CommonTree( IToken t )
     81         {
     82             this.Token = t;
     83         }
     84 
     85         #region Properties
     86 
     87         public override int CharPositionInLine
     88         {
     89             get
     90             {
     91                 if ( Token == null || Token.CharPositionInLine == -1 )
     92                 {
     93                     if ( ChildCount > 0 )
     94                         return Children[0].CharPositionInLine;
     95 
     96                     return 0;
     97                 }
     98                 return Token.CharPositionInLine;
     99             }
    100 
    101             set
    102             {
    103                 base.CharPositionInLine = value;
    104             }
    105         }
    106 
    107         public override int ChildIndex
    108         {
    109             get
    110             {
    111                 return childIndex;
    112             }
    113 
    114             set
    115             {
    116                 childIndex = value;
    117             }
    118         }
    119 
    120         public override bool IsNil
    121         {
    122             get
    123             {
    124                 return Token == null;
    125             }
    126         }
    127 
    128         public override int Line
    129         {
    130             get
    131             {
    132                 if ( Token == null || Token.Line == 0 )
    133                 {
    134                     if ( ChildCount > 0 )
    135                         return Children[0].Line;
    136 
    137                     return 0;
    138                 }
    139 
    140                 return Token.Line;
    141             }
    142 
    143             set
    144             {
    145                 base.Line = value;
    146             }
    147         }
    148 
    149         public override ITree Parent
    150         {
    151             get
    152             {
    153                 return parent;
    154             }
    155 
    156             set
    157             {
    158                 parent = (CommonTree)value;
    159             }
    160         }
    161 
    162         public override string Text
    163         {
    164             get
    165             {
    166                 if ( Token == null )
    167                     return null;
    168 
    169                 return Token.Text;
    170             }
    171 
    172             set
    173             {
    174             }
    175         }
    176 
    177         public IToken Token
    178         {
    179             get
    180             {
    181                 return _token;
    182             }
    183 
    184             set
    185             {
    186                 _token = value;
    187             }
    188         }
    189 
    190         public override int TokenStartIndex
    191         {
    192             get
    193             {
    194                 if ( startIndex == -1 && Token != null )
    195                     return Token.TokenIndex;
    196 
    197                 return startIndex;
    198             }
    199 
    200             set
    201             {
    202                 startIndex = value;
    203             }
    204         }
    205 
    206         public override int TokenStopIndex
    207         {
    208             get
    209             {
    210                 if ( stopIndex == -1 && Token != null )
    211                 {
    212                     return Token.TokenIndex;
    213                 }
    214                 return stopIndex;
    215             }
    216 
    217             set
    218             {
    219                 stopIndex = value;
    220             }
    221         }
    222 
    223         public override int Type
    224         {
    225             get
    226             {
    227                 if ( Token == null )
    228                     return TokenTypes.Invalid;
    229 
    230                 return Token.Type;
    231             }
    232 
    233             set
    234             {
    235             }
    236         }
    237 
    238         #endregion
    239 
    240         public override ITree DupNode()
    241         {
    242             return new CommonTree( this );
    243         }
    244 
    245         /** <summary>
    246          *  For every node in this subtree, make sure it's start/stop token's
    247          *  are set.  Walk depth first, visit bottom up.  Only updates nodes
    248          *  with at least one token index &lt; 0.
    249          *  </summary>
    250          */
    251         public virtual void SetUnknownTokenBoundaries()
    252         {
    253             if ( Children == null )
    254             {
    255                 if ( startIndex < 0 || stopIndex < 0 )
    256                     startIndex = stopIndex = Token.TokenIndex;
    257 
    258                 return;
    259             }
    260 
    261             foreach (ITree childTree in Children)
    262             {
    263                 CommonTree commonTree = childTree as CommonTree;
    264                 if (commonTree == null)
    265                     continue;
    266 
    267                 commonTree.SetUnknownTokenBoundaries();
    268             }
    269 
    270             if ( startIndex >= 0 && stopIndex >= 0 )
    271                 return; // already set
    272 
    273             if ( Children.Count > 0 )
    274             {
    275                 ITree firstChild = Children[0];
    276                 ITree lastChild = Children[Children.Count - 1];
    277                 startIndex = firstChild.TokenStartIndex;
    278                 stopIndex = lastChild.TokenStopIndex;
    279             }
    280         }
    281 
    282         public override string ToString()
    283         {
    284             if (IsNil)
    285                 return "nil";
    286 
    287             if (Type == TokenTypes.Invalid)
    288                 return "<errornode>";
    289 
    290             if (Token == null)
    291                 return string.Empty;
    292 
    293             return Token.Text;
    294         }
    295     }
    296 }
    297