1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver""" @package antlr3.tree
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver@brief ANTLR3 runtime package, tree module
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
4324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverThis module contains all support classes for AST construction and tree parsers.
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver"""
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# begin[licence]
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# [The "BSD licence"]
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# Copyright (c) 2005-2008 Terence Parr
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# All rights reserved.
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# Redistribution and use in source and binary forms, with or without
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# modification, are permitted provided that the following conditions
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# are met:
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# 1. Redistributions of source code must retain the above copyright
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#    notice, this list of conditions and the following disclaimer.
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# 2. Redistributions in binary form must reproduce the above copyright
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#    notice, this list of conditions and the following disclaimer in the
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#    documentation and/or other materials provided with the distribution.
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# 3. The name of the author may not be used to endorse or promote products
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#    derived from this software without specific prior written permission.
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# end[licence]
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# lot's of docstrings are missing, don't complain for now...
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# pylint: disable-msg=C0111
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport re
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverfrom antlr3.constants import UP, DOWN, EOF, INVALID_TOKEN_TYPE
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverfrom antlr3.recognizers import BaseRecognizer, RuleReturnScope
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverfrom antlr3.streams import IntStream
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverfrom antlr3.tokens import CommonToken, Token, INVALID_TOKEN
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverfrom antlr3.exceptions import MismatchedTreeNodeException, \
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     MissingTokenException, UnwantedTokenException, MismatchedTokenException, \
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     NoViableAltException
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver############################################################################
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# tree related exceptions
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver############################################################################
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass RewriteCardinalityException(RuntimeError):
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @brief Base class for all exceptions thrown during AST rewrite construction.
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    This signifies a case where the cardinality of two or more elements
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    in a subrule are different: (ID INT)+ where |ID|!=|INT|
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def __init__(self, elementDescription):
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        RuntimeError.__init__(self, elementDescription)
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.elementDescription = elementDescription
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getMessage(self):
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.elementDescription
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass RewriteEarlyExitException(RewriteCardinalityException):
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """@brief No elements within a (...)+ in a rewrite rule"""
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def __init__(self, elementDescription=None):
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        RewriteCardinalityException.__init__(self, elementDescription)
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass RewriteEmptyStreamException(RewriteCardinalityException):
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @brief Ref to ID or expr but no tokens in ID stream or subtrees in expr stream
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    pass
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver############################################################################
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# basic Tree and TreeAdaptor interfaces
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver############################################################################
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass Tree(object):
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @brief Abstract baseclass for tree nodes.
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    What does a tree look like?  ANTLR has a number of support classes
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    such as CommonTreeNodeStream that work on these kinds of trees.  You
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    don't have to make your trees implement this interface, but if you do,
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    you'll be able to use more support code.
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    NOTE: When constructing trees, ANTLR can build any kind of tree; it can
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    even use Token objects as trees if you add a child list to your tokens.
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    This is a tree node without any payload; just navigation and factory stuff.
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getChild(self, i):
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getChildCount(self):
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getParent(self):
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Tree tracks parent and child index now > 3.0"""
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setParent(self, t):
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Tree tracks parent and child index now > 3.0"""
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def hasAncestor(self, ttype):
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Walk upwards looking for ancestor with this token type."""
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getAncestor(self, ttype):
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Walk upwards and get first ancestor with this token type."""
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getAncestors(self):
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Return a list of all ancestors of this node.
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        The first node of list is the root and the last is the parent of
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        this node.
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getChildIndex(self):
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """This node is what child index? 0..n-1"""
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setChildIndex(self, index):
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """This node is what child index? 0..n-1"""
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def freshenParentAndChildIndexes(self):
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Set the parent and child index values for all children"""
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def addChild(self, t):
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Add t as a child to this node.  If t is null, do nothing.  If t
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        is nil, add all children of t to this' children.
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setChild(self, i, t):
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Set ith child (0..n-1) to t; t must be non-null and non-nil node"""
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def deleteChild(self, i):
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def replaceChildren(self, startChildIndex, stopChildIndex, t):
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Delete children from start to stop and replace with t even if t is
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        a list (nil-root tree).  num of children can increase or decrease.
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        For huge child lists, inserting children can force walking rest of
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        children to set their childindex; could be slow.
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def isNil(self):
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Indicates the node is a nil node but may still have children, meaning
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        the tree is a flat list.
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getTokenStartIndex(self):
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        What is the smallest token index (indexing from 0) for this node
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver           and its children?
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setTokenStartIndex(self, index):
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getTokenStopIndex(self):
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        What is the largest token index (indexing from 0) for this node
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        and its children?
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setTokenStopIndex(self, index):
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def dupNode(self):
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getType(self):
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Return a token type; needed for tree parsing."""
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getText(self):
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getLine(self):
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        In case we don't have a token payload, what is the line for errors?
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getCharPositionInLine(self):
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def toStringTree(self):
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def toString(self):
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass TreeAdaptor(object):
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @brief Abstract baseclass for tree adaptors.
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    How to create and navigate trees.  Rather than have a separate factory
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    and adaptor, I've merged them.  Makes sense to encapsulate.
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    This takes the place of the tree construction code generated in the
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    generated code in 2.x and the ASTFactory.
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    I do not need to know the type of a tree at all so they are all
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    generic Objects.  This may increase the amount of typecasting needed. :(
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # C o n s t r u c t i o n
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def createWithPayload(self, payload):
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Create a tree node from Token object; for CommonTree type trees,
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        then the token just becomes the payload.  This is the most
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        common create call.
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Override if you want another kind of node to be built.
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def dupNode(self, treeNode):
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Duplicate a single tree node.
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Override if you want another kind of node to be built."""
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def dupTree(self, tree):
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Duplicate tree recursively, using dupNode() for each node"""
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def nil(self):
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Return a nil node (an empty but non-null node) that can hold
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        a list of element as the children.  If you want a flat tree (a list)
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        use "t=adaptor.nil(); t.addChild(x); t.addChild(y);"
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def errorNode(self, input, start, stop, exc):
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Return a tree node representing an error.  This node records the
325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        tokens consumed during error recovery.  The start token indicates the
326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        input symbol at which the error was detected.  The stop token indicates
327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        the last symbol consumed during recovery.
328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        You must specify the input stream so that the erroneous text can
330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        be packaged up in the error node.  The exception could be useful
331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        to some applications; default implementation stores ptr to it in
332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        the CommonErrorNode.
333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        This only makes sense during token parsing, not tree parsing.
335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Tree parsing should happen only when parsing and tree construction
336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        succeed.
337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def isNil(self, tree):
343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Is tree considered a nil node used to make lists of child nodes?"""
344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def addChild(self, t, child):
349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Add a child to the tree t.  If child is a flat tree (a list), make all
351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        in list children of t.  Warning: if t has no children, but child does
352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        and child isNil then you can decide it is ok to move children to t via
353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        t.children = child.children; i.e., without copying the array.  Just
354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        make sure that this is consistent with have the user will build
355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ASTs. Do nothing if t or child is null.
356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def becomeRoot(self, newRoot, oldRoot):
362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If oldRoot is a nil root, just copy or move the children to newRoot.
364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If not a nil root, make oldRoot a child of newRoot.
365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver           old=^(nil a b c), new=r yields ^(r a b c)
367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver           old=^(a b c), new=r yields ^(r ^(a b c))
368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If newRoot is a nil-rooted single child tree, use the single
370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        child as the new root node.
371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver           old=^(nil a b c), new=^(nil r) yields ^(r a b c)
373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver           old=^(a b c), new=^(nil r) yields ^(r ^(a b c))
374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If oldRoot was null, it's ok, just return newRoot (even if isNil).
376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver           old=null, new=r yields r
378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver           old=null, new=^(nil r) yields ^(nil r)
379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Return newRoot.  Throw an exception if newRoot is not a
381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        simple node or nil root with a single child node--it must be a root
382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        node.  If newRoot is ^(nil x) return x as newRoot.
383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Be advised that it's ok for newRoot to point at oldRoot's
385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        children; i.e., you don't have to copy the list.  We are
386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        constructing these nodes so we should have this control for
387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        efficiency.
388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def rulePostProcessing(self, root):
394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Given the root of the subtree created for this rule, post process
396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        it to do any simplifications or whatever you want.  A required
397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        behavior is to convert ^(nil singleSubtree) to singleSubtree
398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        as the setting of start/stop indexes relies on a single non-nil root
399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        for non-flat trees.
400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Flat trees such as for lists like "idlist : ID+ ;" are left alone
402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        unless there is only one ID.  For a list, the start/stop indexes
403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        are set in the nil node.
404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        This method is executed after all rule tree construction and right
406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        before setTokenBoundaries().
407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getUniqueID(self, node):
413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """For identifying trees.
414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        How to identify nodes so we can say "add node to a prior node"?
416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Even becomeRoot is an issue.  Use System.identityHashCode(node)
417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        usually.
418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # R e w r i t e  R u l e s
424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def createFromToken(self, tokenType, fromToken, text=None):
426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Create a new node derived from a token, with a new token type and
428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        (optionally) new text.
429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        This is invoked from an imaginary node ref on right side of a
431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        rewrite rule as IMAG[$tokenLabel] or IMAG[$tokenLabel "IMAG"].
432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        This should invoke createToken(Token).
434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def createFromType(self, tokenType, text):
440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Create a new node derived from a token, with a new token type.
441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        This is invoked from an imaginary node ref on right side of a
443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        rewrite rule as IMAG["IMAG"].
444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        This should invoke createToken(int,String).
446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # C o n t e n t
452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getType(self, t):
454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """For tree parsing, I need to know the token type of a node"""
455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setType(self, t, type):
460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Node constructors can set the type of a node"""
461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getText(self, t):
466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setText(self, t, text):
469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Node constructors can set the text of a node"""
470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getToken(self, t):
475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Return the token object from which this node was created.
476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Currently used only for printing an error message.
478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        The error display routine in BaseRecognizer needs to
479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        display where the input the error occurred. If your
480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        tree of limitation does not store information that can
481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        lead you to the token, you can create a token filled with
482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        the appropriate information and pass that back.  See
483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        BaseRecognizer.getErrorMessage().
484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setTokenBoundaries(self, t, startToken, stopToken):
490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Where are the bounds in the input token stream for this node and
492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        all children?  Each rule that creates AST nodes will call this
493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        method right before returning.  Flat trees (i.e., lists) will
494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        still usually have a nil root node just to hold the children list.
495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        That node would contain the start/stop indexes then.
496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getTokenStartIndex(self, t):
502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Get the token start index for this subtree; return -1 if no such index
504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getTokenStopIndex(self, t):
510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Get the token stop index for this subtree; return -1 if no such index
512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # N a v i g a t i o n  /  T r e e  P a r s i n g
518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getChild(self, t, i):
520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Get a child 0..n-1 node"""
521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setChild(self, t, i, child):
526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Set ith child (0..n-1) to t; t must be non-null and non-nil node"""
527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def deleteChild(self, t, i):
532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Remove ith child and shift children down from right."""
533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getChildCount(self, t):
538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """How many children?  If 0, then this is a leaf node"""
539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getParent(self, t):
544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Who is the parent node of this node; if null, implies node is root.
546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If your node type doesn't handle this, it's ok but the tree rewrites
547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        in tree parsers need this functionality.
548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setParent(self, t, parent):
554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Who is the parent node of this node; if null, implies node is root.
556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If your node type doesn't handle this, it's ok but the tree rewrites
557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        in tree parsers need this functionality.
558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getChildIndex(self, t):
564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        What index is this node in the child list? Range: 0..n-1
566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If your node type doesn't handle this, it's ok but the tree rewrites
567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        in tree parsers need this functionality.
568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setChildIndex(self, t, index):
574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        What index is this node in the child list? Range: 0..n-1
576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If your node type doesn't handle this, it's ok but the tree rewrites
577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        in tree parsers need this functionality.
578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def replaceChildren(self, parent, startChildIndex, stopChildIndex, t):
584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Replace from start to stop child index of parent with t, which might
586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        be a list.  Number of children may be different
587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        after this call.
588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If parent is null, don't do anything; must be at root of overall tree.
590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Can't replace whatever points to the parent externally.  Do nothing.
591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # Misc
597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def create(self, *args):
599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Deprecated, use createWithPayload, createFromToken or createFromType.
601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
602324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        This method only exists to mimic the Java interface of TreeAdaptor.
603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if len(args) == 1 and isinstance(args[0], Token):
607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # Object create(Token payload);
608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##             warnings.warn(
609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##                 "Using create() is deprecated, use createWithPayload()",
610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##                 DeprecationWarning,
611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##                 stacklevel=2
612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##                 )
613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.createWithPayload(args[0])
614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (len(args) == 2
616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            and isinstance(args[0], (int, long))
617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            and isinstance(args[1], Token)
618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ):
619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # Object create(int tokenType, Token fromToken);
620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##             warnings.warn(
621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##                 "Using create() is deprecated, use createFromToken()",
622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##                 DeprecationWarning,
623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##                 stacklevel=2
624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##                 )
625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.createFromToken(args[0], args[1])
626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (len(args) == 3
628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            and isinstance(args[0], (int, long))
629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            and isinstance(args[1], Token)
630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            and isinstance(args[2], basestring)
631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ):
632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # Object create(int tokenType, Token fromToken, String text);
633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##             warnings.warn(
634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##                 "Using create() is deprecated, use createFromToken()",
635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##                 DeprecationWarning,
636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##                 stacklevel=2
637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##                 )
638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.createFromToken(args[0], args[1], args[2])
639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (len(args) == 2
641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            and isinstance(args[0], (int, long))
642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            and isinstance(args[1], basestring)
643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ):
644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # Object create(int tokenType, String text);
645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##             warnings.warn(
646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##                 "Using create() is deprecated, use createFromType()",
647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##                 DeprecationWarning,
648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##                 stacklevel=2
649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver##                 )
650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.createFromType(args[0], args[1])
651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise TypeError(
653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            "No create method with this signature found: %s"
654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            % (', '.join(type(v).__name__ for v in args))
655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            )
656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver############################################################################
659324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# base implementation of Tree and TreeAdaptor
661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# Tree
663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# \- BaseTree
664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# TreeAdaptor
666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# \- BaseTreeAdaptor
667324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver############################################################################
669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass BaseTree(Tree):
672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @brief A generic tree implementation with no payload.
674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
675324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    You must subclass to
676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    actually have any user data.  ANTLR v3 uses a list of children approach
677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    instead of the child-sibling approach in v2.  A flat tree (a list) is
678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    an empty node whose children represent the list.  An empty, but
679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    non-null node is called "nil".
680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # BaseTree is abstract, no need to complain about not implemented abstract
683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # methods
684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # pylint: disable-msg=W0223
685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def __init__(self, node=None):
687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Create a new node from an existing node does nothing for BaseTree
689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        as there are no fields other than the children list, which cannot
690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        be copied as the children are not considered part of this node.
691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Tree.__init__(self)
694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.children = []
695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.parent = None
696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.childIndex = 0
697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getChild(self, i):
700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        try:
701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.children[i]
702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        except IndexError:
703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return None
704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getChildren(self):
707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """@brief Get the children internal List
708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Note that if you directly mess with
710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        the list, do so at your own risk.
711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # FIXME: mark as deprecated
714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.children
715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
716324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getFirstChildWithType(self, treeType):
718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        for child in self.children:
719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if child.getType() == treeType:
720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return child
721324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return None
723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getChildCount(self):
726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return len(self.children)
727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def addChild(self, childTree):
730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Add t as child of this node.
731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Warning: if t has no children, but child does
733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        and child isNil then this routine moves children to t via
734324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        t.children = child.children; i.e., without copying the array.
735324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
736324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
737324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # this implementation is much simpler and probably less efficient
738324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # than the mumbo-jumbo that Ter did for the Java runtime.
739324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
740324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if childTree is None:
741324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return
742324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
743324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if childTree.isNil():
744324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # t is an empty node possibly with children
745324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
746324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if self.children is childTree.children:
747324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                raise ValueError("attempt to add child list to itself")
748324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
749324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # fix parent pointer and childIndex for new children
750324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            for idx, child in enumerate(childTree.children):
751324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                child.parent = self
752324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                child.childIndex = len(self.children) + idx
753324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
754324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.children += childTree.children
755324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
756324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        else:
757324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # child is not nil (don't care about children)
758324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.children.append(childTree)
759324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            childTree.parent = self
760324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            childTree.childIndex = len(self.children) - 1
761324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
762324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
763324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def addChildren(self, children):
764324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Add all elements of kids list as children of this node"""
765324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
766324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.children += children
767324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
768324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
769324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setChild(self, i, t):
770324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if t is None:
771324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return
772324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
773324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if t.isNil():
774324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            raise ValueError("Can't set single child to a list")
775324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
776324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.children[i] = t
777324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        t.parent = self
778324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        t.childIndex = i
779324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
780324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
781324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def deleteChild(self, i):
782324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        killed = self.children[i]
783324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
784324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        del self.children[i]
785324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
786324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # walk rest and decrement their child indexes
787324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        for idx, child in enumerate(self.children[i:]):
788324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            child.childIndex = i + idx
789324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
790324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return killed
791324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
792324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
793324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def replaceChildren(self, startChildIndex, stopChildIndex, newTree):
794324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
795324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Delete children from start to stop and replace with t even if t is
796324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        a list (nil-root tree).  num of children can increase or decrease.
797324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        For huge child lists, inserting children can force walking rest of
798324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        children to set their childindex; could be slow.
799324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
800324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
801324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (startChildIndex >= len(self.children)
802324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            or stopChildIndex >= len(self.children)
803324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ):
804324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            raise IndexError("indexes invalid")
805324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
806324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        replacingHowMany = stopChildIndex - startChildIndex + 1
807324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
808324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # normalize to a list of children to add: newChildren
809324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if newTree.isNil():
810324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            newChildren = newTree.children
811324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
812324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        else:
813324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            newChildren = [newTree]
814324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
815324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        replacingWithHowMany = len(newChildren)
816324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        delta = replacingHowMany - replacingWithHowMany
817324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
818324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
819324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if delta == 0:
820324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # if same number of nodes, do direct replace
821324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            for idx, child in enumerate(newChildren):
822324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                self.children[idx + startChildIndex] = child
823324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                child.parent = self
824324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                child.childIndex = idx + startChildIndex
825324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
826324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        else:
827324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # length of children changes...
828324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
829324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # ...delete replaced segment...
830324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            del self.children[startChildIndex:stopChildIndex+1]
831324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
832324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # ...insert new segment...
833324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.children[startChildIndex:startChildIndex] = newChildren
834324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
835324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # ...and fix indeces
836324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.freshenParentAndChildIndexes(startChildIndex)
837324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
838324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
839324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def isNil(self):
840324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return False
841324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
842324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
843324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def freshenParentAndChildIndexes(self, offset=0):
844324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        for idx, child in enumerate(self.children[offset:]):
845324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            child.childIndex = idx + offset
846324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            child.parent = self
847324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
848324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
849324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def sanityCheckParentAndChildIndexes(self, parent=None, i=-1):
850324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if parent != self.parent:
851324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            raise ValueError(
852324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                "parents don't match; expected %r found %r"
853324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                % (parent, self.parent)
854324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                )
855324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
856324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if i != self.childIndex:
857324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            raise ValueError(
858324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                "child indexes don't match; expected %d found %d"
859324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                % (i, self.childIndex)
860324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                )
861324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
862324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        for idx, child in enumerate(self.children):
863324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            child.sanityCheckParentAndChildIndexes(self, idx)
864324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
865324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
866324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getChildIndex(self):
867324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """BaseTree doesn't track child indexes."""
868324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
869324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return 0
870324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
871324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
872324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setChildIndex(self, index):
873324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """BaseTree doesn't track child indexes."""
874324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
875324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        pass
876324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
877324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
878324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getParent(self):
879324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """BaseTree doesn't track parent pointers."""
880324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
881324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return None
882324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
883324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setParent(self, t):
884324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """BaseTree doesn't track parent pointers."""
885324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
886324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        pass
887324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
888324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
889324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def hasAncestor(self, ttype):
890324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Walk upwards looking for ancestor with this token type."""
891324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.getAncestor(ttype) is not None
892324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
893324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getAncestor(self, ttype):
894324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Walk upwards and get first ancestor with this token type."""
895324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        t = self.getParent()
896324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        while t is not None:
897324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if t.getType() == ttype:
898324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return t
899324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            t = t.getParent()
900324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
901324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return None
902324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
903324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getAncestors(self):
904324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Return a list of all ancestors of this node.
905324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
906324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        The first node of list is the root and the last is the parent of
907324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        this node.
908324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
909324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if selfgetParent() is None:
910324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return None
911324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
912324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ancestors = []
913324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        t = self.getParent()
914324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        while t is not None:
915324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ancestors.insert(0, t) # insert at start
916324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            t = t.getParent()
917324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
918324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return ancestors
919324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
920324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
921324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def toStringTree(self):
922324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Print out a whole tree not just a node"""
923324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
924324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if len(self.children) == 0:
925324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.toString()
926324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
927324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        buf = []
928324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if not self.isNil():
929324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.append('(')
930324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.append(self.toString())
931324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.append(' ')
932324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
933324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        for i, child in enumerate(self.children):
934324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if i > 0:
935324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                buf.append(' ')
936324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.append(child.toStringTree())
937324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
938324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if not self.isNil():
939324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.append(')')
940324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
941324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return ''.join(buf)
942324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
943324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
944324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getLine(self):
945324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return 0
946324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
947324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
948324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getCharPositionInLine(self):
949324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return 0
950324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
951324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
952324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def toString(self):
953324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Override to say how a node (not a tree) should look as text"""
954324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
955324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
956324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
957324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
958324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
959324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass BaseTreeAdaptor(TreeAdaptor):
960324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
961324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @brief A TreeAdaptor that works with any Tree implementation.
962324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
963324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
964324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # BaseTreeAdaptor is abstract, no need to complain about not implemented
965324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # abstract methods
966324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # pylint: disable-msg=W0223
967324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
968324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def nil(self):
969324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.createWithPayload(None)
970324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
971324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
972324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def errorNode(self, input, start, stop, exc):
973324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
974324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        create tree node that holds the start and stop tokens associated
975324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        with an error.
976324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
977324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If you specify your own kind of tree nodes, you will likely have to
978324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        override this method. CommonTree returns Token.INVALID_TOKEN_TYPE
979324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if no token payload but you might have to set token type for diff
980324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        node type.
981324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
982324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        You don't have to subclass CommonErrorNode; you will likely need to
983324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        subclass your own tree node class to avoid class cast exception.
984324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
985324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
986324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return CommonErrorNode(input, start, stop, exc)
987324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
988324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
989324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def isNil(self, tree):
990324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return tree.isNil()
991324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
992324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
993324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def dupTree(self, t, parent=None):
994324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
995324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        This is generic in the sense that it will work with any kind of
996324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        tree (not just Tree interface).  It invokes the adaptor routines
997324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        not the tree node routines to do the construction.
998324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
999324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1000324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if t is None:
1001324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return None
1002324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1003324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        newTree = self.dupNode(t)
1004324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1005324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # ensure new subtree root has parent/child index set
1006324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1007324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # same index in new tree
1008324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.setChildIndex(newTree, self.getChildIndex(t))
1009324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1010324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.setParent(newTree, parent)
1011324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1012324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        for i in range(self.getChildCount(t)):
1013324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            child = self.getChild(t, i)
1014324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            newSubTree = self.dupTree(child, t)
1015324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.addChild(newTree, newSubTree)
1016324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1017324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return newTree
1018324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1019324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1020324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def addChild(self, tree, child):
1021324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1022324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Add a child to the tree t.  If child is a flat tree (a list), make all
1023324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        in list children of t.  Warning: if t has no children, but child does
1024324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        and child isNil then you can decide it is ok to move children to t via
1025324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        t.children = child.children; i.e., without copying the array.  Just
1026324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        make sure that this is consistent with have the user will build
1027324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ASTs.
1028324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1029324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1030324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #if isinstance(child, Token):
1031324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #    child = self.createWithPayload(child)
1032324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1033324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if tree is not None and child is not None:
1034324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tree.addChild(child)
1035324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1036324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1037324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def becomeRoot(self, newRoot, oldRoot):
1038324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1039324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If oldRoot is a nil root, just copy or move the children to newRoot.
1040324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If not a nil root, make oldRoot a child of newRoot.
1041324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1042324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          old=^(nil a b c), new=r yields ^(r a b c)
1043324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          old=^(a b c), new=r yields ^(r ^(a b c))
1044324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1045324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If newRoot is a nil-rooted single child tree, use the single
1046324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        child as the new root node.
1047324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1048324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          old=^(nil a b c), new=^(nil r) yields ^(r a b c)
1049324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          old=^(a b c), new=^(nil r) yields ^(r ^(a b c))
1050324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1051324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If oldRoot was null, it's ok, just return newRoot (even if isNil).
1052324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1053324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          old=null, new=r yields r
1054324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          old=null, new=^(nil r) yields ^(nil r)
1055324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1056324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Return newRoot.  Throw an exception if newRoot is not a
1057324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        simple node or nil root with a single child node--it must be a root
1058324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        node.  If newRoot is ^(nil x) return x as newRoot.
1059324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1060324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Be advised that it's ok for newRoot to point at oldRoot's
1061324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        children; i.e., you don't have to copy the list.  We are
1062324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        constructing these nodes so we should have this control for
1063324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        efficiency.
1064324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1065324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1066324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if isinstance(newRoot, Token):
1067324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            newRoot = self.create(newRoot)
1068324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1069324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if oldRoot is None:
1070324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return newRoot
1071324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1072324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if not isinstance(newRoot, CommonTree):
1073324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            newRoot = self.createWithPayload(newRoot)
1074324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1075324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # handle ^(nil real-node)
1076324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if newRoot.isNil():
1077324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            nc = newRoot.getChildCount()
1078324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if nc == 1:
1079324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                newRoot = newRoot.getChild(0)
1080324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1081324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            elif nc > 1:
1082324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                # TODO: make tree run time exceptions hierarchy
1083324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                raise RuntimeError("more than one node as root")
1084324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1085324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # add oldRoot to newRoot; addChild takes care of case where oldRoot
1086324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # is a flat list (i.e., nil-rooted tree).  All children of oldRoot
1087324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # are added to newRoot.
1088324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        newRoot.addChild(oldRoot)
1089324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return newRoot
1090324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1091324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1092324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def rulePostProcessing(self, root):
1093324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Transform ^(nil x) to x and nil to null"""
1094324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1095324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if root is not None and root.isNil():
1096324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if root.getChildCount() == 0:
1097324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                root = None
1098324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1099324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            elif root.getChildCount() == 1:
1100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                root = root.getChild(0)
1101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                # whoever invokes rule will set parent and child index
1102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                root.setParent(None)
1103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                root.setChildIndex(-1)
1104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return root
1106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def createFromToken(self, tokenType, fromToken, text=None):
1109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if fromToken is None:
1110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.createFromType(tokenType, text)
1111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assert isinstance(tokenType, (int, long)), type(tokenType).__name__
1113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assert isinstance(fromToken, Token), type(fromToken).__name__
1114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assert text is None or isinstance(text, basestring), type(text).__name__
1115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        fromToken = self.createToken(fromToken)
1117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        fromToken.type = tokenType
1118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if text is not None:
1119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            fromToken.text = text
1120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        t = self.createWithPayload(fromToken)
1121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return t
1122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def createFromType(self, tokenType, text):
1125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assert isinstance(tokenType, (int, long)), type(tokenType).__name__
1126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        assert isinstance(text, basestring) or text is None, type(text).__name__
1127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        fromToken = self.createToken(tokenType=tokenType, text=text)
1129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        t = self.createWithPayload(fromToken)
1130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return t
1131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getType(self, t):
1134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return t.getType()
1135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setType(self, t, type):
1138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise RuntimeError("don't know enough about Tree node")
1139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getText(self, t):
1142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return t.getText()
1143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setText(self, t, text):
1146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise RuntimeError("don't know enough about Tree node")
1147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getChild(self, t, i):
1150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return t.getChild(i)
1151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setChild(self, t, i, child):
1154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        t.setChild(i, child)
1155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def deleteChild(self, t, i):
1158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return t.deleteChild(i)
1159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getChildCount(self, t):
1162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return t.getChildCount()
1163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getUniqueID(self, node):
1166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return hash(node)
1167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def createToken(self, fromToken=None, tokenType=None, text=None):
1170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Tell me how to create a token for use with imaginary token nodes.
1172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        For example, there is probably no input symbol associated with imaginary
1173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        token DECL, but you need to create it as a payload or whatever for
1174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        the DECL node as in ^(DECL type ID).
1175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If you care what the token payload objects' type is, you should
1177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        override this method and any other createToken variant.
1178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
1181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver############################################################################
1184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
1185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# common tree implementation
1186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
1187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# Tree
1188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# \- BaseTree
1189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#    \- CommonTree
1190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#       \- CommonErrorNode
1191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
1192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# TreeAdaptor
1193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# \- BaseTreeAdaptor
1194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#    \- CommonTreeAdaptor
1195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
1196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver############################################################################
1197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass CommonTree(BaseTree):
1200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """@brief A tree node that is wrapper for a Token object.
1201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    After 3.0 release
1203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    while building tree rewrite stuff, it became clear that computing
1204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parent and child index is very difficult and cumbersome.  Better to
1205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    spend the space in every tree node.  If you don't want these extra
1206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    fields, it's easy to cut them out in your own BaseTree subclass.
1207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
1209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def __init__(self, payload):
1211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        BaseTree.__init__(self)
1212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # What token indexes bracket all tokens associated with this node
1214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # and below?
1215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.startIndex = -1
1216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.stopIndex = -1
1217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # Who is the parent node of this node; if null, implies node is root
1219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.parent = None
1220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # What index is this node in the child list? Range: 0..n-1
1222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.childIndex = -1
1223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # A single token is the payload
1225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if payload is None:
1226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.token = None
1227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        elif isinstance(payload, CommonTree):
1229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.token = payload.token
1230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.startIndex = payload.startIndex
1231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.stopIndex = payload.stopIndex
1232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        elif payload is None or isinstance(payload, Token):
1234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.token = payload
1235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        else:
1237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            raise TypeError(type(payload).__name__)
1238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getToken(self):
1242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.token
1243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def dupNode(self):
1246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return CommonTree(self)
1247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def isNil(self):
1250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.token is None
1251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getType(self):
1254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.token is None:
1255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return INVALID_TOKEN_TYPE
1256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.token.getType()
1258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    type = property(getType)
1260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getText(self):
1263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.token is None:
1264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return None
1265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.token.text
1267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    text = property(getText)
1269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getLine(self):
1272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.token is None or self.token.getLine() == 0:
1273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if self.getChildCount():
1274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return self.getChild(0).getLine()
1275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else:
1276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return 0
1277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.token.getLine()
1279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    line = property(getLine)
1281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getCharPositionInLine(self):
1284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.token is None or self.token.getCharPositionInLine() == -1:
1285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if self.getChildCount():
1286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return self.getChild(0).getCharPositionInLine()
1287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else:
1288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return 0
1289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        else:
1291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.token.getCharPositionInLine()
1292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    charPositionInLine = property(getCharPositionInLine)
1294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getTokenStartIndex(self):
1297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.startIndex == -1 and self.token is not None:
1298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.token.getTokenIndex()
1299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.startIndex
1301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setTokenStartIndex(self, index):
1303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.startIndex = index
1304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tokenStartIndex = property(getTokenStartIndex, setTokenStartIndex)
1306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getTokenStopIndex(self):
1309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.stopIndex == -1 and self.token is not None:
1310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.token.getTokenIndex()
1311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.stopIndex
1313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setTokenStopIndex(self, index):
1315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.stopIndex = index
1316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tokenStopIndex = property(getTokenStopIndex, setTokenStopIndex)
1318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setUnknownTokenBoundaries(self):
1321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """For every node in this subtree, make sure it's start/stop token's
1322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        are set.  Walk depth first, visit bottom up.  Only updates nodes
1323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        with at least one token index < 0.
1324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.children is None:
1327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if self.startIndex < 0 or self.stopIndex < 0:
1328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                self.startIndex = self.stopIndex = self.token.getTokenIndex()
1329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return
1331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        for child in self.children:
1333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            child.setUnknownTokenBoundaries()
1334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.startIndex >= 0 and self.stopIndex >= 0:
1336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # already set
1337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return
1338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.children:
1340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            firstChild = self.children[0]
1341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            lastChild = self.children[-1]
1342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.startIndex = firstChild.getTokenStartIndex()
1343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.stopIndex = lastChild.getTokenStopIndex()
1344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getChildIndex(self):
1347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #FIXME: mark as deprecated
1348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.childIndex
1349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setChildIndex(self, idx):
1352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #FIXME: mark as deprecated
1353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.childIndex = idx
1354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getParent(self):
1357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #FIXME: mark as deprecated
1358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.parent
1359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setParent(self, t):
1362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #FIXME: mark as deprecated
1363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.parent = t
1364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def toString(self):
1367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.isNil():
1368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return "nil"
1369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.getType() == INVALID_TOKEN_TYPE:
1371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return "<errornode>"
1372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.token.text
1374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    __str__ = toString
1376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def toStringTree(self):
1380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if not self.children:
1381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.toString()
1382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ret = ''
1384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if not self.isNil():
1385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ret += '(%s ' % (self.toString())
1386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ret += ' '.join([child.toStringTree() for child in self.children])
1388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if not self.isNil():
1390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ret += ')'
1391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return ret
1393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1395324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverINVALID_NODE = CommonTree(INVALID_TOKEN)
1396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass CommonErrorNode(CommonTree):
1399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """A node representing erroneous token range in token stream"""
1400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def __init__(self, input, start, stop, exc):
1402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        CommonTree.__init__(self, None)
1403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (stop is None or
1405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            (stop.getTokenIndex() < start.getTokenIndex() and
1406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver             stop.getType() != EOF
1407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver             )
1408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ):
1409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # sometimes resync does not consume a token (when LT(1) is
1410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # in follow set.  So, stop will be 1 to left to start. adjust.
1411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # Also handle case where start is the first token and no token
1412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # is consumed during recovery; LT(-1) will return null.
1413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stop = start
1414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.input = input
1416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.start = start
1417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.stop = stop
1418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.trappedException = exc
1419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def isNil(self):
1422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return False
1423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getType(self):
1426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return INVALID_TOKEN_TYPE
1427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getText(self):
1430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if isinstance(self.start, Token):
1431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            i = self.start.getTokenIndex()
1432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            j = self.stop.getTokenIndex()
1433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if self.stop.getType() == EOF:
1434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                j = self.input.size()
1435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            badText = self.input.toString(i, j)
1437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        elif isinstance(self.start, Tree):
1439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            badText = self.input.toString(self.start, self.stop)
1440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        else:
1442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # people should subclass if they alter the tree type so this
1443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # next one is for sure correct.
1444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            badText = "<unknown>"
1445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return badText
1447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def toString(self):
1450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if isinstance(self.trappedException, MissingTokenException):
1451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return ("<missing type: "
1452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    + str(self.trappedException.getMissingType())
1453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    + ">")
1454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        elif isinstance(self.trappedException, UnwantedTokenException):
1456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return ("<extraneous: "
1457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    + str(self.trappedException.getUnexpectedToken())
1458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    + ", resync=" + self.getText() + ">")
1459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        elif isinstance(self.trappedException, MismatchedTokenException):
1461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return ("<mismatched token: "
1462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    + str(self.trappedException.token)
1463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    + ", resync=" + self.getText() + ">")
1464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        elif isinstance(self.trappedException, NoViableAltException):
1466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return ("<unexpected: "
1467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    + str(self.trappedException.token)
1468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    + ", resync=" + self.getText() + ">")
1469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return "<error: "+self.getText()+">"
1471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass CommonTreeAdaptor(BaseTreeAdaptor):
1474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
1475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @brief A TreeAdaptor that works with any Tree implementation.
1476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    It provides
1478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    really just factory methods; all the work is done by BaseTreeAdaptor.
1479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    If you would like to have different tokens created than ClassicToken
1480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    objects, you need to override this and then set the parser tree adaptor to
1481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    use your subclass.
1482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    To get your parser to build nodes of a different type, override
1484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    create(Token), errorNode(), and to be safe, YourTreeClass.dupNode().
1485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    dupNode is called to duplicate nodes during rewrite operations.
1486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
1487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def dupNode(self, treeNode):
1489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Duplicate a node.  This is part of the factory;
1491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        override if you want another kind of node to be built.
1492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        I could use reflection to prevent having to override this
1494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        but reflection is slow.
1495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if treeNode is None:
1498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return None
1499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return treeNode.dupNode()
1501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def createWithPayload(self, payload):
1504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return CommonTree(payload)
1505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def createToken(self, fromToken=None, tokenType=None, text=None):
1508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Tell me how to create a token for use with imaginary token nodes.
1510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        For example, there is probably no input symbol associated with imaginary
1511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        token DECL, but you need to create it as a payload or whatever for
1512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        the DECL node as in ^(DECL type ID).
1513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If you care what the token payload objects' type is, you should
1515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        override this method and any other createToken variant.
1516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if fromToken is not None:
1519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return CommonToken(oldToken=fromToken)
1520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return CommonToken(type=tokenType, text=text)
1522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setTokenBoundaries(self, t, startToken, stopToken):
1525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Track start/stop token for subtree root created for a rule.
1527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Only works with Tree nodes.  For rules that match nothing,
1528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        seems like this will yield start=i and stop=i-1 in a nil node.
1529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Might be useful info so I'll not force to be i..i.
1530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if t is None:
1533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return
1534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        start = 0
1536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        stop = 0
1537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if startToken is not None:
1539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            start = startToken.index
1540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if stopToken is not None:
1542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stop = stopToken.index
1543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        t.setTokenStartIndex(start)
1545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        t.setTokenStopIndex(stop)
1546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getTokenStartIndex(self, t):
1549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if t is None:
1550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return -1
1551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return t.getTokenStartIndex()
1552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getTokenStopIndex(self, t):
1555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if t is None:
1556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return -1
1557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return t.getTokenStopIndex()
1558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getText(self, t):
1561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if t is None:
1562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return None
1563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return t.getText()
1564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getType(self, t):
1567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if t is None:
1568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return INVALID_TOKEN_TYPE
1569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return t.getType()
1571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getToken(self, t):
1574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        What is the Token associated with this node?  If
1576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        you are not using CommonTree, then you must
1577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        override this in your own adaptor.
1578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if isinstance(t, CommonTree):
1581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return t.getToken()
1582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return None # no idea what to do
1584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getChild(self, t, i):
1587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if t is None:
1588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return None
1589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return t.getChild(i)
1590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getChildCount(self, t):
1593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if t is None:
1594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return 0
1595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return t.getChildCount()
1596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getParent(self, t):
1599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return t.getParent()
1600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1602324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setParent(self, t, parent):
1603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        t.setParent(parent)
1604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getChildIndex(self, t):
1607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if t is None:
1608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return 0
1609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return t.getChildIndex()
1610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setChildIndex(self, t, index):
1613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        t.setChildIndex(index)
1614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def replaceChildren(self, parent, startChildIndex, stopChildIndex, t):
1617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if parent is not None:
1618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            parent.replaceChildren(startChildIndex, stopChildIndex, t)
1619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver############################################################################
1622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
1623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# streams
1624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
1625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# TreeNodeStream
1626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# \- BaseTree
1627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#    \- CommonTree
1628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
1629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# TreeAdaptor
1630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# \- BaseTreeAdaptor
1631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#    \- CommonTreeAdaptor
1632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
1633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver############################################################################
1634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass TreeNodeStream(IntStream):
1638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """@brief A stream of tree nodes
1639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    It accessing nodes from a tree of some kind.
1641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
1642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # TreeNodeStream is abstract, no need to complain about not implemented
1644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # abstract methods
1645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # pylint: disable-msg=W0223
1646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def get(self, i):
1648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Get a tree node at an absolute index i; 0..n-1.
1649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If you don't want to buffer up nodes, then this method makes no
1650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        sense for you.
1651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
1654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def LT(self, k):
1657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Get tree node at current input pointer + i ahead where i=1 is next node.
1659324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        i<0 indicates nodes in the past.  So LT(-1) is previous node, but
1660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        implementations are not required to provide results for k < -1.
1661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        LT(0) is undefined.  For i>=n, return null.
1662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Return null for LT(0) and any index that results in an absolute address
1663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        that is negative.
1664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        This is analogus to the LT() method of the TokenStream, but this
1666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        returns a tree node instead of a token.  Makes code gen identical
1667324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        for both parser and tree grammars. :)
1668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
1671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getTreeSource(self):
1674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1675324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Where is this stream pulling nodes from?  This is not the name, but
1676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        the object that provides node objects.
1677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
1680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getTokenStream(self):
1683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If the tree associated with this stream was created from a TokenStream,
1685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        you can specify it here.  Used to do rule $text attribute in tree
1686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        parser.  Optional unless you use tree parser rule text attribute
1687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        or output=template and rewrite=true options.
1688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
1691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getTreeAdaptor(self):
1694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        What adaptor can tell me how to interpret/navigate nodes and
1696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        trees.  E.g., get text of a node.
1697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
1700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setUniqueNavigationNodes(self, uniqueNavigationNodes):
1703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        As we flatten the tree, we use UP, DOWN nodes to represent
1705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        the tree structure.  When debugging we need unique nodes
1706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        so we have to instantiate new ones.  When doing normal tree
1707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        parsing, it's slow and a waste of memory to create unique
1708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        navigation nodes.  Default should be false;
1709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
1712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def reset(self):
1715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1716324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Reset the tree node stream in such a way that it acts like
1717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        a freshly constructed stream.
1718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
1721324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def toString(self, start, stop):
1724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Return the text of all nodes from start to stop, inclusive.
1726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If the stream does not buffer all the nodes then it can still
1727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        walk recursively from start until stop.  You can always return
1728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        null or "" too, but users should not access $ruleLabel.text in
1729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        an action of course in that case.
1730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
1733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1734324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1735324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # REWRITING TREES (used by tree parser)
1736324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def replaceChildren(self, parent, startChildIndex, stopChildIndex, t):
1737324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1738324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 	Replace from start to stop child index of parent with t, which might
1739324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        be a list.  Number of children may be different
1740324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        after this call.  The stream is notified because it is walking the
1741324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        tree and might need to know you are monkeying with the underlying
1742324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        tree.  Also, it might be able to modify the node stream to avoid
1743324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        restreaming for future phases.
1744324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1745324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        If parent is null, don't do anything; must be at root of overall tree.
1746324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Can't replace whatever points to the parent externally.  Do nothing.
1747324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1748324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1749324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
1750324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1751324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1752324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass CommonTreeNodeStream(TreeNodeStream):
1753324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """@brief A buffered stream of tree nodes.
1754324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1755324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    Nodes can be from a tree of ANY kind.
1756324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1757324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    This node stream sucks all nodes out of the tree specified in
1758324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    the constructor during construction and makes pointers into
1759324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    the tree using an array of Object pointers. The stream necessarily
1760324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    includes pointers to DOWN and UP and EOF nodes.
1761324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1762324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    This stream knows how to mark/release for backtracking.
1763324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1764324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    This stream is most suitable for tree interpreters that need to
1765324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    jump around a lot or for tree parsers requiring speed (at cost of memory).
1766324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    There is some duplicated functionality here with UnBufferedTreeNodeStream
1767324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    but just in bookkeeping, not tree walking etc...
1768324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1769324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @see UnBufferedTreeNodeStream
1770324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
1771324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1772324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def __init__(self, *args):
1773324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        TreeNodeStream.__init__(self)
1774324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1775324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if len(args) == 1:
1776324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            adaptor = CommonTreeAdaptor()
1777324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tree = args[0]
1778324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1779324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            nodes = None
1780324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            down = None
1781324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            up = None
1782324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            eof = None
1783324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1784324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        elif len(args) == 2:
1785324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            adaptor = args[0]
1786324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tree = args[1]
1787324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1788324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            nodes = None
1789324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            down = None
1790324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            up = None
1791324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            eof = None
1792324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1793324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        elif len(args) == 3:
1794324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            parent = args[0]
1795324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            start = args[1]
1796324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stop = args[2]
1797324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1798324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            adaptor = parent.adaptor
1799324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tree = parent.root
1800324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1801324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            nodes = parent.nodes[start:stop]
1802324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            down = parent.down
1803324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            up = parent.up
1804324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            eof = parent.eof
1805324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1806324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        else:
1807324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            raise TypeError("Invalid arguments")
1808324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1809324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # all these navigation nodes are shared and hence they
1810324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # cannot contain any line/column info
1811324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if down is not None:
1812324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.down = down
1813324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        else:
1814324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.down = adaptor.createFromType(DOWN, "DOWN")
1815324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1816324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if up is not None:
1817324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.up = up
1818324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        else:
1819324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.up = adaptor.createFromType(UP, "UP")
1820324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1821324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if eof is not None:
1822324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.eof = eof
1823324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        else:
1824324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.eof = adaptor.createFromType(EOF, "EOF")
1825324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1826324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # The complete mapping from stream index to tree node.
1827324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # This buffer includes pointers to DOWN, UP, and EOF nodes.
1828324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # It is built upon ctor invocation.  The elements are type
1829324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #  Object as we don't what the trees look like.
1830324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1831324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # Load upon first need of the buffer so we can set token types
1832324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # of interest for reverseIndexing.  Slows us down a wee bit to
1833324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # do all of the if p==-1 testing everywhere though.
1834324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if nodes is not None:
1835324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.nodes = nodes
1836324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        else:
1837324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.nodes = []
1838324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1839324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # Pull nodes from which tree?
1840324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.root = tree
1841324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1842324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # IF this tree (root) was created from a token stream, track it.
1843324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.tokens = None
1844324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1845324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # What tree adaptor was used to build these trees
1846324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.adaptor = adaptor
1847324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1848324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # Reuse same DOWN, UP navigation nodes unless this is true
1849324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.uniqueNavigationNodes = False
1850324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1851324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # The index into the nodes list of the current node (next node
1852324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # to consume).  If -1, nodes array not filled yet.
1853324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.p = -1
1854324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1855324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # Track the last mark() call result value for use in rewind().
1856324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.lastMarker = None
1857324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1858324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # Stack of indexes used for push/pop calls
1859324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.calls = []
1860324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1861324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1862324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def __iter__(self):
1863324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return TreeIterator(self.root, self.adaptor)
1864324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1865324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1866324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def fillBuffer(self):
1867324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Walk tree with depth-first-search and fill nodes buffer.
1868324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Don't do DOWN, UP nodes if its a list (t is isNil).
1869324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1870324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1871324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self._fillBuffer(self.root)
1872324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.p = 0 # buffer of nodes intialized now
1873324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1874324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1875324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def _fillBuffer(self, t):
1876324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        nil = self.adaptor.isNil(t)
1877324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1878324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if not nil:
1879324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.nodes.append(t) # add this node
1880324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1881324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # add DOWN node if t has children
1882324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        n = self.adaptor.getChildCount(t)
1883324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if not nil and n > 0:
1884324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.addNavigationNode(DOWN)
1885324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1886324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # and now add all its children
1887324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        for c in range(n):
1888324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self._fillBuffer(self.adaptor.getChild(t, c))
1889324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1890324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # add UP node if t has children
1891324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if not nil and n > 0:
1892324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.addNavigationNode(UP)
1893324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1894324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1895324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getNodeIndex(self, node):
1896324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """What is the stream index for node? 0..n-1
1897324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Return -1 if node not found.
1898324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1899324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1900324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.p == -1:
1901324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.fillBuffer()
1902324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1903324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        for i, t in enumerate(self.nodes):
1904324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if t == node:
1905324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return i
1906324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1907324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return -1
1908324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1909324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1910324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def addNavigationNode(self, ttype):
1911324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1912324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        As we flatten the tree, we use UP, DOWN nodes to represent
1913324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        the tree structure.  When debugging we need unique nodes
1914324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        so instantiate new ones when uniqueNavigationNodes is true.
1915324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
1916324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1917324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        navNode = None
1918324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1919324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if ttype == DOWN:
1920324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if self.hasUniqueNavigationNodes():
1921324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                navNode = self.adaptor.createFromType(DOWN, "DOWN")
1922324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1923324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else:
1924324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                navNode = self.down
1925324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1926324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        else:
1927324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if self.hasUniqueNavigationNodes():
1928324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                navNode = self.adaptor.createFromType(UP, "UP")
1929324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1930324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else:
1931324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                navNode = self.up
1932324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1933324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.nodes.append(navNode)
1934324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1935324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1936324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def get(self, i):
1937324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.p == -1:
1938324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.fillBuffer()
1939324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1940324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.nodes[i]
1941324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1942324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1943324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def LT(self, k):
1944324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.p == -1:
1945324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.fillBuffer()
1946324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1947324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if k == 0:
1948324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return None
1949324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1950324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if k < 0:
1951324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.LB(-k)
1952324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1953324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.p + k - 1 >= len(self.nodes):
1954324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.eof
1955324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1956324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.nodes[self.p + k - 1]
1957324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1958324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1959324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getCurrentSymbol(self):
1960324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.LT(1)
1961324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1962324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1963324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def LB(self, k):
1964324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Look backwards k nodes"""
1965324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1966324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if k == 0:
1967324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return None
1968324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1969324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.p - k < 0:
1970324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return None
1971324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1972324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.nodes[self.p - k]
1973324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1974324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1975324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def isEOF(self, obj):
1976324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.adaptor.getType(obj) == EOF
1977324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1978324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1979324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getTreeSource(self):
1980324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.root
1981324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1982324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1983324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getSourceName(self):
1984324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.getTokenStream().getSourceName()
1985324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1986324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1987324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getTokenStream(self):
1988324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.tokens
1989324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1990324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1991324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setTokenStream(self, tokens):
1992324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.tokens = tokens
1993324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1994324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1995324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getTreeAdaptor(self):
1996324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.adaptor
1997324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1998324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1999324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def hasUniqueNavigationNodes(self):
2000324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.uniqueNavigationNodes
2001324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2002324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2003324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setUniqueNavigationNodes(self, uniqueNavigationNodes):
2004324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.uniqueNavigationNodes = uniqueNavigationNodes
2005324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2006324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2007324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def consume(self):
2008324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.p == -1:
2009324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.fillBuffer()
2010324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2011324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.p += 1
2012324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2013324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2014324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def LA(self, i):
2015324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.adaptor.getType(self.LT(i))
2016324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2017324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2018324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def mark(self):
2019324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.p == -1:
2020324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.fillBuffer()
2021324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2022324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2023324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.lastMarker = self.index()
2024324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.lastMarker
2025324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2026324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2027324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def release(self, marker=None):
2028324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # no resources to release
2029324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2030324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        pass
2031324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2032324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2033324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def index(self):
2034324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.p
2035324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2036324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2037324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def rewind(self, marker=None):
2038324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if marker is None:
2039324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            marker = self.lastMarker
2040324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2041324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.seek(marker)
2042324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2043324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2044324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def seek(self, index):
2045324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.p == -1:
2046324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.fillBuffer()
2047324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2048324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.p = index
2049324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2050324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2051324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def push(self, index):
2052324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2053324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Make stream jump to a new location, saving old location.
2054324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Switch back with pop().
2055324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2056324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2057324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.calls.append(self.p) # save current index
2058324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.seek(index)
2059324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2060324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2061324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def pop(self):
2062324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2063324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Seek back to previous index saved during last push() call.
2064324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Return top of stack (return index).
2065324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2066324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2067324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ret = self.calls.pop(-1)
2068324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.seek(ret)
2069324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return ret
2070324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2071324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2072324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def reset(self):
2073324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.p = 0
2074324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.lastMarker = 0
2075324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.calls = []
2076324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2077324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2078324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def size(self):
2079324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.p == -1:
2080324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.fillBuffer()
2081324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2082324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return len(self.nodes)
2083324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2084324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2085324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # TREE REWRITE INTERFACE
2086324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2087324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def replaceChildren(self, parent, startChildIndex, stopChildIndex, t):
2088324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if parent is not None:
2089324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.adaptor.replaceChildren(
2090324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                parent, startChildIndex, stopChildIndex, t
2091324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                )
2092324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2093324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2094324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def __str__(self):
2095324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Used for testing, just return the token type stream"""
2096324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2097324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.p == -1:
2098324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.fillBuffer()
2099324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return ' '.join([str(self.adaptor.getType(node))
2101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                         for node in self.nodes
2102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                         ])
2103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def toString(self, start, stop):
2106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if start is None or stop is None:
2107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return None
2108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.p == -1:
2110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.fillBuffer()
2111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #System.out.println("stop: "+stop);
2113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #if ( start instanceof CommonTree )
2114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #    System.out.print("toString: "+((CommonTree)start).getToken()+", ");
2115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #else
2116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #    System.out.println(start);
2117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #if ( stop instanceof CommonTree )
2118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #    System.out.println(((CommonTree)stop).getToken());
2119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #else
2120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #    System.out.println(stop);
2121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # if we have the token stream, use that to dump text in order
2123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.tokens is not None:
2124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            beginTokenIndex = self.adaptor.getTokenStartIndex(start)
2125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            endTokenIndex = self.adaptor.getTokenStopIndex(stop)
2126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # if it's a tree, use start/stop index from start node
2128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # else use token range from start/stop nodes
2129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if self.adaptor.getType(stop) == UP:
2130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                endTokenIndex = self.adaptor.getTokenStopIndex(start)
2131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            elif self.adaptor.getType(stop) == EOF:
2133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                endTokenIndex = self.size() -2 # don't use EOF
2134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.tokens.toString(beginTokenIndex, endTokenIndex)
2136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # walk nodes looking for start
2138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        i, t = 0, None
2139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        for i, t in enumerate(self.nodes):
2140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if t == start:
2141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                break
2142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # now walk until we see stop, filling string buffer with text
2144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        buf = []
2145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        t = self.nodes[i]
2146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        while t != stop:
2147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            text = self.adaptor.getText(t)
2148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if text is None:
2149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                text = " " + self.adaptor.getType(t)
2150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.append(text)
2152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            i += 1
2153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            t = self.nodes[i]
2154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # include stop node too
2156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        text = self.adaptor.getText(stop)
2157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if text is None:
2158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            text = " " +self.adaptor.getType(stop)
2159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        buf.append(text)
2161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return ''.join(buf)
2163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ## iterator interface
2166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def __iter__(self):
2167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.p == -1:
2168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.fillBuffer()
2169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        for node in self.nodes:
2171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            yield node
2172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#############################################################################
2175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
2176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# tree parser
2177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
2178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#############################################################################
2179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass TreeParser(BaseRecognizer):
2181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """@brief Baseclass for generated tree parsers.
2182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    A parser for a stream of tree nodes.  "tree grammars" result in a subclass
2184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    of this.  All the error reporting and recovery is shared with Parser via
2185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    the BaseRecognizer superclass.
2186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
2187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def __init__(self, input, state=None):
2189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        BaseRecognizer.__init__(self, state)
2190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.input = None
2192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.setTreeNodeStream(input)
2193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def reset(self):
2196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        BaseRecognizer.reset(self) # reset all recognizer state variables
2197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.input is not None:
2198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.input.seek(0) # rewind the input
2199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def setTreeNodeStream(self, input):
2202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Set the input stream"""
2203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.input = input
2205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getTreeNodeStream(self):
2208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.input
2209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getSourceName(self):
2212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.input.getSourceName()
2213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getCurrentInputSymbol(self, input):
2216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return input.LT(1)
2217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getMissingSymbol(self, input, e, expectedTokenType, follow):
2220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        tokenText = "<missing " + self.tokenNames[expectedTokenType] + ">"
2221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        adaptor = input.adaptor
2222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return adaptor.createToken(
2223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            CommonToken(type=expectedTokenType, text=tokenText))
2224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    # precompiled regex used by inContext
2227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    dotdot = ".*[^.]\\.\\.[^.].*"
2228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    doubleEtc = ".*\\.\\.\\.\\s+\\.\\.\\..*"
2229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    dotdotPattern = re.compile(dotdot)
2230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    doubleEtcPattern = re.compile(doubleEtc)
2231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def inContext(self, context, adaptor=None, tokenName=None, t=None):
2233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Check if current node in input has a context.
2234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Context means sequence of nodes towards root of tree.  For example,
2236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        you might say context is "MULT" which means my parent must be MULT.
2237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        "CLASS VARDEF" says current node must be child of a VARDEF and whose
2238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        parent is a CLASS node.  You can use "..." to mean zero-or-more nodes.
2239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        "METHOD ... VARDEF" means my parent is VARDEF and somewhere above
2240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        that is a METHOD node.  The first node in the context is not
2241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        necessarily the root.  The context matcher stops matching and returns
2242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        true when it runs out of context.  There is no way to force the first
2243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        node to be the root.
2244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return _inContext(
2247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.input.getTreeAdaptor(), self.getTokenNames(),
2248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.input.LT(1), context)
2249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @classmethod
2251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def _inContext(cls, adaptor, tokenNames, t, context):
2252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """The worker for inContext.
2253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        It's static and full of parameters for testing purposes.
2255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if cls.dotdotPattern.match(context):
2258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # don't allow "..", must be "..."
2259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            raise ValueError("invalid syntax: ..")
2260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if cls.doubleEtcPattern.match(context):
2262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # don't allow double "..."
2263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            raise ValueError("invalid syntax: ... ...")
2264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # ensure spaces around ...
2266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        context = context.replace("...", " ... ")
2267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        context = context.strip()
2268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        nodes = context.split()
2269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ni = len(nodes) - 1
2271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        t = adaptor.getParent(t)
2272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        while ni >= 0 and t is not None:
2273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if nodes[ni] == "...":
2274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                # walk upwards until we see nodes[ni-1] then continue walking
2275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if ni == 0:
2276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    # ... at start is no-op
2277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    return True
2278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                goal = nodes[ni-1]
2279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                ancestor = cls._getAncestor(adaptor, tokenNames, t, goal)
2280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if ancestor is None:
2281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    return False
2282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                t = ancestor
2283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                ni -= 1
2284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            name = tokenNames[adaptor.getType(t)]
2286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if name != nodes[ni]:
2287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return False
2288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # advance to parent and to previous element in context node list
2290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ni -= 1
2291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            t = adaptor.getParent(t)
2292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # at root but more nodes to match
2294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if t is None and ni >= 0:
2295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return False
2296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return True
2298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @staticmethod
2300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def _getAncestor(adaptor, tokenNames, t, goal):
2301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Helper for static inContext."""
2302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        while t is not None:
2303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            name = tokenNames[adaptor.getType(t)]
2304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if name == goal:
2305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return t
2306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            t = adaptor.getParent(t)
2307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return None
2309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def matchAny(self, ignore): # ignore stream, copy of this.input
2312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Match '.' in tree parser has special meaning.  Skip node or
2314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        entire tree if node has children.  If children, scan until
2315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        corresponding UP node.
2316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self._state.errorRecovery = False
2319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        look = self.input.LT(1)
2321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.input.getTreeAdaptor().getChildCount(look) == 0:
2322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.input.consume() # not subtree, consume 1 node and return
2323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return
2324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # current node is a subtree, skip to corresponding UP.
2326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # must count nesting level to get right UP
2327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        level = 0
2328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        tokenType = self.input.getTreeAdaptor().getType(look)
2329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        while tokenType != EOF and not (tokenType == UP and level==0):
2330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.input.consume()
2331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            look = self.input.LT(1)
2332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            tokenType = self.input.getTreeAdaptor().getType(look)
2333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if tokenType == DOWN:
2334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                level += 1
2335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            elif tokenType == UP:
2337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                level -= 1
2338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.input.consume() # consume UP
2340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def mismatch(self, input, ttype, follow):
2343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        We have DOWN/UP nodes in the stream that have no line info; override.
2345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        plus we want to alter the exception type. Don't try to recover
2346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        from tree parser errors inline...
2347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise MismatchedTreeNodeException(ttype, input)
2350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getErrorHeader(self, e):
2353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Prefix error message with the grammar name because message is
2355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        always intended for the programmer because the parser built
2356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        the input tree not the user.
2357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return (self.getGrammarFileName() +
2360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                ": node from %sline %s:%s"
2361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                % (['', "after "][e.approximateLineInfo],
2362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                   e.line,
2363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                   e.charPositionInLine
2364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                   )
2365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                )
2366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getErrorMessage(self, e, tokenNames):
2368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Tree parsers parse nodes they usually have a token object as
2370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        payload. Set the exception token and do the default behavior.
2371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if isinstance(self, TreeParser):
2374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            adaptor = e.input.getTreeAdaptor()
2375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            e.token = adaptor.getToken(e.node)
2376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if e.token is not None: # could be an UP/DOWN node
2377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                e.token = CommonToken(
2378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    type=adaptor.getType(e.node),
2379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    text=adaptor.getText(e.node)
2380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    )
2381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return BaseRecognizer.getErrorMessage(self, e, tokenNames)
2383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def traceIn(self, ruleName, ruleIndex):
2386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        BaseRecognizer.traceIn(self, ruleName, ruleIndex, self.input.LT(1))
2387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def traceOut(self, ruleName, ruleIndex):
2390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        BaseRecognizer.traceOut(self, ruleName, ruleIndex, self.input.LT(1))
2391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#############################################################################
2394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
2395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# tree visitor
2396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
2397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#############################################################################
2398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass TreeVisitor(object):
2400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """Do a depth first walk of a tree, applying pre() and post() actions
2401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    we go.
2402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
2403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def __init__(self, adaptor=None):
2405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if adaptor is not None:
2406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.adaptor = adaptor
2407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        else:
2408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.adaptor = CommonTreeAdaptor()
2409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def visit(self, t, pre_action=None, post_action=None):
2411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Visit every node in tree t and trigger an action for each node
2412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        before/after having visited all of its children.  Bottom up walk.
2413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Execute both actions even if t has no children.  Ignore return
2414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        results from transforming children since they will have altered
2415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        the child list of this node (their parent).  Return result of
2416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        applying post action to this node.
2417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        The Python version differs from the Java version by taking two
2419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        callables 'pre_action' and 'post_action' instead of a class instance
2420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        that wraps those methods. Those callables must accept a TreeNode as
2421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        their single argument and return the (potentially transformed or
2422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        replaced) TreeNode.
2423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        isNil = self.adaptor.isNil(t)
2426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if pre_action is not None and not isNil:
2427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # if rewritten, walk children of new t
2428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            t = pre_action(t)
2429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        idx = 0
2431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        while idx < self.adaptor.getChildCount(t):
2432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            child = self.adaptor.getChild(t, idx)
2433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.visit(child, pre_action, post_action)
2434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            idx += 1
2435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if post_action is not None and not isNil:
2437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            t = post_action(t)
2438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return t
2440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#############################################################################
2442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
2443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# tree iterator
2444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
2445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#############################################################################
2446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass TreeIterator(object):
2448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
2449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    Return a node stream from a doubly-linked tree whose nodes
2450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    know what child index they are.
2451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    Emit navigation nodes (DOWN, UP, and EOF) to let show tree structure.
2453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
2454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def __init__(self, tree, adaptor=None):
2456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if adaptor is None:
2457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            adaptor = CommonTreeAdaptor()
2458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.root = tree
2460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.adaptor = adaptor
2461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.first_time = True
2463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.tree = tree
2464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # If we emit UP/DOWN nodes, we need to spit out multiple nodes per
2466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # next() call.
2467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.nodes = []
2468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # navigation nodes to return during walk and at end
2470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.down = adaptor.createFromType(DOWN, "DOWN")
2471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.up = adaptor.createFromType(UP, "UP")
2472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.eof = adaptor.createFromType(EOF, "EOF")
2473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def reset(self):
2476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.first_time = True
2477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.tree = self.root
2478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.nodes = []
2479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def __iter__(self):
2482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self
2483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def has_next(self):
2486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.first_time:
2487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.root is not None
2488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if len(self.nodes) > 0:
2490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return True
2491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.tree is None:
2493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return False
2494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.adaptor.getChildCount(self.tree) > 0:
2496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return True
2497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # back at root?
2499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.adaptor.getParent(self.tree) is not None
2500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def next(self):
2503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if not self.has_next():
2504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            raise StopIteration
2505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.first_time:
2507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # initial condition
2508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.first_time = False
2509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if self.adaptor.getChildCount(self.tree) == 0:
2510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                # single node tree (special)
2511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                self.nodes.append(self.eof)
2512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return self.tree
2513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.tree
2515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # if any queued up, use those first
2517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if len(self.nodes) > 0:
2518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.nodes.pop(0)
2519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # no nodes left?
2521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.tree is None:
2522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.eof
2523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # next node will be child 0 if any children
2525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.adaptor.getChildCount(self.tree) > 0:
2526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.tree = self.adaptor.getChild(self.tree, 0)
2527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # real node is next after DOWN
2528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.nodes.append(self.tree)
2529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.down
2530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # if no children, look for next sibling of tree or ancestor
2532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        parent = self.adaptor.getParent(self.tree)
2533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # while we're out of siblings, keep popping back up towards root
2534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        while (parent is not None
2535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver               and self.adaptor.getChildIndex(self.tree)+1 >= self.adaptor.getChildCount(parent)):
2536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # we're moving back up
2537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.nodes.append(self.up)
2538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.tree = parent
2539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            parent = self.adaptor.getParent(self.tree)
2540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # no nodes left?
2542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if parent is None:
2543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.tree = None # back at root? nothing left then
2544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.nodes.append(self.eof) # add to queue, might have UP nodes in there
2545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.nodes.pop(0)
2546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # must have found a node with an unvisited sibling
2548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # move to it and return it
2549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        nextSiblingIndex = self.adaptor.getChildIndex(self.tree) + 1
2550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.tree = self.adaptor.getChild(parent, nextSiblingIndex)
2551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.nodes.append(self.tree) # add to queue, might have UP nodes in there
2552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.nodes.pop(0)
2553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#############################################################################
2557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
2558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# streams for rule rewriting
2559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#
2560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#############################################################################
2561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass RewriteRuleElementStream(object):
2563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """@brief Internal helper class.
2564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    A generic list of elements tracked in an alternative to be used in
2566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    a -> rewrite rule.  We need to subclass to fill in the next() method,
2567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    which returns either an AST node wrapped around a token payload or
2568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    an existing subtree.
2569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    Once you start next()ing, do not try to add more elements.  It will
2571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    break the cursor tracking I believe.
2572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @see org.antlr.runtime.tree.RewriteRuleSubtreeStream
2574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @see org.antlr.runtime.tree.RewriteRuleTokenStream
2575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    TODO: add mechanism to detect/puke on modification after reading from
2577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    stream
2578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
2579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def __init__(self, adaptor, elementDescription, elements=None):
2581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # Cursor 0..n-1.  If singleElement!=null, cursor is 0 until you next(),
2582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # which bumps it to 1 meaning no more elements.
2583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.cursor = 0
2584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # Track single elements w/o creating a list.  Upon 2nd add, alloc list
2586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.singleElement = None
2587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # The list of tokens or subtrees we are tracking
2589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.elements = None
2590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # Once a node / subtree has been used in a stream, it must be dup'd
2592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # from then on.  Streams are reset after subrules so that the streams
2593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # can be reused in future subrules.  So, reset must set a dirty bit.
2594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # If dirty, then next() always returns a dup.
2595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.dirty = False
2596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # The element or stream description; usually has name of the token or
2598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # rule reference that this list tracks.  Can include rulename too, but
2599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # the exception would track that info.
2600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.elementDescription = elementDescription
2601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2602324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.adaptor = adaptor
2603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if isinstance(elements, (list, tuple)):
2605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # Create a stream, but feed off an existing list
2606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.singleElement = None
2607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.elements = elements
2608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        else:
2610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # Create a stream with one element
2611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.add(elements)
2612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def reset(self):
2615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Reset the condition of this stream so that it appears we have
2617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        not consumed any of its elements.  Elements themselves are untouched.
2618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Once we reset the stream, any future use will need duplicates.  Set
2619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        the dirty bit.
2620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.cursor = 0
2623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.dirty = True
2624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def add(self, el):
2627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if el is None:
2628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return
2629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.elements is not None: # if in list, just add
2631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.elements.append(el)
2632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return
2633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.singleElement is None: # no elements yet, track w/o list
2635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.singleElement = el
2636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return
2637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # adding 2nd element, move to list
2639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.elements = []
2640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.elements.append(self.singleElement)
2641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.singleElement = None
2642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.elements.append(el)
2643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def nextTree(self):
2646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Return the next element in the stream.  If out of elements, throw
2648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        an exception unless size()==1.  If size is 1, then return elements[0].
2649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Return a duplicate node/subtree if stream is out of elements and
2651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        size==1. If we've already used the element, dup (dirty bit set).
2652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (self.dirty
2655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            or (self.cursor >= len(self) and len(self) == 1)
2656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ):
2657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # if out of elements and size is 1, dup
2658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            el = self._next()
2659324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.dup(el)
2660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # test size above then fetch
2662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        el = self._next()
2663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return el
2664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def _next(self):
2667324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        do the work of getting the next element, making sure that it's
2669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        a tree node or subtree.  Deal with the optimization of single-
2670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        element list versus list of size > 1.  Throw an exception
2671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if the stream is empty or we're out of elements and size>1.
2672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected so you can override in a subclass if necessary.
2673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2675324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if len(self) == 0:
2676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            raise RewriteEmptyStreamException(self.elementDescription)
2677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.cursor >= len(self): # out of elements?
2679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if len(self) == 1: # if size is 1, it's ok; return and we'll dup
2680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return self.toTree(self.singleElement)
2681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # out of elements and size was not 1, so we can't dup
2683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            raise RewriteCardinalityException(self.elementDescription)
2684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # we have elements
2686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.singleElement is not None:
2687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            self.cursor += 1 # move cursor even for single element list
2688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.toTree(self.singleElement)
2689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # must have more than one in list, pull from elements
2691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        o = self.toTree(self.elements[self.cursor])
2692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.cursor += 1
2693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return o
2694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def dup(self, el):
2697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        When constructing trees, sometimes we need to dup a token or AST
2699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        subtree.  Dup'ing a token means just creating another AST node
2700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        around it.  For trees, you must call the adaptor.dupTree() unless
2701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        the element is for a tree root; then it must be a node dup.
2702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise NotImplementedError
2705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def toTree(self, el):
2708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Ensure stream emits trees; tokens must be converted to AST nodes.
2710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        AST nodes can be passed through unmolested.
2711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return el
2714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2716324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def hasNext(self):
2717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return ( (self.singleElement is not None and self.cursor < 1)
2718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                 or (self.elements is not None
2719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                     and self.cursor < len(self.elements)
2720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                     )
2721324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                 )
2722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def size(self):
2725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.singleElement is not None:
2726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return 1
2727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if self.elements is not None:
2729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return len(self.elements)
2730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return 0
2732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    __len__ = size
2734324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2735324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2736324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getDescription(self):
2737324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """Deprecated. Directly access elementDescription attribute"""
2738324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2739324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.elementDescription
2740324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2741324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2742324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass RewriteRuleTokenStream(RewriteRuleElementStream):
2743324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """@brief Internal helper class."""
2744324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2745324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def toTree(self, el):
2746324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # Don't convert to a tree unless they explicitly call nextTree.
2747324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # This way we can do hetero tree nodes in rewrite.
2748324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return el
2749324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2750324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2751324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def nextNode(self):
2752324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        t = self._next()
2753324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.adaptor.createWithPayload(t)
2754324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2755324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2756324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def nextToken(self):
2757324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self._next()
2758324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2759324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2760324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def dup(self, el):
2761324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise TypeError("dup can't be called for a token stream.")
2762324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2763324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2764324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass RewriteRuleSubtreeStream(RewriteRuleElementStream):
2765324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """@brief Internal helper class."""
2766324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2767324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def nextNode(self):
2768324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2769324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Treat next element as a single node even if it's a subtree.
2770324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        This is used instead of next() when the result has to be a
2771324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        tree root node.  Also prevents us from duplicating recently-added
2772324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        children; e.g., ^(type ID)+ adds ID to type and then 2nd iteration
2773324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        must dup the type node, but ID has been added.
2774324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2775324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Referencing a rule result twice is ok; dup entire tree as
2776324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        we can't be adding trees as root; e.g., expr expr.
2777324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2778324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Hideous code duplication here with super.next().  Can't think of
2779324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        a proper way to refactor.  This needs to always call dup node
2780324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        and super.next() doesn't know which to call: dup node or dup tree.
2781324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        """
2782324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2783324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (self.dirty
2784324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            or (self.cursor >= len(self) and len(self) == 1)
2785324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ):
2786324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # if out of elements and size is 1, dup (at most a single node
2787324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            # since this is for making root nodes).
2788324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            el = self._next()
2789324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return self.adaptor.dupNode(el)
2790324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2791324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # test size above then fetch
2792324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        el = self._next()
2793324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        while self.adaptor.isNil(el) and self.adaptor.getChildCount(el) == 1:
2794324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            el = self.adaptor.getChild(el, 0)
2795324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2796324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # dup just the root (want node here)
2797324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.adaptor.dupNode(el)
2798324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2799324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2800324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def dup(self, el):
2801324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.adaptor.dupTree(el)
2802324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2803324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2804324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2805324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass RewriteRuleNodeStream(RewriteRuleElementStream):
2806324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
2807324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    Queues up nodes matched on left side of -> in a tree parser. This is
2808324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    the analog of RewriteRuleTokenStream for normal parsers.
2809324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
2810324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2811324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def nextNode(self):
2812324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self._next()
2813324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2814324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2815324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def toTree(self, el):
2816324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.adaptor.dupNode(el)
2817324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2818324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2819324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def dup(self, el):
2820324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        # we dup every node, so don't have to worry about calling dup; short-
2821324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        #circuited next() so it doesn't call.
2822324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        raise TypeError("dup can't be called for a node stream.")
2823324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2824324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2825324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass TreeRuleReturnScope(RuleReturnScope):
2826324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
2827324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    This is identical to the ParserRuleReturnScope except that
2828324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    the start property is a tree nodes not Token object
2829324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    when you are parsing trees.  To be generic the tree node types
2830324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    have to be Object.
2831324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    """
2832324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2833324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def __init__(self):
2834324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.start = None
2835324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        self.tree = None
2836324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2837324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2838324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getStart(self):
2839324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.start
2840324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2841324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2842324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    def getTree(self):
2843324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        return self.tree
2844