1unit Antlr.Runtime.Tree;
2(*
3[The "BSD licence"]
4Copyright (c) 2008 Erik van Bilsen
5Copyright (c) 2005-2007 Kunle Odutola
6All rights reserved.
7
8Redistribution and use in source and binary forms, with or without
9modification, are permitted provided that the following conditions
10are met:
111. Redistributions of source code MUST RETAIN the above copyright
12   notice, this list of conditions and the following disclaimer.
132. 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.
173. The name of the author may not be used to endorse or promote products
18   derived from this software without specific prior WRITTEN permission.
194. 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
24THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*)
35
36interface
37
38{$IF CompilerVersion < 20}
39{$MESSAGE ERROR 'You need Delphi 2009 or higher to use the Antlr runtime'}
40{$IFEND}
41
42uses
43  Classes,
44  SysUtils,
45  Antlr.Runtime,
46  Antlr.Runtime.Tools,
47  Antlr.Runtime.Collections;
48
49type
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
1124type
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 }
2111function Def(const X: ICommonTree): ICommonTree; overload;
2112
2113implementation
2114
2115uses
2116  Math;
2117
2118{ TTree }
2119
2120class procedure TTree.Initialize;
2121begin
2122  FINVALID_NODE := TCommonTree.Create(TToken.INVALID_TOKEN);
2123end;
2124
2125{ TBaseTree }
2126
2127constructor TBaseTree.Create;
2128begin
2129  inherited;
2130end;
2131
2132procedure TBaseTree.AddChild(const T: ITree);
2133var
2134  ChildTree: IBaseTree;
2135  C: IBaseTree;
2136begin
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;
2178end;
2179
2180procedure TBaseTree.AddChildren(const Kids: IList<IBaseTree>);
2181var
2182  T: IBaseTree;
2183begin
2184  for T in Kids do
2185    AddChild(T);
2186end;
2187
2188constructor TBaseTree.Create(const ANode: ITree);
2189begin
2190  Create;
2191  // No default implementation
2192end;
2193
2194function TBaseTree.CreateChildrenList: IList<IBaseTree>;
2195begin
2196  Result := TList<IBaseTree>.Create;
2197end;
2198
2199function TBaseTree.DeleteChild(const I: Integer): IANTLRInterface;
2200begin
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;
2210end;
2211
2212procedure TBaseTree.FreshenParentAndChildIndexes(const Offset: Integer);
2213var
2214  N, C: Integer;
2215  Child: ITree;
2216begin
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;
2224end;
2225
2226procedure TBaseTree.FreshenParentAndChildIndexes;
2227begin
2228  FreshenParentAndChildIndexes(0);
2229end;
2230
2231function TBaseTree.GetCharPositionInLine: Integer;
2232begin
2233  Result := 0;
2234end;
2235
2236function TBaseTree.GetChild(const I: Integer): ITree;
2237begin
2238  if (FChildren = nil) or (I >= FChildren.Count) then
2239    Result := nil
2240  else
2241    Result := FChildren[I];
2242end;
2243
2244function TBaseTree.GetChildCount: Integer;
2245begin
2246  if Assigned(FChildren) then
2247    Result := FChildren.Count
2248  else
2249    Result := 0;
2250end;
2251
2252function TBaseTree.GetChildIndex: Integer;
2253begin
2254  // No default implementation
2255  Result := 0;
2256end;
2257
2258function TBaseTree.GetChildren: IList<IBaseTree>;
2259begin
2260  Result := FChildren;
2261end;
2262
2263function TBaseTree.GetIsNil: Boolean;
2264begin
2265  Result := False;
2266end;
2267
2268function TBaseTree.GetLine: Integer;
2269begin
2270  Result := 0;
2271end;
2272
2273function TBaseTree.GetParent: ITree;
2274begin
2275  // No default implementation
2276  Result := nil;
2277end;
2278
2279procedure TBaseTree.ReplaceChildren(const StartChildIndex,
2280  StopChildIndex: Integer; const T: IANTLRInterface);
2281var
2282  ReplacingHowMany, ReplacingWithHowMany, NumNewChildren, Delta, I, J: Integer;
2283  IndexToDelete, C, ReplacedSoFar: Integer;
2284  NewTree, Killed: IBaseTree;
2285  NewChildren: IList<IBaseTree>;
2286  Child: IBaseTree;
2287begin
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;
2355end;
2356
2357procedure TBaseTree.SanityCheckParentAndChildIndexes;
2358begin
2359  SanityCheckParentAndChildIndexes(nil, -1);
2360end;
2361
2362procedure TBaseTree.SanityCheckParentAndChildIndexes(const Parent: ITree;
2363  const I: Integer);
2364var
2365  N, C: Integer;
2366  Child: ICommonTree;
2367begin
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;
2382end;
2383
2384procedure TBaseTree.SetChild(const I: Integer; const T: ITree);
2385begin
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;
2400end;
2401
2402procedure TBaseTree.SetChildIndex(const Value: Integer);
2403begin
2404  // No default implementation
2405end;
2406
2407procedure TBaseTree.SetParent(const Value: ITree);
2408begin
2409  // No default implementation
2410end;
2411
2412function TBaseTree.ToStringTree: String;
2413var
2414  Buf: TStringBuilder;
2415  I: Integer;
2416  T: IBaseTree;
2417begin
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;
2447end;
2448
2449{ TCommonTree }
2450
2451constructor TCommonTree.Create;
2452begin
2453  inherited;
2454  FStartIndex := -1;
2455  FStopIndex := -1;
2456  FChildIndex := -1;
2457end;
2458
2459constructor TCommonTree.Create(const ANode: ICommonTree);
2460begin
2461  inherited Create(ANode);
2462  FToken := ANode.Token;
2463  FStartIndex := ANode.StartIndex;
2464  FStopIndex := ANode.StopIndex;
2465  FChildIndex := -1;
2466end;
2467
2468constructor TCommonTree.Create(const AToken: IToken);
2469begin
2470  Create;
2471  FToken := AToken;
2472end;
2473
2474function TCommonTree.DupNode: ITree;
2475begin
2476  Result := TCommonTree.Create(Self) as ICommonTree;
2477end;
2478
2479function TCommonTree.GetCharPositionInLine: Integer;
2480begin
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;
2490end;
2491
2492function TCommonTree.GetChildIndex: Integer;
2493begin
2494  Result := FChildIndex;
2495end;
2496
2497function TCommonTree.GetIsNil: Boolean;
2498begin
2499  Result := (FToken = nil);
2500end;
2501
2502function TCommonTree.GetLine: Integer;
2503begin
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;
2513end;
2514
2515function TCommonTree.GetParent: ITree;
2516begin
2517  Result := ITree(FParent);
2518end;
2519
2520function TCommonTree.GetStartIndex: Integer;
2521begin
2522  Result := FStartIndex;
2523end;
2524
2525function TCommonTree.GetStopIndex: Integer;
2526begin
2527  Result := FStopIndex;
2528end;
2529
2530function TCommonTree.GetText: String;
2531begin
2532  if (FToken = nil) then
2533    Result := ''
2534  else
2535    Result := FToken.Text;
2536end;
2537
2538function TCommonTree.GetToken: IToken;
2539begin
2540  Result := FToken;
2541end;
2542
2543function TCommonTree.GetTokenStartIndex: Integer;
2544begin
2545  if (FStartIndex = -1) and (FToken <> nil) then
2546    Result := FToken.TokenIndex
2547  else
2548    Result := FStartIndex;
2549end;
2550
2551function TCommonTree.GetTokenStopIndex: Integer;
2552begin
2553  if (FStopIndex = -1) and (FToken <> nil) then
2554    Result := FToken.TokenIndex
2555  else
2556    Result := FStopIndex;
2557end;
2558
2559function TCommonTree.GetTokenType: Integer;
2560begin
2561  if (FToken = nil) then
2562    Result := TToken.INVALID_TOKEN_TYPE
2563  else
2564    Result := FToken.TokenType;
2565end;
2566
2567procedure TCommonTree.SetChildIndex(const Value: Integer);
2568begin
2569  FChildIndex := Value;
2570end;
2571
2572procedure TCommonTree.SetParent(const Value: ITree);
2573begin
2574  FParent := Pointer(Value as ICommonTree);
2575end;
2576
2577procedure TCommonTree.SetStartIndex(const Value: Integer);
2578begin
2579  FStartIndex := Value;
2580end;
2581
2582procedure TCommonTree.SetStopIndex(const Value: Integer);
2583begin
2584  FStopIndex := Value;
2585end;
2586
2587procedure TCommonTree.SetTokenStartIndex(const Value: Integer);
2588begin
2589  FStartIndex := Value;
2590end;
2591
2592procedure TCommonTree.SetTokenStopIndex(const Value: Integer);
2593begin
2594  FStopIndex := Value;
2595end;
2596
2597function TCommonTree.ToString: String;
2598begin
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;
2609end;
2610
2611{ TCommonErrorNode }
2612
2613constructor TCommonErrorNode.Create(const AInput: ITokenStream; const AStart,
2614  AStop: IToken; const AException: ERecognitionException);
2615begin
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;
2630end;
2631
2632function TCommonErrorNode.GetIsNil: Boolean;
2633begin
2634  Result := False;
2635end;
2636
2637function TCommonErrorNode.GetText: String;
2638var
2639  I, J: Integer;
2640begin
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);
2647end;
2648
2649function TCommonErrorNode.GetTokenType: Integer;
2650begin
2651  Result := TToken.INVALID_TOKEN_TYPE;
2652end;
2653
2654function TCommonErrorNode.ToString: String;
2655begin
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 + '>';
2674end;
2675
2676{ TBaseTreeAdaptor }
2677
2678procedure TBaseTreeAdaptor.AddChild(const T, Child: IANTLRInterface);
2679begin
2680  if Assigned(T) and Assigned(Child) then
2681    (T as ITree).AddChild(Child as ITree);
2682end;
2683
2684function TBaseTreeAdaptor.BecomeRoot(const NewRoot,
2685  OldRoot: IANTLRInterface): IANTLRInterface;
2686var
2687  NewRootTree, OldRootTree: ITree;
2688  NC: Integer;
2689begin
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;
2712end;
2713
2714function TBaseTreeAdaptor.BecomeRoot(const NewRoot: IToken;
2715  const OldRoot: IANTLRInterface): IANTLRInterface;
2716begin
2717  Result := BecomeRoot(CreateNode(NewRoot), OldRoot);
2718end;
2719
2720function TBaseTreeAdaptor.CreateNode(const TokenType: Integer;
2721  const FromToken: IToken): IANTLRInterface;
2722var
2723  Token: IToken;
2724begin
2725  Token := CreateToken(FromToken);
2726  Token.TokenType := TokenType;
2727  Result := CreateNode(Token);
2728end;
2729
2730function TBaseTreeAdaptor.CreateNode(const TokenType: Integer;
2731  const Text: String): IANTLRInterface;
2732var
2733  Token: IToken;
2734begin
2735  Token := CreateToken(TokenType, Text);
2736  Result := CreateNode(Token);
2737end;
2738
2739function TBaseTreeAdaptor.CreateNode(const TokenType: Integer;
2740  const FromToken: IToken; const Text: String): IANTLRInterface;
2741var
2742  Token: IToken;
2743begin
2744  Token := CreateToken(FromToken);
2745  Token.TokenType := TokenType;
2746  Token.Text := Text;
2747  Result := CreateNode(Token);
2748end;
2749
2750constructor TBaseTreeAdaptor.Create;
2751begin
2752  inherited Create;
2753  FUniqueNodeID := 1;
2754end;
2755
2756function TBaseTreeAdaptor.DeleteChild(const T: IANTLRInterface;
2757  const I: Integer): IANTLRInterface;
2758begin
2759  Result := (T as ITree).DeleteChild(I);
2760end;
2761
2762function TBaseTreeAdaptor.DupTree(const T,
2763  Parent: IANTLRInterface): IANTLRInterface;
2764var
2765  I, N: Integer;
2766  Child, NewSubTree: IANTLRInterface;
2767begin
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;
2784end;
2785
2786function TBaseTreeAdaptor.DupTree(const Tree: IANTLRInterface): IANTLRInterface;
2787begin
2788  Result := DupTree(Tree, nil);
2789end;
2790
2791function TBaseTreeAdaptor.ErrorNode(const Input: ITokenStream; const Start,
2792  Stop: IToken; const E: ERecognitionException): IANTLRInterface;
2793begin
2794  Result := TCommonErrorNode.Create(Input, Start, Stop, E);
2795end;
2796
2797function TBaseTreeAdaptor.GetChild(const T: IANTLRInterface;
2798  const I: Integer): IANTLRInterface;
2799begin
2800  Result := (T as ITree).GetChild(I);
2801end;
2802
2803function TBaseTreeAdaptor.GetChildCount(const T: IANTLRInterface): Integer;
2804begin
2805  Result := (T as ITree).ChildCount;
2806end;
2807
2808function TBaseTreeAdaptor.GetNilNode: IANTLRInterface;
2809begin
2810  Result := CreateNode(nil);
2811end;
2812
2813function TBaseTreeAdaptor.GetNodeText(const T: IANTLRInterface): String;
2814begin
2815  Result := (T as ITree).Text;
2816end;
2817
2818function TBaseTreeAdaptor.GetNodeType(const T: IANTLRInterface): Integer;
2819begin
2820  Result := 0;
2821end;
2822
2823function TBaseTreeAdaptor.GetUniqueID(const Node: IANTLRInterface): Integer;
2824begin
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;
2833end;
2834
2835function TBaseTreeAdaptor.IsNil(const Tree: IANTLRInterface): Boolean;
2836begin
2837  Result := (Tree as ITree).IsNil;
2838end;
2839
2840function TBaseTreeAdaptor.RulePostProcessing(
2841  const Root: IANTLRInterface): IANTLRInterface;
2842var
2843  R: ITree;
2844begin
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;
2860end;
2861
2862procedure TBaseTreeAdaptor.SetChild(const T: IANTLRInterface; const I: Integer;
2863  const Child: IANTLRInterface);
2864begin
2865  (T as ITree).SetChild(I, Child as ITree);
2866end;
2867
2868procedure TBaseTreeAdaptor.SetNodeText(const T: IANTLRInterface;
2869  const Text: String);
2870begin
2871  raise EInvalidOperation.Create('don''t know enough about Tree node');
2872end;
2873
2874procedure TBaseTreeAdaptor.SetNodeType(const T: IANTLRInterface;
2875  const NodeType: Integer);
2876begin
2877  raise EInvalidOperation.Create('don''t know enough about Tree node');
2878end;
2879
2880{ TCommonTreeAdaptor }
2881
2882function TCommonTreeAdaptor.CreateNode(const Payload: IToken): IANTLRInterface;
2883begin
2884  Result := TCommonTree.Create(Payload);
2885end;
2886
2887function TCommonTreeAdaptor.CreateToken(const TokenType: Integer;
2888  const Text: String): IToken;
2889begin
2890  Result := TCommonToken.Create(TokenType, Text);
2891end;
2892
2893function TCommonTreeAdaptor.CreateToken(const FromToken: IToken): IToken;
2894begin
2895  Result := TCommonToken.Create(FromToken);
2896end;
2897
2898function TCommonTreeAdaptor.DupNode(
2899  const TreeNode: IANTLRInterface): IANTLRInterface;
2900begin
2901  if (TreeNode = nil) then
2902    Result := nil
2903  else
2904    Result := (TreeNode as ITree).DupNode;
2905end;
2906
2907function TCommonTreeAdaptor.GetChild(const T: IANTLRInterface;
2908  const I: Integer): IANTLRInterface;
2909begin
2910  if (T = nil) then
2911    Result := nil
2912  else
2913    Result := (T as ITree).GetChild(I);
2914end;
2915
2916function TCommonTreeAdaptor.GetChildCount(const T: IANTLRInterface): Integer;
2917begin
2918  if (T = nil) then
2919    Result := 0
2920  else
2921    Result := (T as ITree).ChildCount;
2922end;
2923
2924function TCommonTreeAdaptor.GetChildIndex(const T: IANTLRInterface): Integer;
2925begin
2926  Result := (T as ITree).ChildIndex;
2927end;
2928
2929function TCommonTreeAdaptor.GetNodeText(const T: IANTLRInterface): String;
2930begin
2931  if (T = nil) then
2932    Result := ''
2933  else
2934    Result := (T as ITree).Text;
2935end;
2936
2937function TCommonTreeAdaptor.GetNodeType(const T: IANTLRInterface): Integer;
2938begin
2939  if (T = nil) then
2940    Result := TToken.INVALID_TOKEN_TYPE
2941  else
2942    Result := (T as ITree).TokenType;
2943end;
2944
2945function TCommonTreeAdaptor.GetParent(
2946  const T: IANTLRInterface): IANTLRInterface;
2947begin
2948  Result := (T as ITree).Parent;
2949end;
2950
2951function TCommonTreeAdaptor.GetToken(const TreeNode: IANTLRInterface): IToken;
2952var
2953  CommonTree: ICommonTree;
2954begin
2955  if Supports(TreeNode, ICommonTree, CommonTree) then
2956    Result := CommonTree.Token
2957  else
2958    Result := nil; // no idea what to do
2959end;
2960
2961function TCommonTreeAdaptor.GetTokenStartIndex(
2962  const T: IANTLRInterface): Integer;
2963begin
2964  if (T = nil) then
2965    Result := -1
2966  else
2967    Result := (T as ITree).TokenStartIndex;
2968end;
2969
2970function TCommonTreeAdaptor.GetTokenStopIndex(
2971  const T: IANTLRInterface): Integer;
2972begin
2973  if (T = nil) then
2974    Result := -1
2975  else
2976    Result := (T as ITree).TokenStopIndex;
2977end;
2978
2979procedure TCommonTreeAdaptor.ReplaceChildren(const Parent: IANTLRInterface;
2980  const StartChildIndex, StopChildIndex: Integer; const T: IANTLRInterface);
2981begin
2982  if Assigned(Parent) then
2983    (Parent as ITree).ReplaceChildren(StartChildIndex, StopChildIndex, T);
2984end;
2985
2986procedure TCommonTreeAdaptor.SetChildIdex(const T: IANTLRInterface;
2987  const Index: Integer);
2988begin
2989  (T as ITree).ChildIndex := Index;
2990end;
2991
2992procedure TCommonTreeAdaptor.SetParent(const T, Parent: IANTLRInterface);
2993begin
2994  (T as ITree).Parent := (Parent as ITree);
2995end;
2996
2997procedure TCommonTreeAdaptor.SetTokenBoundaries(const T: IANTLRInterface;
2998  const StartToken, StopToken: IToken);
2999var
3000  Start, Stop: Integer;
3001begin
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;
3017end;
3018
3019{ TCommonTreeNodeStream }
3020
3021procedure TCommonTreeNodeStream.AddNavigationNode(const TokenType: Integer);
3022var
3023  NavNode: IANTLRInterface;
3024begin
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);
3040end;
3041
3042procedure TCommonTreeNodeStream.Consume;
3043begin
3044  if (FP = -1) then
3045    FillBuffer;
3046  Inc(FP);
3047end;
3048
3049constructor TCommonTreeNodeStream.Create;
3050begin
3051  inherited;
3052  FP := -1;
3053end;
3054
3055constructor TCommonTreeNodeStream.Create(const ATree: IANTLRInterface);
3056begin
3057  Create(TCommonTreeAdaptor.Create, ATree);
3058end;
3059
3060constructor TCommonTreeNodeStream.Create(const AAdaptor: ITreeAdaptor;
3061  const ATree: IANTLRInterface);
3062begin
3063  Create(AAdaptor, ATree, DEFAULT_INITIAL_BUFFER_SIZE);
3064end;
3065
3066constructor TCommonTreeNodeStream.Create(const AAdaptor: ITreeAdaptor;
3067  const ATree: IANTLRInterface; const AInitialBufferSize: Integer);
3068begin
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');
3077end;
3078
3079procedure TCommonTreeNodeStream.FillBuffer;
3080begin
3081  FillBuffer(FRoot);
3082  FP := 0; // buffer of nodes intialized now
3083end;
3084
3085procedure TCommonTreeNodeStream.FillBuffer(const T: IANTLRInterface);
3086var
3087  IsNil: Boolean;
3088  C, N: Integer;
3089begin
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);
3106end;
3107
3108function TCommonTreeNodeStream.Get(const I: Integer): IANTLRInterface;
3109begin
3110  if (FP = -1) then
3111    FillBuffer;
3112  Result := FNodes[I];
3113end;
3114
3115function TCommonTreeNodeStream.GetCurrentSymbol: IANTLRInterface;
3116begin
3117  Result := LT(1);
3118end;
3119
3120function TCommonTreeNodeStream.GetHasUniqueNavigationNodes: Boolean;
3121begin
3122  Result := FUniqueNavigationNodes;
3123end;
3124
3125function TCommonTreeNodeStream.GetNodeIndex(
3126  const Node: IANTLRInterface): Integer;
3127var
3128  T: IANTLRInterface;
3129begin
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;
3139end;
3140
3141function TCommonTreeNodeStream.GetSourceName: String;
3142begin
3143  Result := GetTokenStream.SourceName;
3144end;
3145
3146function TCommonTreeNodeStream.GetTokenStream: ITokenStream;
3147begin
3148  Result := FTokens;
3149end;
3150
3151function TCommonTreeNodeStream.GetTreeAdaptor: ITreeAdaptor;
3152begin
3153  Result := FAdaptor;
3154end;
3155
3156function TCommonTreeNodeStream.GetTreeSource: IANTLRInterface;
3157begin
3158  Result := FRoot;
3159end;
3160
3161function TCommonTreeNodeStream.Index: Integer;
3162begin
3163  Result := FP;
3164end;
3165
3166function TCommonTreeNodeStream.LA(I: Integer): Integer;
3167begin
3168  Result := FAdaptor.GetNodeType(LT(I));
3169end;
3170
3171function TCommonTreeNodeStream.LAChar(I: Integer): Char;
3172begin
3173  Result := Char(LA(I));
3174end;
3175
3176function TCommonTreeNodeStream.LB(const K: Integer): IANTLRInterface;
3177begin
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];
3185end;
3186
3187function TCommonTreeNodeStream.LT(const K: Integer): IANTLRInterface;
3188begin
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];
3201end;
3202
3203function TCommonTreeNodeStream.Mark: Integer;
3204begin
3205  if (FP = -1) then
3206    FillBuffer;
3207  FLastMarker := Index;
3208  Result := FLastMarker;
3209end;
3210
3211function TCommonTreeNodeStream.Pop: Integer;
3212begin
3213  Result := FCalls.Pop;
3214  Seek(Result);
3215end;
3216
3217procedure TCommonTreeNodeStream.Push(const Index: Integer);
3218begin
3219  if (FCalls = nil) then
3220    FCalls := TStackList<Integer>.Create;
3221  FCalls.Push(FP); // save current index
3222  Seek(Index);
3223end;
3224
3225procedure TCommonTreeNodeStream.Release(const Marker: Integer);
3226begin
3227  // no resources to release
3228end;
3229
3230procedure TCommonTreeNodeStream.ReplaceChildren(const Parent: IANTLRInterface;
3231  const StartChildIndex, StopChildIndex: Integer; const T: IANTLRInterface);
3232begin
3233  if Assigned(Parent) then
3234    FAdaptor.ReplaceChildren(Parent, StartChildIndex, StopChildIndex, T);
3235end;
3236
3237procedure TCommonTreeNodeStream.Reset;
3238begin
3239  FP := -1;
3240  FLastMarker := 0;
3241  if Assigned(FCalls) then
3242    FCalls.Clear;
3243end;
3244
3245procedure TCommonTreeNodeStream.Rewind(const Marker: Integer);
3246begin
3247  Seek(Marker);
3248end;
3249
3250procedure TCommonTreeNodeStream.Rewind;
3251begin
3252  Seek(FLastMarker);
3253end;
3254
3255procedure TCommonTreeNodeStream.Seek(const Index: Integer);
3256begin
3257  if (FP = -1) then
3258    FillBuffer;
3259  FP := Index;
3260end;
3261
3262procedure TCommonTreeNodeStream.SetHasUniqueNavigationNodes(
3263  const Value: Boolean);
3264begin
3265  FUniqueNavigationNodes := Value;
3266end;
3267
3268procedure TCommonTreeNodeStream.SetTokenStream(const Value: ITokenStream);
3269begin
3270  FTokens := Value;
3271end;
3272
3273procedure TCommonTreeNodeStream.SetTreeAdaptor(const Value: ITreeAdaptor);
3274begin
3275  FAdaptor := Value;
3276end;
3277
3278function TCommonTreeNodeStream.Size: Integer;
3279begin
3280  if (FP = -1) then
3281    FillBuffer;
3282  Result := FNodes.Count;
3283end;
3284
3285function TCommonTreeNodeStream.ToString(const Start,
3286  Stop: IANTLRInterface): String;
3287var
3288  CommonTree: ICommonTree;
3289  I, BeginTokenIndex, EndTokenIndex: Integer;
3290  T: IANTLRInterface;
3291  Buf: TStringBuilder;
3292  Text: String;
3293begin
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;
3360end;
3361
3362function TCommonTreeNodeStream.ToString: String;
3363var
3364  Buf: TStringBuilder;
3365  T: IANTLRInterface;
3366begin
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;
3380end;
3381
3382function TCommonTreeNodeStream.ToTokenString(const Start,
3383  Stop: Integer): String;
3384var
3385  I: Integer;
3386  T: IANTLRInterface;
3387  Buf: TStringBuilder;
3388begin
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;
3404end;
3405
3406{ TParseTree }
3407
3408constructor TParseTree.Create(const ALabel: IANTLRInterface);
3409begin
3410  inherited Create;
3411  FPayload := ALabel;
3412end;
3413
3414function TParseTree.DupNode: ITree;
3415begin
3416  Result := nil;
3417end;
3418
3419function TParseTree.GetText: String;
3420begin
3421  Result := ToString;
3422end;
3423
3424function TParseTree.GetTokenStartIndex: Integer;
3425begin
3426  Result := 0;
3427end;
3428
3429function TParseTree.GetTokenStopIndex: Integer;
3430begin
3431  Result := 0;
3432end;
3433
3434function TParseTree.GetTokenType: Integer;
3435begin
3436  Result := 0;
3437end;
3438
3439procedure TParseTree.SetTokenStartIndex(const Value: Integer);
3440begin
3441  // No implementation
3442end;
3443
3444procedure TParseTree.SetTokenStopIndex(const Value: Integer);
3445begin
3446  // No implementation
3447end;
3448
3449function TParseTree.ToInputString: String;
3450var
3451  Buf: TStringBuilder;
3452begin
3453  Buf := TStringBuilder.Create;
3454  try
3455    _ToStringLeaves(Buf);
3456    Result := Buf.ToString;
3457  finally
3458    Buf.Free;
3459  end;
3460end;
3461
3462function TParseTree.ToString: String;
3463var
3464  T: IToken;
3465begin
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;
3475end;
3476
3477function TParseTree.ToStringWithHiddenTokens: String;
3478var
3479  Buf: TStringBuilder;
3480  Hidden: IToken;
3481  NodeText: String;
3482begin
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;
3497end;
3498
3499procedure TParseTree._ToStringLeaves(const Buf: TStringBuilder);
3500var
3501  T: IBaseTree;
3502begin
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);
3512end;
3513
3514{ ERewriteCardinalityException }
3515
3516constructor ERewriteCardinalityException.Create(
3517  const AElementDescription: String);
3518begin
3519  inherited Create(AElementDescription);
3520  FElementDescription := AElementDescription;
3521end;
3522
3523{ TRewriteRuleElementStream }
3524
3525procedure TRewriteRuleElementStream.Add(const El: IANTLRInterface);
3526begin
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;
3545end;
3546
3547constructor TRewriteRuleElementStream.Create(const AAdaptor: ITreeAdaptor;
3548  const AElementDescription: String);
3549begin
3550  inherited Create;
3551  FAdaptor := AAdaptor;
3552  FElementDescription := AElementDescription;
3553end;
3554
3555constructor TRewriteRuleElementStream.Create(const AAdaptor: ITreeAdaptor;
3556  const AElementDescription: String; const AOneElement: IANTLRInterface);
3557begin
3558  Create(AAdaptor, AElementDescription);
3559  Add(AOneElement);
3560end;
3561
3562constructor TRewriteRuleElementStream.Create(const AAdaptor: ITreeAdaptor;
3563  const AElementDescription: String; const AElements: IList<IANTLRInterface>);
3564begin
3565  Create(AAdaptor, AElementDescription);
3566  FElements := AElements;
3567end;
3568
3569function TRewriteRuleElementStream.GetDescription: String;
3570begin
3571  Result := FElementDescription;
3572end;
3573
3574function TRewriteRuleElementStream.HasNext: Boolean;
3575begin
3576  Result := ((FSingleElement <> nil) and (FCursor < 1))
3577    or ((FElements <> nil) and (FCursor < FElements.Count));
3578end;
3579
3580function TRewriteRuleElementStream.NextTree: IANTLRInterface;
3581begin
3582  Result := _Next;
3583end;
3584
3585procedure TRewriteRuleElementStream.Reset;
3586begin
3587  FCursor := 0;
3588  FDirty := True;
3589end;
3590
3591function TRewriteRuleElementStream.Size: Integer;
3592begin
3593  if Assigned(FSingleElement) then
3594    Result := 1
3595  else
3596    if Assigned(FElements) then
3597      Result := FElements.Count
3598    else
3599      Result := 0;
3600end;
3601
3602function TRewriteRuleElementStream.ToTree(const El: IANTLRInterface): IANTLRInterface;
3603begin
3604  Result := El;
3605end;
3606
3607function TRewriteRuleElementStream._Next: IANTLRInterface;
3608var
3609  Size: Integer;
3610begin
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;
3640end;
3641
3642{ TRewriteRuleNodeStream }
3643
3644function TRewriteRuleNodeStream.NextNode: IANTLRInterface;
3645begin
3646  Result := _Next;
3647end;
3648
3649function TRewriteRuleNodeStream.ToTree(
3650  const El: IANTLRInterface): IANTLRInterface;
3651begin
3652  Result := FAdaptor.DupNode(El);
3653end;
3654
3655{ TRewriteRuleSubtreeStream }
3656
3657function TRewriteRuleSubtreeStream.Dup(
3658  const O: IANTLRInterface): IANTLRInterface;
3659begin
3660  Result := FAdaptor.DupTree(O);
3661end;
3662
3663function TRewriteRuleSubtreeStream.DupNode(
3664  const O: IANTLRInterface): IANTLRInterface;
3665begin
3666  Result := FAdaptor.DupNode(O);
3667end;
3668
3669function TRewriteRuleSubtreeStream.FetchObject(
3670  const PH: TProcessHandler): IANTLRInterface;
3671begin
3672  if (RequiresDuplication) then
3673    // process the object
3674    Result := PH(_Next)
3675  else
3676    // test above then fetch
3677    Result := _Next;
3678end;
3679
3680function TRewriteRuleSubtreeStream.NextNode: IANTLRInterface;
3681begin
3682  // if necessary, dup (at most a single node since this is for making root nodes).
3683  Result := FetchObject(DupNode);
3684end;
3685
3686function TRewriteRuleSubtreeStream.NextTree: IANTLRInterface;
3687begin
3688  // if out of elements and size is 1, dup
3689  Result := FetchObject(Dup);
3690end;
3691
3692function TRewriteRuleSubtreeStream.RequiresDuplication: Boolean;
3693var
3694  Size: Integer;
3695begin
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));
3699end;
3700
3701{ TRewriteRuleTokenStream }
3702
3703function TRewriteRuleTokenStream.NextNode: IANTLRInterface;
3704begin
3705  Result := FAdaptor.CreateNode(_Next as IToken)
3706end;
3707
3708function TRewriteRuleTokenStream.NextToken: IToken;
3709begin
3710  Result := _Next as IToken;
3711end;
3712
3713function TRewriteRuleTokenStream.ToTree(
3714  const El: IANTLRInterface): IANTLRInterface;
3715begin
3716  Result := El;
3717end;
3718
3719{ TTreeParser }
3720
3721constructor TTreeParser.Create(const AInput: ITreeNodeStream);
3722begin
3723  inherited Create; // highlight that we go to super to set state object
3724  SetTreeNodeStream(AInput);
3725end;
3726
3727constructor TTreeParser.Create(const AInput: ITreeNodeStream;
3728  const AState: IRecognizerSharedState);
3729begin
3730  inherited Create(AState); // share the state object with another parser
3731  SetTreeNodeStream(AInput);
3732end;
3733
3734function TTreeParser.GetCurrentInputSymbol(
3735  const Input: IIntStream): IANTLRInterface;
3736begin
3737  Result := FInput.LT(1);
3738end;
3739
3740function TTreeParser.GetErrorHeader(const E: ERecognitionException): String;
3741begin
3742  Result := GetGrammarFileName + ': node from ';
3743  if (E.ApproximateLineInfo) then
3744    Result := Result + 'after ';
3745  Result := Result + 'line ' + IntToStr(E.Line) + ':' + IntToStr(E.CharPositionInLine);
3746end;
3747
3748function TTreeParser.GetErrorMessage(const E: ERecognitionException;
3749  const TokenNames: TStringArray): String;
3750var
3751  Adaptor: ITreeAdaptor;
3752begin
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);
3763end;
3764
3765function TTreeParser.GetInput: IIntStream;
3766begin
3767  Result := FInput;
3768end;
3769
3770function TTreeParser.GetMissingSymbol(const Input: IIntStream;
3771  const E: ERecognitionException; const ExpectedTokenType: Integer;
3772  const Follow: IBitSet): IANTLRInterface;
3773var
3774  TokenText: String;
3775begin
3776  TokenText := '<missing ' + GetTokenNames[ExpectedTokenType] + '>';
3777  Result := TCommonTree.Create(TCommonToken.Create(ExpectedTokenType, TokenText));
3778end;
3779
3780function TTreeParser.GetSourceName: String;
3781begin
3782  Result := FInput.SourceName;
3783end;
3784
3785function TTreeParser.GetTreeNodeStream: ITreeNodeStream;
3786begin
3787  Result := FInput;
3788end;
3789
3790procedure TTreeParser.MatchAny(const Input: IIntStream);
3791var
3792  Look: IANTLRInterface;
3793  Level, TokenType: Integer;
3794begin
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
3820end;
3821
3822procedure TTreeParser.Mismatch(const Input: IIntStream;
3823  const TokenType: Integer; const Follow: IBitSet);
3824begin
3825  raise EMismatchedTreeNodeException.Create(TokenType, FInput);
3826end;
3827
3828procedure TTreeParser.Reset;
3829begin
3830  inherited; // reset all recognizer state variables
3831  if Assigned(FInput) then
3832    FInput.Seek(0); // rewind the input
3833end;
3834
3835procedure TTreeParser.SetTreeNodeStream(const Value: ITreeNodeStream);
3836begin
3837  FInput := Value;
3838end;
3839
3840procedure TTreeParser.TraceIn(const RuleName: String; const RuleIndex: Integer);
3841begin
3842  inherited TraceIn(RuleName, RuleIndex, FInput.LT(1).ToString);
3843end;
3844
3845procedure TTreeParser.TraceOut(const RuleName: String;
3846  const RuleIndex: Integer);
3847begin
3848  inherited TraceOut(RuleName, RuleIndex, FInput.LT(1).ToString);
3849end;
3850
3851{ TTreePatternLexer }
3852
3853constructor TTreePatternLexer.Create;
3854begin
3855  inherited;
3856  FSVal := TStringBuilder.Create;
3857end;
3858
3859procedure TTreePatternLexer.Consume;
3860begin
3861  Inc(FP);
3862  if (FP > FN) then
3863    FC := EOF
3864  else
3865    FC := Integer(FPattern[FP]);
3866end;
3867
3868constructor TTreePatternLexer.Create(const APattern: String);
3869begin
3870  Create;
3871  FPattern := APattern;
3872  FN := Length(FPattern);
3873  Consume;
3874end;
3875
3876destructor TTreePatternLexer.Destroy;
3877begin
3878  FSVal.Free;
3879  inherited;
3880end;
3881
3882function TTreePatternLexer.NextToken: Integer;
3883begin
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;
3966end;
3967
3968function TTreePatternLexer.SVal: String;
3969begin
3970  Result := FSVal.ToString;
3971end;
3972
3973{ TTreeWizard }
3974
3975function TTreeWizard.ComputeTokenTypes(
3976  const TokenNames: TStringArray): IDictionary<String, Integer>;
3977var
3978  TokenType: Integer;
3979begin
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;
3986end;
3987
3988constructor TTreeWizard.Create(const AAdaptor: ITreeAdaptor);
3989begin
3990  inherited Create;
3991  FAdaptor := AAdaptor;
3992end;
3993
3994constructor TTreeWizard.Create(const AAdaptor: ITreeAdaptor;
3995  const ATokenNameToTypeMap: IDictionary<String, Integer>);
3996begin
3997  inherited Create;
3998  FAdaptor := AAdaptor;
3999  FTokenNameToTypeMap := ATokenNameToTypeMap;
4000end;
4001
4002constructor TTreeWizard.Create(const AAdaptor: ITreeAdaptor;
4003  const TokenNames: TStringArray);
4004begin
4005  inherited Create;
4006  FAdaptor := AAdaptor;
4007  FTokenNameToTypeMap := ComputeTokenTypes(TokenNames);
4008end;
4009
4010function TTreeWizard.CreateTreeOrNode(const Pattern: String): IANTLRInterface;
4011var
4012  Tokenizer: ITreePatternLexer;
4013  Parser: ITreePatternParser;
4014begin
4015  Tokenizer := TTreePatternLexer.Create(Pattern);
4016  Parser := TTreePatternParser.Create(Tokenizer, Self, FAdaptor);
4017  Result := Parser.Pattern;
4018end;
4019
4020function TTreeWizard.Equals(const T1, T2: IANTLRInterface;
4021  const Adaptor: ITreeAdaptor): Boolean;
4022begin
4023  Result := _Equals(T1, T2, Adaptor);
4024end;
4025
4026function TTreeWizard.Equals(const T1, T2: IANTLRInterface): Boolean;
4027begin
4028  Result := _Equals(T1, T2, FAdaptor);
4029end;
4030
4031function TTreeWizard.Find(const T: IANTLRInterface;
4032  const Pattern: String): IList<IANTLRInterface>;
4033var
4034  Tokenizer: ITreePatternLexer;
4035  Parser: ITreePatternParser;
4036  TreePattern: ITreePattern;
4037  RootTokenType: Integer;
4038  Visitor: IContextVisitor;
4039begin
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);
4056end;
4057
4058function TTreeWizard.Find(const T: IANTLRInterface;
4059  const TokenType: Integer): IList<IANTLRInterface>;
4060begin
4061  Result := TList<IANTLRInterface>.Create;
4062  Visit(T, TokenType, TRecordAllElementsVisitor.Create(Result));
4063end;
4064
4065function TTreeWizard.FindFirst(const T: IANTLRInterface;
4066  const TokenType: Integer): IANTLRInterface;
4067begin
4068  Result := nil;
4069end;
4070
4071function TTreeWizard.FindFirst(const T: IANTLRInterface;
4072  const Pattern: String): IANTLRInterface;
4073begin
4074  Result := nil;
4075end;
4076
4077function TTreeWizard.GetTokenType(const TokenName: String): Integer;
4078begin
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;
4083end;
4084
4085function TTreeWizard.Index(
4086  const T: IANTLRInterface): IDictionary<Integer, IList<IANTLRInterface>>;
4087begin
4088  Result := TDictionary<Integer, IList<IANTLRInterface>>.Create;
4089  _Index(T, Result);
4090end;
4091
4092function TTreeWizard.Parse(const T: IANTLRInterface;
4093  const Pattern: String): Boolean;
4094begin
4095  Result := Parse(T, Pattern, nil);
4096end;
4097
4098function TTreeWizard.Parse(const T: IANTLRInterface; const Pattern: String;
4099  const Labels: IDictionary<String, IANTLRInterface>): Boolean;
4100var
4101  Tokenizer: ITreePatternLexer;
4102  Parser: ITreePatternParser;
4103  TreePattern: ITreePattern;
4104begin
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);
4109end;
4110
4111procedure TTreeWizard.Visit(const T: IANTLRInterface; const Pattern: String;
4112  const Visitor: IContextVisitor);
4113var
4114  Tokenizer: ITreePatternLexer;
4115  Parser: ITreePatternParser;
4116  TreePattern: ITreePattern;
4117  RootTokenType: Integer;
4118  PatternVisitor: IContextVisitor;
4119begin
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);
4131end;
4132
4133class function TTreeWizard._Equals(const T1, T2: IANTLRInterface;
4134  const Adaptor: ITreeAdaptor): Boolean;
4135var
4136  I, N1, N2: Integer;
4137  Child1, Child2: IANTLRInterface;
4138begin
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;
4163end;
4164
4165procedure TTreeWizard._Index(const T: IANTLRInterface;
4166  const M: IDictionary<Integer, IList<IANTLRInterface>>);
4167var
4168  I, N, TType: Integer;
4169  Elements: IList<IANTLRInterface>;
4170begin
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);
4185end;
4186
4187function TTreeWizard._Parse(const T1: IANTLRInterface; const T2: ITreePattern;
4188  const Labels: IDictionary<String, IANTLRInterface>): Boolean;
4189var
4190  I, N1, N2: Integer;
4191  Child1: IANTLRInterface;
4192  Child2: ITreePattern;
4193begin
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;
4226end;
4227
4228procedure TTreeWizard._Visit(const T, Parent: IANTLRInterface; const ChildIndex,
4229  TokenType: Integer; const Visitor: IContextVisitor);
4230var
4231  I, N: Integer;
4232begin
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);
4241end;
4242
4243procedure TTreeWizard.Visit(const T: IANTLRInterface; const TokenType: Integer;
4244  const Visitor: IContextVisitor);
4245begin
4246  _Visit(T, nil, 0, TokenType, Visitor);
4247end;
4248
4249constructor TTreeWizard.Create(const TokenNames: TStringArray);
4250begin
4251  Create(nil, TokenNames);
4252end;
4253
4254{ TTreePatternParser }
4255
4256constructor TTreePatternParser.Create(const ATokenizer: ITreePatternLexer;
4257  const AWizard: ITreeWizard; const AAdaptor: ITreeAdaptor);
4258begin
4259  inherited Create;
4260  FTokenizer := ATokenizer;
4261  FWizard := AWizard;
4262  FAdaptor := AAdaptor;
4263  FTokenType := FTokenizer.NextToken; // kickstart
4264end;
4265
4266function TTreePatternParser.ParseNode: IANTLRInterface;
4267var
4268  Lbl, TokenName, Text, Arg: String;
4269  WildcardPayload: IToken;
4270  Node: TTreeWizard.ITreePattern;
4271  TreeNodeType: Integer;
4272begin
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;
4326end;
4327
4328function TTreePatternParser.ParseTree: IANTLRInterface;
4329var
4330  Subtree, Child: IANTLRInterface;
4331begin
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;
4367end;
4368
4369function TTreePatternParser.Pattern: IANTLRInterface;
4370var
4371  Node: IANTLRInterface;
4372begin
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;
4386end;
4387
4388{ TTreeWizard.TVisitor }
4389
4390procedure TTreeWizard.TVisitor.Visit(const T, Parent: IANTLRInterface;
4391  const ChildIndex: Integer;
4392  const Labels: IDictionary<String, IANTLRInterface>);
4393begin
4394  Visit(T);
4395end;
4396
4397{ TTreeWizard.TRecordAllElementsVisitor }
4398
4399constructor TTreeWizard.TRecordAllElementsVisitor.Create(
4400  const AList: IList<IANTLRInterface>);
4401begin
4402  inherited Create;
4403  FList := AList;
4404end;
4405
4406procedure TTreeWizard.TRecordAllElementsVisitor.Visit(const T: IANTLRInterface);
4407begin
4408  FList.Add(T);
4409end;
4410
4411{ TTreeWizard.TPatternMatchingContextVisitor }
4412
4413constructor TTreeWizard.TPatternMatchingContextVisitor.Create(
4414  const AOwner: TTreeWizard; const APattern: ITreePattern;
4415  const AList: IList<IANTLRInterface>);
4416begin
4417  inherited Create;
4418  FOwner := AOwner;
4419  FPattern := APattern;
4420  FList := AList;
4421end;
4422
4423procedure TTreeWizard.TPatternMatchingContextVisitor.Visit(const T,
4424  Parent: IANTLRInterface; const ChildIndex: Integer;
4425  const Labels: IDictionary<String, IANTLRInterface>);
4426begin
4427  if (FOwner._Parse(T, FPattern, nil)) then
4428    FList.Add(T);
4429end;
4430
4431{ TTreeWizard.TInvokeVisitorOnPatternMatchContextVisitor }
4432
4433constructor TTreeWizard.TInvokeVisitorOnPatternMatchContextVisitor.Create(
4434  const AOwner: TTreeWizard; const APattern: ITreePattern;
4435  const AVisitor: IContextVisitor);
4436begin
4437  inherited Create;
4438  FOwner := AOwner;
4439  FPattern := APattern;
4440  FVisitor := AVisitor;
4441  FLabels := TDictionary<String, IANTLRInterface>.Create;
4442end;
4443
4444procedure TTreeWizard.TInvokeVisitorOnPatternMatchContextVisitor.Visit(const T,
4445  Parent: IANTLRInterface; const ChildIndex: Integer;
4446  const UnusedLabels: IDictionary<String, IANTLRInterface>);
4447begin
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);
4452end;
4453
4454{ TTreeWizard.TTreePattern }
4455
4456function TTreeWizard.TTreePattern.GetHasTextArg: Boolean;
4457begin
4458  Result := FHasTextArg;
4459end;
4460
4461function TTreeWizard.TTreePattern.GetTokenLabel: String;
4462begin
4463  Result := FLabel;
4464end;
4465
4466procedure TTreeWizard.TTreePattern.SetHasTextArg(const Value: Boolean);
4467begin
4468  FHasTextArg := Value;
4469end;
4470
4471procedure TTreeWizard.TTreePattern.SetTokenLabel(const Value: String);
4472begin
4473  FLabel := Value;
4474end;
4475
4476function TTreeWizard.TTreePattern.ToString: String;
4477begin
4478  if (FLabel <> '') then
4479    Result := '%' + FLabel + ':' + inherited ToString
4480  else
4481    Result := inherited ToString;
4482end;
4483
4484{ TTreeWizard.TTreePatternTreeAdaptor }
4485
4486function TTreeWizard.TTreePatternTreeAdaptor.CreateNode(
4487  const Payload: IToken): IANTLRInterface;
4488begin
4489  Result := TTreePattern.Create(Payload);
4490end;
4491
4492{ TTreeRuleReturnScope }
4493
4494function TTreeRuleReturnScope.GetStart: IANTLRInterface;
4495begin
4496  Result := FStart;
4497end;
4498
4499procedure TTreeRuleReturnScope.SetStart(const Value: IANTLRInterface);
4500begin
4501  FStart := Value;
4502end;
4503
4504{ TUnBufferedTreeNodeStream }
4505
4506procedure TUnBufferedTreeNodeStream.AddLookahead(const Node: IANTLRInterface);
4507var
4508  Bigger: TANTLRInterfaceArray;
4509  I, RemainderHeadToEnd: Integer;
4510begin
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;
4529end;
4530
4531procedure TUnBufferedTreeNodeStream.AddNavigationNode(const TokenType: Integer);
4532var
4533  NavNode: IANTLRInterface;
4534begin
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);
4550end;
4551
4552procedure TUnBufferedTreeNodeStream.Consume;
4553begin
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);
4559end;
4560
4561constructor TUnBufferedTreeNodeStream.Create;
4562begin
4563  inherited;
4564  SetLength(FLookAhead,INITIAL_LOOKAHEAD_BUFFER_SIZE);
4565  FNodeStack := TStackList<IANTLRInterface>.Create;
4566  FIndexStack := TStackList<Integer>.Create;
4567end;
4568
4569constructor TUnBufferedTreeNodeStream.Create(const ATree: IANTLRInterface);
4570begin
4571  Create(TCommonTreeAdaptor.Create, ATree);
4572end;
4573
4574constructor TUnBufferedTreeNodeStream.Create(const AAdaptor: ITreeAdaptor;
4575  const ATree: IANTLRInterface);
4576begin
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');
4584end;
4585
4586procedure TUnBufferedTreeNodeStream.Fill(const K: Integer);
4587var
4588  I, N: Integer;
4589begin
4590  N := LookaheadSize;
4591  for I := 1 to K - N do
4592    MoveNext; // get at least k-depth lookahead nodes
4593end;
4594
4595function TUnBufferedTreeNodeStream.Get(const I: Integer): IANTLRInterface;
4596begin
4597  raise EInvalidOperation.Create('stream is unbuffered');
4598end;
4599
4600function TUnBufferedTreeNodeStream.GetCurrent: IANTLRInterface;
4601begin
4602  Result := FCurrentEnumerationNode;
4603end;
4604
4605function TUnBufferedTreeNodeStream.GetHasUniqueNavigationNodes: Boolean;
4606begin
4607  Result := FUniqueNavigationNodes;
4608end;
4609
4610function TUnBufferedTreeNodeStream.GetSourceName: String;
4611begin
4612  Result := GetTokenStream.SourceName;
4613end;
4614
4615function TUnBufferedTreeNodeStream.GetTokenStream: ITokenStream;
4616begin
4617  Result := FTokens;
4618end;
4619
4620function TUnBufferedTreeNodeStream.GetTreeAdaptor: ITreeAdaptor;
4621begin
4622  Result := FAdaptor;
4623end;
4624
4625function TUnBufferedTreeNodeStream.GetTreeSource: IANTLRInterface;
4626begin
4627  Result := FRoot;
4628end;
4629
4630function TUnBufferedTreeNodeStream.HandleRootNode: IANTLRInterface;
4631begin
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;
4645end;
4646
4647function TUnBufferedTreeNodeStream.Index: Integer;
4648begin
4649  Result := FAbsoluteNodeIndex + 1;
4650end;
4651
4652function TUnBufferedTreeNodeStream.LA(I: Integer): Integer;
4653var
4654  T: IANTLRInterface;
4655begin
4656  T := LT(I);
4657  if (T = nil) then
4658    Result := TToken.INVALID_TOKEN_TYPE
4659  else
4660    Result := FAdaptor.GetNodeType(T);
4661end;
4662
4663function TUnBufferedTreeNodeStream.LAChar(I: Integer): Char;
4664begin
4665  Result := Char(LA(I));
4666end;
4667
4668function TUnBufferedTreeNodeStream.LookaheadSize: Integer;
4669begin
4670  if (FTail < FHead) then
4671    Result := Length(FLookahead) - FHead + FTail
4672  else
4673    Result := FTail - FHead;
4674end;
4675
4676function TUnBufferedTreeNodeStream.LT(const K: Integer): IANTLRInterface;
4677begin
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)];
4689end;
4690
4691function TUnBufferedTreeNodeStream.Mark: Integer;
4692var
4693  State: ITreeWalkState;
4694  I, N, K: Integer;
4695  LA: TANTLRInterfaceArray;
4696begin
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;
4732end;
4733
4734function TUnBufferedTreeNodeStream.MoveNext: Boolean;
4735begin
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;
4769end;
4770
4771procedure TUnBufferedTreeNodeStream.Release(const Marker: Integer);
4772begin
4773  // unwind any other markers made after marker and release marker
4774  FMarkDepth := Marker;
4775  // release this marker
4776  Dec(FMarkDepth);
4777end;
4778
4779procedure TUnBufferedTreeNodeStream.ReplaceChildren(
4780  const Parent: IANTLRInterface; const StartChildIndex, StopChildIndex: Integer;
4781  const T: IANTLRInterface);
4782begin
4783  raise EInvalidOperation.Create('can''t do stream rewrites yet');
4784end;
4785
4786procedure TUnBufferedTreeNodeStream.Reset;
4787begin
4788  FCurrentNode := FRoot;
4789  FPreviousNode := nil;
4790  FCurrentChildIndex := -1;
4791  FAbsoluteNodeIndex := -1;
4792  FHead := 0;
4793  FTail := 0;
4794end;
4795
4796procedure TUnBufferedTreeNodeStream.Rewind(const Marker: Integer);
4797var
4798  State: ITreeWalkState;
4799begin
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);
4818end;
4819
4820procedure TUnBufferedTreeNodeStream.Rewind;
4821begin
4822  Rewind(FLastMarker);
4823end;
4824
4825procedure TUnBufferedTreeNodeStream.Seek(const Index: Integer);
4826begin
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;
4833end;
4834
4835procedure TUnBufferedTreeNodeStream.SetHasUniqueNavigationNodes(
4836  const Value: Boolean);
4837begin
4838  FUniqueNavigationNodes := Value;
4839end;
4840
4841procedure TUnBufferedTreeNodeStream.SetTokenStream(const Value: ITokenStream);
4842begin
4843  FTokens := Value;
4844end;
4845
4846function TUnBufferedTreeNodeStream.Size: Integer;
4847var
4848  S: ICommonTreeNodeStream;
4849begin
4850  S := TCommonTreeNodeStream.Create(FRoot);
4851  Result := S.Size;
4852end;
4853
4854function TUnBufferedTreeNodeStream.ToString: String;
4855begin
4856  Result := ToString(FRoot, nil);
4857end;
4858
4859procedure TUnBufferedTreeNodeStream.ToStringWork(const P, Stop: IANTLRInterface;
4860  const Buf: TStringBuilder);
4861var
4862  Text: String;
4863  C, N: Integer;
4864begin
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;
4891end;
4892
4893function TUnBufferedTreeNodeStream.VisitChild(
4894  const Child: Integer): IANTLRInterface;
4895begin
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;
4908end;
4909
4910procedure TUnBufferedTreeNodeStream.WalkBackToMostRecentNodeWithUnvisitedChildren;
4911begin
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;
4930end;
4931
4932function TUnBufferedTreeNodeStream.ToString(const Start,
4933  Stop: IANTLRInterface): String;
4934var
4935  BeginTokenIndex, EndTokenIndex: Integer;
4936  Buf: TStringBuilder;
4937begin
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;
4962end;
4963
4964{ TUnBufferedTreeNodeStream.TTreeWalkState }
4965
4966function TUnBufferedTreeNodeStream.TTreeWalkState.GetAbsoluteNodeIndex: Integer;
4967begin
4968  Result := FAbsoluteNodeIndex;
4969end;
4970
4971function TUnBufferedTreeNodeStream.TTreeWalkState.GetCurrentChildIndex: Integer;
4972begin
4973  Result := FCurrentChildIndex;
4974end;
4975
4976function TUnBufferedTreeNodeStream.TTreeWalkState.GetCurrentNode: IANTLRInterface;
4977begin
4978  Result := FCurrentNode;
4979end;
4980
4981function TUnBufferedTreeNodeStream.TTreeWalkState.GetIndexStackSize: integer;
4982begin
4983  Result := FIndexStackSize;
4984end;
4985
4986function TUnBufferedTreeNodeStream.TTreeWalkState.GetLookAhead: TANTLRInterfaceArray;
4987begin
4988  Result := FLookAhead;
4989end;
4990
4991function TUnBufferedTreeNodeStream.TTreeWalkState.GetNodeStackSize: Integer;
4992begin
4993  Result := FNodeStackSize;
4994end;
4995
4996function TUnBufferedTreeNodeStream.TTreeWalkState.GetPreviousNode: IANTLRInterface;
4997begin
4998  Result := FPreviousNode;
4999end;
5000
5001procedure TUnBufferedTreeNodeStream.TTreeWalkState.SetAbsoluteNodeIndex(
5002  const Value: Integer);
5003begin
5004  FAbsoluteNodeIndex := Value;
5005end;
5006
5007procedure TUnBufferedTreeNodeStream.TTreeWalkState.SetCurrentChildIndex(
5008  const Value: Integer);
5009begin
5010  FCurrentChildIndex := Value;
5011end;
5012
5013procedure TUnBufferedTreeNodeStream.TTreeWalkState.SetCurrentNode(
5014  const Value: IANTLRInterface);
5015begin
5016  FCurrentNode := Value;
5017end;
5018
5019procedure TUnBufferedTreeNodeStream.TTreeWalkState.SetIndexStackSize(
5020  const Value: integer);
5021begin
5022  FIndexStackSize := Value;
5023end;
5024
5025procedure TUnBufferedTreeNodeStream.TTreeWalkState.SetLookAhead(
5026  const Value: TANTLRInterfaceArray);
5027begin
5028  FLookAhead := Value;
5029end;
5030
5031procedure TUnBufferedTreeNodeStream.TTreeWalkState.SetNodeStackSize(
5032  const Value: Integer);
5033begin
5034  FNodeStackSize := Value;
5035end;
5036
5037procedure TUnBufferedTreeNodeStream.TTreeWalkState.SetPreviousNode(
5038  const Value: IANTLRInterface);
5039begin
5040  FPreviousNode := Value;
5041end;
5042
5043{ Utilities }
5044
5045var
5046  EmptyCommonTree: ICommonTree = nil;
5047
5048function Def(const X: ICommonTree): ICommonTree; overload;
5049begin
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;
5058end;
5059
5060initialization
5061  TTree.Initialize;
5062
5063end.
5064