1/*
2 * [The "BSD licence"]
3 * Copyright (c) 2005-2008 Terence Parr
4 * All rights reserved.
5 *
6 * Conversion to C#:
7 * Copyright (c) 2008 Sam Harwell, Pixel Mine, Inc.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote products
19 *    derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33namespace Antlr.Runtime.Tree {
34
35    /** <summary>
36     *  How to create and navigate trees.  Rather than have a separate factory
37     *  and adaptor, I've merged them.  Makes sense to encapsulate.
38     *  </summary>
39     *
40     *  <remarks>
41     *  This takes the place of the tree construction code generated in the
42     *  generated code in 2.x and the ASTFactory.
43     *
44     *  I do not need to know the type of a tree at all so they are all
45     *  generic Objects.  This may increase the amount of typecasting needed. :(
46     *  </remarks>
47     */
48    public interface ITreeAdaptor {
49        #region Construction
50
51        /** <summary>
52         *  Create a tree node from Token object; for CommonTree type trees,
53         *  then the token just becomes the payload.  This is the most
54         *  common create call.
55         *  </summary>
56         *
57         *  <remarks>
58         *  Override if you want another kind of node to be built.
59         *  </remarks>
60         */
61        object Create(IToken payload);
62
63        /** <summary>Duplicate a single tree node.</summary>
64         *  <remarks>Override if you want another kind of node to be built.</remarks>
65         */
66        object DupNode(object treeNode);
67
68        /** <summary>Duplicate tree recursively, using dupNode() for each node</summary> */
69        object DupTree(object tree);
70
71        /** <summary>
72         *  Return a nil node (an empty but non-null node) that can hold
73         *  a list of element as the children.  If you want a flat tree (a list)
74         *  use "t=adaptor.nil(); t.addChild(x); t.addChild(y);"
75         *  </summary>
76         */
77        object Nil();
78
79        /** <summary>
80         *  Return a tree node representing an error.  This node records the
81         *  tokens consumed during error recovery.  The start token indicates the
82         *  input symbol at which the error was detected.  The stop token indicates
83         *  the last symbol consumed during recovery.
84         *  </summary>
85         *
86         *  </remarks>
87         *  You must specify the input stream so that the erroneous text can
88         *  be packaged up in the error node.  The exception could be useful
89         *  to some applications; default implementation stores ptr to it in
90         *  the CommonErrorNode.
91         *
92         *  This only makes sense during token parsing, not tree parsing.
93         *  Tree parsing should happen only when parsing and tree construction
94         *  succeed.
95         *  </remarks>
96         */
97        object ErrorNode(ITokenStream input, IToken start, IToken stop, RecognitionException e);
98
99        /** <summary>Is tree considered a nil node used to make lists of child nodes?</summary> */
100        bool IsNil(object tree);
101
102        /** <summary>
103         *  Add a child to the tree t.  If child is a flat tree (a list), make all
104         *  in list children of t.  Warning: if t has no children, but child does
105         *  and child isNil then you can decide it is ok to move children to t via
106         *  t.children = child.children; i.e., without copying the array.  Just
107         *  make sure that this is consistent with have the user will build
108         *  ASTs.  Do nothing if t or child is null.
109         *  </summary>
110         */
111        void AddChild(object t, object child);
112
113        /** <summary>
114         *  If oldRoot is a nil root, just copy or move the children to newRoot.
115         *  If not a nil root, make oldRoot a child of newRoot.
116         *  </summary>
117         *
118         *  <remarks>
119         *    old=^(nil a b c), new=r yields ^(r a b c)
120         *    old=^(a b c), new=r yields ^(r ^(a b c))
121         *
122         *  If newRoot is a nil-rooted single child tree, use the single
123         *  child as the new root node.
124         *
125         *    old=^(nil a b c), new=^(nil r) yields ^(r a b c)
126         *    old=^(a b c), new=^(nil r) yields ^(r ^(a b c))
127         *
128         *  If oldRoot was null, it's ok, just return newRoot (even if isNil).
129         *
130         *    old=null, new=r yields r
131         *    old=null, new=^(nil r) yields ^(nil r)
132         *
133         *  Return newRoot.  Throw an exception if newRoot is not a
134         *  simple node or nil root with a single child node--it must be a root
135         *  node.  If newRoot is ^(nil x) return x as newRoot.
136         *
137         *  Be advised that it's ok for newRoot to point at oldRoot's
138         *  children; i.e., you don't have to copy the list.  We are
139         *  constructing these nodes so we should have this control for
140         *  efficiency.
141         *  </remarks>
142         */
143        object BecomeRoot(object newRoot, object oldRoot);
144
145        /** <summary>
146         *  Given the root of the subtree created for this rule, post process
147         *  it to do any simplifications or whatever you want.  A required
148         *  behavior is to convert ^(nil singleSubtree) to singleSubtree
149         *  as the setting of start/stop indexes relies on a single non-nil root
150         *  for non-flat trees.
151         *  </summary>
152         *
153         *  <remarks>
154         *  Flat trees such as for lists like "idlist : ID+ ;" are left alone
155         *  unless there is only one ID.  For a list, the start/stop indexes
156         *  are set in the nil node.
157         *
158         *  This method is executed after all rule tree construction and right
159         *  before setTokenBoundaries().
160         *  </remarks>
161         */
162        object RulePostProcessing(object root);
163
164        /** <summary>For identifying trees.</summary>
165         *
166         *  <remarks>
167         *  How to identify nodes so we can say "add node to a prior node"?
168         *  Even becomeRoot is an issue.  Use System.identityHashCode(node)
169         *  usually.
170         *  </remarks>
171         */
172        int GetUniqueID(object node);
173
174
175        // R e w r i t e  R u l e s
176
177        /** <summary>
178         *  Create a node for newRoot make it the root of oldRoot.
179         *  If oldRoot is a nil root, just copy or move the children to newRoot.
180         *  If not a nil root, make oldRoot a child of newRoot.
181         *  </summary>
182         *
183         *  <returns>
184         *  Return node created for newRoot.
185         *  </returns>
186         *
187         *  <remarks>
188         *  Be advised: when debugging ASTs, the DebugTreeAdaptor manually
189         *  calls create(Token child) and then plain becomeRoot(node, node)
190         *  because it needs to trap calls to create, but it can't since it delegates
191         *  to not inherits from the TreeAdaptor.
192         *  </remarks>
193         */
194        object BecomeRoot(IToken newRoot, object oldRoot);
195
196        /** <summary>
197         *  Create a new node derived from a token, with a new token type.
198         *  This is invoked from an imaginary node ref on right side of a
199         *  rewrite rule as IMAG[$tokenLabel].
200         *  </summary>
201         *
202         *  <remarks>
203         *  This should invoke createToken(Token).
204         *  </remarks>
205         */
206        object Create(int tokenType, IToken fromToken);
207
208        /** <summary>
209         *  Same as create(tokenType,fromToken) except set the text too.
210         *  This is invoked from an imaginary node ref on right side of a
211         *  rewrite rule as IMAG[$tokenLabel, "IMAG"].
212         *  </summary>
213         *
214         *  <remarks>
215         *  This should invoke createToken(Token).
216         *  </remarks>
217         */
218        object Create(int tokenType, IToken fromToken, string text);
219
220        /** <summary>
221         *  Create a new node derived from a token, with a new token type.
222         *  This is invoked from an imaginary node ref on right side of a
223         *  rewrite rule as IMAG["IMAG"].
224         *  </summary>
225         *
226         *  <remarks>
227         *  This should invoke createToken(int,String).
228         *  </remarks>
229         */
230        object Create(int tokenType, string text);
231
232        #endregion
233
234
235        #region Content
236
237        /** <summary>For tree parsing, I need to know the token type of a node</summary> */
238        int GetType(object t);
239
240        /** <summary>Node constructors can set the type of a node</summary> */
241        void SetType(object t, int type);
242
243        string GetText(object t);
244
245        /** <summary>Node constructors can set the text of a node</summary> */
246        void SetText(object t, string text);
247
248        /** <summary>
249         *  Return the token object from which this node was created.
250         *  Currently used only for printing an error message.
251         *  The error display routine in BaseRecognizer needs to
252         *  display where the input the error occurred. If your
253         *  tree of limitation does not store information that can
254         *  lead you to the token, you can create a token filled with
255         *  the appropriate information and pass that back.  See
256         *  BaseRecognizer.getErrorMessage().
257         *  </summary>
258         */
259        IToken GetToken(object t);
260
261        /** <summary>
262         *  Where are the bounds in the input token stream for this node and
263         *  all children?  Each rule that creates AST nodes will call this
264         *  method right before returning.  Flat trees (i.e., lists) will
265         *  still usually have a nil root node just to hold the children list.
266         *  That node would contain the start/stop indexes then.
267         *  </summary>
268         */
269        void SetTokenBoundaries(object t, IToken startToken, IToken stopToken);
270
271        /** <summary>Get the token start index for this subtree; return -1 if no such index</summary> */
272        int GetTokenStartIndex(object t);
273
274        /** <summary>Get the token stop index for this subtree; return -1 if no such index</summary> */
275        int GetTokenStopIndex(object t);
276
277        #endregion
278
279
280        #region Navigation / Tree Parsing
281
282        /** <summary>Get a child 0..n-1 node</summary> */
283        object GetChild(object t, int i);
284
285        /** <summary>Set ith child (0..n-1) to t; t must be non-null and non-nil node</summary> */
286        void SetChild(object t, int i, object child);
287
288        /** <summary>Remove ith child and shift children down from right.</summary> */
289        object DeleteChild(object t, int i);
290
291        /** <summary>How many children?  If 0, then this is a leaf node</summary> */
292        int GetChildCount(object t);
293
294        /** <summary>
295         *  Who is the parent node of this node; if null, implies node is root.
296         *  If your node type doesn't handle this, it's ok but the tree rewrites
297         *  in tree parsers need this functionality.
298         *  </summary>
299         */
300        object GetParent(object t);
301        void SetParent(object t, object parent);
302
303        /** <summary>
304         *  What index is this node in the child list? Range: 0..n-1
305         *  If your node type doesn't handle this, it's ok but the tree rewrites
306         *  in tree parsers need this functionality.
307         *  </summary>
308         */
309        int GetChildIndex(object t);
310        void SetChildIndex(object t, int index);
311
312        /** <summary>
313         *  Replace from start to stop child index of parent with t, which might
314         *  be a list.  Number of children may be different after this call.
315         *  </summary>
316         *
317         *  <remarks>
318         *  If parent is null, don't do anything; must be at root of overall tree.
319         *  Can't replace whatever points to the parent externally.  Do nothing.
320         *  </remarks>
321         */
322        void ReplaceChildren(object parent, int startChildIndex, int stopChildIndex, object t);
323
324        #endregion
325    }
326}
327