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