Home | History | Annotate | Download | only in Antlr3.Runtime
      1 unit Antlr.Runtime.Tree;
      2 (*
      3 [The "BSD licence"]
      4 Copyright (c) 2008 Erik van Bilsen
      5 Copyright (c) 2005-2007 Kunle Odutola
      6 All rights reserved.
      7 
      8 Redistribution and use in source and binary forms, with or without
      9 modification, are permitted provided that the following conditions
     10 are met:
     11 1. Redistributions of source code MUST RETAIN the above copyright
     12    notice, this list of conditions and the following disclaimer.
     13 2. Redistributions in binary form MUST REPRODUCE the above copyright
     14    notice, this list of conditions and the following disclaimer in 
     15    the documentation and/or other materials provided with the 
     16    distribution.
     17 3. The name of the author may not be used to endorse or promote products
     18    derived from this software without specific prior WRITTEN permission.
     19 4. Unless explicitly state otherwise, any contribution intentionally 
     20    submitted for inclusion in this work to the copyright owner or licensor
     21    shall be under the terms and conditions of this license, without any 
     22    additional terms or conditions.
     23 
     24 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     25 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     26 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     27 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     28 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     29 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     30 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     31 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     33 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     34 *)
     35 
     36 interface
     37 
     38 {$IF CompilerVersion < 20}
     39 {$MESSAGE ERROR 'You need Delphi 2009 or higher to use the Antlr runtime'}
     40 {$IFEND}
     41 
     42 uses
     43   Classes,
     44   SysUtils,
     45   Antlr.Runtime,
     46   Antlr.Runtime.Tools,
     47   Antlr.Runtime.Collections;
     48 
     49 type
     50   /// <summary>
     51   /// How to create and navigate trees.  Rather than have a separate factory
     52   /// and adaptor, I've merged them.  Makes sense to encapsulate.
     53   ///
     54   /// This takes the place of the tree construction code generated in the
     55   /// generated code in 2.x and the ASTFactory.
     56   ///
     57   /// I do not need to know the type of a tree at all so they are all
     58   /// generic Objects.  This may increase the amount of typecasting needed. :(
     59   /// </summary>
     60   ITreeAdaptor = interface(IANTLRInterface)
     61   ['{F9DEB286-F555-4CC8-A51A-93F3F649B248}']
     62     { Methods }
     63 
     64     // C o n s t r u c t i o n
     65 
     66     /// <summary>
     67     /// Create a tree node from Token object; for CommonTree type trees,
     68     /// then the token just becomes the payload.
     69     /// </summary>
     70     /// <remarks>
     71     /// This is the most common create call. Override if you want another kind of node to be built.
     72     /// </remarks>
     73     function CreateNode(const Payload: IToken): IANTLRInterface; overload;
     74 
     75     /// <summary>Duplicate a single tree node </summary>
     76     /// <remarks> Override if you want another kind of node to be built.</remarks>
     77     function DupNode(const TreeNode: IANTLRInterface): IANTLRInterface;
     78 
     79     /// <summary>Duplicate tree recursively, using DupNode() for each node </summary>
     80     function DupTree(const Tree: IANTLRInterface): IANTLRInterface;
     81 
     82     /// <summary>
     83     /// Return a nil node (an empty but non-null node) that can hold
     84     /// a list of element as the children.  If you want a flat tree (a list)
     85     /// use "t=adaptor.nil(); t.AddChild(x); t.AddChild(y);"
     86     /// </summary>
     87     function GetNilNode: IANTLRInterface;
     88 
     89     /// <summary>
     90     /// Return a tree node representing an error. This node records the
     91     /// tokens consumed during error recovery. The start token indicates the
     92     /// input symbol at which the error was detected. The stop token indicates
     93     /// the last symbol consumed during recovery.
     94     /// </summary>
     95     /// <remarks>
     96     /// <para>You must specify the input stream so that the erroneous text can
     97     /// be packaged up in the error node. The exception could be useful
     98     /// to some applications; default implementation stores ptr to it in
     99     /// the CommonErrorNode.</para>
    100     ///
    101     /// <para>This only makes sense during token parsing, not tree parsing.
    102     /// Tree parsing should happen only when parsing and tree construction
    103     /// succeed.</para>
    104     /// </remarks>
    105     function ErrorNode(const Input: ITokenStream; const Start, Stop: IToken;
    106       const E: ERecognitionException): IANTLRInterface;
    107 
    108     /// <summary>
    109     /// Is tree considered a nil node used to make lists of child nodes?
    110     /// </summary>
    111     function IsNil(const Tree: IANTLRInterface): Boolean;
    112 
    113     /// <summary>
    114     /// Add a child to the tree t.  If child is a flat tree (a list), make all
    115     /// in list children of t.
    116     /// </summary>
    117     /// <remarks>
    118     /// <para>
    119     /// Warning: if t has no children, but child does and child isNil then you
    120     /// can decide it is ok to move children to t via t.children = child.children;
    121     /// i.e., without copying the array.  Just make sure that this is consistent
    122     /// with have the user will build ASTs. Do nothing if t or child is null.
    123     /// </para>
    124     /// <para>
    125     /// This is for construction and I'm not sure it's completely general for
    126     /// a tree's addChild method to work this way.  Make sure you differentiate
    127     /// between your tree's addChild and this parser tree construction addChild
    128     /// if it's not ok to move children to t with a simple assignment.
    129     /// </para>
    130     /// </remarks>
    131     procedure AddChild(const T, Child: IANTLRInterface);
    132 
    133     /// <summary>
    134     /// If oldRoot is a nil root, just copy or move the children to newRoot.
    135     /// If not a nil root, make oldRoot a child of newRoot.
    136     /// </summary>
    137     /// <remarks>
    138     ///
    139     ///   old=^(nil a b c), new=r yields ^(r a b c)
    140     ///   old=^(a b c), new=r yields ^(r ^(a b c))
    141     ///
    142     /// If newRoot is a nil-rooted single child tree, use the single
    143     /// child as the new root node.
    144     ///
    145     ///   old=^(nil a b c), new=^(nil r) yields ^(r a b c)
    146     ///   old=^(a b c), new=^(nil r) yields ^(r ^(a b c))
    147     ///
    148     /// If oldRoot was null, it's ok, just return newRoot (even if isNil).
    149     ///
    150     ///   old=null, new=r yields r
    151     ///   old=null, new=^(nil r) yields ^(nil r)
    152     ///
    153     /// Return newRoot.  Throw an exception if newRoot is not a
    154     /// simple node or nil root with a single child node--it must be a root
    155     /// node.  If newRoot is ^(nil x) return x as newRoot.
    156     ///
    157     /// Be advised that it's ok for newRoot to point at oldRoot's
    158     /// children; i.e., you don't have to copy the list.  We are
    159     /// constructing these nodes so we should have this control for
    160     /// efficiency.
    161     /// </remarks>
    162     function BecomeRoot(const NewRoot, OldRoot: IANTLRInterface): IANTLRInterface; overload;
    163 
    164     /// <summary>
    165     /// Given the root of the subtree created for this rule, post process
    166     /// it to do any simplifications or whatever you want.  A required
    167     /// behavior is to convert ^(nil singleSubtree) to singleSubtree
    168     /// as the setting of start/stop indexes relies on a single non-nil root
    169     /// for non-flat trees.
    170     ///
    171     /// Flat trees such as for lists like "idlist : ID+ ;" are left alone
    172     /// unless there is only one ID.  For a list, the start/stop indexes
    173     /// are set in the nil node.
    174     ///
    175     /// This method is executed after all rule tree construction and right
    176     /// before SetTokenBoundaries().
    177     /// </summary>
    178     function RulePostProcessing(const Root: IANTLRInterface): IANTLRInterface;
    179 
    180     /// <summary>
    181     /// For identifying trees. How to identify nodes so we can say "add node
    182     /// to a prior node"?
    183     /// </summary>
    184     /// <remarks>
    185     /// Even BecomeRoot is an issue. Ok, we could:
    186     /// <list type="number">
    187     ///   <item>Number the nodes as they are created?</item>
    188     ///   <item>
    189     ///     Use the original framework assigned hashcode that's unique
    190     ///     across instances of a given type.
    191     ///     WARNING: This is usually implemented either as IL to make a
    192     ///     non-virt call to object.GetHashCode() or by via a call to
    193     ///     System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode().
    194     ///     Both have issues especially on .NET 1.x and Mono.
    195     ///   </item>
    196     /// </list>
    197     /// </remarks>
    198     function GetUniqueID(const Node: IANTLRInterface): Integer;
    199 
    200     // R e w r i t e  R u l e s
    201 
    202     /// <summary>
    203     /// Create a node for newRoot make it the root of oldRoot.
    204     /// If oldRoot is a nil root, just copy or move the children to newRoot.
    205     /// If not a nil root, make oldRoot a child of newRoot.
    206     ///
    207     /// Return node created for newRoot.
    208     /// </summary>
    209     function BecomeRoot(const NewRoot: IToken; const OldRoot: IANTLRInterface): IANTLRInterface; overload;
    210 
    211     /// <summary>Create a new node derived from a token, with a new token type.
    212     /// This is invoked from an imaginary node ref on right side of a
    213     /// rewrite rule as IMAG[$tokenLabel].
    214     ///
    215     /// This should invoke createToken(Token).
    216     /// </summary>
    217     function CreateNode(const TokenType: Integer; const FromToken: IToken): IANTLRInterface; overload;
    218 
    219     /// <summary>Same as Create(tokenType,fromToken) except set the text too.
    220     /// This is invoked from an imaginary node ref on right side of a
    221     /// rewrite rule as IMAG[$tokenLabel, "IMAG"].
    222     ///
    223     /// This should invoke createToken(Token).
    224     /// </summary>
    225     function CreateNode(const TokenType: Integer; const FromToken: IToken;
    226       const Text: String): IANTLRInterface; overload;
    227 
    228     /// <summary>Create a new node derived from a token, with a new token type.
    229     /// This is invoked from an imaginary node ref on right side of a
    230     /// rewrite rule as IMAG["IMAG"].
    231     ///
    232     /// This should invoke createToken(int,String).
    233     /// </summary>
    234     function CreateNode(const TokenType: Integer; const Text: String): IANTLRInterface; overload;
    235 
    236     // C o n t e n t
    237 
    238     /// <summary>For tree parsing, I need to know the token type of a node </summary>
    239     function GetNodeType(const T: IANTLRInterface): Integer;
    240 
    241     /// <summary>Node constructors can set the type of a node </summary>
    242     procedure SetNodeType(const T: IANTLRInterface; const NodeType: Integer);
    243 
    244     function GetNodeText(const T: IANTLRInterface): String;
    245 
    246     /// <summary>Node constructors can set the text of a node </summary>
    247     procedure SetNodeText(const T: IANTLRInterface; const Text: String);
    248 
    249     /// <summary>
    250     /// Return the token object from which this node was created.
    251     /// </summary>
    252     /// <remarks>
    253     /// Currently used only for printing an error message. The error
    254     /// display routine in BaseRecognizer needs to display where the
    255     /// input the error occurred. If your tree of limitation does not
    256     /// store information that can lead you to the token, you can create
    257     /// a token filled with the appropriate information and pass that back.
    258     /// <see cref="BaseRecognizer.GetErrorMessage"/>
    259     /// </remarks>
    260     function GetToken(const TreeNode: IANTLRInterface): IToken;
    261 
    262     /// <summary>
    263     /// Where are the bounds in the input token stream for this node and
    264     /// all children?
    265     /// </summary>
    266     /// <remarks>
    267     /// Each rule that creates AST nodes will call this
    268     /// method right before returning.  Flat trees (i.e., lists) will
    269     /// still usually have a nil root node just to hold the children list.
    270     /// That node would contain the start/stop indexes then.
    271     /// </remarks>
    272     procedure SetTokenBoundaries(const T: IANTLRInterface; const StartToken,
    273       StopToken: IToken);
    274 
    275     /// <summary>
    276     /// Get the token start index for this subtree; return -1 if no such index
    277     /// </summary>
    278     function GetTokenStartIndex(const T: IANTLRInterface): Integer;
    279 
    280     /// <summary>
    281     /// Get the token stop index for this subtree; return -1 if no such index
    282     /// </summary>
    283     function GetTokenStopIndex(const T: IANTLRInterface): Integer;
    284 
    285     // N a v i g a t i o n  /  T r e e  P a r s i n g
    286 
    287     /// <summary>Get a child 0..n-1 node </summary>
    288     function GetChild(const T: IANTLRInterface; const I: Integer): IANTLRInterface;
    289 
    290     /// <summary>Set ith child (0..n-1) to t; t must be non-null and non-nil node</summary>
    291     procedure SetChild(const T: IANTLRInterface; const I: Integer; const Child: IANTLRInterface);
    292 
    293     /// <summary>Remove ith child and shift children down from right.</summary>
    294     function DeleteChild(const T: IANTLRInterface; const I: Integer): IANTLRInterface;
    295 
    296     /// <summary>How many children?  If 0, then this is a leaf node </summary>
    297     function GetChildCount(const T: IANTLRInterface): Integer;
    298 
    299     /// <summary>
    300     /// Who is the parent node of this node; if null, implies node is root.
    301     /// </summary>
    302     /// <remarks>
    303     /// If your node type doesn't handle this, it's ok but the tree rewrites
    304     /// in tree parsers need this functionality.
    305     /// </remarks>
    306     function GetParent(const T: IANTLRInterface): IANTLRInterface;
    307     procedure SetParent(const T, Parent: IANTLRInterface);
    308 
    309     /// <summary>
    310     /// What index is this node in the child list? Range: 0..n-1
    311     /// </summary>
    312     /// <remarks>
    313     /// If your node type doesn't handle this, it's ok but the tree rewrites
    314     /// in tree parsers need this functionality.
    315     /// </remarks>
    316     function GetChildIndex(const T: IANTLRInterface): Integer;
    317     procedure SetChildIdex(const T: IANTLRInterface; const Index: Integer);
    318 
    319     /// <summary>
    320     /// Replace from start to stop child index of parent with t, which might
    321     /// be a list.  Number of children may be different after this call.
    322     /// </summary>
    323     /// <remarks>
    324     /// If parent is null, don't do anything; must be at root of overall tree.
    325     /// Can't replace whatever points to the parent externally.  Do nothing.
    326     /// </remarks>
    327     procedure ReplaceChildren(const Parent: IANTLRInterface; const StartChildIndex,
    328       StopChildIndex: Integer; const T: IANTLRInterface);
    329   end;
    330 
    331   /// <summary>A stream of tree nodes, accessing nodes from a tree of some kind </summary>
    332   ITreeNodeStream = interface(IIntStream)
    333   ['{75EA5C06-8145-48F5-9A56-43E481CE86C6}']
    334     { Property accessors }
    335     function GetTreeSource: IANTLRInterface;
    336     function GetTokenStream: ITokenStream;
    337     function GetTreeAdaptor: ITreeAdaptor;
    338     procedure SetHasUniqueNavigationNodes(const Value: Boolean);
    339 
    340     { Methods }
    341 
    342     /// <summary>Get a tree node at an absolute index i; 0..n-1.</summary>
    343     /// <remarks>
    344     /// If you don't want to buffer up nodes, then this method makes no
    345     /// sense for you.
    346     /// </remarks>
    347     function Get(const I: Integer): IANTLRInterface;
    348 
    349     /// <summary>
    350     /// Get tree node at current input pointer + i ahead where i=1 is next node.
    351     /// i&lt;0 indicates nodes in the past.  So LT(-1) is previous node, but
    352     /// implementations are not required to provide results for k &lt; -1.
    353     /// LT(0) is undefined.  For i&gt;=n, return null.
    354     /// Return null for LT(0) and any index that results in an absolute address
    355     /// that is negative.
    356     ///
    357     /// This is analogus to the LT() method of the TokenStream, but this
    358     /// returns a tree node instead of a token.  Makes code gen identical
    359     /// for both parser and tree grammars. :)
    360     /// </summary>
    361     function LT(const K: Integer): IANTLRInterface;
    362 
    363     /// <summary>Return the text of all nodes from start to stop, inclusive.
    364     /// If the stream does not buffer all the nodes then it can still
    365     /// walk recursively from start until stop.  You can always return
    366     /// null or "" too, but users should not access $ruleLabel.text in
    367     /// an action of course in that case.
    368     /// </summary>
    369     function ToString(const Start, Stop: IANTLRInterface): String; overload;
    370     function ToString: String; overload;
    371 
    372     // REWRITING TREES (used by tree parser)
    373 
    374     /// <summary>
    375     /// Replace from start to stop child index of parent with t, which might
    376     /// be a list.  Number of children may be different after this call.
    377     /// </summary>
    378     /// <remarks>
    379     /// The stream is notified because it is walking the tree and might need
    380     /// to know you are monkeying with the underlying tree.  Also, it might be
    381     /// able to modify the node stream to avoid restreaming for future phases.
    382     ///
    383     /// If parent is null, don't do anything; must be at root of overall tree.
    384     /// Can't replace whatever points to the parent externally.  Do nothing.
    385     /// </remarks>
    386     procedure ReplaceChildren(const Parent: IANTLRInterface; const StartChildIndex,
    387       StopChildIndex: Integer; const T: IANTLRInterface);
    388 
    389     { Properties }
    390 
    391     /// <summary>
    392     /// Where is this stream pulling nodes from?  This is not the name, but
    393     /// the object that provides node objects.
    394     ///
    395     /// TODO: do we really need this?
    396     /// </summary>
    397     property TreeSource: IANTLRInterface read GetTreeSource;
    398 
    399     /// <summary>
    400     /// Get the ITokenStream from which this stream's Tree was created
    401     /// (may be null)
    402     /// </summary>
    403     /// <remarks>
    404     /// If the tree associated with this stream was created from a
    405     /// TokenStream, you can specify it here.  Used to do rule $text
    406     /// attribute in tree parser.  Optional unless you use tree parser
    407     /// rule text attribute or output=template and rewrite=true options.
    408     /// </remarks>
    409     property TokenStream: ITokenStream read GetTokenStream;
    410 
    411     /// <summary>
    412     /// What adaptor can tell me how to interpret/navigate nodes and trees.
    413     /// E.g., get text of a node.
    414     /// </summary>
    415     property TreeAdaptor: ITreeAdaptor read GetTreeAdaptor;
    416 
    417     /// <summary>
    418     /// As we flatten the tree, we use UP, DOWN nodes to represent
    419     /// the tree structure.  When debugging we need unique nodes
    420     /// so we have to instantiate new ones.  When doing normal tree
    421     /// parsing, it's slow and a waste of memory to create unique
    422     /// navigation nodes.  Default should be false;
    423     /// </summary>
    424     property HasUniqueNavigationNodes: Boolean write SetHasUniqueNavigationNodes;
    425   end;
    426 
    427   /// <summary>
    428   /// What does a tree look like?  ANTLR has a number of support classes
    429   /// such as CommonTreeNodeStream that work on these kinds of trees.  You
    430   /// don't have to make your trees implement this interface, but if you do,
    431   /// you'll be able to use more support code.
    432   ///
    433   /// NOTE: When constructing trees, ANTLR can build any kind of tree; it can
    434   /// even use Token objects as trees if you add a child list to your tokens.
    435   ///
    436   /// This is a tree node without any payload; just navigation and factory stuff.
    437   /// </summary>
    438   ITree = interface(IANTLRInterface)
    439   ['{4B6EFB53-EBF6-4647-BA4D-48B68134DC2A}']
    440     { Property accessors }
    441     function GetChildCount: Integer;
    442     function GetParent: ITree;
    443     procedure SetParent(const Value: ITree);
    444     function GetChildIndex: Integer;
    445     procedure SetChildIndex(const Value: Integer);
    446     function GetIsNil: Boolean;
    447     function GetTokenType: Integer;
    448     function GetText: String;
    449     function GetLine: Integer;
    450     function GetCharPositionInLine: Integer;
    451     function GetTokenStartIndex: Integer;
    452     procedure SetTokenStartIndex(const Value: Integer);
    453     function GetTokenStopIndex: Integer;
    454     procedure SetTokenStopIndex(const Value: Integer);
    455 
    456     { Methods }
    457 
    458     /// <summary>Set (or reset) the parent and child index values for all children</summary>
    459     procedure FreshenParentAndChildIndexes;
    460 
    461     function GetChild(const I: Integer): ITree;
    462 
    463     /// <summary>
    464     /// Add t as a child to this node.  If t is null, do nothing.  If t
    465     /// is nil, add all children of t to this' children.
    466     /// </summary>
    467     /// <param name="t">Tree to add</param>
    468     procedure AddChild(const T: ITree);
    469 
    470     /// <summary>Set ith child (0..n-1) to t; t must be non-null and non-nil node</summary>
    471     procedure SetChild(const I: Integer; const T: ITree);
    472 
    473     function DeleteChild(const I: Integer): IANTLRInterface;
    474 
    475     /// <summary>
    476     /// Delete children from start to stop and replace with t even if t is
    477     /// a list (nil-root tree).  num of children can increase or decrease.
    478     /// For huge child lists, inserting children can force walking rest of
    479     /// children to set their childindex; could be slow.
    480     /// </summary>
    481     procedure ReplaceChildren(const StartChildIndex, StopChildIndex: Integer;
    482       const T: IANTLRInterface);
    483 
    484     function DupNode: ITree;
    485 
    486     function ToStringTree: String;
    487 
    488     function ToString: String;
    489 
    490     { Properties }
    491 
    492     property ChildCount: Integer read GetChildCount;
    493 
    494     // Tree tracks parent and child index now > 3.0
    495     property Parent: ITree read GetParent write SetParent;
    496 
    497     /// <summary>This node is what child index? 0..n-1</summary>
    498     property ChildIndex: Integer read GetChildIndex write SetChildIndex;
    499 
    500     /// <summary>
    501     /// Indicates the node is a nil node but may still have children, meaning
    502     /// the tree is a flat list.
    503     /// </summary>
    504     property IsNil: Boolean read GetIsNil;
    505 
    506     /// <summary>Return a token type; needed for tree parsing </summary>
    507     property TokenType: Integer read GetTokenType;
    508 
    509     property Text: String read GetText;
    510 
    511     /// <summary>In case we don't have a token payload, what is the line for errors? </summary>
    512     property Line: Integer read GetLine;
    513     property CharPositionInLine: Integer read GetCharPositionInLine;
    514 
    515     /// <summary>
    516     /// What is the smallest token index (indexing from 0) for this node
    517     /// and its children?
    518     /// </summary>
    519     property TokenStartIndex: Integer read GetTokenStartIndex write SetTokenStartIndex;
    520 
    521     /// <summary>
    522     /// What is the largest token index (indexing from 0) for this node
    523     /// and its children?
    524     /// </summary>
    525     property TokenStopIndex: Integer read GetTokenStopIndex write SetTokenStopIndex;
    526   end;
    527 
    528   /// <summary>
    529   /// A generic tree implementation with no payload.  You must subclass to
    530   /// actually have any user data.  ANTLR v3 uses a list of children approach
    531   /// instead of the child-sibling approach in v2.  A flat tree (a list) is
    532   /// an empty node whose children represent the list.  An empty, but
    533   /// non-null node is called "nil".
    534   /// </summary>
    535   IBaseTree = interface(ITree)
    536   ['{6772F6EA-5FE0-40C6-BE5C-800AB2540E55}']
    537     { Property accessors }
    538     function GetChildren: IList<IBaseTree>;
    539     function GetChildIndex: Integer;
    540     procedure SetChildIndex(const Value: Integer);
    541     function GetParent: ITree;
    542     procedure SetParent(const Value: ITree);
    543     function GetTokenType: Integer;
    544     function GetTokenStartIndex: Integer;
    545     procedure SetTokenStartIndex(const Value: Integer);
    546     function GetTokenStopIndex: Integer;
    547     procedure SetTokenStopIndex(const Value: Integer);
    548     function GetText: String;
    549 
    550     { Methods }
    551 
    552     /// <summary>
    553     /// Add all elements of kids list as children of this node
    554     /// </summary>
    555     /// <param name="kids"></param>
    556     procedure AddChildren(const Kids: IList<IBaseTree>);
    557 
    558     procedure SetChild(const I: Integer; const T: ITree);
    559     procedure FreshenParentAndChildIndexes(const Offset: Integer);
    560 
    561     procedure SanityCheckParentAndChildIndexes; overload;
    562     procedure SanityCheckParentAndChildIndexes(const Parent: ITree;
    563       const I: Integer); overload;
    564 
    565     /// <summary>
    566     /// Print out a whole tree not just a node
    567     /// </summary>
    568     function ToStringTree: String;
    569 
    570     function DupNode: ITree;
    571 
    572     { Properties }
    573 
    574     /// <summary>
    575     /// Get the children internal list of children. Manipulating the list
    576     /// directly is not a supported operation (i.e. you do so at your own risk)
    577     /// </summary>
    578     property Children: IList<IBaseTree> read GetChildren;
    579 
    580     /// <summary>BaseTree doesn't track child indexes.</summary>
    581     property ChildIndex: Integer read GetChildIndex write SetChildIndex;
    582 
    583     /// <summary>BaseTree doesn't track parent pointers.</summary>
    584     property Parent: ITree read GetParent write SetParent;
    585 
    586     /// <summary>Return a token type; needed for tree parsing </summary>
    587     property TokenType: Integer read GetTokenType;
    588 
    589     /// <summary>
    590     /// What is the smallest token index (indexing from 0) for this node
    591     /// and its children?
    592     /// </summary>
    593     property TokenStartIndex: Integer read GetTokenStartIndex write SetTokenStartIndex;
    594 
    595     /// <summary>
    596     /// What is the largest token index (indexing from 0) for this node
    597     /// and its children?
    598     /// </summary>
    599     property TokenStopIndex: Integer read GetTokenStopIndex write SetTokenStopIndex;
    600 
    601     property Text: String read GetText;
    602   end;
    603 
    604   /// <summary>A tree node that is wrapper for a Token object. </summary>
    605   /// <remarks>
    606   /// After 3.0 release while building tree rewrite stuff, it became clear
    607   /// that computing parent and child index is very difficult and cumbersome.
    608   /// Better to spend the space in every tree node.  If you don't want these
    609   /// extra fields, it's easy to cut them out in your own BaseTree subclass.
    610   /// </remarks>
    611   ICommonTree = interface(IBaseTree)
    612   ['{791C0EA6-1E4D-443E-83E2-CC1EFEAECC8B}']
    613     { Property accessors }
    614     function GetToken: IToken;
    615     function GetStartIndex: Integer;
    616     procedure SetStartIndex(const Value: Integer);
    617     function GetStopIndex: Integer;
    618     procedure SetStopIndex(const Value: Integer);
    619 
    620     { Properties }
    621     property Token: IToken read GetToken;
    622     property StartIndex: Integer read GetStartIndex write SetStartIndex;
    623     property StopIndex: Integer read GetStopIndex write SetStopIndex;
    624   end;
    625 
    626   // A node representing erroneous token range in token stream
    627   ICommonErrorNode = interface(ICommonTree)
    628   ['{20FF30BA-C055-4E8F-B3E7-7FFF6313853E}']
    629   end;
    630 
    631   /// <summary>
    632   /// A TreeAdaptor that works with any Tree implementation
    633   /// </summary>
    634   IBaseTreeAdaptor = interface(ITreeAdaptor)
    635   ['{B9CE670A-E53F-494C-B700-E4A3DF42D482}']
    636     /// <summary>
    637     /// This is generic in the sense that it will work with any kind of
    638     /// tree (not just the ITree interface).  It invokes the adaptor routines
    639     /// not the tree node routines to do the construction.
    640     /// </summary>
    641     function DupTree(const Tree: IANTLRInterface): IANTLRInterface; overload;
    642     function DupTree(const T, Parent: IANTLRInterface): IANTLRInterface; overload;
    643 
    644     /// <summary>
    645     /// Tell me how to create a token for use with imaginary token nodes.
    646     /// For example, there is probably no input symbol associated with imaginary
    647     /// token DECL, but you need to create it as a payload or whatever for
    648     /// the DECL node as in ^(DECL type ID).
    649     ///
    650     /// If you care what the token payload objects' type is, you should
    651     /// override this method and any other createToken variant.
    652     /// </summary>
    653     function CreateToken(const TokenType: Integer; const Text: String): IToken; overload;
    654 
    655     /// <summary>
    656     /// Tell me how to create a token for use with imaginary token nodes.
    657     /// For example, there is probably no input symbol associated with imaginary
    658     /// token DECL, but you need to create it as a payload or whatever for
    659     /// the DECL node as in ^(DECL type ID).
    660     ///
    661     /// This is a variant of createToken where the new token is derived from
    662     /// an actual real input token.  Typically this is for converting '{'
    663     /// tokens to BLOCK etc...  You'll see
    664     ///
    665     ///    r : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ;
    666     ///
    667     /// If you care what the token payload objects' type is, you should
    668     /// override this method and any other createToken variant.
    669     /// </summary>
    670     function CreateToken(const FromToken: IToken): IToken; overload;
    671   end;
    672 
    673   /// <summary>
    674   /// A TreeAdaptor that works with any Tree implementation.  It provides
    675   /// really just factory methods; all the work is done by BaseTreeAdaptor.
    676   /// If you would like to have different tokens created than ClassicToken
    677   /// objects, you need to override this and then set the parser tree adaptor to
    678   /// use your subclass.
    679   ///
    680   /// To get your parser to build nodes of a different type, override
    681   /// Create(Token).
    682   /// </summary>
    683   ICommonTreeAdaptor = interface(IBaseTreeAdaptor)
    684   ['{B067EE7A-38EB-4156-9447-CDD6DDD6D13B}']
    685   end;
    686 
    687   /// <summary>
    688   /// A buffered stream of tree nodes.  Nodes can be from a tree of ANY kind.
    689   /// </summary>
    690   /// <remarks>
    691   /// This node stream sucks all nodes out of the tree specified in the
    692   /// constructor during construction and makes pointers into the tree
    693   /// using an array of Object pointers. The stream necessarily includes
    694   /// pointers to DOWN and UP and EOF nodes.
    695   ///
    696   /// This stream knows how to mark/release for backtracking.
    697   ///
    698   /// This stream is most suitable for tree interpreters that need to
    699   /// jump around a lot or for tree parsers requiring speed (at cost of memory).
    700   /// There is some duplicated functionality here with UnBufferedTreeNodeStream
    701   /// but just in bookkeeping, not tree walking etc...
    702   ///
    703   /// <see cref="UnBufferedTreeNodeStream"/>
    704   ///
    705   /// </remarks>
    706   ICommonTreeNodeStream = interface(ITreeNodeStream)
    707   ['{0112FB31-AA1E-471C-ADC3-D97AC5D77E05}']
    708     { Property accessors }
    709     function GetCurrentSymbol: IANTLRInterface;
    710     function GetTreeSource: IANTLRInterface;
    711     function GetSourceName: String;
    712     function GetTokenStream: ITokenStream;
    713     procedure SetTokenStream(const Value: ITokenStream);
    714     function GetTreeAdaptor: ITreeAdaptor;
    715     procedure SetTreeAdaptor(const Value: ITreeAdaptor);
    716     function GetHasUniqueNavigationNodes: Boolean;
    717     procedure SetHasUniqueNavigationNodes(const Value: Boolean);
    718 
    719     { Methods }
    720     /// <summary>
    721     /// Walk tree with depth-first-search and fill nodes buffer.
    722     /// Don't do DOWN, UP nodes if its a list (t is isNil).
    723     /// </summary>
    724     procedure FillBuffer(const T: IANTLRInterface);
    725 
    726     function Get(const I: Integer): IANTLRInterface;
    727 
    728     function LT(const K: Integer): IANTLRInterface;
    729 
    730     /// <summary>
    731     /// Look backwards k nodes
    732     /// </summary>
    733     function LB(const K: Integer): IANTLRInterface;
    734 
    735     /// <summary>
    736     /// Make stream jump to a new location, saving old location.
    737     /// Switch back with pop().
    738     /// </summary>
    739     procedure Push(const Index: Integer);
    740 
    741     /// <summary>
    742     /// Seek back to previous index saved during last Push() call.
    743     /// Return top of stack (return index).
    744     /// </summary>
    745     function Pop: Integer;
    746 
    747     procedure Reset;
    748 
    749     // Debugging
    750     function ToTokenString(const Start, Stop: Integer): String;
    751     function ToString(const Start, Stop: IANTLRInterface): String; overload;
    752     function ToString: String; overload;
    753 
    754     { Properties }
    755     property CurrentSymbol: IANTLRInterface read GetCurrentSymbol;
    756 
    757     /// <summary>
    758     /// Where is this stream pulling nodes from?  This is not the name, but
    759     /// the object that provides node objects.
    760     /// </summary>
    761     property TreeSource: IANTLRInterface read GetTreeSource;
    762 
    763     property SourceName: String read GetSourceName;
    764     property TokenStream: ITokenStream read GetTokenStream write SetTokenStream;
    765     property TreeAdaptor: ITreeAdaptor read GetTreeAdaptor write SetTreeAdaptor;
    766     property HasUniqueNavigationNodes: Boolean read GetHasUniqueNavigationNodes write SetHasUniqueNavigationNodes;
    767   end;
    768 
    769   /// <summary>
    770   /// A record of the rules used to Match a token sequence.  The tokens
    771   /// end up as the leaves of this tree and rule nodes are the interior nodes.
    772   /// This really adds no functionality, it is just an alias for CommonTree
    773   /// that is more meaningful (specific) and holds a String to display for a node.
    774   /// </summary>
    775   IParseTree = interface(IANTLRInterface)
    776   ['{1558F260-CAF8-4488-A242-3559BCE4E573}']
    777     { Methods }
    778 
    779     // Emit a token and all hidden nodes before.  EOF node holds all
    780     // hidden tokens after last real token.
    781     function ToStringWithHiddenTokens: String;
    782 
    783     // Print out the leaves of this tree, which means printing original
    784     // input back out.
    785     function ToInputString: String;
    786 
    787     procedure _ToStringLeaves(const Buf: TStringBuilder);
    788   end;
    789 
    790   /// <summary>
    791   /// A generic list of elements tracked in an alternative to be used in
    792   /// a -> rewrite rule.  We need to subclass to fill in the next() method,
    793   /// which returns either an AST node wrapped around a token payload or
    794   /// an existing subtree.
    795   ///
    796   /// Once you start next()ing, do not try to add more elements.  It will
    797   /// break the cursor tracking I believe.
    798   ///
    799   /// <see cref="RewriteRuleSubtreeStream"/>
    800   /// <see cref="RewriteRuleTokenStream"/>
    801   ///
    802   /// TODO: add mechanism to detect/puke on modification after reading from stream
    803   /// </summary>
    804   IRewriteRuleElementStream = interface(IANTLRInterface)
    805   ['{3CB6C521-F583-40DC-A1E3-4D7D57B98C74}']
    806     { Property accessors }
    807     function GetDescription: String;
    808 
    809     { Methods }
    810     procedure Add(const El: IANTLRInterface);
    811 
    812     /// <summary>
    813     /// Reset the condition of this stream so that it appears we have
    814     /// not consumed any of its elements.  Elements themselves are untouched.
    815     /// </summary>
    816     /// <remarks>
    817     /// Once we reset the stream, any future use will need duplicates.  Set
    818     /// the dirty bit.
    819     /// </remarks>
    820     procedure Reset;
    821 
    822     function HasNext: Boolean;
    823 
    824     /// <summary>
    825     /// Return the next element in the stream.
    826     /// </summary>
    827     function NextTree: IANTLRInterface;
    828     function NextNode: IANTLRInterface;
    829 
    830     function Size: Integer;
    831 
    832     { Properties }
    833     property Description: String read GetDescription;
    834   end;
    835 
    836   /// <summary>
    837   /// Queues up nodes matched on left side of -> in a tree parser. This is
    838   /// the analog of RewriteRuleTokenStream for normal parsers.
    839   /// </summary>
    840   IRewriteRuleNodeStream = interface(IRewriteRuleElementStream)
    841   ['{F60D1D36-FE13-4312-99DA-11E5F4BEBB66}']
    842     { Methods }
    843     function NextNode: IANTLRInterface;
    844   end;
    845 
    846   IRewriteRuleSubtreeStream = interface(IRewriteRuleElementStream)
    847   ['{C6BDA145-D926-45BC-B293-67490D72829B}']
    848     { Methods }
    849 
    850     /// <summary>
    851     /// Treat next element as a single node even if it's a subtree.
    852     /// </summary>
    853     /// <remarks>
    854     /// This is used instead of next() when the result has to be a
    855     /// tree root node.  Also prevents us from duplicating recently-added
    856     /// children; e.g., ^(type ID)+ adds ID to type and then 2nd iteration
    857     /// must dup the type node, but ID has been added.
    858     ///
    859     /// Referencing a rule result twice is ok; dup entire tree as
    860     /// we can't be adding trees as root; e.g., expr expr.
    861     /// </remarks>
    862     function NextNode: IANTLRInterface;
    863   end;
    864 
    865   IRewriteRuleTokenStream = interface(IRewriteRuleElementStream)
    866   ['{4D46AB00-7A19-4F69-B159-1EF09DB8C09C}']
    867     /// <summary>
    868     /// Get next token from stream and make a node for it.
    869     /// </summary>
    870     /// <remarks>
    871     /// ITreeAdaptor.Create() returns an object, so no further restrictions possible.
    872     /// </remarks>
    873     function NextNode: IANTLRInterface;
    874 
    875     function NextToken: IToken;
    876   end;
    877 
    878   /// <summary>
    879   /// A parser for a stream of tree nodes.  "tree grammars" result in a subclass
    880   /// of this.  All the error reporting and recovery is shared with Parser via
    881   /// the BaseRecognizer superclass.
    882   /// </summary>
    883   ITreeParser = interface(IBaseRecognizer)
    884   ['{20611FB3-9830-444D-B385-E8C2D094484B}']
    885     { Property accessors }
    886     function GetTreeNodeStream: ITreeNodeStream;
    887     procedure SetTreeNodeStream(const Value: ITreeNodeStream);
    888 
    889     { Methods }
    890     procedure TraceIn(const RuleName: String; const RuleIndex: Integer);
    891     procedure TraceOut(const RuleName: String; const RuleIndex: Integer);
    892 
    893     { Properties }
    894     property TreeNodeStream: ITreeNodeStream read GetTreeNodeStream write SetTreeNodeStream;
    895   end;
    896 
    897   ITreePatternLexer = interface(IANTLRInterface)
    898   ['{C3FEC614-9E6F-48D2-ABAB-59FC83D8BC2F}']
    899     { Methods }
    900     function NextToken: Integer;
    901     function SVal: String;
    902   end;
    903 
    904   IContextVisitor = interface(IANTLRInterface)
    905   ['{92B80D23-C63E-48B4-A9CD-EC2639317E43}']
    906     { Methods }
    907     procedure Visit(const T, Parent: IANTLRInterface; const ChildIndex: Integer;
    908       const Labels: IDictionary<String, IANTLRInterface>);
    909   end;
    910 
    911   /// <summary>
    912   /// Build and navigate trees with this object.  Must know about the names
    913   /// of tokens so you have to pass in a map or array of token names (from which
    914   /// this class can build the map).  I.e., Token DECL means nothing unless the
    915   /// class can translate it to a token type.
    916   /// </summary>
    917   /// <remarks>
    918   /// In order to create nodes and navigate, this class needs a TreeAdaptor.
    919   ///
    920   /// This class can build a token type -> node index for repeated use or for
    921   /// iterating over the various nodes with a particular type.
    922   ///
    923   /// This class works in conjunction with the TreeAdaptor rather than moving
    924   /// all this functionality into the adaptor.  An adaptor helps build and
    925   /// navigate trees using methods.  This class helps you do it with string
    926   /// patterns like "(A B C)".  You can create a tree from that pattern or
    927   /// match subtrees against it.
    928   /// </remarks>
    929   ITreeWizard = interface(IANTLRInterface)
    930   ['{4F440E19-893A-4E52-A979-E5377EAFA3B8}']
    931     { Methods }
    932     /// <summary>
    933     /// Compute a Map&lt;String, Integer&gt; that is an inverted index of
    934     /// tokenNames (which maps int token types to names).
    935     /// </summary>
    936     function ComputeTokenTypes(const TokenNames: TStringArray): IDictionary<String, Integer>;
    937 
    938     /// <summary>
    939     /// Using the map of token names to token types, return the type.
    940     /// </summary>
    941     function GetTokenType(const TokenName: String): Integer;
    942 
    943     /// <summary>
    944     /// Walk the entire tree and make a node name to nodes mapping.
    945     /// </summary>
    946     /// <remarks>
    947     /// For now, use recursion but later nonrecursive version may be
    948     /// more efficient.  Returns Map&lt;Integer, List&gt; where the List is
    949     /// of your AST node type.  The Integer is the token type of the node.
    950     ///
    951     /// TODO: save this index so that find and visit are faster
    952     /// </remarks>
    953     function Index(const T: IANTLRInterface): IDictionary<Integer, IList<IANTLRInterface>>;
    954 
    955     /// <summary>Return a List of tree nodes with token type ttype</summary>
    956     function Find(const T: IANTLRInterface; const TokenType: Integer): IList<IANTLRInterface>; overload;
    957 
    958     /// <summary>Return a List of subtrees matching pattern</summary>
    959     function Find(const T: IANTLRInterface; const Pattern: String): IList<IANTLRInterface>; overload;
    960 
    961     function FindFirst(const T: IANTLRInterface; const TokenType: Integer): IANTLRInterface; overload;
    962     function FindFirst(const T: IANTLRInterface; const Pattern: String): IANTLRInterface; overload;
    963 
    964     /// <summary>
    965     /// Visit every ttype node in t, invoking the visitor.
    966     /// </summary>
    967     /// <remarks>
    968     /// This is a quicker
    969     /// version of the general visit(t, pattern) method.  The labels arg
    970     /// of the visitor action method is never set (it's null) since using
    971     /// a token type rather than a pattern doesn't let us set a label.
    972     /// </remarks>
    973     procedure Visit(const T: IANTLRInterface; const TokenType: Integer;
    974       const Visitor: IContextVisitor); overload;
    975 
    976     /// <summary>
    977     /// For all subtrees that match the pattern, execute the visit action.
    978     /// </summary>
    979     /// <remarks>
    980     /// The implementation uses the root node of the pattern in combination
    981     /// with visit(t, ttype, visitor) so nil-rooted patterns are not allowed.
    982     /// Patterns with wildcard roots are also not allowed.
    983     /// </remarks>
    984     procedure Visit(const T: IANTLRInterface; const Pattern: String;
    985       const Visitor: IContextVisitor); overload;
    986 
    987     /// <summary>
    988     /// Given a pattern like (ASSIGN %lhs:ID %rhs:.) with optional labels
    989     /// on the various nodes and '.' (dot) as the node/subtree wildcard,
    990     /// return true if the pattern matches and fill the labels Map with
    991     /// the labels pointing at the appropriate nodes.  Return false if
    992     /// the pattern is malformed or the tree does not match.
    993     /// </summary>
    994     /// <remarks>
    995     /// If a node specifies a text arg in pattern, then that must match
    996     /// for that node in t.
    997     ///
    998     /// TODO: what's a better way to indicate bad pattern? Exceptions are a hassle
    999     /// </remarks>
   1000     function Parse(const T: IANTLRInterface; const Pattern: String;
   1001       const Labels: IDictionary<String, IANTLRInterface>): Boolean; overload;
   1002     function Parse(const T: IANTLRInterface; const Pattern: String): Boolean; overload;
   1003 
   1004     /// <summary>
   1005     /// Create a tree or node from the indicated tree pattern that closely
   1006     /// follows ANTLR tree grammar tree element syntax:
   1007     ///
   1008     ///   (root child1 ... child2).
   1009     ///
   1010     /// </summary>
   1011     /// <remarks>
   1012     /// You can also just pass in a node: ID
   1013     ///
   1014     /// Any node can have a text argument: ID[foo]
   1015     /// (notice there are no quotes around foo--it's clear it's a string).
   1016     ///
   1017     /// nil is a special name meaning "give me a nil node".  Useful for
   1018     /// making lists: (nil A B C) is a list of A B C.
   1019     /// </remarks>
   1020     function CreateTreeOrNode(const Pattern: String): IANTLRInterface;
   1021 
   1022     /// <summary>
   1023     /// Compare type, structure, and text of two trees, assuming adaptor in
   1024     /// this instance of a TreeWizard.
   1025     /// </summary>
   1026     function Equals(const T1, T2: IANTLRInterface): Boolean; overload;
   1027 
   1028     /// <summary>
   1029     /// Compare t1 and t2; return true if token types/text, structure match exactly.
   1030     /// The trees are examined in their entirety so that (A B) does not match
   1031     /// (A B C) nor (A (B C)).
   1032     /// </summary>
   1033     /// <remarks>
   1034     /// TODO: allow them to pass in a comparator
   1035     /// TODO: have a version that is nonstatic so it can use instance adaptor
   1036     ///
   1037     /// I cannot rely on the tree node's equals() implementation as I make
   1038     /// no constraints at all on the node types nor interface etc...
   1039     /// </remarks>
   1040     function Equals(const T1, T2: IANTLRInterface; const Adaptor: ITreeAdaptor): Boolean; overload;
   1041   end;
   1042 
   1043   ITreePatternParser = interface(IANTLRInterface)
   1044   ['{0CE3DF2A-7E4C-4A7C-8FE8-F1D7AFF97CAE}']
   1045     { Methods }
   1046     function Pattern: IANTLRInterface;
   1047     function ParseTree: IANTLRInterface;
   1048     function ParseNode: IANTLRInterface;
   1049   end;
   1050 
   1051   /// <summary>
   1052   /// This is identical to the ParserRuleReturnScope except that
   1053   /// the start property is a tree node and not a Token object
   1054   /// when you are parsing trees.  To be generic the tree node types
   1055   /// have to be Object :(
   1056   /// </summary>
   1057   ITreeRuleReturnScope = interface(IRuleReturnScope)
   1058   ['{FA2B1766-34E5-4D92-8996-371D5CFED999}']
   1059   end;
   1060 
   1061   /// <summary>
   1062   /// A stream of tree nodes, accessing nodes from a tree of ANY kind.
   1063   /// </summary>
   1064   /// <remarks>
   1065   /// No new nodes should be created in tree during the walk.  A small buffer
   1066   /// of tokens is kept to efficiently and easily handle LT(i) calls, though
   1067   /// the lookahead mechanism is fairly complicated.
   1068   ///
   1069   /// For tree rewriting during tree parsing, this must also be able
   1070   /// to replace a set of children without "losing its place".
   1071   /// That part is not yet implemented.  Will permit a rule to return
   1072   /// a different tree and have it stitched into the output tree probably.
   1073   ///
   1074   /// <see cref="CommonTreeNodeStream"/>
   1075   ///
   1076   /// </remarks>
   1077   IUnBufferedTreeNodeStream = interface(ITreeNodeStream)
   1078   ['{E46367AD-ED41-4D97-824E-575A48F7435D}']
   1079     { Property accessors }
   1080     function GetHasUniqueNavigationNodes: Boolean;
   1081     procedure SetHasUniqueNavigationNodes(const Value: Boolean);
   1082     function GetCurrent: IANTLRInterface;
   1083     function GetTokenStream: ITokenStream;
   1084     procedure SetTokenStream(const Value: ITokenStream);
   1085 
   1086     { Methods }
   1087     procedure Reset;
   1088     function MoveNext: Boolean;
   1089 
   1090     { Properties }
   1091     property HasUniqueNavigationNodes: Boolean read GetHasUniqueNavigationNodes write SetHasUniqueNavigationNodes;
   1092     property Current: IANTLRInterface read GetCurrent;
   1093     property TokenStream: ITokenStream read GetTokenStream write SetTokenStream;
   1094   end;
   1095 
   1096   /// <summary>Base class for all exceptions thrown during AST rewrite construction.</summary>
   1097   /// <remarks>
   1098   /// This signifies a case where the cardinality of two or more elements
   1099   /// in a subrule are different: (ID INT)+ where |ID|!=|INT|
   1100   /// </remarks>
   1101   ERewriteCardinalityException = class(Exception)
   1102   strict private
   1103     FElementDescription: String;
   1104   public
   1105     constructor Create(const AElementDescription: String);
   1106 
   1107     property ElementDescription: String read FElementDescription write FElementDescription;
   1108   end;
   1109 
   1110   /// <summary>
   1111   /// No elements within a (...)+ in a rewrite rule
   1112   /// </summary>
   1113   ERewriteEarlyExitException = class(ERewriteCardinalityException)
   1114     // No new declarations
   1115   end;
   1116 
   1117   /// <summary>
   1118   /// Ref to ID or expr but no tokens in ID stream or subtrees in expr stream
   1119   /// </summary>
   1120   ERewriteEmptyStreamException = class(ERewriteCardinalityException)
   1121     // No new declarations
   1122   end;
   1123 
   1124 type
   1125   TTree = class sealed
   1126   strict private
   1127     class var
   1128       FINVALID_NODE: ITree;
   1129   private
   1130     class procedure Initialize; static;
   1131   public
   1132     class property INVALID_NODE: ITree read FINVALID_NODE;
   1133   end;
   1134 
   1135   TBaseTree = class abstract(TANTLRObject, IBaseTree, ITree)
   1136   protected
   1137     { ITree / IBaseTree }
   1138     function GetParent: ITree; virtual;
   1139     procedure SetParent(const Value: ITree); virtual;
   1140     function GetChildIndex: Integer; virtual;
   1141     procedure SetChildIndex(const Value: Integer); virtual;
   1142     function GetTokenType: Integer; virtual; abstract;
   1143     function GetText: String; virtual; abstract;
   1144     function GetTokenStartIndex: Integer; virtual; abstract;
   1145     procedure SetTokenStartIndex(const Value: Integer); virtual; abstract;
   1146     function GetTokenStopIndex: Integer; virtual; abstract;
   1147     procedure SetTokenStopIndex(const Value: Integer); virtual; abstract;
   1148     function DupNode: ITree; virtual; abstract;
   1149     function ToStringTree: String; virtual;
   1150     function GetChildCount: Integer; virtual;
   1151     function GetIsNil: Boolean; virtual;
   1152     function GetLine: Integer; virtual;
   1153     function GetCharPositionInLine: Integer; virtual;
   1154     function GetChild(const I: Integer): ITree; virtual;
   1155     procedure AddChild(const T: ITree);
   1156     function DeleteChild(const I: Integer): IANTLRInterface;
   1157     procedure FreshenParentAndChildIndexes; overload;
   1158     procedure ReplaceChildren(const StartChildIndex, StopChildIndex: Integer;
   1159       const T: IANTLRInterface);
   1160   protected
   1161     { IBaseTree }
   1162     function GetChildren: IList<IBaseTree>;
   1163     procedure AddChildren(const Kids: IList<IBaseTree>);
   1164     procedure SetChild(const I: Integer; const T: ITree); virtual;
   1165     procedure FreshenParentAndChildIndexes(const Offset: Integer); overload;
   1166     procedure SanityCheckParentAndChildIndexes; overload; virtual;
   1167     procedure SanityCheckParentAndChildIndexes(const Parent: ITree;
   1168       const I: Integer); overload; virtual;
   1169   strict protected
   1170     FChildren: IList<IBaseTree>;
   1171 
   1172     /// <summary>Override in a subclass to change the impl of children list </summary>
   1173     function CreateChildrenList: IList<IBaseTree>; virtual;
   1174 
   1175   public
   1176     constructor Create; overload;
   1177 
   1178     /// <summary>Create a new node from an existing node does nothing for BaseTree
   1179     /// as there are no fields other than the children list, which cannot
   1180     /// be copied as the children are not considered part of this node.
   1181     /// </summary>
   1182     constructor Create(const ANode: ITree); overload;
   1183 
   1184     function ToString: String; override; abstract;
   1185   end;
   1186 
   1187   TCommonTree = class(TBaseTree, ICommonTree)
   1188   strict protected
   1189     /// <summary>A single token is the payload </summary>
   1190     FToken: IToken;
   1191 
   1192     /// <summary>
   1193     /// What token indexes bracket all tokens associated with this node
   1194     /// and below?
   1195     /// </summary>
   1196     FStartIndex: Integer;
   1197     FStopIndex: Integer;
   1198 
   1199     /// <summary>Who is the parent node of this node; if null, implies node is root</summary>
   1200     /// <remarks>
   1201     /// FParent should be of type ICommonTree, but that would introduce a
   1202     /// circular reference because the tree also maintains links to it's
   1203     /// children. This circular reference would cause a memory leak because
   1204     /// the reference count will never reach 0. This is avoided by making
   1205     /// FParent a regular pointer and letting the GetParent and SetParent
   1206     /// property accessors do the conversion to/from ICommonTree.
   1207     /// </remarks>
   1208     FParent: Pointer; { ICommonTree ; }
   1209 
   1210     /// <summary>What index is this node in the child list? Range: 0..n-1</summary>
   1211     FChildIndex: Integer;
   1212   protected
   1213     { ITree / IBaseTree }
   1214     function GetIsNil: Boolean; override;
   1215     function GetTokenType: Integer; override;
   1216     function GetText: String; override;
   1217     function GetLine: Integer; override;
   1218     function GetCharPositionInLine: Integer; override;
   1219     function GetTokenStartIndex: Integer; override;
   1220     procedure SetTokenStartIndex(const Value: Integer); override;
   1221     function GetTokenStopIndex: Integer; override;
   1222     procedure SetTokenStopIndex(const Value: Integer); override;
   1223     function GetChildIndex: Integer; override;
   1224     procedure SetChildIndex(const Value: Integer); override;
   1225     function GetParent: ITree; override;
   1226     procedure SetParent(const Value: ITree); override;
   1227     function DupNode: ITree; override;
   1228   protected
   1229     { ICommonTree }
   1230     function GetToken: IToken;
   1231     function GetStartIndex: Integer;
   1232     procedure SetStartIndex(const Value: Integer);
   1233     function GetStopIndex: Integer;
   1234     procedure SetStopIndex(const Value: Integer);
   1235   public
   1236     constructor Create; overload;
   1237     constructor Create(const ANode: ICommonTree); overload;
   1238     constructor Create(const AToken: IToken); overload;
   1239 
   1240     function ToString: String; override;
   1241   end;
   1242 
   1243   TCommonErrorNode = class(TCommonTree, ICommonErrorNode)
   1244   strict private
   1245     FInput: IIntStream;
   1246     FStart: IToken;
   1247     FStop: IToken;
   1248     FTrappedException: ERecognitionException;
   1249   protected
   1250     { ITree / IBaseTree }
   1251     function GetIsNil: Boolean; override;
   1252     function GetTokenType: Integer; override;
   1253     function GetText: String; override;
   1254   public
   1255     constructor Create(const AInput: ITokenStream; const AStart, AStop: IToken;
   1256       const AException: ERecognitionException);
   1257 
   1258     function ToString: String; override;
   1259   end;
   1260 
   1261   TBaseTreeAdaptor = class abstract(TANTLRObject, IBaseTreeAdaptor, ITreeAdaptor)
   1262   strict private
   1263     /// <summary>A map of tree node to unique IDs.</summary>
   1264     FTreeToUniqueIDMap: IDictionary<IANTLRInterface, Integer>;
   1265 
   1266     /// <summary>Next available unique ID.</summary>
   1267     FUniqueNodeID: Integer;
   1268   protected
   1269     { ITreeAdaptor }
   1270     function CreateNode(const Payload: IToken): IANTLRInterface; overload; virtual; abstract;
   1271     function DupNode(const TreeNode: IANTLRInterface): IANTLRInterface; virtual; abstract;
   1272     function DupTree(const Tree: IANTLRInterface): IANTLRInterface; overload; virtual;
   1273     function GetNilNode: IANTLRInterface; virtual;
   1274     function ErrorNode(const Input: ITokenStream; const Start, Stop: IToken;
   1275       const E: ERecognitionException): IANTLRInterface; virtual;
   1276     function IsNil(const Tree: IANTLRInterface): Boolean; virtual;
   1277     procedure AddChild(const T, Child: IANTLRInterface); virtual;
   1278     function BecomeRoot(const NewRoot, OldRoot: IANTLRInterface): IANTLRInterface; overload; virtual;
   1279     function RulePostProcessing(const Root: IANTLRInterface): IANTLRInterface; virtual;
   1280     function GetUniqueID(const Node: IANTLRInterface): Integer;
   1281     function BecomeRoot(const NewRoot: IToken; const OldRoot: IANTLRInterface): IANTLRInterface; overload; virtual;
   1282     function CreateNode(const TokenType: Integer; const FromToken: IToken): IANTLRInterface; overload; virtual;
   1283     function CreateNode(const TokenType: Integer; const FromToken: IToken;
   1284       const Text: String): IANTLRInterface; overload; virtual;
   1285     function CreateNode(const TokenType: Integer; const Text: String): IANTLRInterface; overload; virtual;
   1286     function GetNodeType(const T: IANTLRInterface): Integer; virtual;
   1287     procedure SetNodeType(const T: IANTLRInterface; const NodeType: Integer); virtual;
   1288     function GetNodeText(const T: IANTLRInterface): String; virtual;
   1289     procedure SetNodeText(const T: IANTLRInterface; const Text: String); virtual;
   1290     function GetToken(const TreeNode: IANTLRInterface): IToken; virtual; abstract;
   1291     procedure SetTokenBoundaries(const T: IANTLRInterface; const StartToken,
   1292       StopToken: IToken); virtual; abstract;
   1293     function GetTokenStartIndex(const T: IANTLRInterface): Integer; virtual; abstract;
   1294     function GetTokenStopIndex(const T: IANTLRInterface): Integer; virtual; abstract;
   1295     function GetChild(const T: IANTLRInterface; const I: Integer): IANTLRInterface; virtual;
   1296     procedure SetChild(const T: IANTLRInterface; const I: Integer; const Child: IANTLRInterface); virtual;
   1297     function DeleteChild(const T: IANTLRInterface; const I: Integer): IANTLRInterface; virtual;
   1298     function GetChildCount(const T: IANTLRInterface): Integer; virtual;
   1299     function GetParent(const T: IANTLRInterface): IANTLRInterface; virtual; abstract;
   1300     procedure SetParent(const T, Parent: IANTLRInterface); virtual; abstract;
   1301     function GetChildIndex(const T: IANTLRInterface): Integer; virtual; abstract;
   1302     procedure SetChildIdex(const T: IANTLRInterface; const Index: Integer); virtual; abstract;
   1303     procedure ReplaceChildren(const Parent: IANTLRInterface; const StartChildIndex,
   1304       StopChildIndex: Integer; const T: IANTLRInterface); virtual; abstract;
   1305   protected
   1306     { IBaseTreeAdaptor }
   1307     function DupTree(const T, Parent: IANTLRInterface): IANTLRInterface; overload; virtual;
   1308     function CreateToken(const TokenType: Integer; const Text: String): IToken; overload; virtual; abstract;
   1309     function CreateToken(const FromToken: IToken): IToken; overload; virtual; abstract;
   1310   public
   1311     constructor Create;
   1312   end;
   1313 
   1314   TCommonTreeAdaptor = class(TBaseTreeAdaptor, ICommonTreeAdaptor)
   1315   protected
   1316     { ITreeAdaptor }
   1317     function DupNode(const TreeNode: IANTLRInterface): IANTLRInterface; override;
   1318     function CreateNode(const Payload: IToken): IANTLRInterface; overload; override;
   1319     procedure SetTokenBoundaries(const T: IANTLRInterface; const StartToken,
   1320       StopToken: IToken); override;
   1321     function GetTokenStartIndex(const T: IANTLRInterface): Integer; override;
   1322     function GetTokenStopIndex(const T: IANTLRInterface): Integer; override;
   1323     function GetNodeText(const T: IANTLRInterface): String; override;
   1324     function GetToken(const TreeNode: IANTLRInterface): IToken; override;
   1325     function GetNodeType(const T: IANTLRInterface): Integer; override;
   1326     function GetChild(const T: IANTLRInterface; const I: Integer): IANTLRInterface; override;
   1327     function GetChildCount(const T: IANTLRInterface): Integer; override;
   1328     function GetParent(const T: IANTLRInterface): IANTLRInterface; override;
   1329     procedure SetParent(const T, Parent: IANTLRInterface); override;
   1330     function GetChildIndex(const T: IANTLRInterface): Integer; override;
   1331     procedure SetChildIdex(const T: IANTLRInterface; const Index: Integer); override;
   1332     procedure ReplaceChildren(const Parent: IANTLRInterface; const StartChildIndex,
   1333       StopChildIndex: Integer; const T: IANTLRInterface); override;
   1334   protected
   1335     { IBaseTreeAdaptor }
   1336     function CreateToken(const TokenType: Integer; const Text: String): IToken; overload; override;
   1337     function CreateToken(const FromToken: IToken): IToken; overload; override;
   1338   end;
   1339 
   1340   TCommonTreeNodeStream = class(TANTLRObject, ICommonTreeNodeStream, ITreeNodeStream)
   1341   public
   1342     const
   1343       DEFAULT_INITIAL_BUFFER_SIZE = 100;
   1344       INITIAL_CALL_STACK_SIZE = 10;
   1345   strict private
   1346     // all these navigation nodes are shared and hence they
   1347     // cannot contain any line/column info
   1348     FDown: IANTLRInterface;
   1349     FUp: IANTLRInterface;
   1350     FEof: IANTLRInterface;
   1351 
   1352     /// <summary>
   1353     /// The complete mapping from stream index to tree node. This buffer
   1354     /// includes pointers to DOWN, UP, and EOF nodes.
   1355     ///
   1356     /// It is built upon ctor invocation.  The elements are type Object
   1357     /// as we don't what the trees look like. Load upon first need of
   1358     /// the buffer so we can set token types of interest for reverseIndexing.
   1359     /// Slows us down a wee bit  to do all of the if p==-1 testing everywhere though.
   1360     /// </summary>
   1361     FNodes: IList<IANTLRInterface>;
   1362 
   1363     /// <summary>Pull nodes from which tree? </summary>
   1364     FRoot: IANTLRInterface;
   1365 
   1366     /// <summary>IF this tree (root) was created from a token stream, track it</summary>
   1367     FTokens: ITokenStream;
   1368 
   1369     /// <summary>What tree adaptor was used to build these trees</summary>
   1370     FAdaptor: ITreeAdaptor;
   1371 
   1372     /// <summary>
   1373     /// Reuse same DOWN, UP navigation nodes unless this is true
   1374     /// </summary>
   1375     FUniqueNavigationNodes: Boolean;
   1376 
   1377     /// <summary>
   1378     /// The index into the nodes list of the current node (next node
   1379     /// to consume).  If -1, nodes array not filled yet.
   1380     /// </summary>
   1381     FP: Integer;
   1382 
   1383     /// <summary>
   1384     /// Track the last mark() call result value for use in rewind().
   1385     /// </summary>
   1386     FLastMarker: Integer;
   1387 
   1388     /// <summary>
   1389     /// Stack of indexes used for push/pop calls
   1390     /// </summary>
   1391     FCalls: IStackList<Integer>;
   1392   protected
   1393     { IIntStream }
   1394     function GetSourceName: String; virtual;
   1395 
   1396     procedure Consume; virtual;
   1397     function LA(I: Integer): Integer; virtual;
   1398     function LAChar(I: Integer): Char;
   1399     function Mark: Integer; virtual;
   1400     function Index: Integer; virtual;
   1401     procedure Rewind(const Marker: Integer); overload; virtual;
   1402     procedure Rewind; overload;
   1403     procedure Release(const Marker: Integer); virtual;
   1404     procedure Seek(const Index: Integer); virtual;
   1405     function Size: Integer; virtual;
   1406   protected
   1407     { ITreeNodeStream }
   1408     function GetTreeSource: IANTLRInterface; virtual;
   1409     function GetTokenStream: ITokenStream; virtual;
   1410     function GetTreeAdaptor: ITreeAdaptor;
   1411     procedure SetHasUniqueNavigationNodes(const Value: Boolean);
   1412 
   1413     function Get(const I: Integer): IANTLRInterface;
   1414     function LT(const K: Integer): IANTLRInterface;
   1415     function ToString(const Start, Stop: IANTLRInterface): String; reintroduce; overload;
   1416     procedure ReplaceChildren(const Parent: IANTLRInterface; const StartChildIndex,
   1417       StopChildIndex: Integer; const T: IANTLRInterface);
   1418   protected
   1419     { ICommonTreeNodeStream }
   1420     function GetCurrentSymbol: IANTLRInterface; virtual;
   1421     procedure SetTokenStream(const Value: ITokenStream); virtual;
   1422     procedure SetTreeAdaptor(const Value: ITreeAdaptor);
   1423     function GetHasUniqueNavigationNodes: Boolean;
   1424 
   1425     procedure FillBuffer(const T: IANTLRInterface); overload;
   1426     function LB(const K: Integer): IANTLRInterface;
   1427     procedure Push(const Index: Integer);
   1428     function Pop: Integer;
   1429     procedure Reset;
   1430     function ToTokenString(const Start, Stop: Integer): String;
   1431   strict protected
   1432     /// <summary>
   1433     /// Walk tree with depth-first-search and fill nodes buffer.
   1434     /// Don't do DOWN, UP nodes if its a list (t is isNil).
   1435     /// </summary>
   1436     procedure FillBuffer; overload;
   1437 
   1438     /// <summary>
   1439     /// As we flatten the tree, we use UP, DOWN nodes to represent
   1440     /// the tree structure.  When debugging we need unique nodes
   1441     /// so instantiate new ones when uniqueNavigationNodes is true.
   1442     /// </summary>
   1443     procedure AddNavigationNode(const TokenType: Integer);
   1444 
   1445     /// <summary>
   1446     /// Returns the stream index for the spcified node in the range 0..n-1 or,
   1447     /// -1 if node not found.
   1448     /// </summary>
   1449     function GetNodeIndex(const Node: IANTLRInterface): Integer;
   1450   public
   1451     constructor Create; overload;
   1452     constructor Create(const ATree: IANTLRInterface); overload;
   1453     constructor Create(const AAdaptor: ITreeAdaptor;
   1454       const ATree: IANTLRInterface); overload;
   1455     constructor Create(const AAdaptor: ITreeAdaptor;
   1456       const ATree: IANTLRInterface; const AInitialBufferSize: Integer); overload;
   1457 
   1458     function ToString: String; overload; override;
   1459   end;
   1460 
   1461   TParseTree = class(TBaseTree, IParseTree)
   1462   strict private
   1463     FPayload: IANTLRInterface;
   1464     FHiddenTokens: IList<IToken>;
   1465   protected
   1466     { ITree / IBaseTree }
   1467     function GetTokenType: Integer; override;
   1468     function GetText: String; override;
   1469     function GetTokenStartIndex: Integer; override;
   1470     procedure SetTokenStartIndex(const Value: Integer); override;
   1471     function GetTokenStopIndex: Integer; override;
   1472     procedure SetTokenStopIndex(const Value: Integer); override;
   1473     function DupNode: ITree; override;
   1474   protected
   1475     { IParseTree }
   1476     function ToStringWithHiddenTokens: String;
   1477     function ToInputString: String;
   1478     procedure _ToStringLeaves(const Buf: TStringBuilder);
   1479   public
   1480     constructor Create(const ALabel: IANTLRInterface);
   1481 
   1482     function ToString: String; override;
   1483   end;
   1484 
   1485   TRewriteRuleElementStream = class abstract(TANTLRObject, IRewriteRuleElementStream)
   1486   private
   1487     /// <summary>
   1488     /// Cursor 0..n-1.  If singleElement!=null, cursor is 0 until you next(),
   1489     /// which bumps it to 1 meaning no more elements.
   1490     /// </summary>
   1491     FCursor: Integer;
   1492 
   1493     /// <summary>
   1494     /// Track single elements w/o creating a list.  Upon 2nd add, alloc list
   1495     /// </summary>
   1496     FSingleElement: IANTLRInterface;
   1497 
   1498     /// <summary>
   1499     /// The list of tokens or subtrees we are tracking
   1500     /// </summary>
   1501     FElements: IList<IANTLRInterface>;
   1502 
   1503     /// <summary>
   1504     /// Tracks whether a node or subtree has been used in a stream
   1505     /// </summary>
   1506     /// <remarks>
   1507     /// Once a node or subtree has been used in a stream, it must be dup'd
   1508     /// from then on.  Streams are reset after subrules so that the streams
   1509     /// can be reused in future subrules.  So, reset must set a dirty bit.
   1510     /// If dirty, then next() always returns a dup.
   1511     /// </remarks>
   1512     FDirty: Boolean;
   1513 
   1514     /// <summary>
   1515     /// The element or stream description; usually has name of the token or
   1516     /// rule reference that this list tracks.  Can include rulename too, but
   1517     /// the exception would track that info.
   1518     /// </summary>
   1519     FElementDescription: String;
   1520     FAdaptor: ITreeAdaptor;
   1521   protected
   1522     { IRewriteRuleElementStream }
   1523     function GetDescription: String;
   1524 
   1525     procedure Add(const El: IANTLRInterface);
   1526     procedure Reset; virtual;
   1527     function HasNext: Boolean;
   1528     function NextTree: IANTLRInterface; virtual;
   1529     function NextNode: IANTLRInterface; virtual; abstract;
   1530     function Size: Integer;
   1531   strict protected
   1532     /// <summary>
   1533     /// Do the work of getting the next element, making sure that
   1534     /// it's a tree node or subtree.
   1535     /// </summary>
   1536     /// <remarks>
   1537     /// Deal with the optimization of single-element list versus
   1538     /// list of size > 1.  Throw an exception if the stream is
   1539     /// empty or we're out of elements and size>1.
   1540     /// </remarks>
   1541     function _Next: IANTLRInterface;
   1542 
   1543     /// <summary>
   1544     /// Ensure stream emits trees; tokens must be converted to AST nodes.
   1545     /// AST nodes can be passed through unmolested.
   1546     /// </summary>
   1547     function ToTree(const El: IANTLRInterface): IANTLRInterface; virtual;
   1548   public
   1549     constructor Create(const AAdaptor: ITreeAdaptor;
   1550       const AElementDescription: String); overload;
   1551 
   1552     /// <summary>
   1553     /// Create a stream with one element
   1554     /// </summary>
   1555     constructor Create(const AAdaptor: ITreeAdaptor;
   1556       const AElementDescription: String; const AOneElement: IANTLRInterface); overload;
   1557 
   1558     /// <summary>
   1559     /// Create a stream, but feed off an existing list
   1560     /// </summary>
   1561     constructor Create(const AAdaptor: ITreeAdaptor;
   1562       const AElementDescription: String; const AElements: IList<IANTLRInterface>); overload;
   1563   end;
   1564 
   1565   TRewriteRuleNodeStream = class(TRewriteRuleElementStream, IRewriteRuleNodeStream)
   1566   protected
   1567     { IRewriteRuleElementStream }
   1568     function NextNode: IANTLRInterface; override;
   1569     function ToTree(const El: IANTLRInterface): IANTLRInterface; override;
   1570   end;
   1571 
   1572   TRewriteRuleSubtreeStream = class(TRewriteRuleElementStream, IRewriteRuleSubtreeStream)
   1573   public
   1574     type
   1575       /// <summary>
   1576       /// This delegate is used to allow the outfactoring of some common code.
   1577       /// </summary>
   1578       /// <param name="o">The to be processed object</param>
   1579       TProcessHandler = function(const O: IANTLRInterface): IANTLRInterface of Object;
   1580   strict private
   1581     /// <summary>
   1582     /// This method has the common code of two other methods, which differed in only one
   1583     /// function call.
   1584     /// </summary>
   1585     /// <param name="ph">The delegate, which has the chosen function</param>
   1586     /// <returns>The required object</returns>
   1587     function FetchObject(const PH: TProcessHandler): IANTLRInterface;
   1588     function DupNode(const O: IANTLRInterface): IANTLRInterface;
   1589 
   1590     /// <summary>
   1591     /// Tests, if the to be returned object requires duplication
   1592     /// </summary>
   1593     /// <returns><code>true</code>, if positive, <code>false</code>, if negative.</returns>
   1594     function RequiresDuplication: Boolean;
   1595 
   1596     /// <summary>
   1597     /// When constructing trees, sometimes we need to dup a token or AST
   1598     /// subtree. Dup'ing a token means just creating another AST node
   1599     /// around it. For trees, you must call the adaptor.dupTree()
   1600     /// unless the element is for a tree root; then it must be a node dup
   1601     /// </summary>
   1602     function Dup(const O: IANTLRInterface): IANTLRInterface;
   1603   protected
   1604     { IRewriteRuleElementStream }
   1605     function NextNode: IANTLRInterface; override;
   1606     function NextTree: IANTLRInterface; override;
   1607   end;
   1608 
   1609   TRewriteRuleTokenStream = class(TRewriteRuleElementStream, IRewriteRuleTokenStream)
   1610   protected
   1611     { IRewriteRuleElementStream }
   1612     function NextNode: IANTLRInterface; override;
   1613     function NextToken: IToken;
   1614     function ToTree(const El: IANTLRInterface): IANTLRInterface; override;
   1615   end;
   1616 
   1617   TTreeParser = class(TBaseRecognizer, ITreeParser)
   1618   public
   1619     const
   1620       DOWN = TToken.DOWN;
   1621       UP = TToken.UP;
   1622   strict private
   1623     FInput: ITreeNodeStream;
   1624   strict protected
   1625     property Input: ITreeNodeStream read FInput;
   1626   protected
   1627     { IBaseRecognizer }
   1628     function GetSourceName: String; override;
   1629     procedure Reset; override;
   1630     procedure MatchAny(const Input: IIntStream); override;
   1631     function GetInput: IIntStream; override;
   1632     function GetErrorHeader(const E: ERecognitionException): String; override;
   1633     function GetErrorMessage(const E: ERecognitionException;
   1634       const TokenNames: TStringArray): String; override;
   1635   protected
   1636     { ITreeParser }
   1637     function GetTreeNodeStream: ITreeNodeStream; virtual;
   1638     procedure SetTreeNodeStream(const Value: ITreeNodeStream); virtual;
   1639 
   1640     procedure TraceIn(const RuleName: String; const RuleIndex: Integer); reintroduce; overload; virtual;
   1641     procedure TraceOut(const RuleName: String; const RuleIndex: Integer); reintroduce; overload; virtual;
   1642   strict protected
   1643     function GetCurrentInputSymbol(const Input: IIntStream): IANTLRInterface; override;
   1644     function GetMissingSymbol(const Input: IIntStream;
   1645       const E: ERecognitionException; const ExpectedTokenType: Integer;
   1646       const Follow: IBitSet): IANTLRInterface; override;
   1647     procedure Mismatch(const Input: IIntStream; const TokenType: Integer;
   1648       const Follow: IBitSet); override;
   1649   public
   1650     constructor Create(const AInput: ITreeNodeStream); overload;
   1651     constructor Create(const AInput: ITreeNodeStream;
   1652       const AState: IRecognizerSharedState); overload;
   1653   end;
   1654 
   1655   TTreePatternLexer = class(TANTLRObject, ITreePatternLexer)
   1656   public
   1657     const
   1658       EOF = -1;
   1659       START = 1;
   1660       STOP = 2;
   1661       ID = 3;
   1662       ARG = 4;
   1663       PERCENT = 5;
   1664       COLON = 6;
   1665       DOT = 7;
   1666   strict private
   1667     /// <summary>The tree pattern to lex like "(A B C)"</summary>
   1668     FPattern: String;
   1669 
   1670     /// <summary>Index into input string</summary>
   1671     FP: Integer;
   1672 
   1673     /// <summary>Current char</summary>
   1674     FC: Integer;
   1675 
   1676     /// <summary>How long is the pattern in char?</summary>
   1677     FN: Integer;
   1678 
   1679     /// <summary>
   1680     /// Set when token type is ID or ARG (name mimics Java's StreamTokenizer)
   1681     /// </summary>
   1682     FSVal: TStringBuilder;
   1683 
   1684     FError: Boolean;
   1685   protected
   1686     { ITreePatternLexer }
   1687     function NextToken: Integer;
   1688     function SVal: String;
   1689   strict protected
   1690     procedure Consume;
   1691   public
   1692     constructor Create; overload;
   1693     constructor Create(const APattern: String); overload;
   1694     destructor Destroy; override;
   1695   end;
   1696 
   1697   TTreeWizard = class(TANTLRObject, ITreeWizard)
   1698   strict private
   1699     FAdaptor: ITreeAdaptor;
   1700     FTokenNameToTypeMap: IDictionary<String, Integer>;
   1701   public
   1702     type
   1703       /// <summary>
   1704       /// When using %label:TOKENNAME in a tree for parse(), we must track the label.
   1705       /// </summary>
   1706       ITreePattern = interface(ICommonTree)
   1707       ['{893C6B4E-8474-4A1E-BEAA-8B704868401B}']
   1708         { Property accessors }
   1709         function GetHasTextArg: Boolean;
   1710         procedure SetHasTextArg(const Value: Boolean);
   1711         function GetTokenLabel: String;
   1712         procedure SetTokenLabel(const Value: String);
   1713 
   1714         { Properties }
   1715         property HasTextArg: Boolean read GetHasTextArg write SetHasTextArg;
   1716         property TokenLabel: String read GetTokenLabel write SetTokenLabel;
   1717       end;
   1718 
   1719       IWildcardTreePattern = interface(ITreePattern)
   1720       ['{4778789A-5EAB-47E3-A05B-7F35CD87ECE4}']
   1721       end;
   1722     type
   1723       TVisitor = class abstract(TANTLRObject, IContextVisitor)
   1724       protected
   1725         { IContextVisitor }
   1726         procedure Visit(const T, Parent: IANTLRInterface; const ChildIndex: Integer;
   1727           const Labels: IDictionary<String, IANTLRInterface>); overload;
   1728       strict protected
   1729         procedure Visit(const T: IANTLRInterface); overload; virtual; abstract;
   1730       end;
   1731 
   1732       TTreePattern = class(TCommonTree, ITreePattern)
   1733       strict private
   1734         FLabel: String;
   1735         FHasTextArg: Boolean;
   1736       protected
   1737         { ITreePattern }
   1738         function GetHasTextArg: Boolean;
   1739         procedure SetHasTextArg(const Value: Boolean);
   1740         function GetTokenLabel: String;
   1741         procedure SetTokenLabel(const Value: String);
   1742       public
   1743         function ToString: String; override;
   1744       end;
   1745 
   1746       TWildcardTreePattern = class(TTreePattern, IWildcardTreePattern)
   1747 
   1748       end;
   1749 
   1750       /// <summary>
   1751       /// This adaptor creates TreePattern objects for use during scan()
   1752       /// </summary>
   1753       TTreePatternTreeAdaptor = class(TCommonTreeAdaptor)
   1754       protected
   1755         { ITreeAdaptor }
   1756         function CreateNode(const Payload: IToken): IANTLRInterface; overload; override;
   1757       end;
   1758   strict private
   1759     type
   1760       TRecordAllElementsVisitor = class sealed(TVisitor)
   1761       strict private
   1762         FList: IList<IANTLRInterface>;
   1763       strict protected
   1764         procedure Visit(const T: IANTLRInterface); override;
   1765       public
   1766         constructor Create(const AList: IList<IANTLRInterface>);
   1767       end;
   1768 
   1769     type
   1770       TPatternMatchingContextVisitor = class sealed(TANTLRObject, IContextVisitor)
   1771       strict private
   1772         FOwner: TTreeWizard;
   1773         FPattern: ITreePattern;
   1774         FList: IList<IANTLRInterface>;
   1775       protected
   1776         { IContextVisitor }
   1777         procedure Visit(const T, Parent: IANTLRInterface; const ChildIndex: Integer;
   1778           const Labels: IDictionary<String, IANTLRInterface>); overload;
   1779       public
   1780         constructor Create(const AOwner: TTreeWizard; const APattern: ITreePattern;
   1781           const AList: IList<IANTLRInterface>);
   1782       end;
   1783 
   1784     type
   1785       TInvokeVisitorOnPatternMatchContextVisitor = class sealed(TANTLRObject, IContextVisitor)
   1786       strict private
   1787         FOwner: TTreeWizard;
   1788         FPattern: ITreePattern;
   1789         FVisitor: IContextVisitor;
   1790         FLabels: IDictionary<String, IANTLRInterface>;
   1791       protected
   1792         { IContextVisitor }
   1793         procedure Visit(const T, Parent: IANTLRInterface; const ChildIndex: Integer;
   1794           const UnusedLabels: IDictionary<String, IANTLRInterface>); overload;
   1795       public
   1796         constructor Create(const AOwner: TTreeWizard; const APattern: ITreePattern;
   1797           const AVisitor: IContextVisitor);
   1798       end;
   1799   protected
   1800     { ITreeWizard }
   1801     function ComputeTokenTypes(const TokenNames: TStringArray): IDictionary<String, Integer>;
   1802     function GetTokenType(const TokenName: String): Integer;
   1803     function Index(const T: IANTLRInterface): IDictionary<Integer, IList<IANTLRInterface>>;
   1804     function Find(const T: IANTLRInterface; const TokenType: Integer): IList<IANTLRInterface>; overload;
   1805     function Find(const T: IANTLRInterface; const Pattern: String): IList<IANTLRInterface>; overload;
   1806     function FindFirst(const T: IANTLRInterface; const TokenType: Integer): IANTLRInterface; overload;
   1807     function FindFirst(const T: IANTLRInterface; const Pattern: String): IANTLRInterface; overload;
   1808     procedure Visit(const T: IANTLRInterface; const TokenType: Integer;
   1809       const Visitor: IContextVisitor); overload;
   1810     procedure Visit(const T: IANTLRInterface; const Pattern: String;
   1811       const Visitor: IContextVisitor); overload;
   1812     function Parse(const T: IANTLRInterface; const Pattern: String;
   1813       const Labels: IDictionary<String, IANTLRInterface>): Boolean; overload;
   1814     function Parse(const T: IANTLRInterface; const Pattern: String): Boolean; overload;
   1815     function CreateTreeOrNode(const Pattern: String): IANTLRInterface;
   1816     function Equals(const T1, T2: IANTLRInterface): Boolean; reintroduce; overload;
   1817     function Equals(const T1, T2: IANTLRInterface;
   1818       const Adaptor: ITreeAdaptor): Boolean; reintroduce; overload;
   1819   strict protected
   1820     function _Parse(const T1: IANTLRInterface; const T2: ITreePattern;
   1821       const Labels: IDictionary<String, IANTLRInterface>): Boolean;
   1822 
   1823     /// <summary>Do the work for index</summary>
   1824     procedure _Index(const T: IANTLRInterface;
   1825       const M: IDictionary<Integer, IList<IANTLRInterface>>);
   1826 
   1827     /// <summary>Do the recursive work for visit</summary>
   1828     procedure _Visit(const T, Parent: IANTLRInterface; const ChildIndex,
   1829       TokenType: Integer; const Visitor: IContextVisitor);
   1830 
   1831     class function _Equals(const T1, T2: IANTLRInterface;
   1832       const Adaptor: ITreeAdaptor): Boolean; static;
   1833   public
   1834     constructor Create(const AAdaptor: ITreeAdaptor); overload;
   1835     constructor Create(const AAdaptor: ITreeAdaptor;
   1836       const ATokenNameToTypeMap: IDictionary<String, Integer>); overload;
   1837     constructor Create(const AAdaptor: ITreeAdaptor;
   1838       const TokenNames: TStringArray); overload;
   1839     constructor Create(const TokenNames: TStringArray); overload;
   1840   end;
   1841 
   1842   TTreePatternParser = class(TANTLRObject, ITreePatternParser)
   1843   strict private
   1844     FTokenizer: ITreePatternLexer;
   1845     FTokenType: Integer;
   1846     FWizard: ITreeWizard;
   1847     FAdaptor: ITreeAdaptor;
   1848   protected
   1849     { ITreePatternParser }
   1850     function Pattern: IANTLRInterface;
   1851     function ParseTree: IANTLRInterface;
   1852     function ParseNode: IANTLRInterface;
   1853   public
   1854     constructor Create(const ATokenizer: ITreePatternLexer;
   1855       const AWizard: ITreeWizard; const AAdaptor: ITreeAdaptor);
   1856   end;
   1857 
   1858   TTreeRuleReturnScope = class(TRuleReturnScope, ITreeRuleReturnScope)
   1859   strict private
   1860     /// <summary>First node or root node of tree matched for this rule.</summary>
   1861     FStart: IANTLRInterface;
   1862   protected
   1863     { IRuleReturnScope }
   1864     function GetStart: IANTLRInterface; override;
   1865     procedure SetStart(const Value: IANTLRInterface); override;
   1866   end;
   1867 
   1868   TUnBufferedTreeNodeStream = class(TANTLRObject, IUnBufferedTreeNodeStream, ITreeNodeStream)
   1869   public
   1870     const
   1871       INITIAL_LOOKAHEAD_BUFFER_SIZE = 5;
   1872   strict protected
   1873     type
   1874       /// <summary>
   1875       /// When walking ahead with cyclic DFA or for syntactic predicates,
   1876       /// we need to record the state of the tree node stream.  This
   1877       /// class wraps up the current state of the UnBufferedTreeNodeStream.
   1878       /// Calling Mark() will push another of these on the markers stack.
   1879       /// </summary>
   1880       ITreeWalkState = interface(IANTLRInterface)
   1881       ['{506D1014-53CF-4B9D-BE0E-1666E9C22091}']
   1882         { Property accessors }
   1883         function GetCurrentChildIndex: Integer;
   1884         procedure SetCurrentChildIndex(const Value: Integer);
   1885         function GetAbsoluteNodeIndex: Integer;
   1886         procedure SetAbsoluteNodeIndex(const Value: Integer);
   1887         function GetCurrentNode: IANTLRInterface;
   1888         procedure SetCurrentNode(const Value: IANTLRInterface);
   1889         function GetPreviousNode: IANTLRInterface;
   1890         procedure SetPreviousNode(const Value: IANTLRInterface);
   1891         function GetNodeStackSize: Integer;
   1892         procedure SetNodeStackSize(const Value: Integer);
   1893         function GetIndexStackSize: integer;
   1894         procedure SetIndexStackSize(const Value: integer);
   1895         function GetLookAhead: TANTLRInterfaceArray;
   1896         procedure SetLookAhead(const Value: TANTLRInterfaceArray);
   1897 
   1898         { Properties }
   1899         property CurrentChildIndex: Integer read GetCurrentChildIndex write SetCurrentChildIndex;
   1900         property AbsoluteNodeIndex: Integer read GetAbsoluteNodeIndex write SetAbsoluteNodeIndex;
   1901         property CurrentNode: IANTLRInterface read GetCurrentNode write SetCurrentNode;
   1902         property PreviousNode: IANTLRInterface read GetPreviousNode write SetPreviousNode;
   1903         ///<summary>Record state of the nodeStack</summary>
   1904         property NodeStackSize: Integer read GetNodeStackSize write SetNodeStackSize;
   1905         ///<summary>Record state of the indexStack</summary>
   1906         property IndexStackSize: integer read GetIndexStackSize write SetIndexStackSize;
   1907         property LookAhead: TANTLRInterfaceArray read GetLookAhead write SetLookAhead;
   1908       end;
   1909 
   1910       TTreeWalkState = class(TANTLRObject, ITreeWalkState)
   1911       strict private
   1912         FCurrentChildIndex: Integer;
   1913         FAbsoluteNodeIndex: Integer;
   1914         FCurrentNode: IANTLRInterface;
   1915         FPreviousNode: IANTLRInterface;
   1916         ///<summary>Record state of the nodeStack</summary>
   1917         FNodeStackSize: Integer;
   1918         ///<summary>Record state of the indexStack</summary>
   1919         FIndexStackSize: integer;
   1920         FLookAhead: TANTLRInterfaceArray;
   1921       protected
   1922         { ITreeWalkState }
   1923         function GetCurrentChildIndex: Integer;
   1924         procedure SetCurrentChildIndex(const Value: Integer);
   1925         function GetAbsoluteNodeIndex: Integer;
   1926         procedure SetAbsoluteNodeIndex(const Value: Integer);
   1927         function GetCurrentNode: IANTLRInterface;
   1928         procedure SetCurrentNode(const Value: IANTLRInterface);
   1929         function GetPreviousNode: IANTLRInterface;
   1930         procedure SetPreviousNode(const Value: IANTLRInterface);
   1931         function GetNodeStackSize: Integer;
   1932         procedure SetNodeStackSize(const Value: Integer);
   1933         function GetIndexStackSize: integer;
   1934         procedure SetIndexStackSize(const Value: integer);
   1935         function GetLookAhead: TANTLRInterfaceArray;
   1936         procedure SetLookAhead(const Value: TANTLRInterfaceArray);
   1937       end;
   1938   strict private
   1939     /// <summary>Reuse same DOWN, UP navigation nodes unless this is true</summary>
   1940     FUniqueNavigationNodes: Boolean;
   1941 
   1942     /// <summary>Pull nodes from which tree? </summary>
   1943     FRoot: IANTLRInterface;
   1944 
   1945     /// <summary>IF this tree (root) was created from a token stream, track it.</summary>
   1946     FTokens: ITokenStream;
   1947 
   1948     /// <summary>What tree adaptor was used to build these trees</summary>
   1949     FAdaptor: ITreeAdaptor;
   1950 
   1951     /// <summary>
   1952     /// As we walk down the nodes, we must track parent nodes so we know
   1953     /// where to go after walking the last child of a node.  When visiting
   1954     /// a child, push current node and current index.
   1955     /// </summary>
   1956     FNodeStack: IStackList<IANTLRInterface>;
   1957 
   1958     /// <summary>
   1959     /// Track which child index you are visiting for each node we push.
   1960     /// TODO: pretty inefficient...use int[] when you have time
   1961     /// </summary>
   1962     FIndexStack: IStackList<Integer>;
   1963 
   1964     /// <summary>Which node are we currently visiting? </summary>
   1965     FCurrentNode: IANTLRInterface;
   1966 
   1967     /// <summary>Which node did we visit last?  Used for LT(-1) calls. </summary>
   1968     FPreviousNode: IANTLRInterface;
   1969 
   1970     /// <summary>
   1971     /// Which child are we currently visiting?  If -1 we have not visited
   1972     /// this node yet; next Consume() request will set currentIndex to 0.
   1973     /// </summary>
   1974     FCurrentChildIndex: Integer;
   1975 
   1976     /// <summary>
   1977     /// What node index did we just consume?  i=0..n-1 for n node trees.
   1978     /// IntStream.next is hence 1 + this value.  Size will be same.
   1979     /// </summary>
   1980     FAbsoluteNodeIndex: Integer;
   1981 
   1982     /// <summary>
   1983     /// Buffer tree node stream for use with LT(i).  This list grows
   1984     /// to fit new lookahead depths, but Consume() wraps like a circular
   1985     /// buffer.
   1986     /// </summary>
   1987     FLookahead: TANTLRInterfaceArray;
   1988 
   1989     /// <summary>lookahead[head] is the first symbol of lookahead, LT(1). </summary>
   1990     FHead: Integer;
   1991 
   1992     /// <summary>
   1993     /// Add new lookahead at lookahead[tail].  tail wraps around at the
   1994     /// end of the lookahead buffer so tail could be less than head.
   1995     /// </summary>
   1996     FTail: Integer;
   1997 
   1998     /// <summary>
   1999     /// Calls to Mark() may be nested so we have to track a stack of them.
   2000     /// The marker is an index into this stack. This is a List&lt;TreeWalkState&gt;.
   2001     /// Indexed from 1..markDepth. A null is kept at index 0. It is created
   2002     /// upon first call to Mark().
   2003     /// </summary>
   2004     FMarkers: IList<ITreeWalkState>;
   2005 
   2006     ///<summary>
   2007     /// tracks how deep Mark() calls are nested
   2008     /// </summary>
   2009     FMarkDepth: Integer;
   2010 
   2011     ///<summary>
   2012     /// Track the last Mark() call result value for use in Rewind().
   2013     /// </summary>
   2014     FLastMarker: Integer;
   2015 
   2016     // navigation nodes
   2017     FDown: IANTLRInterface;
   2018     FUp: IANTLRInterface;
   2019     FEof: IANTLRInterface;
   2020 
   2021     FCurrentEnumerationNode: ITree;
   2022   protected
   2023     { IIntStream }
   2024     function GetSourceName: String;
   2025 
   2026     procedure Consume; virtual;
   2027     function LA(I: Integer): Integer; virtual;
   2028     function LAChar(I: Integer): Char;
   2029     function Mark: Integer; virtual;
   2030     function Index: Integer; virtual;
   2031     procedure Rewind(const Marker: Integer); overload; virtual;
   2032     procedure Rewind; overload;
   2033     procedure Release(const Marker: Integer); virtual;
   2034     procedure Seek(const Index: Integer); virtual;
   2035     function Size: Integer; virtual;
   2036   protected
   2037     { ITreeNodeStream }
   2038     function GetTreeSource: IANTLRInterface; virtual;
   2039     function GetTokenStream: ITokenStream;
   2040     function GetTreeAdaptor: ITreeAdaptor;
   2041 
   2042     function Get(const I: Integer): IANTLRInterface; virtual;
   2043     function LT(const K: Integer): IANTLRInterface; virtual;
   2044     function ToString(const Start, Stop: IANTLRInterface): String; reintroduce; overload; virtual;
   2045     procedure ReplaceChildren(const Parent: IANTLRInterface; const StartChildIndex,
   2046       StopChildIndex: Integer; const T: IANTLRInterface);
   2047   protected
   2048     { IUnBufferedTreeNodeStream }
   2049     function GetHasUniqueNavigationNodes: Boolean;
   2050     procedure SetHasUniqueNavigationNodes(const Value: Boolean);
   2051     function GetCurrent: IANTLRInterface; virtual;
   2052     procedure SetTokenStream(const Value: ITokenStream);
   2053 
   2054     procedure Reset; virtual;
   2055 
   2056     /// <summary>
   2057     /// Navigates to the next node found during a depth-first walk of root.
   2058     /// Also, adds these nodes and DOWN/UP imaginary nodes into the lokoahead
   2059     /// buffer as a side-effect.  Normally side-effects are bad, but because
   2060     /// we can Emit many tokens for every MoveNext() call, it's pretty hard to
   2061     /// use a single return value for that.  We must add these tokens to
   2062     /// the lookahead buffer.
   2063     ///
   2064     /// This routine does *not* cause the 'Current' property to ever return the
   2065     /// DOWN/UP nodes; those are only returned by the LT() method.
   2066     ///
   2067     /// Ugh.  This mechanism is much more complicated than a recursive
   2068     /// solution, but it's the only way to provide nodes on-demand instead
   2069     /// of walking once completely through and buffering up the nodes. :(
   2070     /// </summary>
   2071     function MoveNext: Boolean; virtual;
   2072   strict protected
   2073     /// <summary>Make sure we have at least k symbols in lookahead buffer </summary>
   2074     procedure Fill(const K: Integer); virtual;
   2075     function LookaheadSize: Integer;
   2076 
   2077     /// <summary>
   2078     /// Add a node to the lookahead buffer.  Add at lookahead[tail].
   2079     /// If you tail+1 == head, then we must create a bigger buffer
   2080     /// and copy all the nodes over plus reset head, tail.  After
   2081     /// this method, LT(1) will be lookahead[0].
   2082     /// </summary>
   2083     procedure AddLookahead(const Node: IANTLRInterface); virtual;
   2084 
   2085     procedure ToStringWork(const P, Stop: IANTLRInterface;
   2086       const Buf: TStringBuilder); virtual;
   2087 
   2088     function HandleRootNode: IANTLRInterface; virtual;
   2089     function VisitChild(const Child: Integer): IANTLRInterface; virtual;
   2090 
   2091     /// <summary>
   2092     ///  Walk upwards looking for a node with more children to walk.
   2093     /// </summary>
   2094     procedure WalkBackToMostRecentNodeWithUnvisitedChildren; virtual;
   2095 
   2096     /// <summary>
   2097     /// As we flatten the tree, we use UP, DOWN nodes to represent
   2098     /// the tree structure.  When debugging we need unique nodes
   2099     /// so instantiate new ones when uniqueNavigationNodes is true.
   2100     /// </summary>
   2101     procedure AddNavigationNode(const TokenType: Integer); virtual;
   2102   public
   2103     constructor Create; overload;
   2104     constructor Create(const ATree: IANTLRInterface); overload;
   2105     constructor Create(const AAdaptor: ITreeAdaptor; const ATree: IANTLRInterface); overload;
   2106 
   2107     function ToString: String; overload; override;
   2108   end;
   2109 
   2110 { These functions return X or, if X = nil, an empty default instance }
   2111 function Def(const X: ICommonTree): ICommonTree; overload;
   2112 
   2113 implementation
   2114 
   2115 uses
   2116   Math;
   2117 
   2118 { TTree }
   2119 
   2120 class procedure TTree.Initialize;
   2121 begin
   2122   FINVALID_NODE := TCommonTree.Create(TToken.INVALID_TOKEN);
   2123 end;
   2124 
   2125 { TBaseTree }
   2126 
   2127 constructor TBaseTree.Create;
   2128 begin
   2129   inherited;
   2130 end;
   2131 
   2132 procedure TBaseTree.AddChild(const T: ITree);
   2133 var
   2134   ChildTree: IBaseTree;
   2135   C: IBaseTree;
   2136 begin
   2137   if (T = nil) then
   2138     Exit;
   2139 
   2140   ChildTree := T as IBaseTree;
   2141   if ChildTree.IsNil then // t is an empty node possibly with children
   2142   begin
   2143     if Assigned(FChildren) and SameObj(FChildren, ChildTree.Children) then
   2144       raise EInvalidOperation.Create('Attempt to add child list to itself');
   2145 
   2146     // just add all of childTree's children to this
   2147     if Assigned(ChildTree.Children) then
   2148     begin
   2149       if Assigned(FChildren) then // must copy, this has children already
   2150       begin
   2151         for C in ChildTree.Children do
   2152         begin
   2153           FChildren.Add(C);
   2154           // handle double-link stuff for each child of nil root
   2155           C.Parent := Self;
   2156           C.ChildIndex := FChildren.Count - 1;
   2157         end;
   2158       end
   2159       else begin
   2160         // no children for this but t has children; just set pointer
   2161         // call general freshener routine
   2162         FChildren := ChildTree.Children;
   2163         FreshenParentAndChildIndexes;
   2164       end;
   2165     end;
   2166   end
   2167   else
   2168   begin
   2169     // child is not nil (don't care about children)
   2170     if (FChildren = nil) then
   2171     begin
   2172       FChildren := CreateChildrenList; // create children list on demand
   2173     end;
   2174     FChildren.Add(ChildTree);
   2175     ChildTree.Parent := Self;
   2176     ChildTree.ChildIndex := FChildren.Count - 1;
   2177   end;
   2178 end;
   2179 
   2180 procedure TBaseTree.AddChildren(const Kids: IList<IBaseTree>);
   2181 var
   2182   T: IBaseTree;
   2183 begin
   2184   for T in Kids do
   2185     AddChild(T);
   2186 end;
   2187 
   2188 constructor TBaseTree.Create(const ANode: ITree);
   2189 begin
   2190   Create;
   2191   // No default implementation
   2192 end;
   2193 
   2194 function TBaseTree.CreateChildrenList: IList<IBaseTree>;
   2195 begin
   2196   Result := TList<IBaseTree>.Create;
   2197 end;
   2198 
   2199 function TBaseTree.DeleteChild(const I: Integer): IANTLRInterface;
   2200 begin
   2201   if (FChildren = nil) then
   2202     Result := nil
   2203   else
   2204   begin
   2205     Result := FChildren[I];
   2206     FChildren.Delete(I);
   2207     // walk rest and decrement their child indexes
   2208     FreshenParentAndChildIndexes(I);
   2209   end;
   2210 end;
   2211 
   2212 procedure TBaseTree.FreshenParentAndChildIndexes(const Offset: Integer);
   2213 var
   2214   N, C: Integer;
   2215   Child: ITree;
   2216 begin
   2217   N := GetChildCount;
   2218   for C := Offset to N - 1 do
   2219   begin
   2220     Child := GetChild(C);
   2221     Child.ChildIndex := C;
   2222     Child.Parent := Self;
   2223   end;
   2224 end;
   2225 
   2226 procedure TBaseTree.FreshenParentAndChildIndexes;
   2227 begin
   2228   FreshenParentAndChildIndexes(0);
   2229 end;
   2230 
   2231 function TBaseTree.GetCharPositionInLine: Integer;
   2232 begin
   2233   Result := 0;
   2234 end;
   2235 
   2236 function TBaseTree.GetChild(const I: Integer): ITree;
   2237 begin
   2238   if (FChildren = nil) or (I >= FChildren.Count) then
   2239     Result := nil
   2240   else
   2241     Result := FChildren[I];
   2242 end;
   2243 
   2244 function TBaseTree.GetChildCount: Integer;
   2245 begin
   2246   if Assigned(FChildren) then
   2247     Result := FChildren.Count
   2248   else
   2249     Result := 0;
   2250 end;
   2251 
   2252 function TBaseTree.GetChildIndex: Integer;
   2253 begin
   2254   // No default implementation
   2255   Result := 0;
   2256 end;
   2257 
   2258 function TBaseTree.GetChildren: IList<IBaseTree>;
   2259 begin
   2260   Result := FChildren;
   2261 end;
   2262 
   2263 function TBaseTree.GetIsNil: Boolean;
   2264 begin
   2265   Result := False;
   2266 end;
   2267 
   2268 function TBaseTree.GetLine: Integer;
   2269 begin
   2270   Result := 0;
   2271 end;
   2272 
   2273 function TBaseTree.GetParent: ITree;
   2274 begin
   2275   // No default implementation
   2276   Result := nil;
   2277 end;
   2278 
   2279 procedure TBaseTree.ReplaceChildren(const StartChildIndex,
   2280   StopChildIndex: Integer; const T: IANTLRInterface);
   2281 var
   2282   ReplacingHowMany, ReplacingWithHowMany, NumNewChildren, Delta, I, J: Integer;
   2283   IndexToDelete, C, ReplacedSoFar: Integer;
   2284   NewTree, Killed: IBaseTree;
   2285   NewChildren: IList<IBaseTree>;
   2286   Child: IBaseTree;
   2287 begin
   2288   if (FChildren = nil) then
   2289     raise EArgumentException.Create('indexes invalid; no children in list');
   2290   ReplacingHowMany := StopChildIndex - StartChildIndex + 1;
   2291   NewTree := T as IBaseTree;
   2292 
   2293   // normalize to a list of children to add: newChildren
   2294   if (NewTree.IsNil) then
   2295     NewChildren := NewTree.Children
   2296   else
   2297   begin
   2298     NewChildren := TList<IBaseTree>.Create;
   2299     NewChildren.Add(NewTree);
   2300   end;
   2301 
   2302   ReplacingWithHowMany := NewChildren.Count;
   2303   NumNewChildren := NewChildren.Count;
   2304   Delta := ReplacingHowMany - ReplacingWithHowMany;
   2305 
   2306   // if same number of nodes, do direct replace
   2307   if (Delta = 0) then
   2308   begin
   2309     J := 0; // index into new children
   2310     for I := StartChildIndex to StopChildIndex do
   2311     begin
   2312       Child := NewChildren[J];
   2313       FChildren[I] := Child;
   2314       Child.Parent := Self;
   2315       Child.ChildIndex := I;
   2316       Inc(J);
   2317     end;
   2318   end
   2319   else
   2320     if (Delta > 0) then
   2321     begin
   2322       // fewer new nodes than there were
   2323       // set children and then delete extra
   2324       for J := 0 to NumNewChildren - 1 do
   2325         FChildren[StartChildIndex + J] := NewChildren[J];
   2326       IndexToDelete := StartChildIndex + NumNewChildren;
   2327       for C := IndexToDelete to StopChildIndex do
   2328       begin
   2329         // delete same index, shifting everybody down each time
   2330         Killed := FChildren[IndexToDelete];
   2331         FChildren.Delete(IndexToDelete);
   2332       end;
   2333       FreshenParentAndChildIndexes(StartChildIndex);
   2334     end
   2335     else
   2336       begin
   2337         // more new nodes than were there before
   2338         // fill in as many children as we can (replacingHowMany) w/o moving data
   2339         ReplacedSoFar := 0;
   2340         while (ReplacedSoFar < ReplacingHowMany) do
   2341         begin
   2342           FChildren[StartChildIndex + ReplacedSoFar] := NewChildren[ReplacedSoFar];
   2343           Inc(ReplacedSoFar);
   2344         end;
   2345 
   2346         // replacedSoFar has correct index for children to add
   2347         while (ReplacedSoFar < ReplacingWithHowMany) do
   2348         begin
   2349           FChildren.Insert(StartChildIndex + ReplacedSoFar,NewChildren[ReplacedSoFar]);
   2350           Inc(ReplacedSoFar);
   2351         end;
   2352 
   2353         FreshenParentAndChildIndexes(StartChildIndex);
   2354       end;
   2355 end;
   2356 
   2357 procedure TBaseTree.SanityCheckParentAndChildIndexes;
   2358 begin
   2359   SanityCheckParentAndChildIndexes(nil, -1);
   2360 end;
   2361 
   2362 procedure TBaseTree.SanityCheckParentAndChildIndexes(const Parent: ITree;
   2363   const I: Integer);
   2364 var
   2365   N, C: Integer;
   2366   Child: ICommonTree;
   2367 begin
   2368   if not SameObj(Parent, GetParent) then
   2369     raise EArgumentException.Create('parents don''t match; expected '
   2370       + Parent.ToString + ' found ' + GetParent.ToString);
   2371 
   2372   if (I <> GetChildIndex) then
   2373     raise EArgumentException.Create('child indexes don''t match; expected '
   2374       + IntToStr(I) + ' found ' + IntToStr(GetChildIndex));
   2375 
   2376   N := GetChildCount;
   2377   for C := 0 to N - 1 do
   2378   begin
   2379     Child := GetChild(C) as ICommonTree;
   2380     Child.SanityCheckParentAndChildIndexes(Self, C);
   2381   end;
   2382 end;
   2383 
   2384 procedure TBaseTree.SetChild(const I: Integer; const T: ITree);
   2385 begin
   2386   if (T = nil) then
   2387     Exit;
   2388 
   2389   if T.IsNil then
   2390     raise EArgumentException.Create('Cannot set single child to a list');
   2391 
   2392   if (FChildren = nil) then
   2393   begin
   2394     FChildren := CreateChildrenList;
   2395   end;
   2396 
   2397   FChildren[I] := T as IBaseTree;
   2398   T.Parent := Self;
   2399   T.ChildIndex := I;
   2400 end;
   2401 
   2402 procedure TBaseTree.SetChildIndex(const Value: Integer);
   2403 begin
   2404   // No default implementation
   2405 end;
   2406 
   2407 procedure TBaseTree.SetParent(const Value: ITree);
   2408 begin
   2409   // No default implementation
   2410 end;
   2411 
   2412 function TBaseTree.ToStringTree: String;
   2413 var
   2414   Buf: TStringBuilder;
   2415   I: Integer;
   2416   T: IBaseTree;
   2417 begin
   2418   if (FChildren = nil) or (FChildren.Count = 0) then
   2419     Result := ToString
   2420   else
   2421   begin
   2422     Buf := TStringBuilder.Create;
   2423     try
   2424       if (not GetIsNil) then
   2425       begin
   2426         Buf.Append('(');
   2427         Buf.Append(ToString);
   2428         Buf.Append(' ');
   2429       end;
   2430 
   2431       for I := 0 to FChildren.Count - 1 do
   2432       begin
   2433         T := FChildren[I];
   2434         if (I > 0) then
   2435           Buf.Append(' ');
   2436         Buf.Append(T.ToStringTree);
   2437       end;
   2438 
   2439       if (not GetIsNil) then
   2440         Buf.Append(')');
   2441 
   2442       Result := Buf.ToString;
   2443     finally
   2444       Buf.Free;
   2445     end;
   2446   end;
   2447 end;
   2448 
   2449 { TCommonTree }
   2450 
   2451 constructor TCommonTree.Create;
   2452 begin
   2453   inherited;
   2454   FStartIndex := -1;
   2455   FStopIndex := -1;
   2456   FChildIndex := -1;
   2457 end;
   2458 
   2459 constructor TCommonTree.Create(const ANode: ICommonTree);
   2460 begin
   2461   inherited Create(ANode);
   2462   FToken := ANode.Token;
   2463   FStartIndex := ANode.StartIndex;
   2464   FStopIndex := ANode.StopIndex;
   2465   FChildIndex := -1;
   2466 end;
   2467 
   2468 constructor TCommonTree.Create(const AToken: IToken);
   2469 begin
   2470   Create;
   2471   FToken := AToken;
   2472 end;
   2473 
   2474 function TCommonTree.DupNode: ITree;
   2475 begin
   2476   Result := TCommonTree.Create(Self) as ICommonTree;
   2477 end;
   2478 
   2479 function TCommonTree.GetCharPositionInLine: Integer;
   2480 begin
   2481   if (FToken = nil) or (FToken.CharPositionInLine = -1) then
   2482   begin
   2483     if (GetChildCount > 0) then
   2484       Result := GetChild(0).CharPositionInLine
   2485     else
   2486       Result := 0;
   2487   end
   2488   else
   2489     Result := FToken.CharPositionInLine;
   2490 end;
   2491 
   2492 function TCommonTree.GetChildIndex: Integer;
   2493 begin
   2494   Result := FChildIndex;
   2495 end;
   2496 
   2497 function TCommonTree.GetIsNil: Boolean;
   2498 begin
   2499   Result := (FToken = nil);
   2500 end;
   2501 
   2502 function TCommonTree.GetLine: Integer;
   2503 begin
   2504   if (FToken = nil) or (FToken.Line = 0) then
   2505   begin
   2506     if (GetChildCount > 0) then
   2507       Result := GetChild(0).Line
   2508     else
   2509       Result := 0
   2510   end
   2511   else
   2512     Result := FToken.Line;
   2513 end;
   2514 
   2515 function TCommonTree.GetParent: ITree;
   2516 begin
   2517   Result := ITree(FParent);
   2518 end;
   2519 
   2520 function TCommonTree.GetStartIndex: Integer;
   2521 begin
   2522   Result := FStartIndex;
   2523 end;
   2524 
   2525 function TCommonTree.GetStopIndex: Integer;
   2526 begin
   2527   Result := FStopIndex;
   2528 end;
   2529 
   2530 function TCommonTree.GetText: String;
   2531 begin
   2532   if (FToken = nil) then
   2533     Result := ''
   2534   else
   2535     Result := FToken.Text;
   2536 end;
   2537 
   2538 function TCommonTree.GetToken: IToken;
   2539 begin
   2540   Result := FToken;
   2541 end;
   2542 
   2543 function TCommonTree.GetTokenStartIndex: Integer;
   2544 begin
   2545   if (FStartIndex = -1) and (FToken <> nil) then
   2546     Result := FToken.TokenIndex
   2547   else
   2548     Result := FStartIndex;
   2549 end;
   2550 
   2551 function TCommonTree.GetTokenStopIndex: Integer;
   2552 begin
   2553   if (FStopIndex = -1) and (FToken <> nil) then
   2554     Result := FToken.TokenIndex
   2555   else
   2556     Result := FStopIndex;
   2557 end;
   2558 
   2559 function TCommonTree.GetTokenType: Integer;
   2560 begin
   2561   if (FToken = nil) then
   2562     Result := TToken.INVALID_TOKEN_TYPE
   2563   else
   2564     Result := FToken.TokenType;
   2565 end;
   2566 
   2567 procedure TCommonTree.SetChildIndex(const Value: Integer);
   2568 begin
   2569   FChildIndex := Value;
   2570 end;
   2571 
   2572 procedure TCommonTree.SetParent(const Value: ITree);
   2573 begin
   2574   FParent := Pointer(Value as ICommonTree);
   2575 end;
   2576 
   2577 procedure TCommonTree.SetStartIndex(const Value: Integer);
   2578 begin
   2579   FStartIndex := Value;
   2580 end;
   2581 
   2582 procedure TCommonTree.SetStopIndex(const Value: Integer);
   2583 begin
   2584   FStopIndex := Value;
   2585 end;
   2586 
   2587 procedure TCommonTree.SetTokenStartIndex(const Value: Integer);
   2588 begin
   2589   FStartIndex := Value;
   2590 end;
   2591 
   2592 procedure TCommonTree.SetTokenStopIndex(const Value: Integer);
   2593 begin
   2594   FStopIndex := Value;
   2595 end;
   2596 
   2597 function TCommonTree.ToString: String;
   2598 begin
   2599   if (GetIsNil) then
   2600     Result := 'nil'
   2601   else
   2602     if (GetTokenType = TToken.INVALID_TOKEN_TYPE) then
   2603       Result := '<errornode>'
   2604     else
   2605       if (FToken = nil) then
   2606         Result := ''
   2607       else
   2608         Result := FToken.Text;
   2609 end;
   2610 
   2611 { TCommonErrorNode }
   2612 
   2613 constructor TCommonErrorNode.Create(const AInput: ITokenStream; const AStart,
   2614   AStop: IToken; const AException: ERecognitionException);
   2615 begin
   2616   inherited Create;
   2617   if (AStop = nil) or ((AStop.TokenIndex < AStart.TokenIndex)
   2618     and (AStop.TokenType <> TToken.EOF))
   2619   then
   2620     // sometimes resync does not consume a token (when LT(1) is
   2621     // in follow set). So, stop will be 1 to left to start. adjust.
   2622     // Also handle case where start is the first token and no token
   2623     // is consumed during recovery; LT(-1) will return null.
   2624     FStop := AStart
   2625   else
   2626     FStop := AStop;
   2627   FInput := AInput;
   2628   FStart := AStart;
   2629   FTrappedException := AException;
   2630 end;
   2631 
   2632 function TCommonErrorNode.GetIsNil: Boolean;
   2633 begin
   2634   Result := False;
   2635 end;
   2636 
   2637 function TCommonErrorNode.GetText: String;
   2638 var
   2639   I, J: Integer;
   2640 begin
   2641   I := FStart.TokenIndex;
   2642   if (FStop.TokenType = TToken.EOF) then
   2643     J := (FInput as ITokenStream).Size
   2644   else
   2645     J := FStop.TokenIndex;
   2646   Result := (FInput as ITokenStream).ToString(I, J);
   2647 end;
   2648 
   2649 function TCommonErrorNode.GetTokenType: Integer;
   2650 begin
   2651   Result := TToken.INVALID_TOKEN_TYPE;
   2652 end;
   2653 
   2654 function TCommonErrorNode.ToString: String;
   2655 begin
   2656   if (FTrappedException is EMissingTokenException) then
   2657     Result := '<missing type: '
   2658       + IntToStr(EMissingTokenException(FTrappedException).MissingType) + '>'
   2659   else
   2660     if (FTrappedException is EUnwantedTokenException) then
   2661       Result := '<extraneous: '
   2662         + EUnwantedTokenException(FTrappedException).UnexpectedToken.ToString
   2663         + ', resync=' + GetText + '>'
   2664     else
   2665       if (FTrappedException is EMismatchedTokenException) then
   2666         Result := '<mismatched token: ' + FTrappedException.Token.ToString
   2667           + ', resync=' + GetText + '>'
   2668       else
   2669         if (FTrappedException is ENoViableAltException) then
   2670           Result := '<unexpected: ' + FTrappedException.Token.ToString
   2671             + ', resync=' + GetText + '>'
   2672         else
   2673           Result := '<error: ' + GetText + '>';
   2674 end;
   2675 
   2676 { TBaseTreeAdaptor }
   2677 
   2678 procedure TBaseTreeAdaptor.AddChild(const T, Child: IANTLRInterface);
   2679 begin
   2680   if Assigned(T) and Assigned(Child) then
   2681     (T as ITree).AddChild(Child as ITree);
   2682 end;
   2683 
   2684 function TBaseTreeAdaptor.BecomeRoot(const NewRoot,
   2685   OldRoot: IANTLRInterface): IANTLRInterface;
   2686 var
   2687   NewRootTree, OldRootTree: ITree;
   2688   NC: Integer;
   2689 begin
   2690   NewRootTree := NewRoot as ITree;
   2691   OldRootTree := OldRoot as ITree;
   2692   if (OldRoot = nil) then
   2693     Result := NewRoot
   2694   else
   2695   begin
   2696     // handle ^(nil real-node)
   2697     if (NewRootTree.IsNil) then
   2698     begin
   2699       NC := NewRootTree.ChildCount;
   2700       if (NC = 1) then
   2701         NewRootTree := NewRootTree.GetChild(0)
   2702       else
   2703         if (NC > 1) then
   2704           raise Exception.Create('more than one node as root');
   2705     end;
   2706     // add oldRoot to newRoot; AddChild takes care of case where oldRoot
   2707     // is a flat list (i.e., nil-rooted tree).  All children of oldRoot
   2708     // are added to newRoot.
   2709     NewRootTree.AddChild(OldRootTree);
   2710     Result := NewRootTree;
   2711   end;
   2712 end;
   2713 
   2714 function TBaseTreeAdaptor.BecomeRoot(const NewRoot: IToken;
   2715   const OldRoot: IANTLRInterface): IANTLRInterface;
   2716 begin
   2717   Result := BecomeRoot(CreateNode(NewRoot), OldRoot);
   2718 end;
   2719 
   2720 function TBaseTreeAdaptor.CreateNode(const TokenType: Integer;
   2721   const FromToken: IToken): IANTLRInterface;
   2722 var
   2723   Token: IToken;
   2724 begin
   2725   Token := CreateToken(FromToken);
   2726   Token.TokenType := TokenType;
   2727   Result := CreateNode(Token);
   2728 end;
   2729 
   2730 function TBaseTreeAdaptor.CreateNode(const TokenType: Integer;
   2731   const Text: String): IANTLRInterface;
   2732 var
   2733   Token: IToken;
   2734 begin
   2735   Token := CreateToken(TokenType, Text);
   2736   Result := CreateNode(Token);
   2737 end;
   2738 
   2739 function TBaseTreeAdaptor.CreateNode(const TokenType: Integer;
   2740   const FromToken: IToken; const Text: String): IANTLRInterface;
   2741 var
   2742   Token: IToken;
   2743 begin
   2744   Token := CreateToken(FromToken);
   2745   Token.TokenType := TokenType;
   2746   Token.Text := Text;
   2747   Result := CreateNode(Token);
   2748 end;
   2749 
   2750 constructor TBaseTreeAdaptor.Create;
   2751 begin
   2752   inherited Create;
   2753   FUniqueNodeID := 1;
   2754 end;
   2755 
   2756 function TBaseTreeAdaptor.DeleteChild(const T: IANTLRInterface;
   2757   const I: Integer): IANTLRInterface;
   2758 begin
   2759   Result := (T as ITree).DeleteChild(I);
   2760 end;
   2761 
   2762 function TBaseTreeAdaptor.DupTree(const T,
   2763   Parent: IANTLRInterface): IANTLRInterface;
   2764 var
   2765   I, N: Integer;
   2766   Child, NewSubTree: IANTLRInterface;
   2767 begin
   2768   if (T = nil) then
   2769     Result := nil
   2770   else
   2771   begin
   2772     Result := DupNode(T);
   2773     // ensure new subtree root has parent/child index set
   2774     SetChildIdex(Result, GetChildIndex(T));
   2775     SetParent(Result, Parent);
   2776     N := GetChildCount(T);
   2777     for I := 0 to N - 1 do
   2778     begin
   2779       Child := GetChild(T, I);
   2780       NewSubTree := DupTree(Child, T);
   2781       AddChild(Result, NewSubTree);
   2782     end;
   2783   end;
   2784 end;
   2785 
   2786 function TBaseTreeAdaptor.DupTree(const Tree: IANTLRInterface): IANTLRInterface;
   2787 begin
   2788   Result := DupTree(Tree, nil);
   2789 end;
   2790 
   2791 function TBaseTreeAdaptor.ErrorNode(const Input: ITokenStream; const Start,
   2792   Stop: IToken; const E: ERecognitionException): IANTLRInterface;
   2793 begin
   2794   Result := TCommonErrorNode.Create(Input, Start, Stop, E);
   2795 end;
   2796 
   2797 function TBaseTreeAdaptor.GetChild(const T: IANTLRInterface;
   2798   const I: Integer): IANTLRInterface;
   2799 begin
   2800   Result := (T as ITree).GetChild(I);
   2801 end;
   2802 
   2803 function TBaseTreeAdaptor.GetChildCount(const T: IANTLRInterface): Integer;
   2804 begin
   2805   Result := (T as ITree).ChildCount;
   2806 end;
   2807 
   2808 function TBaseTreeAdaptor.GetNilNode: IANTLRInterface;
   2809 begin
   2810   Result := CreateNode(nil);
   2811 end;
   2812 
   2813 function TBaseTreeAdaptor.GetNodeText(const T: IANTLRInterface): String;
   2814 begin
   2815   Result := (T as ITree).Text;
   2816 end;
   2817 
   2818 function TBaseTreeAdaptor.GetNodeType(const T: IANTLRInterface): Integer;
   2819 begin
   2820   Result := 0;
   2821 end;
   2822 
   2823 function TBaseTreeAdaptor.GetUniqueID(const Node: IANTLRInterface): Integer;
   2824 begin
   2825   if (FTreeToUniqueIDMap = nil) then
   2826     FTreeToUniqueIDMap := TDictionary<IANTLRInterface, Integer>.Create;
   2827   if (not FTreeToUniqueIDMap.TryGetValue(Node, Result)) then
   2828   begin
   2829     Result := FUniqueNodeID;
   2830     FTreeToUniqueIDMap[Node] := Result;
   2831     Inc(FUniqueNodeID);
   2832   end;
   2833 end;
   2834 
   2835 function TBaseTreeAdaptor.IsNil(const Tree: IANTLRInterface): Boolean;
   2836 begin
   2837   Result := (Tree as ITree).IsNil;
   2838 end;
   2839 
   2840 function TBaseTreeAdaptor.RulePostProcessing(
   2841   const Root: IANTLRInterface): IANTLRInterface;
   2842 var
   2843   R: ITree;
   2844 begin
   2845   R := Root as ITree;
   2846   if Assigned(R) and (R.IsNil) then
   2847   begin
   2848     if (R.ChildCount = 0) then
   2849       R := nil
   2850     else
   2851       if (R.ChildCount = 1) then
   2852       begin
   2853         R := R.GetChild(0);
   2854         // whoever invokes rule will set parent and child index
   2855         R.Parent := nil;
   2856         R.ChildIndex := -1;
   2857       end;
   2858   end;
   2859   Result := R;
   2860 end;
   2861 
   2862 procedure TBaseTreeAdaptor.SetChild(const T: IANTLRInterface; const I: Integer;
   2863   const Child: IANTLRInterface);
   2864 begin
   2865   (T as ITree).SetChild(I, Child as ITree);
   2866 end;
   2867 
   2868 procedure TBaseTreeAdaptor.SetNodeText(const T: IANTLRInterface;
   2869   const Text: String);
   2870 begin
   2871   raise EInvalidOperation.Create('don''t know enough about Tree node');
   2872 end;
   2873 
   2874 procedure TBaseTreeAdaptor.SetNodeType(const T: IANTLRInterface;
   2875   const NodeType: Integer);
   2876 begin
   2877   raise EInvalidOperation.Create('don''t know enough about Tree node');
   2878 end;
   2879 
   2880 { TCommonTreeAdaptor }
   2881 
   2882 function TCommonTreeAdaptor.CreateNode(const Payload: IToken): IANTLRInterface;
   2883 begin
   2884   Result := TCommonTree.Create(Payload);
   2885 end;
   2886 
   2887 function TCommonTreeAdaptor.CreateToken(const TokenType: Integer;
   2888   const Text: String): IToken;
   2889 begin
   2890   Result := TCommonToken.Create(TokenType, Text);
   2891 end;
   2892 
   2893 function TCommonTreeAdaptor.CreateToken(const FromToken: IToken): IToken;
   2894 begin
   2895   Result := TCommonToken.Create(FromToken);
   2896 end;
   2897 
   2898 function TCommonTreeAdaptor.DupNode(
   2899   const TreeNode: IANTLRInterface): IANTLRInterface;
   2900 begin
   2901   if (TreeNode = nil) then
   2902     Result := nil
   2903   else
   2904     Result := (TreeNode as ITree).DupNode;
   2905 end;
   2906 
   2907 function TCommonTreeAdaptor.GetChild(const T: IANTLRInterface;
   2908   const I: Integer): IANTLRInterface;
   2909 begin
   2910   if (T = nil) then
   2911     Result := nil
   2912   else
   2913     Result := (T as ITree).GetChild(I);
   2914 end;
   2915 
   2916 function TCommonTreeAdaptor.GetChildCount(const T: IANTLRInterface): Integer;
   2917 begin
   2918   if (T = nil) then
   2919     Result := 0
   2920   else
   2921     Result := (T as ITree).ChildCount;
   2922 end;
   2923 
   2924 function TCommonTreeAdaptor.GetChildIndex(const T: IANTLRInterface): Integer;
   2925 begin
   2926   Result := (T as ITree).ChildIndex;
   2927 end;
   2928 
   2929 function TCommonTreeAdaptor.GetNodeText(const T: IANTLRInterface): String;
   2930 begin
   2931   if (T = nil) then
   2932     Result := ''
   2933   else
   2934     Result := (T as ITree).Text;
   2935 end;
   2936 
   2937 function TCommonTreeAdaptor.GetNodeType(const T: IANTLRInterface): Integer;
   2938 begin
   2939   if (T = nil) then
   2940     Result := TToken.INVALID_TOKEN_TYPE
   2941   else
   2942     Result := (T as ITree).TokenType;
   2943 end;
   2944 
   2945 function TCommonTreeAdaptor.GetParent(
   2946   const T: IANTLRInterface): IANTLRInterface;
   2947 begin
   2948   Result := (T as ITree).Parent;
   2949 end;
   2950 
   2951 function TCommonTreeAdaptor.GetToken(const TreeNode: IANTLRInterface): IToken;
   2952 var
   2953   CommonTree: ICommonTree;
   2954 begin
   2955   if Supports(TreeNode, ICommonTree, CommonTree) then
   2956     Result := CommonTree.Token
   2957   else
   2958     Result := nil; // no idea what to do
   2959 end;
   2960 
   2961 function TCommonTreeAdaptor.GetTokenStartIndex(
   2962   const T: IANTLRInterface): Integer;
   2963 begin
   2964   if (T = nil) then
   2965     Result := -1
   2966   else
   2967     Result := (T as ITree).TokenStartIndex;
   2968 end;
   2969 
   2970 function TCommonTreeAdaptor.GetTokenStopIndex(
   2971   const T: IANTLRInterface): Integer;
   2972 begin
   2973   if (T = nil) then
   2974     Result := -1
   2975   else
   2976     Result := (T as ITree).TokenStopIndex;
   2977 end;
   2978 
   2979 procedure TCommonTreeAdaptor.ReplaceChildren(const Parent: IANTLRInterface;
   2980   const StartChildIndex, StopChildIndex: Integer; const T: IANTLRInterface);
   2981 begin
   2982   if Assigned(Parent) then
   2983     (Parent as ITree).ReplaceChildren(StartChildIndex, StopChildIndex, T);
   2984 end;
   2985 
   2986 procedure TCommonTreeAdaptor.SetChildIdex(const T: IANTLRInterface;
   2987   const Index: Integer);
   2988 begin
   2989   (T as ITree).ChildIndex := Index;
   2990 end;
   2991 
   2992 procedure TCommonTreeAdaptor.SetParent(const T, Parent: IANTLRInterface);
   2993 begin
   2994   (T as ITree).Parent := (Parent as ITree);
   2995 end;
   2996 
   2997 procedure TCommonTreeAdaptor.SetTokenBoundaries(const T: IANTLRInterface;
   2998   const StartToken, StopToken: IToken);
   2999 var
   3000   Start, Stop: Integer;
   3001 begin
   3002   if Assigned(T) then
   3003   begin
   3004     if Assigned(StartToken) then
   3005       Start := StartToken.TokenIndex
   3006     else
   3007       Start := 0;
   3008 
   3009     if Assigned(StopToken) then
   3010       Stop := StopToken.TokenIndex
   3011     else
   3012       Stop := 0;
   3013 
   3014     (T as ITree).TokenStartIndex := Start;
   3015     (T as ITree).TokenStopIndex := Stop;
   3016   end;
   3017 end;
   3018 
   3019 { TCommonTreeNodeStream }
   3020 
   3021 procedure TCommonTreeNodeStream.AddNavigationNode(const TokenType: Integer);
   3022 var
   3023   NavNode: IANTLRInterface;
   3024 begin
   3025   if (TokenType = TToken.DOWN) then
   3026   begin
   3027     if (GetHasUniqueNavigationNodes) then
   3028       NavNode := FAdaptor.CreateNode(TToken.DOWN, 'DOWN')
   3029     else
   3030       NavNode := FDown;
   3031   end
   3032   else
   3033   begin
   3034     if (GetHasUniqueNavigationNodes) then
   3035       NavNode := FAdaptor.CreateNode(TToken.UP, 'UP')
   3036     else
   3037       NavNode := FUp;
   3038   end;
   3039   FNodes.Add(NavNode);
   3040 end;
   3041 
   3042 procedure TCommonTreeNodeStream.Consume;
   3043 begin
   3044   if (FP = -1) then
   3045     FillBuffer;
   3046   Inc(FP);
   3047 end;
   3048 
   3049 constructor TCommonTreeNodeStream.Create;
   3050 begin
   3051   inherited;
   3052   FP := -1;
   3053 end;
   3054 
   3055 constructor TCommonTreeNodeStream.Create(const ATree: IANTLRInterface);
   3056 begin
   3057   Create(TCommonTreeAdaptor.Create, ATree);
   3058 end;
   3059 
   3060 constructor TCommonTreeNodeStream.Create(const AAdaptor: ITreeAdaptor;
   3061   const ATree: IANTLRInterface);
   3062 begin
   3063   Create(AAdaptor, ATree, DEFAULT_INITIAL_BUFFER_SIZE);
   3064 end;
   3065 
   3066 constructor TCommonTreeNodeStream.Create(const AAdaptor: ITreeAdaptor;
   3067   const ATree: IANTLRInterface; const AInitialBufferSize: Integer);
   3068 begin
   3069   Create;
   3070   FRoot := ATree;
   3071   FAdaptor := AAdaptor;
   3072   FNodes := TList<IANTLRInterface>.Create;
   3073   FNodes.Capacity := AInitialBufferSize;
   3074   FDown := FAdaptor.CreateNode(TToken.DOWN, 'DOWN');
   3075   FUp := FAdaptor.CreateNode(TToken.UP, 'UP');
   3076   FEof := FAdaptor.CreateNode(TToken.EOF, 'EOF');
   3077 end;
   3078 
   3079 procedure TCommonTreeNodeStream.FillBuffer;
   3080 begin
   3081   FillBuffer(FRoot);
   3082   FP := 0; // buffer of nodes intialized now
   3083 end;
   3084 
   3085 procedure TCommonTreeNodeStream.FillBuffer(const T: IANTLRInterface);
   3086 var
   3087   IsNil: Boolean;
   3088   C, N: Integer;
   3089 begin
   3090   IsNil := FAdaptor.IsNil(T);
   3091   if (not IsNil) then
   3092     FNodes.Add(T); // add this node
   3093 
   3094   // add DOWN node if t has children
   3095   N := FAdaptor.GetChildCount(T);
   3096   if (not IsNil) and (N > 0) then
   3097     AddNavigationNode(TToken.DOWN);
   3098 
   3099   // and now add all its children
   3100   for C := 0 to N - 1 do
   3101     FillBuffer(FAdaptor.GetChild(T, C));
   3102 
   3103   // add UP node if t has children
   3104   if (not IsNil) and (N > 0) then
   3105     AddNavigationNode(TToken.UP);
   3106 end;
   3107 
   3108 function TCommonTreeNodeStream.Get(const I: Integer): IANTLRInterface;
   3109 begin
   3110   if (FP = -1) then
   3111     FillBuffer;
   3112   Result := FNodes[I];
   3113 end;
   3114 
   3115 function TCommonTreeNodeStream.GetCurrentSymbol: IANTLRInterface;
   3116 begin
   3117   Result := LT(1);
   3118 end;
   3119 
   3120 function TCommonTreeNodeStream.GetHasUniqueNavigationNodes: Boolean;
   3121 begin
   3122   Result := FUniqueNavigationNodes;
   3123 end;
   3124 
   3125 function TCommonTreeNodeStream.GetNodeIndex(
   3126   const Node: IANTLRInterface): Integer;
   3127 var
   3128   T: IANTLRInterface;
   3129 begin
   3130   if (FP = -1) then
   3131     FillBuffer;
   3132   for Result := 0 to FNodes.Count - 1 do
   3133   begin
   3134     T := FNodes[Result];
   3135     if (T = Node) then
   3136       Exit;
   3137   end;
   3138   Result := -1;
   3139 end;
   3140 
   3141 function TCommonTreeNodeStream.GetSourceName: String;
   3142 begin
   3143   Result := GetTokenStream.SourceName;
   3144 end;
   3145 
   3146 function TCommonTreeNodeStream.GetTokenStream: ITokenStream;
   3147 begin
   3148   Result := FTokens;
   3149 end;
   3150 
   3151 function TCommonTreeNodeStream.GetTreeAdaptor: ITreeAdaptor;
   3152 begin
   3153   Result := FAdaptor;
   3154 end;
   3155 
   3156 function TCommonTreeNodeStream.GetTreeSource: IANTLRInterface;
   3157 begin
   3158   Result := FRoot;
   3159 end;
   3160 
   3161 function TCommonTreeNodeStream.Index: Integer;
   3162 begin
   3163   Result := FP;
   3164 end;
   3165 
   3166 function TCommonTreeNodeStream.LA(I: Integer): Integer;
   3167 begin
   3168   Result := FAdaptor.GetNodeType(LT(I));
   3169 end;
   3170 
   3171 function TCommonTreeNodeStream.LAChar(I: Integer): Char;
   3172 begin
   3173   Result := Char(LA(I));
   3174 end;
   3175 
   3176 function TCommonTreeNodeStream.LB(const K: Integer): IANTLRInterface;
   3177 begin
   3178   if (K = 0) then
   3179     Result := nil
   3180   else
   3181     if ((FP - K) < 0) then
   3182       Result := nil
   3183     else
   3184       Result := FNodes[FP - K];
   3185 end;
   3186 
   3187 function TCommonTreeNodeStream.LT(const K: Integer): IANTLRInterface;
   3188 begin
   3189   if (FP = -1) then
   3190     FillBuffer;
   3191   if (K = 0) then
   3192     Result := nil
   3193   else
   3194     if (K < 0) then
   3195       Result := LB(-K)
   3196     else
   3197       if ((FP + K - 1) >= FNodes.Count) then
   3198         Result := FEof
   3199       else
   3200         Result := FNodes[FP + K - 1];
   3201 end;
   3202 
   3203 function TCommonTreeNodeStream.Mark: Integer;
   3204 begin
   3205   if (FP = -1) then
   3206     FillBuffer;
   3207   FLastMarker := Index;
   3208   Result := FLastMarker;
   3209 end;
   3210 
   3211 function TCommonTreeNodeStream.Pop: Integer;
   3212 begin
   3213   Result := FCalls.Pop;
   3214   Seek(Result);
   3215 end;
   3216 
   3217 procedure TCommonTreeNodeStream.Push(const Index: Integer);
   3218 begin
   3219   if (FCalls = nil) then
   3220     FCalls := TStackList<Integer>.Create;
   3221   FCalls.Push(FP); // save current index
   3222   Seek(Index);
   3223 end;
   3224 
   3225 procedure TCommonTreeNodeStream.Release(const Marker: Integer);
   3226 begin
   3227   // no resources to release
   3228 end;
   3229 
   3230 procedure TCommonTreeNodeStream.ReplaceChildren(const Parent: IANTLRInterface;
   3231   const StartChildIndex, StopChildIndex: Integer; const T: IANTLRInterface);
   3232 begin
   3233   if Assigned(Parent) then
   3234     FAdaptor.ReplaceChildren(Parent, StartChildIndex, StopChildIndex, T);
   3235 end;
   3236 
   3237 procedure TCommonTreeNodeStream.Reset;
   3238 begin
   3239   FP := -1;
   3240   FLastMarker := 0;
   3241   if Assigned(FCalls) then
   3242     FCalls.Clear;
   3243 end;
   3244 
   3245 procedure TCommonTreeNodeStream.Rewind(const Marker: Integer);
   3246 begin
   3247   Seek(Marker);
   3248 end;
   3249 
   3250 procedure TCommonTreeNodeStream.Rewind;
   3251 begin
   3252   Seek(FLastMarker);
   3253 end;
   3254 
   3255 procedure TCommonTreeNodeStream.Seek(const Index: Integer);
   3256 begin
   3257   if (FP = -1) then
   3258     FillBuffer;
   3259   FP := Index;
   3260 end;
   3261 
   3262 procedure TCommonTreeNodeStream.SetHasUniqueNavigationNodes(
   3263   const Value: Boolean);
   3264 begin
   3265   FUniqueNavigationNodes := Value;
   3266 end;
   3267 
   3268 procedure TCommonTreeNodeStream.SetTokenStream(const Value: ITokenStream);
   3269 begin
   3270   FTokens := Value;
   3271 end;
   3272 
   3273 procedure TCommonTreeNodeStream.SetTreeAdaptor(const Value: ITreeAdaptor);
   3274 begin
   3275   FAdaptor := Value;
   3276 end;
   3277 
   3278 function TCommonTreeNodeStream.Size: Integer;
   3279 begin
   3280   if (FP = -1) then
   3281     FillBuffer;
   3282   Result := FNodes.Count;
   3283 end;
   3284 
   3285 function TCommonTreeNodeStream.ToString(const Start,
   3286   Stop: IANTLRInterface): String;
   3287 var
   3288   CommonTree: ICommonTree;
   3289   I, BeginTokenIndex, EndTokenIndex: Integer;
   3290   T: IANTLRInterface;
   3291   Buf: TStringBuilder;
   3292   Text: String;
   3293 begin
   3294   WriteLn('ToString');
   3295   if (Start = nil) or (Stop = nil) then
   3296     Exit;
   3297   if (FP = -1) then
   3298     FillBuffer;
   3299 
   3300   if Supports(Start, ICommonTree, CommonTree) then
   3301     Write('ToString: ' + CommonTree.Token.ToString + ', ')
   3302   else
   3303     WriteLn(Start.ToString);
   3304 
   3305   if Supports(Stop, ICommonTree, CommonTree) then
   3306     WriteLn(CommonTree.Token.ToString)
   3307   else
   3308     WriteLn(Stop.ToString);
   3309 
   3310   // if we have the token stream, use that to dump text in order
   3311   if Assigned(FTokens) then
   3312   begin
   3313     BeginTokenIndex := FAdaptor.GetTokenStartIndex(Start);
   3314     EndTokenIndex := FAdaptor.GetTokenStartIndex(Stop);
   3315     // if it's a tree, use start/stop index from start node
   3316     // else use token range from start/stop nodes
   3317     if (FAdaptor.GetNodeType(Stop) = TToken.UP) then
   3318       EndTokenIndex := FAdaptor.GetTokenStopIndex(Start)
   3319     else
   3320       if (FAdaptor.GetNodeType(Stop) = TToken.EOF) then
   3321         EndTokenIndex := Size - 2; // don't use EOF
   3322     Result := FTokens.ToString(BeginTokenIndex, EndTokenIndex);
   3323     Exit;
   3324   end;
   3325 
   3326   // walk nodes looking for start
   3327   T := nil;
   3328   I := 0;
   3329   while (I < FNodes.Count) do
   3330   begin
   3331     T := FNodes[I];
   3332     if SameObj(T, Start) then
   3333       Break;
   3334     Inc(I);
   3335   end;
   3336 
   3337   // now walk until we see stop, filling string buffer with text
   3338   Buf := TStringBuilder.Create;
   3339   try
   3340     T := FNodes[I];
   3341     while (T <> Stop) do
   3342     begin
   3343       Text := FAdaptor.GetNodeText(T);
   3344       if (Text = '') then
   3345         Text := ' ' + IntToStr(FAdaptor.GetNodeType(T));
   3346       Buf.Append(Text);
   3347       Inc(I);
   3348       T := FNodes[I];
   3349     end;
   3350 
   3351     // include stop node too
   3352     Text := FAdaptor.GetNodeText(Stop);
   3353     if (Text = '') then
   3354       Text := ' ' + IntToStr(FAdaptor.GetNodeType(Stop));
   3355     Buf.Append(Text);
   3356     Result := Buf.ToString;
   3357   finally
   3358     Buf.Free;
   3359   end;
   3360 end;
   3361 
   3362 function TCommonTreeNodeStream.ToString: String;
   3363 var
   3364   Buf: TStringBuilder;
   3365   T: IANTLRInterface;
   3366 begin
   3367   if (FP = -1) then
   3368     FillBuffer;
   3369   Buf := TStringBuilder.Create;
   3370   try
   3371     for T in FNodes do
   3372     begin
   3373       Buf.Append(' ');
   3374       Buf.Append(FAdaptor.GetNodeType(T));
   3375     end;
   3376     Result := Buf.ToString;
   3377   finally
   3378     Buf.Free;
   3379   end;
   3380 end;
   3381 
   3382 function TCommonTreeNodeStream.ToTokenString(const Start,
   3383   Stop: Integer): String;
   3384 var
   3385   I: Integer;
   3386   T: IANTLRInterface;
   3387   Buf: TStringBuilder;
   3388 begin
   3389   if (FP = -1) then
   3390     FillBuffer;
   3391   Buf := TStringBuilder.Create;
   3392   try
   3393     for I := Stop to Min(FNodes.Count - 1, Stop) do
   3394     begin
   3395       T := FNodes[I];
   3396       Buf.Append(' ');
   3397       Buf.Append(FAdaptor.GetToken(T).ToString);
   3398     end;
   3399 
   3400     Result := Buf.ToString;
   3401   finally
   3402     Buf.Free;
   3403   end;
   3404 end;
   3405 
   3406 { TParseTree }
   3407 
   3408 constructor TParseTree.Create(const ALabel: IANTLRInterface);
   3409 begin
   3410   inherited Create;
   3411   FPayload := ALabel;
   3412 end;
   3413 
   3414 function TParseTree.DupNode: ITree;
   3415 begin
   3416   Result := nil;
   3417 end;
   3418 
   3419 function TParseTree.GetText: String;
   3420 begin
   3421   Result := ToString;
   3422 end;
   3423 
   3424 function TParseTree.GetTokenStartIndex: Integer;
   3425 begin
   3426   Result := 0;
   3427 end;
   3428 
   3429 function TParseTree.GetTokenStopIndex: Integer;
   3430 begin
   3431   Result := 0;
   3432 end;
   3433 
   3434 function TParseTree.GetTokenType: Integer;
   3435 begin
   3436   Result := 0;
   3437 end;
   3438 
   3439 procedure TParseTree.SetTokenStartIndex(const Value: Integer);
   3440 begin
   3441   // No implementation
   3442 end;
   3443 
   3444 procedure TParseTree.SetTokenStopIndex(const Value: Integer);
   3445 begin
   3446   // No implementation
   3447 end;
   3448 
   3449 function TParseTree.ToInputString: String;
   3450 var
   3451   Buf: TStringBuilder;
   3452 begin
   3453   Buf := TStringBuilder.Create;
   3454   try
   3455     _ToStringLeaves(Buf);
   3456     Result := Buf.ToString;
   3457   finally
   3458     Buf.Free;
   3459   end;
   3460 end;
   3461 
   3462 function TParseTree.ToString: String;
   3463 var
   3464   T: IToken;
   3465 begin
   3466   if Supports(FPayload, IToken, T) then
   3467   begin
   3468     if (T.TokenType = TToken.EOF) then
   3469       Result := '<EOF>'
   3470     else
   3471       Result := T.Text;
   3472   end
   3473   else
   3474     Result := FPayload.ToString;
   3475 end;
   3476 
   3477 function TParseTree.ToStringWithHiddenTokens: String;
   3478 var
   3479   Buf: TStringBuilder;
   3480   Hidden: IToken;
   3481   NodeText: String;
   3482 begin
   3483   Buf := TStringBuilder.Create;
   3484   try
   3485     if Assigned(FHiddenTokens) then
   3486     begin
   3487       for Hidden in FHiddenTokens do
   3488         Buf.Append(Hidden.Text);
   3489     end;
   3490     NodeText := ToString;
   3491     if (NodeText <> '<EOF>') then
   3492       Buf.Append(NodeText);
   3493     Result := Buf.ToString;
   3494   finally
   3495     Buf.Free;
   3496   end;
   3497 end;
   3498 
   3499 procedure TParseTree._ToStringLeaves(const Buf: TStringBuilder);
   3500 var
   3501   T: IBaseTree;
   3502 begin
   3503   if Supports(FPayload, IToken) then
   3504   begin
   3505     // leaf node token?
   3506     Buf.Append(ToStringWithHiddenTokens);
   3507     Exit;
   3508   end;
   3509   if Assigned(FChildren) then
   3510     for T in FChildren do
   3511       (T as IParseTree)._ToStringLeaves(Buf);
   3512 end;
   3513 
   3514 { ERewriteCardinalityException }
   3515 
   3516 constructor ERewriteCardinalityException.Create(
   3517   const AElementDescription: String);
   3518 begin
   3519   inherited Create(AElementDescription);
   3520   FElementDescription := AElementDescription;
   3521 end;
   3522 
   3523 { TRewriteRuleElementStream }
   3524 
   3525 procedure TRewriteRuleElementStream.Add(const El: IANTLRInterface);
   3526 begin
   3527   if (El = nil) then
   3528     Exit;
   3529   if Assigned(FElements) then
   3530      // if in list, just add
   3531     FElements.Add(El)
   3532   else
   3533     if (FSingleElement = nil) then
   3534       // no elements yet, track w/o list
   3535       FSingleElement := El
   3536     else
   3537     begin
   3538       // adding 2nd element, move to list
   3539       FElements := TList<IANTLRInterface>.Create;
   3540       FElements.Capacity := 5;
   3541       FElements.Add(FSingleElement);
   3542       FSingleElement := nil;
   3543       FElements.Add(El);
   3544     end;
   3545 end;
   3546 
   3547 constructor TRewriteRuleElementStream.Create(const AAdaptor: ITreeAdaptor;
   3548   const AElementDescription: String);
   3549 begin
   3550   inherited Create;
   3551   FAdaptor := AAdaptor;
   3552   FElementDescription := AElementDescription;
   3553 end;
   3554 
   3555 constructor TRewriteRuleElementStream.Create(const AAdaptor: ITreeAdaptor;
   3556   const AElementDescription: String; const AOneElement: IANTLRInterface);
   3557 begin
   3558   Create(AAdaptor, AElementDescription);
   3559   Add(AOneElement);
   3560 end;
   3561 
   3562 constructor TRewriteRuleElementStream.Create(const AAdaptor: ITreeAdaptor;
   3563   const AElementDescription: String; const AElements: IList<IANTLRInterface>);
   3564 begin
   3565   Create(AAdaptor, AElementDescription);
   3566   FElements := AElements;
   3567 end;
   3568 
   3569 function TRewriteRuleElementStream.GetDescription: String;
   3570 begin
   3571   Result := FElementDescription;
   3572 end;
   3573 
   3574 function TRewriteRuleElementStream.HasNext: Boolean;
   3575 begin
   3576   Result := ((FSingleElement <> nil) and (FCursor < 1))
   3577     or ((FElements <> nil) and (FCursor < FElements.Count));
   3578 end;
   3579 
   3580 function TRewriteRuleElementStream.NextTree: IANTLRInterface;
   3581 begin
   3582   Result := _Next;
   3583 end;
   3584 
   3585 procedure TRewriteRuleElementStream.Reset;
   3586 begin
   3587   FCursor := 0;
   3588   FDirty := True;
   3589 end;
   3590 
   3591 function TRewriteRuleElementStream.Size: Integer;
   3592 begin
   3593   if Assigned(FSingleElement) then
   3594     Result := 1
   3595   else
   3596     if Assigned(FElements) then
   3597       Result := FElements.Count
   3598     else
   3599       Result := 0;
   3600 end;
   3601 
   3602 function TRewriteRuleElementStream.ToTree(const El: IANTLRInterface): IANTLRInterface;
   3603 begin
   3604   Result := El;
   3605 end;
   3606 
   3607 function TRewriteRuleElementStream._Next: IANTLRInterface;
   3608 var
   3609   Size: Integer;
   3610 begin
   3611   Size := Self.Size;
   3612   if (Size = 0) then
   3613     raise ERewriteEmptyStreamException.Create(FElementDescription);
   3614 
   3615   if (FCursor >= Size) then
   3616   begin
   3617      // out of elements?
   3618      if (Size = 1) then
   3619        // if size is 1, it's ok; return and we'll dup
   3620        Result := ToTree(FSingleElement)
   3621      else
   3622        // out of elements and size was not 1, so we can't dup
   3623        raise ERewriteCardinalityException.Create(FElementDescription);
   3624   end
   3625   else
   3626   begin
   3627     // we have elements
   3628     if Assigned(FSingleElement) then
   3629     begin
   3630       Inc(FCursor); // move cursor even for single element list
   3631       Result := ToTree(FSingleElement);
   3632     end
   3633     else
   3634     begin
   3635       // must have more than one in list, pull from elements
   3636       Result := ToTree(FElements[FCursor]);
   3637       Inc(FCursor);
   3638     end;
   3639   end;
   3640 end;
   3641 
   3642 { TRewriteRuleNodeStream }
   3643 
   3644 function TRewriteRuleNodeStream.NextNode: IANTLRInterface;
   3645 begin
   3646   Result := _Next;
   3647 end;
   3648 
   3649 function TRewriteRuleNodeStream.ToTree(
   3650   const El: IANTLRInterface): IANTLRInterface;
   3651 begin
   3652   Result := FAdaptor.DupNode(El);
   3653 end;
   3654 
   3655 { TRewriteRuleSubtreeStream }
   3656 
   3657 function TRewriteRuleSubtreeStream.Dup(
   3658   const O: IANTLRInterface): IANTLRInterface;
   3659 begin
   3660   Result := FAdaptor.DupTree(O);
   3661 end;
   3662 
   3663 function TRewriteRuleSubtreeStream.DupNode(
   3664   const O: IANTLRInterface): IANTLRInterface;
   3665 begin
   3666   Result := FAdaptor.DupNode(O);
   3667 end;
   3668 
   3669 function TRewriteRuleSubtreeStream.FetchObject(
   3670   const PH: TProcessHandler): IANTLRInterface;
   3671 begin
   3672   if (RequiresDuplication) then
   3673     // process the object
   3674     Result := PH(_Next)
   3675   else
   3676     // test above then fetch
   3677     Result := _Next;
   3678 end;
   3679 
   3680 function TRewriteRuleSubtreeStream.NextNode: IANTLRInterface;
   3681 begin
   3682   // if necessary, dup (at most a single node since this is for making root nodes).
   3683   Result := FetchObject(DupNode);
   3684 end;
   3685 
   3686 function TRewriteRuleSubtreeStream.NextTree: IANTLRInterface;
   3687 begin
   3688   // if out of elements and size is 1, dup
   3689   Result := FetchObject(Dup);
   3690 end;
   3691 
   3692 function TRewriteRuleSubtreeStream.RequiresDuplication: Boolean;
   3693 var
   3694   Size: Integer;
   3695 begin
   3696   Size := Self.Size;
   3697   // if dirty or if out of elements and size is 1
   3698   Result := FDirty or ((FCursor >= Size) and (Size = 1));
   3699 end;
   3700 
   3701 { TRewriteRuleTokenStream }
   3702 
   3703 function TRewriteRuleTokenStream.NextNode: IANTLRInterface;
   3704 begin
   3705   Result := FAdaptor.CreateNode(_Next as IToken)
   3706 end;
   3707 
   3708 function TRewriteRuleTokenStream.NextToken: IToken;
   3709 begin
   3710   Result := _Next as IToken;
   3711 end;
   3712 
   3713 function TRewriteRuleTokenStream.ToTree(
   3714   const El: IANTLRInterface): IANTLRInterface;
   3715 begin
   3716   Result := El;
   3717 end;
   3718 
   3719 { TTreeParser }
   3720 
   3721 constructor TTreeParser.Create(const AInput: ITreeNodeStream);
   3722 begin
   3723   inherited Create; // highlight that we go to super to set state object
   3724   SetTreeNodeStream(AInput);
   3725 end;
   3726 
   3727 constructor TTreeParser.Create(const AInput: ITreeNodeStream;
   3728   const AState: IRecognizerSharedState);
   3729 begin
   3730   inherited Create(AState); // share the state object with another parser
   3731   SetTreeNodeStream(AInput);
   3732 end;
   3733 
   3734 function TTreeParser.GetCurrentInputSymbol(
   3735   const Input: IIntStream): IANTLRInterface;
   3736 begin
   3737   Result := FInput.LT(1);
   3738 end;
   3739 
   3740 function TTreeParser.GetErrorHeader(const E: ERecognitionException): String;
   3741 begin
   3742   Result := GetGrammarFileName + ': node from ';
   3743   if (E.ApproximateLineInfo) then
   3744     Result := Result + 'after ';
   3745   Result := Result + 'line ' + IntToStr(E.Line) + ':' + IntToStr(E.CharPositionInLine);
   3746 end;
   3747 
   3748 function TTreeParser.GetErrorMessage(const E: ERecognitionException;
   3749   const TokenNames: TStringArray): String;
   3750 var
   3751   Adaptor: ITreeAdaptor;
   3752 begin
   3753   if (Self is TTreeParser) then
   3754   begin
   3755     Adaptor := (E.Input as ITreeNodeStream).TreeAdaptor;
   3756     E.Token := Adaptor.GetToken(E.Node);
   3757     if (E.Token = nil) then
   3758       // could be an UP/DOWN node
   3759       E.Token := TCommonToken.Create(Adaptor.GetNodeType(E.Node),
   3760         Adaptor.GetNodeText(E.Node));
   3761   end;
   3762   Result := inherited GetErrorMessage(E, TokenNames);
   3763 end;
   3764 
   3765 function TTreeParser.GetInput: IIntStream;
   3766 begin
   3767   Result := FInput;
   3768 end;
   3769 
   3770 function TTreeParser.GetMissingSymbol(const Input: IIntStream;
   3771   const E: ERecognitionException; const ExpectedTokenType: Integer;
   3772   const Follow: IBitSet): IANTLRInterface;
   3773 var
   3774   TokenText: String;
   3775 begin
   3776   TokenText := '<missing ' + GetTokenNames[ExpectedTokenType] + '>';
   3777   Result := TCommonTree.Create(TCommonToken.Create(ExpectedTokenType, TokenText));
   3778 end;
   3779 
   3780 function TTreeParser.GetSourceName: String;
   3781 begin
   3782   Result := FInput.SourceName;
   3783 end;
   3784 
   3785 function TTreeParser.GetTreeNodeStream: ITreeNodeStream;
   3786 begin
   3787   Result := FInput;
   3788 end;
   3789 
   3790 procedure TTreeParser.MatchAny(const Input: IIntStream);
   3791 var
   3792   Look: IANTLRInterface;
   3793   Level, TokenType: Integer;
   3794 begin
   3795   FState.ErrorRecovery := False;
   3796   FState.Failed := False;
   3797   Look := FInput.LT(1);
   3798   if (FInput.TreeAdaptor.GetChildCount(Look) = 0) then
   3799   begin
   3800     FInput.Consume; // not subtree, consume 1 node and return
   3801     Exit;
   3802   end;
   3803 
   3804   // current node is a subtree, skip to corresponding UP.
   3805   // must count nesting level to get right UP
   3806   Level := 0;
   3807   TokenType := FInput.TreeAdaptor.GetNodeType(Look);
   3808   while (TokenType <> TToken.EOF) and not ((TokenType = UP) and (Level = 0)) do
   3809   begin
   3810     FInput.Consume;
   3811     Look := FInput.LT(1);
   3812     TokenType := FInput.TreeAdaptor.GetNodeType(Look);
   3813     if (TokenType = DOWN) then
   3814       Inc(Level)
   3815     else
   3816       if (TokenType = UP) then
   3817         Dec(Level);
   3818   end;
   3819   FInput.Consume; // consume UP
   3820 end;
   3821 
   3822 procedure TTreeParser.Mismatch(const Input: IIntStream;
   3823   const TokenType: Integer; const Follow: IBitSet);
   3824 begin
   3825   raise EMismatchedTreeNodeException.Create(TokenType, FInput);
   3826 end;
   3827 
   3828 procedure TTreeParser.Reset;
   3829 begin
   3830   inherited; // reset all recognizer state variables
   3831   if Assigned(FInput) then
   3832     FInput.Seek(0); // rewind the input
   3833 end;
   3834 
   3835 procedure TTreeParser.SetTreeNodeStream(const Value: ITreeNodeStream);
   3836 begin
   3837   FInput := Value;
   3838 end;
   3839 
   3840 procedure TTreeParser.TraceIn(const RuleName: String; const RuleIndex: Integer);
   3841 begin
   3842   inherited TraceIn(RuleName, RuleIndex, FInput.LT(1).ToString);
   3843 end;
   3844 
   3845 procedure TTreeParser.TraceOut(const RuleName: String;
   3846   const RuleIndex: Integer);
   3847 begin
   3848   inherited TraceOut(RuleName, RuleIndex, FInput.LT(1).ToString);
   3849 end;
   3850 
   3851 { TTreePatternLexer }
   3852 
   3853 constructor TTreePatternLexer.Create;
   3854 begin
   3855   inherited;
   3856   FSVal := TStringBuilder.Create;
   3857 end;
   3858 
   3859 procedure TTreePatternLexer.Consume;
   3860 begin
   3861   Inc(FP);
   3862   if (FP > FN) then
   3863     FC := EOF
   3864   else
   3865     FC := Integer(FPattern[FP]);
   3866 end;
   3867 
   3868 constructor TTreePatternLexer.Create(const APattern: String);
   3869 begin
   3870   Create;
   3871   FPattern := APattern;
   3872   FN := Length(FPattern);
   3873   Consume;
   3874 end;
   3875 
   3876 destructor TTreePatternLexer.Destroy;
   3877 begin
   3878   FSVal.Free;
   3879   inherited;
   3880 end;
   3881 
   3882 function TTreePatternLexer.NextToken: Integer;
   3883 begin
   3884   FSVal.Length := 0; // reset, but reuse buffer
   3885   while (FC <> EOF) do
   3886   begin
   3887     if (FC = 32) or (FC = 10) or (FC = 13) or (FC = 9) then
   3888     begin
   3889       Consume;
   3890       Continue;
   3891     end;
   3892 
   3893     if ((FC >= Ord('a')) and (FC <= Ord('z')))
   3894       or ((FC >= Ord('A')) and (FC <= Ord('Z')))
   3895       or (FC = Ord('_'))
   3896     then begin
   3897       FSVal.Append(Char(FC));
   3898       Consume;
   3899       while ((FC >= Ord('a')) and (FC <= Ord('z')))
   3900         or ((FC >= Ord('A')) and (FC <= Ord('Z')))
   3901         or ((FC >= Ord('0')) and (FC <= Ord('9')))
   3902         or (FC = Ord('_')) do
   3903       begin
   3904         FSVal.Append(Char(FC));
   3905         Consume;
   3906       end;
   3907       Exit(ID);
   3908     end;
   3909 
   3910     if (FC = Ord('(')) then
   3911     begin
   3912       Consume;
   3913       Exit(START);
   3914     end;
   3915 
   3916     if (FC = Ord(')')) then
   3917     begin
   3918       Consume;
   3919       Exit(STOP);
   3920     end;
   3921 
   3922     if (FC = Ord('%')) then
   3923     begin
   3924       Consume;
   3925       Exit(PERCENT);
   3926     end;
   3927 
   3928     if (FC = Ord(':')) then
   3929     begin
   3930       Consume;
   3931       Exit(COLON);
   3932     end;
   3933 
   3934     if (FC = Ord('.')) then
   3935     begin
   3936       Consume;
   3937       Exit(DOT);
   3938     end;
   3939 
   3940     if (FC = Ord('[')) then
   3941     begin
   3942       // grab [x] as a string, returning x
   3943       Consume;
   3944       while (FC <> Ord(']')) do
   3945       begin
   3946         if (FC = Ord('\')) then
   3947         begin
   3948           Consume;
   3949           if (FC <> Ord(']')) then
   3950             FSVal.Append('\');
   3951           FSVal.Append(Char(FC));
   3952         end
   3953         else
   3954           FSVal.Append(Char(FC));
   3955         Consume;
   3956       end;
   3957       Consume;
   3958       Exit(ARG);
   3959     end;
   3960 
   3961     Consume;
   3962     FError := True;
   3963     Exit(EOF);
   3964   end;
   3965   Result := EOF;
   3966 end;
   3967 
   3968 function TTreePatternLexer.SVal: String;
   3969 begin
   3970   Result := FSVal.ToString;
   3971 end;
   3972 
   3973 { TTreeWizard }
   3974 
   3975 function TTreeWizard.ComputeTokenTypes(
   3976   const TokenNames: TStringArray): IDictionary<String, Integer>;
   3977 var
   3978   TokenType: Integer;
   3979 begin
   3980   Result := TDictionary<String, Integer>.Create;
   3981   if (Length(TokenNames) > 0)then
   3982   begin
   3983     for TokenType := TToken.MIN_TOKEN_TYPE to Length(TokenNames) - 1 do
   3984       Result.Add(TokenNames[TokenType], TokenType);
   3985   end;
   3986 end;
   3987 
   3988 constructor TTreeWizard.Create(const AAdaptor: ITreeAdaptor);
   3989 begin
   3990   inherited Create;
   3991   FAdaptor := AAdaptor;
   3992 end;
   3993 
   3994 constructor TTreeWizard.Create(const AAdaptor: ITreeAdaptor;
   3995   const ATokenNameToTypeMap: IDictionary<String, Integer>);
   3996 begin
   3997   inherited Create;
   3998   FAdaptor := AAdaptor;
   3999   FTokenNameToTypeMap := ATokenNameToTypeMap;
   4000 end;
   4001 
   4002 constructor TTreeWizard.Create(const AAdaptor: ITreeAdaptor;
   4003   const TokenNames: TStringArray);
   4004 begin
   4005   inherited Create;
   4006   FAdaptor := AAdaptor;
   4007   FTokenNameToTypeMap := ComputeTokenTypes(TokenNames);
   4008 end;
   4009 
   4010 function TTreeWizard.CreateTreeOrNode(const Pattern: String): IANTLRInterface;
   4011 var
   4012   Tokenizer: ITreePatternLexer;
   4013   Parser: ITreePatternParser;
   4014 begin
   4015   Tokenizer := TTreePatternLexer.Create(Pattern);
   4016   Parser := TTreePatternParser.Create(Tokenizer, Self, FAdaptor);
   4017   Result := Parser.Pattern;
   4018 end;
   4019 
   4020 function TTreeWizard.Equals(const T1, T2: IANTLRInterface;
   4021   const Adaptor: ITreeAdaptor): Boolean;
   4022 begin
   4023   Result := _Equals(T1, T2, Adaptor);
   4024 end;
   4025 
   4026 function TTreeWizard.Equals(const T1, T2: IANTLRInterface): Boolean;
   4027 begin
   4028   Result := _Equals(T1, T2, FAdaptor);
   4029 end;
   4030 
   4031 function TTreeWizard.Find(const T: IANTLRInterface;
   4032   const Pattern: String): IList<IANTLRInterface>;
   4033 var
   4034   Tokenizer: ITreePatternLexer;
   4035   Parser: ITreePatternParser;
   4036   TreePattern: ITreePattern;
   4037   RootTokenType: Integer;
   4038   Visitor: IContextVisitor;
   4039 begin
   4040   Result := TList<IANTLRInterface>.Create;
   4041 
   4042   // Create a TreePattern from the pattern
   4043   Tokenizer := TTreePatternLexer.Create(Pattern);
   4044   Parser := TTreePatternParser.Create(Tokenizer, Self, TTreePatternTreeAdaptor.Create);
   4045   TreePattern := Parser.Pattern as ITreePattern;
   4046 
   4047   // don't allow invalid patterns
   4048   if (TreePattern = nil) or (TreePattern.IsNil)
   4049     or Supports(TreePattern, IWildcardTreePattern)
   4050   then
   4051     Exit(nil);
   4052 
   4053   RootTokenType := TreePattern.TokenType;
   4054   Visitor := TPatternMatchingContextVisitor.Create(Self, TreePattern, Result);
   4055   Visit(T, RootTokenType, Visitor);
   4056 end;
   4057 
   4058 function TTreeWizard.Find(const T: IANTLRInterface;
   4059   const TokenType: Integer): IList<IANTLRInterface>;
   4060 begin
   4061   Result := TList<IANTLRInterface>.Create;
   4062   Visit(T, TokenType, TRecordAllElementsVisitor.Create(Result));
   4063 end;
   4064 
   4065 function TTreeWizard.FindFirst(const T: IANTLRInterface;
   4066   const TokenType: Integer): IANTLRInterface;
   4067 begin
   4068   Result := nil;
   4069 end;
   4070 
   4071 function TTreeWizard.FindFirst(const T: IANTLRInterface;
   4072   const Pattern: String): IANTLRInterface;
   4073 begin
   4074   Result := nil;
   4075 end;
   4076 
   4077 function TTreeWizard.GetTokenType(const TokenName: String): Integer;
   4078 begin
   4079   if (FTokenNameToTypeMap = nil) then
   4080     Exit(TToken.INVALID_TOKEN_TYPE);
   4081   if (not FTokenNameToTypeMap.TryGetValue(TokenName, Result)) then
   4082     Result := TToken.INVALID_TOKEN_TYPE;
   4083 end;
   4084 
   4085 function TTreeWizard.Index(
   4086   const T: IANTLRInterface): IDictionary<Integer, IList<IANTLRInterface>>;
   4087 begin
   4088   Result := TDictionary<Integer, IList<IANTLRInterface>>.Create;
   4089   _Index(T, Result);
   4090 end;
   4091 
   4092 function TTreeWizard.Parse(const T: IANTLRInterface;
   4093   const Pattern: String): Boolean;
   4094 begin
   4095   Result := Parse(T, Pattern, nil);
   4096 end;
   4097 
   4098 function TTreeWizard.Parse(const T: IANTLRInterface; const Pattern: String;
   4099   const Labels: IDictionary<String, IANTLRInterface>): Boolean;
   4100 var
   4101   Tokenizer: ITreePatternLexer;
   4102   Parser: ITreePatternParser;
   4103   TreePattern: ITreePattern;
   4104 begin
   4105   Tokenizer := TTreePatternLexer.Create(Pattern);
   4106   Parser := TTreePatternParser.Create(Tokenizer, Self, TTreePatternTreeAdaptor.Create);
   4107   TreePattern := Parser.Pattern as ITreePattern;
   4108   Result := _Parse(T, TreePattern, Labels);
   4109 end;
   4110 
   4111 procedure TTreeWizard.Visit(const T: IANTLRInterface; const Pattern: String;
   4112   const Visitor: IContextVisitor);
   4113 var
   4114   Tokenizer: ITreePatternLexer;
   4115   Parser: ITreePatternParser;
   4116   TreePattern: ITreePattern;
   4117   RootTokenType: Integer;
   4118   PatternVisitor: IContextVisitor;
   4119 begin
   4120   // Create a TreePattern from the pattern
   4121   Tokenizer := TTreePatternLexer.Create(Pattern);
   4122   Parser := TTreePatternParser.Create(Tokenizer, Self, TTreePatternTreeAdaptor.Create);
   4123   TreePattern := Parser.Pattern as ITreePattern;
   4124   if (TreePattern = nil) or (TreePattern.IsNil)
   4125     or Supports(TreePattern, IWildcardTreePattern)
   4126   then
   4127     Exit;
   4128   RootTokenType := TreePattern.TokenType;
   4129   PatternVisitor := TInvokeVisitorOnPatternMatchContextVisitor.Create(Self, TreePattern, Visitor);
   4130   Visit(T, RootTokenType, PatternVisitor);
   4131 end;
   4132 
   4133 class function TTreeWizard._Equals(const T1, T2: IANTLRInterface;
   4134   const Adaptor: ITreeAdaptor): Boolean;
   4135 var
   4136   I, N1, N2: Integer;
   4137   Child1, Child2: IANTLRInterface;
   4138 begin
   4139   // make sure both are non-null
   4140   if (T1 = nil) or (T2 = nil) then
   4141     Exit(False);
   4142 
   4143   // check roots
   4144   if (Adaptor.GetNodeType(T1) <> Adaptor.GetNodeType(T2)) then
   4145     Exit(False);
   4146   if (Adaptor.GetNodeText(T1) <> Adaptor.GetNodeText(T2)) then
   4147     Exit(False);
   4148 
   4149   // check children
   4150   N1 := Adaptor.GetChildCount(T1);
   4151   N2 := Adaptor.GetChildCount(T2);
   4152   if (N1 <> N2) then
   4153     Exit(False);
   4154   for I := 0 to N1 - 1 do
   4155   begin
   4156     Child1 := Adaptor.GetChild(T1, I);
   4157     Child2 := Adaptor.GetChild(T2, I);
   4158     if (not _Equals(Child1, Child2, Adaptor)) then
   4159       Exit(False);
   4160   end;
   4161 
   4162   Result := True;
   4163 end;
   4164 
   4165 procedure TTreeWizard._Index(const T: IANTLRInterface;
   4166   const M: IDictionary<Integer, IList<IANTLRInterface>>);
   4167 var
   4168   I, N, TType: Integer;
   4169   Elements: IList<IANTLRInterface>;
   4170 begin
   4171   if (T = nil) then
   4172     Exit;
   4173   TType := FAdaptor.GetNodeType(T);
   4174   if (not M.TryGetValue(TType, Elements)) then
   4175     Elements := nil;
   4176   if (Elements = nil) then
   4177   begin
   4178     Elements := TList<IANTLRInterface>.Create;
   4179     M.Add(TType, Elements);
   4180   end;
   4181   Elements.Add(T);
   4182   N := FAdaptor.GetChildCount(T);
   4183   for I := 0 to N - 1 do
   4184     _Index(FAdaptor.GetChild(T, I), M);
   4185 end;
   4186 
   4187 function TTreeWizard._Parse(const T1: IANTLRInterface; const T2: ITreePattern;
   4188   const Labels: IDictionary<String, IANTLRInterface>): Boolean;
   4189 var
   4190   I, N1, N2: Integer;
   4191   Child1: IANTLRInterface;
   4192   Child2: ITreePattern;
   4193 begin
   4194   // make sure both are non-null
   4195   if (T1 = nil) or (T2 = nil) then
   4196     Exit(False);
   4197 
   4198   // check roots (wildcard matches anything)
   4199   if (not Supports(T2, IWildcardTreePattern)) then
   4200   begin
   4201     if (FAdaptor.GetNodeType(T1) <> T2.TokenType) then
   4202       Exit(False);
   4203     if (T2.HasTextArg) and (FAdaptor.GetNodeText(T1) <> T2.Text) then
   4204       Exit(False);
   4205   end;
   4206 
   4207   if (T2.TokenLabel <> '') and Assigned(Labels) then
   4208     // map label in pattern to node in t1
   4209     Labels.AddOrSetValue(T2.TokenLabel, T1);
   4210 
   4211   // check children
   4212   N1 := FAdaptor.GetChildCount(T1);
   4213   N2 := T2.ChildCount;
   4214   if (N1 <> N2) then
   4215     Exit(False);
   4216 
   4217   for I := 0 to N1 - 1 do
   4218   begin
   4219     Child1 := FAdaptor.GetChild(T1, I);
   4220     Child2 := T2.GetChild(I) as ITreePattern;
   4221     if (not _Parse(Child1, Child2, Labels)) then
   4222       Exit(False);
   4223   end;
   4224 
   4225   Result := True;
   4226 end;
   4227 
   4228 procedure TTreeWizard._Visit(const T, Parent: IANTLRInterface; const ChildIndex,
   4229   TokenType: Integer; const Visitor: IContextVisitor);
   4230 var
   4231   I, N: Integer;
   4232 begin
   4233   if (T = nil) then
   4234     Exit;
   4235   if (FAdaptor.GetNodeType(T) = TokenType) then
   4236     Visitor.Visit(T, Parent, ChildIndex, nil);
   4237 
   4238   N := FAdaptor.GetChildCount(T);
   4239   for I := 0 to N - 1 do
   4240     _Visit(FAdaptor.GetChild(T, I), T, I, TokenType, Visitor);
   4241 end;
   4242 
   4243 procedure TTreeWizard.Visit(const T: IANTLRInterface; const TokenType: Integer;
   4244   const Visitor: IContextVisitor);
   4245 begin
   4246   _Visit(T, nil, 0, TokenType, Visitor);
   4247 end;
   4248 
   4249 constructor TTreeWizard.Create(const TokenNames: TStringArray);
   4250 begin
   4251   Create(nil, TokenNames);
   4252 end;
   4253 
   4254 { TTreePatternParser }
   4255 
   4256 constructor TTreePatternParser.Create(const ATokenizer: ITreePatternLexer;
   4257   const AWizard: ITreeWizard; const AAdaptor: ITreeAdaptor);
   4258 begin
   4259   inherited Create;
   4260   FTokenizer := ATokenizer;
   4261   FWizard := AWizard;
   4262   FAdaptor := AAdaptor;
   4263   FTokenType := FTokenizer.NextToken; // kickstart
   4264 end;
   4265 
   4266 function TTreePatternParser.ParseNode: IANTLRInterface;
   4267 var
   4268   Lbl, TokenName, Text, Arg: String;
   4269   WildcardPayload: IToken;
   4270   Node: TTreeWizard.ITreePattern;
   4271   TreeNodeType: Integer;
   4272 begin
   4273   // "%label:" prefix
   4274   Lbl := '';
   4275   if (FTokenType = TTreePatternLexer.PERCENT) then
   4276   begin
   4277     FTokenType := FTokenizer.NextToken;
   4278     if (FTokenType <> TTreePatternLexer.ID) then
   4279       Exit(nil);
   4280     Lbl := FTokenizer.SVal;
   4281     FTokenType := FTokenizer.NextToken;
   4282     if (FTokenType <> TTreePatternLexer.COLON) then
   4283       Exit(nil);
   4284     FTokenType := FTokenizer.NextToken; // move to ID following colon
   4285   end;
   4286 
   4287   // Wildcard?
   4288   if (FTokenType = TTreePatternLexer.DOT) then
   4289   begin
   4290     FTokenType := FTokenizer.NextToken;
   4291     WildcardPayload := TCommonToken.Create(0, '.');
   4292     Node := TTreeWizard.TWildcardTreePattern.Create(WildcardPayload);
   4293     if (Lbl <> '') then
   4294       Node.TokenLabel := Lbl;
   4295     Exit(Node);
   4296   end;
   4297 
   4298   // "ID" or "ID[arg]"
   4299   if (FTokenType <> TTreePatternLexer.ID) then
   4300     Exit(nil);
   4301   TokenName := FTokenizer.SVal;
   4302   FTokenType := FTokenizer.NextToken;
   4303   if (TokenName = 'nil') then
   4304     Exit(FAdaptor.GetNilNode);
   4305   Text := TokenName;
   4306 
   4307   // check for arg
   4308   Arg := '';
   4309   if (FTokenType = TTreePatternLexer.ARG) then
   4310   begin
   4311     Arg := FTokenizer.SVal;
   4312     Text := Arg;
   4313     FTokenType := FTokenizer.NextToken;
   4314   end;
   4315 
   4316   // create node
   4317   TreeNodeType := FWizard.GetTokenType(TokenName);
   4318   if (TreeNodeType = TToken.INVALID_TOKEN_TYPE) then
   4319     Exit(nil);
   4320 
   4321   Result := FAdaptor.CreateNode(TreeNodeType, Text);
   4322   if (Lbl <> '') and Supports(Result, TTreeWizard.ITreePattern, Node) then
   4323     Node.TokenLabel := Lbl;
   4324   if (Arg <> '') and Supports(Result, TTreeWizard.ITreePattern, Node) then
   4325     Node.HasTextArg := True;
   4326 end;
   4327 
   4328 function TTreePatternParser.ParseTree: IANTLRInterface;
   4329 var
   4330   Subtree, Child: IANTLRInterface;
   4331 begin
   4332   if (FTokenType <> TTreePatternLexer.START) then
   4333   begin
   4334     WriteLn('no BEGIN');
   4335     Exit(nil);
   4336   end;
   4337 
   4338   FTokenType := FTokenizer.NextToken;
   4339   Result := ParseNode;
   4340   if (Result = nil) then
   4341     Exit;
   4342 
   4343   while (FTokenType in [TTreePatternLexer.START, TTreePatternLexer.ID,
   4344     TTreePatternLexer.PERCENT, TTreePatternLexer.DOT]) do
   4345   begin
   4346     if (FTokenType = TTreePatternLexer.START) then
   4347     begin
   4348       Subtree := ParseTree;
   4349       FAdaptor.AddChild(Result, Subtree);
   4350     end
   4351     else
   4352     begin
   4353       Child := ParseNode;
   4354       if (Child = nil) then
   4355         Exit(nil);
   4356       FAdaptor.AddChild(Result, Child);
   4357     end;
   4358   end;
   4359 
   4360   if (FTokenType <> TTreePatternLexer.STOP) then
   4361   begin
   4362     WriteLn('no END');
   4363     Exit(nil);
   4364   end;
   4365 
   4366   FTokenType := FTokenizer.NextToken;
   4367 end;
   4368 
   4369 function TTreePatternParser.Pattern: IANTLRInterface;
   4370 var
   4371   Node: IANTLRInterface;
   4372 begin
   4373   if (FTokenType = TTreePatternLexer.START) then
   4374     Exit(ParseTree);
   4375 
   4376   if (FTokenType = TTreePatternLexer.ID) then
   4377   begin
   4378     Node := ParseNode;
   4379     if (FTokenType = TTreePatternLexer.EOF) then
   4380       Result := Node
   4381     else
   4382       Result := nil; // extra junk on end
   4383   end
   4384   else
   4385     Result := nil;
   4386 end;
   4387 
   4388 { TTreeWizard.TVisitor }
   4389 
   4390 procedure TTreeWizard.TVisitor.Visit(const T, Parent: IANTLRInterface;
   4391   const ChildIndex: Integer;
   4392   const Labels: IDictionary<String, IANTLRInterface>);
   4393 begin
   4394   Visit(T);
   4395 end;
   4396 
   4397 { TTreeWizard.TRecordAllElementsVisitor }
   4398 
   4399 constructor TTreeWizard.TRecordAllElementsVisitor.Create(
   4400   const AList: IList<IANTLRInterface>);
   4401 begin
   4402   inherited Create;
   4403   FList := AList;
   4404 end;
   4405 
   4406 procedure TTreeWizard.TRecordAllElementsVisitor.Visit(const T: IANTLRInterface);
   4407 begin
   4408   FList.Add(T);
   4409 end;
   4410 
   4411 { TTreeWizard.TPatternMatchingContextVisitor }
   4412 
   4413 constructor TTreeWizard.TPatternMatchingContextVisitor.Create(
   4414   const AOwner: TTreeWizard; const APattern: ITreePattern;
   4415   const AList: IList<IANTLRInterface>);
   4416 begin
   4417   inherited Create;
   4418   FOwner := AOwner;
   4419   FPattern := APattern;
   4420   FList := AList;
   4421 end;
   4422 
   4423 procedure TTreeWizard.TPatternMatchingContextVisitor.Visit(const T,
   4424   Parent: IANTLRInterface; const ChildIndex: Integer;
   4425   const Labels: IDictionary<String, IANTLRInterface>);
   4426 begin
   4427   if (FOwner._Parse(T, FPattern, nil)) then
   4428     FList.Add(T);
   4429 end;
   4430 
   4431 { TTreeWizard.TInvokeVisitorOnPatternMatchContextVisitor }
   4432 
   4433 constructor TTreeWizard.TInvokeVisitorOnPatternMatchContextVisitor.Create(
   4434   const AOwner: TTreeWizard; const APattern: ITreePattern;
   4435   const AVisitor: IContextVisitor);
   4436 begin
   4437   inherited Create;
   4438   FOwner := AOwner;
   4439   FPattern := APattern;
   4440   FVisitor := AVisitor;
   4441   FLabels := TDictionary<String, IANTLRInterface>.Create;
   4442 end;
   4443 
   4444 procedure TTreeWizard.TInvokeVisitorOnPatternMatchContextVisitor.Visit(const T,
   4445   Parent: IANTLRInterface; const ChildIndex: Integer;
   4446   const UnusedLabels: IDictionary<String, IANTLRInterface>);
   4447 begin
   4448   // the unusedlabels arg is null as visit on token type doesn't set.
   4449   FLabels.Clear;
   4450   if (FOwner._Parse(T, FPattern, FLabels)) then
   4451     FVisitor.Visit(T, Parent, ChildIndex, FLabels);
   4452 end;
   4453 
   4454 { TTreeWizard.TTreePattern }
   4455 
   4456 function TTreeWizard.TTreePattern.GetHasTextArg: Boolean;
   4457 begin
   4458   Result := FHasTextArg;
   4459 end;
   4460 
   4461 function TTreeWizard.TTreePattern.GetTokenLabel: String;
   4462 begin
   4463   Result := FLabel;
   4464 end;
   4465 
   4466 procedure TTreeWizard.TTreePattern.SetHasTextArg(const Value: Boolean);
   4467 begin
   4468   FHasTextArg := Value;
   4469 end;
   4470 
   4471 procedure TTreeWizard.TTreePattern.SetTokenLabel(const Value: String);
   4472 begin
   4473   FLabel := Value;
   4474 end;
   4475 
   4476 function TTreeWizard.TTreePattern.ToString: String;
   4477 begin
   4478   if (FLabel <> '') then
   4479     Result := '%' + FLabel + ':' + inherited ToString
   4480   else
   4481     Result := inherited ToString;
   4482 end;
   4483 
   4484 { TTreeWizard.TTreePatternTreeAdaptor }
   4485 
   4486 function TTreeWizard.TTreePatternTreeAdaptor.CreateNode(
   4487   const Payload: IToken): IANTLRInterface;
   4488 begin
   4489   Result := TTreePattern.Create(Payload);
   4490 end;
   4491 
   4492 { TTreeRuleReturnScope }
   4493 
   4494 function TTreeRuleReturnScope.GetStart: IANTLRInterface;
   4495 begin
   4496   Result := FStart;
   4497 end;
   4498 
   4499 procedure TTreeRuleReturnScope.SetStart(const Value: IANTLRInterface);
   4500 begin
   4501   FStart := Value;
   4502 end;
   4503 
   4504 { TUnBufferedTreeNodeStream }
   4505 
   4506 procedure TUnBufferedTreeNodeStream.AddLookahead(const Node: IANTLRInterface);
   4507 var
   4508   Bigger: TANTLRInterfaceArray;
   4509   I, RemainderHeadToEnd: Integer;
   4510 begin
   4511   FLookahead[FTail] := Node;
   4512   FTail := (FTail + 1) mod Length(FLookahead);
   4513   if (FTail = FHead) then
   4514   begin
   4515     // buffer overflow: tail caught up with head
   4516     // allocate a buffer 2x as big
   4517     SetLength(Bigger,2 * Length(FLookahead));
   4518     // copy head to end of buffer to beginning of bigger buffer
   4519     RemainderHeadToEnd := Length(FLookahead) - FHead;
   4520     for I := 0 to RemainderHeadToEnd - 1 do
   4521       Bigger[I] := FLookahead[FHead + I];
   4522     // copy 0..tail to after that
   4523     for I := 0 to FTail - 1 do
   4524       Bigger[RemainderHeadToEnd + I] := FLookahead[I];
   4525     FLookahead := Bigger; // reset to bigger buffer
   4526     FHead := 0;
   4527     Inc(FTail,RemainderHeadToEnd);
   4528   end;
   4529 end;
   4530 
   4531 procedure TUnBufferedTreeNodeStream.AddNavigationNode(const TokenType: Integer);
   4532 var
   4533   NavNode: IANTLRInterface;
   4534 begin
   4535   if (TokenType = TToken.DOWN) then
   4536   begin
   4537     if (GetHasUniqueNavigationNodes) then
   4538       NavNode := FAdaptor.CreateNode(TToken.DOWN,'DOWN')
   4539     else
   4540       NavNode := FDown;
   4541   end
   4542   else
   4543   begin
   4544     if (GetHasUniqueNavigationNodes) then
   4545       NavNode := FAdaptor.CreateNode(TToken.UP,'UP')
   4546     else
   4547       NavNode := FUp;
   4548   end;
   4549   AddLookahead(NavNode);
   4550 end;
   4551 
   4552 procedure TUnBufferedTreeNodeStream.Consume;
   4553 begin
   4554   // make sure there is something in lookahead buf, which might call next()
   4555   Fill(1);
   4556   Inc(FAbsoluteNodeIndex);
   4557   FPreviousNode := FLookahead[FHead]; // track previous node before moving on
   4558   FHead := (FHead + 1) mod Length(FLookahead);
   4559 end;
   4560 
   4561 constructor TUnBufferedTreeNodeStream.Create;
   4562 begin
   4563   inherited;
   4564   SetLength(FLookAhead,INITIAL_LOOKAHEAD_BUFFER_SIZE);
   4565   FNodeStack := TStackList<IANTLRInterface>.Create;
   4566   FIndexStack := TStackList<Integer>.Create;
   4567 end;
   4568 
   4569 constructor TUnBufferedTreeNodeStream.Create(const ATree: IANTLRInterface);
   4570 begin
   4571   Create(TCommonTreeAdaptor.Create, ATree);
   4572 end;
   4573 
   4574 constructor TUnBufferedTreeNodeStream.Create(const AAdaptor: ITreeAdaptor;
   4575   const ATree: IANTLRInterface);
   4576 begin
   4577   Create;
   4578   FRoot := ATree;
   4579   FAdaptor := AAdaptor;
   4580   Reset;
   4581   FDown := FAdaptor.CreateNode(TToken.DOWN, 'DOWN');
   4582   FUp := FAdaptor.CreateNode(TToken.UP, 'UP');
   4583   FEof := FAdaptor.CreateNode(TToken.EOF, 'EOF');
   4584 end;
   4585 
   4586 procedure TUnBufferedTreeNodeStream.Fill(const K: Integer);
   4587 var
   4588   I, N: Integer;
   4589 begin
   4590   N := LookaheadSize;
   4591   for I := 1 to K - N do
   4592     MoveNext; // get at least k-depth lookahead nodes
   4593 end;
   4594 
   4595 function TUnBufferedTreeNodeStream.Get(const I: Integer): IANTLRInterface;
   4596 begin
   4597   raise EInvalidOperation.Create('stream is unbuffered');
   4598 end;
   4599 
   4600 function TUnBufferedTreeNodeStream.GetCurrent: IANTLRInterface;
   4601 begin
   4602   Result := FCurrentEnumerationNode;
   4603 end;
   4604 
   4605 function TUnBufferedTreeNodeStream.GetHasUniqueNavigationNodes: Boolean;
   4606 begin
   4607   Result := FUniqueNavigationNodes;
   4608 end;
   4609 
   4610 function TUnBufferedTreeNodeStream.GetSourceName: String;
   4611 begin
   4612   Result := GetTokenStream.SourceName;
   4613 end;
   4614 
   4615 function TUnBufferedTreeNodeStream.GetTokenStream: ITokenStream;
   4616 begin
   4617   Result := FTokens;
   4618 end;
   4619 
   4620 function TUnBufferedTreeNodeStream.GetTreeAdaptor: ITreeAdaptor;
   4621 begin
   4622   Result := FAdaptor;
   4623 end;
   4624 
   4625 function TUnBufferedTreeNodeStream.GetTreeSource: IANTLRInterface;
   4626 begin
   4627   Result := FRoot;
   4628 end;
   4629 
   4630 function TUnBufferedTreeNodeStream.HandleRootNode: IANTLRInterface;
   4631 begin
   4632   Result := FCurrentNode;
   4633   // point to first child in prep for subsequent next()
   4634   FCurrentChildIndex := 0;
   4635   if (FAdaptor.IsNil(Result)) then
   4636     // don't count this root nil node
   4637     Result := VisitChild(FCurrentChildIndex)
   4638   else
   4639   begin
   4640     AddLookahead(Result);
   4641     if (FAdaptor.GetChildCount(FCurrentNode) = 0) then
   4642       // single node case
   4643       Result := nil; // say we're done
   4644   end;
   4645 end;
   4646 
   4647 function TUnBufferedTreeNodeStream.Index: Integer;
   4648 begin
   4649   Result := FAbsoluteNodeIndex + 1;
   4650 end;
   4651 
   4652 function TUnBufferedTreeNodeStream.LA(I: Integer): Integer;
   4653 var
   4654   T: IANTLRInterface;
   4655 begin
   4656   T := LT(I);
   4657   if (T = nil) then
   4658     Result := TToken.INVALID_TOKEN_TYPE
   4659   else
   4660     Result := FAdaptor.GetNodeType(T);
   4661 end;
   4662 
   4663 function TUnBufferedTreeNodeStream.LAChar(I: Integer): Char;
   4664 begin
   4665   Result := Char(LA(I));
   4666 end;
   4667 
   4668 function TUnBufferedTreeNodeStream.LookaheadSize: Integer;
   4669 begin
   4670   if (FTail < FHead) then
   4671     Result := Length(FLookahead) - FHead + FTail
   4672   else
   4673     Result := FTail - FHead;
   4674 end;
   4675 
   4676 function TUnBufferedTreeNodeStream.LT(const K: Integer): IANTLRInterface;
   4677 begin
   4678   if (K = -1) then
   4679     Exit(FPreviousNode);
   4680 
   4681   if (K < 0) then
   4682     raise EArgumentException.Create('tree node streams cannot look backwards more than 1 node');
   4683 
   4684   if (K = 0) then
   4685     Exit(TTree.INVALID_NODE);
   4686 
   4687   Fill(K);
   4688   Result := FLookahead[(FHead + K - 1) mod Length(FLookahead)];
   4689 end;
   4690 
   4691 function TUnBufferedTreeNodeStream.Mark: Integer;
   4692 var
   4693   State: ITreeWalkState;
   4694   I, N, K: Integer;
   4695   LA: TANTLRInterfaceArray;
   4696 begin
   4697   if (FMarkers = nil) then
   4698   begin
   4699     FMarkers := TList<ITreeWalkState>.Create;
   4700     FMarkers.Add(nil); // depth 0 means no backtracking, leave blank
   4701   end;
   4702 
   4703   Inc(FMarkDepth);
   4704   State := nil;
   4705   if (FMarkDepth >= FMarkers.Count) then
   4706   begin
   4707     State := TTreeWalkState.Create;
   4708     FMarkers.Add(State);
   4709   end
   4710   else
   4711     State := FMarkers[FMarkDepth];
   4712 
   4713   State.AbsoluteNodeIndex := FAbsoluteNodeIndex;
   4714   State.CurrentChildIndex := FCurrentChildIndex;
   4715   State.CurrentNode := FCurrentNode;
   4716   State.PreviousNode := FPreviousNode;
   4717   State.NodeStackSize := FNodeStack.Count;
   4718   State.IndexStackSize := FIndexStack.Count;
   4719 
   4720   // take snapshot of lookahead buffer
   4721   N := LookaheadSize;
   4722   I := 0;
   4723   SetLength(LA,N);
   4724   for K := 1 to N do
   4725   begin
   4726     LA[I] := LT(K);
   4727     Inc(I);
   4728   end;
   4729   State.LookAhead := LA;
   4730   FLastMarker := FMarkDepth;
   4731   Result := FMarkDepth;
   4732 end;
   4733 
   4734 function TUnBufferedTreeNodeStream.MoveNext: Boolean;
   4735 begin
   4736   // already walked entire tree; nothing to return
   4737   if (FCurrentNode = nil) then
   4738   begin
   4739     AddLookahead(FEof);
   4740     FCurrentEnumerationNode := nil;
   4741     // this is infinite stream returning EOF at end forever
   4742     // so don't throw NoSuchElementException
   4743     Exit(False);
   4744   end;
   4745 
   4746   // initial condition (first time method is called)
   4747   if (FCurrentChildIndex = -1) then
   4748   begin
   4749     FCurrentEnumerationNode := HandleRootNode as ITree;
   4750     Exit(True);
   4751   end;
   4752 
   4753   // index is in the child list?
   4754   if (FCurrentChildIndex < FAdaptor.GetChildCount(FCurrentNode)) then
   4755   begin
   4756     FCurrentEnumerationNode := VisitChild(FCurrentChildIndex) as ITree;
   4757     Exit(True);
   4758   end;
   4759 
   4760   // hit end of child list, return to parent node or its parent ...
   4761   WalkBackToMostRecentNodeWithUnvisitedChildren;
   4762   if (FCurrentNode <> nil) then
   4763   begin
   4764     FCurrentEnumerationNode := VisitChild(FCurrentChildIndex) as ITree;
   4765     Result := True;
   4766   end
   4767   else
   4768     Result := False;
   4769 end;
   4770 
   4771 procedure TUnBufferedTreeNodeStream.Release(const Marker: Integer);
   4772 begin
   4773   // unwind any other markers made after marker and release marker
   4774   FMarkDepth := Marker;
   4775   // release this marker
   4776   Dec(FMarkDepth);
   4777 end;
   4778 
   4779 procedure TUnBufferedTreeNodeStream.ReplaceChildren(
   4780   const Parent: IANTLRInterface; const StartChildIndex, StopChildIndex: Integer;
   4781   const T: IANTLRInterface);
   4782 begin
   4783   raise EInvalidOperation.Create('can''t do stream rewrites yet');
   4784 end;
   4785 
   4786 procedure TUnBufferedTreeNodeStream.Reset;
   4787 begin
   4788   FCurrentNode := FRoot;
   4789   FPreviousNode := nil;
   4790   FCurrentChildIndex := -1;
   4791   FAbsoluteNodeIndex := -1;
   4792   FHead := 0;
   4793   FTail := 0;
   4794 end;
   4795 
   4796 procedure TUnBufferedTreeNodeStream.Rewind(const Marker: Integer);
   4797 var
   4798   State: ITreeWalkState;
   4799 begin
   4800   if (FMarkers = nil) then
   4801     Exit;
   4802   State := FMarkers[Marker];
   4803   FAbsoluteNodeIndex := State.AbsoluteNodeIndex;
   4804   FCurrentChildIndex := State.CurrentChildIndex;
   4805   FCurrentNode := State.CurrentNode;
   4806   FPreviousNode := State.PreviousNode;
   4807   // drop node and index stacks back to old size
   4808   FNodeStack.Capacity := State.NodeStackSize;
   4809   FIndexStack.Capacity := State.IndexStackSize;
   4810   FHead := 0; // wack lookahead buffer and then refill
   4811   FTail := 0;
   4812   while (FTail < Length(State.LookAhead)) do
   4813   begin
   4814     FLookahead[FTail] := State.LookAhead[FTail];
   4815     Inc(FTail);
   4816   end;
   4817   Release(Marker);
   4818 end;
   4819 
   4820 procedure TUnBufferedTreeNodeStream.Rewind;
   4821 begin
   4822   Rewind(FLastMarker);
   4823 end;
   4824 
   4825 procedure TUnBufferedTreeNodeStream.Seek(const Index: Integer);
   4826 begin
   4827   if (Index < Self.Index) then
   4828     raise EArgumentOutOfRangeException.Create('can''t seek backwards in node stream');
   4829 
   4830   // seek forward, consume until we hit index
   4831   while (Self.Index < Index) do
   4832     Consume;
   4833 end;
   4834 
   4835 procedure TUnBufferedTreeNodeStream.SetHasUniqueNavigationNodes(
   4836   const Value: Boolean);
   4837 begin
   4838   FUniqueNavigationNodes := Value;
   4839 end;
   4840 
   4841 procedure TUnBufferedTreeNodeStream.SetTokenStream(const Value: ITokenStream);
   4842 begin
   4843   FTokens := Value;
   4844 end;
   4845 
   4846 function TUnBufferedTreeNodeStream.Size: Integer;
   4847 var
   4848   S: ICommonTreeNodeStream;
   4849 begin
   4850   S := TCommonTreeNodeStream.Create(FRoot);
   4851   Result := S.Size;
   4852 end;
   4853 
   4854 function TUnBufferedTreeNodeStream.ToString: String;
   4855 begin
   4856   Result := ToString(FRoot, nil);
   4857 end;
   4858 
   4859 procedure TUnBufferedTreeNodeStream.ToStringWork(const P, Stop: IANTLRInterface;
   4860   const Buf: TStringBuilder);
   4861 var
   4862   Text: String;
   4863   C, N: Integer;
   4864 begin
   4865   if (not FAdaptor.IsNil(P)) then
   4866   begin
   4867     Text := FAdaptor.GetNodeText(P);
   4868     if (Text = '') then
   4869       Text := ' ' + IntToStr(FAdaptor.GetNodeType(P));
   4870     Buf.Append(Text); // ask the node to go to string
   4871   end;
   4872 
   4873   if SameObj(P, Stop) then
   4874     Exit;
   4875 
   4876   N := FAdaptor.GetChildCount(P);
   4877   if (N > 0) and (not FAdaptor.IsNil(P)) then
   4878   begin
   4879     Buf.Append(' ');
   4880     Buf.Append(TToken.DOWN);
   4881   end;
   4882 
   4883   for C := 0 to N - 1 do
   4884     ToStringWork(FAdaptor.GetChild(P, C), Stop, Buf);
   4885 
   4886   if (N > 0) and (not FAdaptor.IsNil(P)) then
   4887   begin
   4888     Buf.Append(' ');
   4889     Buf.Append(TToken.UP);
   4890   end;
   4891 end;
   4892 
   4893 function TUnBufferedTreeNodeStream.VisitChild(
   4894   const Child: Integer): IANTLRInterface;
   4895 begin
   4896   Result := nil;
   4897   // save state
   4898   FNodeStack.Push(FCurrentNode);
   4899   FIndexStack.Push(Child);
   4900   if (Child = 0) and (not FAdaptor.IsNil(FCurrentNode)) then
   4901     AddNavigationNode(TToken.DOWN);
   4902   // visit child
   4903   FCurrentNode := FAdaptor.GetChild(FCurrentNode, Child);
   4904   FCurrentChildIndex := 0;
   4905   Result := FCurrentNode;
   4906   AddLookahead(Result);
   4907   WalkBackToMostRecentNodeWithUnvisitedChildren;
   4908 end;
   4909 
   4910 procedure TUnBufferedTreeNodeStream.WalkBackToMostRecentNodeWithUnvisitedChildren;
   4911 begin
   4912   while (FCurrentNode <> nil) and (FCurrentChildIndex >= FAdaptor.GetChildCount(FCurrentNode)) do
   4913   begin
   4914     FCurrentNode := FNodeStack.Pop;
   4915     if (FCurrentNode = nil) then
   4916       // hit the root?
   4917       Exit;
   4918 
   4919     FCurrentChildIndex := FIndexStack.Pop;
   4920     Inc(FCurrentChildIndex); // move to next child
   4921     if (FCurrentChildIndex >= FAdaptor.GetChildCount(FCurrentNode)) then
   4922     begin
   4923       if (not FAdaptor.IsNil(FCurrentNode)) then
   4924         AddNavigationNode(TToken.UP);
   4925       if SameObj(FCurrentNode, FRoot) then
   4926         // we done yet?
   4927         FCurrentNode := nil;
   4928     end;
   4929   end;
   4930 end;
   4931 
   4932 function TUnBufferedTreeNodeStream.ToString(const Start,
   4933   Stop: IANTLRInterface): String;
   4934 var
   4935   BeginTokenIndex, EndTokenIndex: Integer;
   4936   Buf: TStringBuilder;
   4937 begin
   4938   if (Start = nil) then
   4939     Exit('');
   4940 
   4941   // if we have the token stream, use that to dump text in order
   4942   if (FTokens <> nil) then
   4943   begin
   4944     // don't trust stop node as it's often an UP node etc...
   4945     // walk backwards until you find a non-UP, non-DOWN node
   4946     // and ask for it's token index.
   4947     BeginTokenIndex := FAdaptor.GetTokenStartIndex(Start);
   4948     if (Stop <> nil) and (FAdaptor.GetNodeType(Stop) = TToken.UP) then
   4949       EndTokenIndex := FAdaptor.GetTokenStopIndex(Start)
   4950     else
   4951       EndTokenIndex := Size - 1;
   4952     Exit(FTokens.ToString(BeginTokenIndex, EndTokenIndex));
   4953   end;
   4954 
   4955   Buf := TStringBuilder.Create;
   4956   try
   4957     ToStringWork(Start, Stop, Buf);
   4958     Result := Buf.ToString;
   4959   finally
   4960     Buf.Free;
   4961   end;
   4962 end;
   4963 
   4964 { TUnBufferedTreeNodeStream.TTreeWalkState }
   4965 
   4966 function TUnBufferedTreeNodeStream.TTreeWalkState.GetAbsoluteNodeIndex: Integer;
   4967 begin
   4968   Result := FAbsoluteNodeIndex;
   4969 end;
   4970 
   4971 function TUnBufferedTreeNodeStream.TTreeWalkState.GetCurrentChildIndex: Integer;
   4972 begin
   4973   Result := FCurrentChildIndex;
   4974 end;
   4975 
   4976 function TUnBufferedTreeNodeStream.TTreeWalkState.GetCurrentNode: IANTLRInterface;
   4977 begin
   4978   Result := FCurrentNode;
   4979 end;
   4980 
   4981 function TUnBufferedTreeNodeStream.TTreeWalkState.GetIndexStackSize: integer;
   4982 begin
   4983   Result := FIndexStackSize;
   4984 end;
   4985 
   4986 function TUnBufferedTreeNodeStream.TTreeWalkState.GetLookAhead: TANTLRInterfaceArray;
   4987 begin
   4988   Result := FLookAhead;
   4989 end;
   4990 
   4991 function TUnBufferedTreeNodeStream.TTreeWalkState.GetNodeStackSize: Integer;
   4992 begin
   4993   Result := FNodeStackSize;
   4994 end;
   4995 
   4996 function TUnBufferedTreeNodeStream.TTreeWalkState.GetPreviousNode: IANTLRInterface;
   4997 begin
   4998   Result := FPreviousNode;
   4999 end;
   5000 
   5001 procedure TUnBufferedTreeNodeStream.TTreeWalkState.SetAbsoluteNodeIndex(
   5002   const Value: Integer);
   5003 begin
   5004   FAbsoluteNodeIndex := Value;
   5005 end;
   5006 
   5007 procedure TUnBufferedTreeNodeStream.TTreeWalkState.SetCurrentChildIndex(
   5008   const Value: Integer);
   5009 begin
   5010   FCurrentChildIndex := Value;
   5011 end;
   5012 
   5013 procedure TUnBufferedTreeNodeStream.TTreeWalkState.SetCurrentNode(
   5014   const Value: IANTLRInterface);
   5015 begin
   5016   FCurrentNode := Value;
   5017 end;
   5018 
   5019 procedure TUnBufferedTreeNodeStream.TTreeWalkState.SetIndexStackSize(
   5020   const Value: integer);
   5021 begin
   5022   FIndexStackSize := Value;
   5023 end;
   5024 
   5025 procedure TUnBufferedTreeNodeStream.TTreeWalkState.SetLookAhead(
   5026   const Value: TANTLRInterfaceArray);
   5027 begin
   5028   FLookAhead := Value;
   5029 end;
   5030 
   5031 procedure TUnBufferedTreeNodeStream.TTreeWalkState.SetNodeStackSize(
   5032   const Value: Integer);
   5033 begin
   5034   FNodeStackSize := Value;
   5035 end;
   5036 
   5037 procedure TUnBufferedTreeNodeStream.TTreeWalkState.SetPreviousNode(
   5038   const Value: IANTLRInterface);
   5039 begin
   5040   FPreviousNode := Value;
   5041 end;
   5042 
   5043 { Utilities }
   5044 
   5045 var
   5046   EmptyCommonTree: ICommonTree = nil;
   5047 
   5048 function Def(const X: ICommonTree): ICommonTree; overload;
   5049 begin
   5050   if Assigned(X) then
   5051     Result := X
   5052   else
   5053   begin
   5054     if (EmptyCommonTree = nil) then
   5055       EmptyCommonTree := TCommonTree.Create;
   5056     Result := EmptyCommonTree;
   5057   end;
   5058 end;
   5059 
   5060 initialization
   5061   TTree.Initialize;
   5062 
   5063 end.
   5064