00001 ## 00002 # @package antlr3.tree 00003 # @brief ANTLR3 runtime package, tree module 00004 # 00005 # This module contains all support classes for AST construction and tree parsers. 00006 # 00007 # 00008 00009 # begin[licence] 00010 # 00011 # [The "BSD licence"] 00012 # Copyright (c) 2005-2008 Terence Parr 00013 # All rights reserved. 00014 # 00015 # Redistribution and use in source and binary forms, with or without 00016 # modification, are permitted provided that the following conditions 00017 # are met: 00018 # 1. Redistributions of source code must retain the above copyright 00019 # notice, this list of conditions and the following disclaimer. 00020 # 2. Redistributions in binary form must reproduce the above copyright 00021 # notice, this list of conditions and the following disclaimer in the 00022 # documentation and/or other materials provided with the distribution. 00023 # 3. The name of the author may not be used to endorse or promote products 00024 # derived from this software without specific prior written permission. 00025 # 00026 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00027 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00028 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00029 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 00030 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00031 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00032 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00033 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00034 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00035 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 # 00037 # end[licence] 00038 00039 # lot's of docstrings are missing, don't complain for now... 00040 # pylint: disable-msg=C0111 00041 00042 from antlr3.constants import UP, DOWN, EOF, INVALID_TOKEN_TYPE 00043 from antlr3.recognizers import BaseRecognizer, RuleReturnScope 00044 from antlr3.streams import IntStream 00045 from antlr3.tokens import CommonToken, Token, INVALID_TOKEN 00046 from antlr3.exceptions import MismatchedTreeNodeException, \ 00047 MissingTokenException, UnwantedTokenException, MismatchedTokenException, \ 00048 NoViableAltException 00049 00050 00051 ############################################################################ 00052 # 00053 # tree related exceptions 00054 # 00055 ############################################################################ 00056 00057 00058 ## 00059 # 00060 # @brief Base class for all exceptions thrown during AST rewrite construction. 00061 # 00062 # This signifies a case where the cardinality of two or more elements 00063 # in a subrule are different: (ID INT)+ where |ID|!=|INT| 00064 # 00065 class RewriteCardinalityException(RuntimeError): 00066 00067 def __init__(self, elementDescription): 00068 RuntimeError.__init__(self, elementDescription) 00069 00070 self.elementDescription = elementDescription 00071 00072 00073 def getMessage(self): 00074 return self.elementDescription 00075 00076 00077 ## 00078 # @brief No elements within a (...)+ in a rewrite rule 00079 class RewriteEarlyExitException(RewriteCardinalityException): 00080 00081 def __init__(self, elementDescription=None): 00082 RewriteCardinalityException.__init__(self, elementDescription) 00083 00084 00085 ## 00086 # 00087 # @brief Ref to ID or expr but no tokens in ID stream or subtrees in expr stream 00088 # 00089 class RewriteEmptyStreamException(RewriteCardinalityException): 00090 00091 pass 00092 00093 00094 ############################################################################ 00095 # 00096 # basic Tree and TreeAdaptor interfaces 00097 # 00098 ############################################################################ 00099 00100 ## 00101 # 00102 # @brief Abstract baseclass for tree nodes. 00103 # 00104 # What does a tree look like? ANTLR has a number of support classes 00105 # such as CommonTreeNodeStream that work on these kinds of trees. You 00106 # don't have to make your trees implement this interface, but if you do, 00107 # you'll be able to use more support code. 00108 # 00109 # NOTE: When constructing trees, ANTLR can build any kind of tree; it can 00110 # even use Token objects as trees if you add a child list to your tokens. 00111 # 00112 # This is a tree node without any payload; just navigation and factory stuff. 00113 # 00114 class Tree(object): 00115 00116 00117 def getChild(self, i): 00118 raise NotImplementedError 00119 00120 00121 def getChildCount(self): 00122 raise NotImplementedError 00123 00124 00125 ## 00126 # Tree tracks parent and child index now > 3.0 00127 def getParent(self): 00128 00129 raise NotImplementedError 00130 00131 ## 00132 # Tree tracks parent and child index now > 3.0 00133 def setParent(self, t): 00134 00135 raise NotImplementedError 00136 00137 00138 ## 00139 # This node is what child index? 0..n-1 00140 def getChildIndex(self): 00141 00142 raise NotImplementedError 00143 00144 ## 00145 # This node is what child index? 0..n-1 00146 def setChildIndex(self, index): 00147 00148 raise NotImplementedError 00149 00150 00151 ## 00152 # Set the parent and child index values for all children 00153 def freshenParentAndChildIndexes(self): 00154 00155 raise NotImplementedError 00156 00157 00158 ## 00159 # 00160 # Add t as a child to this node. If t is null, do nothing. If t 00161 # is nil, add all children of t to this' children. 00162 # 00163 def addChild(self, t): 00164 00165 raise NotImplementedError 00166 00167 00168 ## 00169 # Set ith child (0..n-1) to t; t must be non-null and non-nil node 00170 def setChild(self, i, t): 00171 00172 raise NotImplementedError 00173 00174 00175 def deleteChild(self, i): 00176 raise NotImplementedError 00177 00178 00179 ## 00180 # 00181 # Delete children from start to stop and replace with t even if t is 00182 # a list (nil-root tree). num of children can increase or decrease. 00183 # For huge child lists, inserting children can force walking rest of 00184 # children to set their childindex; could be slow. 00185 # 00186 def replaceChildren(self, startChildIndex, stopChildIndex, t): 00187 00188 raise NotImplementedError 00189 00190 00191 ## 00192 # 00193 # Indicates the node is a nil node but may still have children, meaning 00194 # the tree is a flat list. 00195 # 00196 def isNil(self): 00197 00198 raise NotImplementedError 00199 00200 00201 ## 00202 # 00203 # What is the smallest token index (indexing from 0) for this node 00204 # and its children? 00205 # 00206 def getTokenStartIndex(self): 00207 00208 raise NotImplementedError 00209 00210 00211 def setTokenStartIndex(self, index): 00212 raise NotImplementedError 00213 00214 00215 ## 00216 # 00217 # What is the largest token index (indexing from 0) for this node 00218 # and its children? 00219 # 00220 def getTokenStopIndex(self): 00221 00222 raise NotImplementedError 00223 00224 00225 def setTokenStopIndex(self, index): 00226 raise NotImplementedError 00227 00228 00229 def dupNode(self): 00230 raise NotImplementedError 00231 00232 00233 ## 00234 # Return a token type; needed for tree parsing. 00235 def getType(self): 00236 00237 raise NotImplementedError 00238 00239 00240 def getText(self): 00241 raise NotImplementedError 00242 00243 00244 ## 00245 # 00246 # In case we don't have a token payload, what is the line for errors? 00247 # 00248 def getLine(self): 00249 00250 raise NotImplementedError 00251 00252 00253 def getCharPositionInLine(self): 00254 raise NotImplementedError 00255 00256 00257 def toStringTree(self): 00258 raise NotImplementedError 00259 00260 00261 def toString(self): 00262 raise NotImplementedError 00263 00264 00265 00266 ## 00267 # 00268 # @brief Abstract baseclass for tree adaptors. 00269 # 00270 # How to create and navigate trees. Rather than have a separate factory 00271 # and adaptor, I've merged them. Makes sense to encapsulate. 00272 # 00273 # This takes the place of the tree construction code generated in the 00274 # generated code in 2.x and the ASTFactory. 00275 # 00276 # I do not need to know the type of a tree at all so they are all 00277 # generic Objects. This may increase the amount of typecasting needed. :( 00278 # 00279 class TreeAdaptor(object): 00280 00281 # C o n s t r u c t i o n 00282 00283 ## 00284 # 00285 # Create a tree node from Token object; for CommonTree type trees, 00286 # then the token just becomes the payload. This is the most 00287 # common create call. 00288 # 00289 # Override if you want another kind of node to be built. 00290 # 00291 def createWithPayload(self, payload): 00292 00293 raise NotImplementedError 00294 00295 00296 ## 00297 # Duplicate a single tree node. 00298 # 00299 # Override if you want another kind of node to be built. 00300 def dupNode(self, treeNode): 00301 00302 raise NotImplementedError 00303 00304 00305 ## 00306 # Duplicate tree recursively, using dupNode() for each node 00307 def dupTree(self, tree): 00308 00309 raise NotImplementedError 00310 00311 00312 ## 00313 # 00314 # Return a nil node (an empty but non-null node) that can hold 00315 # a list of element as the children. If you want a flat tree (a list) 00316 # use "t=adaptor.nil(); t.addChild(x); t.addChild(y);" 00317 # 00318 def nil(self): 00319 00320 raise NotImplementedError 00321 00322 00323 ## 00324 # 00325 # Return a tree node representing an error. This node records the 00326 # tokens consumed during error recovery. The start token indicates the 00327 # input symbol at which the error was detected. The stop token indicates 00328 # the last symbol consumed during recovery. 00329 # 00330 # You must specify the input stream so that the erroneous text can 00331 # be packaged up in the error node. The exception could be useful 00332 # to some applications; default implementation stores ptr to it in 00333 # the CommonErrorNode. 00334 # 00335 # This only makes sense during token parsing, not tree parsing. 00336 # Tree parsing should happen only when parsing and tree construction 00337 # succeed. 00338 # 00339 def errorNode(self, input, start, stop, exc): 00340 00341 raise NotImplementedError 00342 00343 00344 ## 00345 # Is tree considered a nil node used to make lists of child nodes? 00346 def isNil(self, tree): 00347 00348 raise NotImplementedError 00349 00350 00351 ## 00352 # 00353 # Add a child to the tree t. If child is a flat tree (a list), make all 00354 # in list children of t. Warning: if t has no children, but child does 00355 # and child isNil then you can decide it is ok to move children to t via 00356 # t.children = child.children; i.e., without copying the array. Just 00357 # make sure that this is consistent with have the user will build 00358 # ASTs. Do nothing if t or child is null. 00359 # 00360 def addChild(self, t, child): 00361 00362 raise NotImplementedError 00363 00364 00365 ## 00366 # 00367 # If oldRoot is a nil root, just copy or move the children to newRoot. 00368 # If not a nil root, make oldRoot a child of newRoot. 00369 # 00370 # old=^(nil a b c), new=r yields ^(r a b c) 00371 # old=^(a b c), new=r yields ^(r ^(a b c)) 00372 # 00373 # If newRoot is a nil-rooted single child tree, use the single 00374 # child as the new root node. 00375 # 00376 # old=^(nil a b c), new=^(nil r) yields ^(r a b c) 00377 # old=^(a b c), new=^(nil r) yields ^(r ^(a b c)) 00378 # 00379 # If oldRoot was null, it's ok, just return newRoot (even if isNil). 00380 # 00381 # old=null, new=r yields r 00382 # old=null, new=^(nil r) yields ^(nil r) 00383 # 00384 # Return newRoot. Throw an exception if newRoot is not a 00385 # simple node or nil root with a single child node--it must be a root 00386 # node. If newRoot is ^(nil x) return x as newRoot. 00387 # 00388 # Be advised that it's ok for newRoot to point at oldRoot's 00389 # children; i.e., you don't have to copy the list. We are 00390 # constructing these nodes so we should have this control for 00391 # efficiency. 00392 # 00393 def becomeRoot(self, newRoot, oldRoot): 00394 00395 raise NotImplementedError 00396 00397 00398 ## 00399 # 00400 # Given the root of the subtree created for this rule, post process 00401 # it to do any simplifications or whatever you want. A required 00402 # behavior is to convert ^(nil singleSubtree) to singleSubtree 00403 # as the setting of start/stop indexes relies on a single non-nil root 00404 # for non-flat trees. 00405 # 00406 # Flat trees such as for lists like "idlist : ID+ ;" are left alone 00407 # unless there is only one ID. For a list, the start/stop indexes 00408 # are set in the nil node. 00409 # 00410 # This method is executed after all rule tree construction and right 00411 # before setTokenBoundaries(). 00412 # 00413 def rulePostProcessing(self, root): 00414 00415 raise NotImplementedError 00416 00417 00418 ## 00419 # For identifying trees. 00420 # 00421 # How to identify nodes so we can say "add node to a prior node"? 00422 # Even becomeRoot is an issue. Use System.identityHashCode(node) 00423 # usually. 00424 # 00425 def getUniqueID(self, node): 00426 00427 raise NotImplementedError 00428 00429 00430 # R e w r i t e R u l e s 00431 00432 ## 00433 # 00434 # Create a new node derived from a token, with a new token type and 00435 # (optionally) new text. 00436 # 00437 # This is invoked from an imaginary node ref on right side of a 00438 # rewrite rule as IMAG[$tokenLabel] or IMAG[$tokenLabel "IMAG"]. 00439 # 00440 # This should invoke createToken(Token). 00441 # 00442 def createFromToken(self, tokenType, fromToken, text=None): 00443 00444 raise NotImplementedError 00445 00446 00447 ## 00448 # Create a new node derived from a token, with a new token type. 00449 # 00450 # This is invoked from an imaginary node ref on right side of a 00451 # rewrite rule as IMAG["IMAG"]. 00452 # 00453 # This should invoke createToken(int,String). 00454 # 00455 def createFromType(self, tokenType, text): 00456 00457 raise NotImplementedError 00458 00459 00460 # C o n t e n t 00461 00462 ## 00463 # For tree parsing, I need to know the token type of a node 00464 def getType(self, t): 00465 00466 raise NotImplementedError 00467 00468 00469 ## 00470 # Node constructors can set the type of a node 00471 def setType(self, t, type): 00472 00473 raise NotImplementedError 00474 00475 00476 def getText(self, t): 00477 raise NotImplementedError 00478 00479 ## 00480 # Node constructors can set the text of a node 00481 def setText(self, t, text): 00482 00483 raise NotImplementedError 00484 00485 00486 ## 00487 # Return the token object from which this node was created. 00488 # 00489 # Currently used only for printing an error message. 00490 # The error display routine in BaseRecognizer needs to 00491 # display where the input the error occurred. If your 00492 # tree of limitation does not store information that can 00493 # lead you to the token, you can create a token filled with 00494 # the appropriate information and pass that back. See 00495 # BaseRecognizer.getErrorMessage(). 00496 # 00497 def getToken(self, t): 00498 00499 raise NotImplementedError 00500 00501 00502 ## 00503 # 00504 # Where are the bounds in the input token stream for this node and 00505 # all children? Each rule that creates AST nodes will call this 00506 # method right before returning. Flat trees (i.e., lists) will 00507 # still usually have a nil root node just to hold the children list. 00508 # That node would contain the start/stop indexes then. 00509 # 00510 def setTokenBoundaries(self, t, startToken, stopToken): 00511 00512 raise NotImplementedError 00513 00514 00515 ## 00516 # 00517 # Get the token start index for this subtree; return -1 if no such index 00518 # 00519 def getTokenStartIndex(self, t): 00520 00521 raise NotImplementedError 00522 00523 00524 ## 00525 # 00526 # Get the token stop index for this subtree; return -1 if no such index 00527 # 00528 def getTokenStopIndex(self, t): 00529 00530 raise NotImplementedError 00531 00532 00533 # N a v i g a t i o n / T r e e P a r s i n g 00534 00535 ## 00536 # Get a child 0..n-1 node 00537 def getChild(self, t, i): 00538 00539 raise NotImplementedError 00540 00541 00542 ## 00543 # Set ith child (0..n-1) to t; t must be non-null and non-nil node 00544 def setChild(self, t, i, child): 00545 00546 raise NotImplementedError 00547 00548 00549 ## 00550 # Remove ith child and shift children down from right. 00551 def deleteChild(self, t, i): 00552 00553 raise NotImplementedError 00554 00555 00556 ## 00557 # How many children? If 0, then this is a leaf node 00558 def getChildCount(self, t): 00559 00560 raise NotImplementedError 00561 00562 00563 ## 00564 # 00565 # Who is the parent node of this node; if null, implies node is root. 00566 # If your node type doesn't handle this, it's ok but the tree rewrites 00567 # in tree parsers need this functionality. 00568 # 00569 def getParent(self, t): 00570 00571 raise NotImplementedError 00572 00573 00574 ## 00575 # 00576 # Who is the parent node of this node; if null, implies node is root. 00577 # If your node type doesn't handle this, it's ok but the tree rewrites 00578 # in tree parsers need this functionality. 00579 # 00580 def setParent(self, t, parent): 00581 00582 raise NotImplementedError 00583 00584 00585 ## 00586 # 00587 # What index is this node in the child list? Range: 0..n-1 00588 # If your node type doesn't handle this, it's ok but the tree rewrites 00589 # in tree parsers need this functionality. 00590 # 00591 def getChildIndex(self, t): 00592 00593 raise NotImplementedError 00594 00595 00596 ## 00597 # 00598 # What index is this node in the child list? Range: 0..n-1 00599 # If your node type doesn't handle this, it's ok but the tree rewrites 00600 # in tree parsers need this functionality. 00601 # 00602 def setChildIndex(self, t, index): 00603 00604 raise NotImplementedError 00605 00606 00607 ## 00608 # 00609 # Replace from start to stop child index of parent with t, which might 00610 # be a list. Number of children may be different 00611 # after this call. 00612 # 00613 # If parent is null, don't do anything; must be at root of overall tree. 00614 # Can't replace whatever points to the parent externally. Do nothing. 00615 # 00616 def replaceChildren(self, parent, startChildIndex, stopChildIndex, t): 00617 00618 raise NotImplementedError 00619 00620 00621 # Misc 00622 00623 ## 00624 # 00625 # Deprecated, use createWithPayload, createFromToken or createFromType. 00626 # 00627 # This method only exists to mimic the Java interface of TreeAdaptor. 00628 # 00629 # 00630 def create(self, *args): 00631 00632 if len(args) == 1 and isinstance(args[0], Token): 00633 # Object create(Token payload); 00634 ## warnings.warn( 00635 ## "Using create() is deprecated, use createWithPayload()", 00636 ## DeprecationWarning, 00637 ## stacklevel=2 00638 ## ) 00639 return self.createWithPayload(args[0]) 00640 00641 if (len(args) == 2 00642 and isinstance(args[0], (int, long)) 00643 and isinstance(args[1], Token) 00644 ): 00645 # Object create(int tokenType, Token fromToken); 00646 ## warnings.warn( 00647 ## "Using create() is deprecated, use createFromToken()", 00648 ## DeprecationWarning, 00649 ## stacklevel=2 00650 ## ) 00651 return self.createFromToken(args[0], args[1]) 00652 00653 if (len(args) == 3 00654 and isinstance(args[0], (int, long)) 00655 and isinstance(args[1], Token) 00656 and isinstance(args[2], basestring) 00657 ): 00658 # Object create(int tokenType, Token fromToken, String text); 00659 ## warnings.warn( 00660 ## "Using create() is deprecated, use createFromToken()", 00661 ## DeprecationWarning, 00662 ## stacklevel=2 00663 ## ) 00664 return self.createFromToken(args[0], args[1], args[2]) 00665 00666 if (len(args) == 2 00667 and isinstance(args[0], (int, long)) 00668 and isinstance(args[1], basestring) 00669 ): 00670 # Object create(int tokenType, String text); 00671 ## warnings.warn( 00672 ## "Using create() is deprecated, use createFromType()", 00673 ## DeprecationWarning, 00674 ## stacklevel=2 00675 ## ) 00676 return self.createFromType(args[0], args[1]) 00677 00678 raise TypeError( 00679 "No create method with this signature found: %s" 00680 % (', '.join(type(v).__name__ for v in args)) 00681 ) 00682 00683 00684 ############################################################################ 00685 # 00686 # base implementation of Tree and TreeAdaptor 00687 # 00688 # Tree 00689 # \- BaseTree 00690 # 00691 # TreeAdaptor 00692 # \- BaseTreeAdaptor 00693 # 00694 ############################################################################ 00695 00696 00697 ## 00698 # 00699 # @brief A generic tree implementation with no payload. 00700 # 00701 # You must subclass to 00702 # actually have any user data. ANTLR v3 uses a list of children approach 00703 # instead of the child-sibling approach in v2. A flat tree (a list) is 00704 # an empty node whose children represent the list. An empty, but 00705 # non-null node is called "nil". 00706 # 00707 class BaseTree(Tree): 00708 00709 # BaseTree is abstract, no need to complain about not implemented abstract 00710 # methods 00711 # pylint: disable-msg=W0223 00712 00713 ## 00714 # 00715 # Create a new node from an existing node does nothing for BaseTree 00716 # as there are no fields other than the children list, which cannot 00717 # be copied as the children are not considered part of this node. 00718 # 00719 def __init__(self, node=None): 00720 00721 Tree.__init__(self) 00722 self.children = [] 00723 self.parent = None 00724 self.childIndex = 0 00725 00726 00727 def getChild(self, i): 00728 try: 00729 return self.children[i] 00730 except IndexError: 00731 return None 00732 00733 00734 ## 00735 # @brief Get the children internal List 00736 # 00737 # Note that if you directly mess with 00738 # the list, do so at your own risk. 00739 # 00740 def getChildren(self): 00741 00742 # FIXME: mark as deprecated 00743 return self.children 00744 00745 00746 def getFirstChildWithType(self, treeType): 00747 for child in self.children: 00748 if child.getType() == treeType: 00749 return child 00750 00751 return None 00752 00753 00754 def getChildCount(self): 00755 return len(self.children) 00756 00757 00758 ## 00759 # Add t as child of this node. 00760 # 00761 # Warning: if t has no children, but child does 00762 # and child isNil then this routine moves children to t via 00763 # t.children = child.children; i.e., without copying the array. 00764 # 00765 def addChild(self, childTree): 00766 00767 # this implementation is much simpler and probably less efficient 00768 # than the mumbo-jumbo that Ter did for the Java runtime. 00769 00770 if childTree is None: 00771 return 00772 00773 if childTree.isNil(): 00774 # t is an empty node possibly with children 00775 00776 if self.children is childTree.children: 00777 raise ValueError("attempt to add child list to itself") 00778 00779 # fix parent pointer and childIndex for new children 00780 for idx, child in enumerate(childTree.children): 00781 child.parent = self 00782 child.childIndex = len(self.children) + idx 00783 00784 self.children += childTree.children 00785 00786 else: 00787 # child is not nil (don't care about children) 00788 self.children.append(childTree) 00789 childTree.parent = self 00790 childTree.childIndex = len(self.children) - 1 00791 00792 00793 ## 00794 # Add all elements of kids list as children of this node 00795 def addChildren(self, children): 00796 00797 self.children += children 00798 00799 00800 def setChild(self, i, t): 00801 if t is None: 00802 return 00803 00804 if t.isNil(): 00805 raise ValueError("Can't set single child to a list") 00806 00807 self.children[i] = t 00808 t.parent = self 00809 t.childIndex = i 00810 00811 00812 def deleteChild(self, i): 00813 killed = self.children[i] 00814 00815 del self.children[i] 00816 00817 # walk rest and decrement their child indexes 00818 for idx, child in enumerate(self.children[i:]): 00819 child.childIndex = i + idx 00820 00821 return killed 00822 00823 00824 ## 00825 # 00826 # Delete children from start to stop and replace with t even if t is 00827 # a list (nil-root tree). num of children can increase or decrease. 00828 # For huge child lists, inserting children can force walking rest of 00829 # children to set their childindex; could be slow. 00830 # 00831 def replaceChildren(self, startChildIndex, stopChildIndex, newTree): 00832 00833 if (startChildIndex >= len(self.children) 00834 or stopChildIndex >= len(self.children) 00835 ): 00836 raise IndexError("indexes invalid") 00837 00838 replacingHowMany = stopChildIndex - startChildIndex + 1 00839 00840 # normalize to a list of children to add: newChildren 00841 if newTree.isNil(): 00842 newChildren = newTree.children 00843 00844 else: 00845 newChildren = [newTree] 00846 00847 replacingWithHowMany = len(newChildren) 00848 delta = replacingHowMany - replacingWithHowMany 00849 00850 00851 if delta == 0: 00852 # if same number of nodes, do direct replace 00853 for idx, child in enumerate(newChildren): 00854 self.children[idx + startChildIndex] = child 00855 child.parent = self 00856 child.childIndex = idx + startChildIndex 00857 00858 else: 00859 # length of children changes... 00860 00861 # ...delete replaced segment... 00862 del self.children[startChildIndex:stopChildIndex+1] 00863 00864 # ...insert new segment... 00865 self.children[startChildIndex:startChildIndex] = newChildren 00866 00867 # ...and fix indeces 00868 self.freshenParentAndChildIndexes(startChildIndex) 00869 00870 00871 def isNil(self): 00872 return False 00873 00874 00875 def freshenParentAndChildIndexes(self, offset=0): 00876 for idx, child in enumerate(self.children[offset:]): 00877 child.childIndex = idx + offset 00878 child.parent = self 00879 00880 00881 def sanityCheckParentAndChildIndexes(self, parent=None, i=-1): 00882 if parent != self.parent: 00883 raise ValueError( 00884 "parents don't match; expected %r found %r" 00885 % (parent, self.parent) 00886 ) 00887 00888 if i != self.childIndex: 00889 raise ValueError( 00890 "child indexes don't match; expected %d found %d" 00891 % (i, self.childIndex) 00892 ) 00893 00894 for idx, child in enumerate(self.children): 00895 child.sanityCheckParentAndChildIndexes(self, idx) 00896 00897 00898 ## 00899 # BaseTree doesn't track child indexes. 00900 def getChildIndex(self): 00901 00902 return 0 00903 00904 00905 ## 00906 # BaseTree doesn't track child indexes. 00907 def setChildIndex(self, index): 00908 00909 pass 00910 00911 00912 ## 00913 # BaseTree doesn't track parent pointers. 00914 def getParent(self): 00915 00916 return None 00917 00918 ## 00919 # BaseTree doesn't track parent pointers. 00920 def setParent(self, t): 00921 00922 pass 00923 00924 00925 ## 00926 # Print out a whole tree not just a node 00927 def toStringTree(self): 00928 00929 if len(self.children) == 0: 00930 return self.toString() 00931 00932 buf = [] 00933 if not self.isNil(): 00934 buf.append('(') 00935 buf.append(self.toString()) 00936 buf.append(' ') 00937 00938 for i, child in enumerate(self.children): 00939 if i > 0: 00940 buf.append(' ') 00941 buf.append(child.toStringTree()) 00942 00943 if not self.isNil(): 00944 buf.append(')') 00945 00946 return ''.join(buf) 00947 00948 00949 def getLine(self): 00950 return 0 00951 00952 00953 def getCharPositionInLine(self): 00954 return 0 00955 00956 00957 ## 00958 # Override to say how a node (not a tree) should look as text 00959 def toString(self): 00960 00961 raise NotImplementedError 00962 00963 00964 00965 ## 00966 # 00967 # @brief A TreeAdaptor that works with any Tree implementation. 00968 # 00969 class BaseTreeAdaptor(TreeAdaptor): 00970 00971 # BaseTreeAdaptor is abstract, no need to complain about not implemented 00972 # abstract methods 00973 # pylint: disable-msg=W0223 00974 00975 def nil(self): 00976 return self.createWithPayload(None) 00977 00978 00979 ## 00980 # 00981 # create tree node that holds the start and stop tokens associated 00982 # with an error. 00983 # 00984 # If you specify your own kind of tree nodes, you will likely have to 00985 # override this method. CommonTree returns Token.INVALID_TOKEN_TYPE 00986 # if no token payload but you might have to set token type for diff 00987 # node type. 00988 # 00989 def errorNode(self, input, start, stop, exc): 00990 00991 return CommonErrorNode(input, start, stop, exc) 00992 00993 00994 def isNil(self, tree): 00995 return tree.isNil() 00996 00997 00998 ## 00999 # 01000 # This is generic in the sense that it will work with any kind of 01001 # tree (not just Tree interface). It invokes the adaptor routines 01002 # not the tree node routines to do the construction. 01003 # 01004 def dupTree(self, t, parent=None): 01005 01006 if t is None: 01007 return None 01008 01009 newTree = self.dupNode(t) 01010 01011 # ensure new subtree root has parent/child index set 01012 01013 # same index in new tree 01014 self.setChildIndex(newTree, self.getChildIndex(t)) 01015 01016 self.setParent(newTree, parent) 01017 01018 for i in range(self.getChildCount(t)): 01019 child = self.getChild(t, i) 01020 newSubTree = self.dupTree(child, t) 01021 self.addChild(newTree, newSubTree) 01022 01023 return newTree 01024 01025 01026 ## 01027 # 01028 # Add a child to the tree t. If child is a flat tree (a list), make all 01029 # in list children of t. Warning: if t has no children, but child does 01030 # and child isNil then you can decide it is ok to move children to t via 01031 # t.children = child.children; i.e., without copying the array. Just 01032 # make sure that this is consistent with have the user will build 01033 # ASTs. 01034 # 01035 def addChild(self, tree, child): 01036 01037 #if isinstance(child, Token): 01038 # child = self.createWithPayload(child) 01039 01040 if tree is not None and child is not None: 01041 tree.addChild(child) 01042 01043 01044 ## 01045 # 01046 # If oldRoot is a nil root, just copy or move the children to newRoot. 01047 # If not a nil root, make oldRoot a child of newRoot. 01048 # 01049 # old=^(nil a b c), new=r yields ^(r a b c) 01050 # old=^(a b c), new=r yields ^(r ^(a b c)) 01051 # 01052 # If newRoot is a nil-rooted single child tree, use the single 01053 # child as the new root node. 01054 # 01055 # old=^(nil a b c), new=^(nil r) yields ^(r a b c) 01056 # old=^(a b c), new=^(nil r) yields ^(r ^(a b c)) 01057 # 01058 # If oldRoot was null, it's ok, just return newRoot (even if isNil). 01059 # 01060 # old=null, new=r yields r 01061 # old=null, new=^(nil r) yields ^(nil r) 01062 # 01063 # Return newRoot. Throw an exception if newRoot is not a 01064 # simple node or nil root with a single child node--it must be a root 01065 # node. If newRoot is ^(nil x) return x as newRoot. 01066 # 01067 # Be advised that it's ok for newRoot to point at oldRoot's 01068 # children; i.e., you don't have to copy the list. We are 01069 # constructing these nodes so we should have this control for 01070 # efficiency. 01071 # 01072 def becomeRoot(self, newRoot, oldRoot): 01073 01074 if isinstance(newRoot, Token): 01075 newRoot = self.create(newRoot) 01076 01077 if oldRoot is None: 01078 return newRoot 01079 01080 if not isinstance(newRoot, CommonTree): 01081 newRoot = self.createWithPayload(newRoot) 01082 01083 # handle ^(nil real-node) 01084 if newRoot.isNil(): 01085 nc = newRoot.getChildCount() 01086 if nc == 1: 01087 newRoot = newRoot.getChild(0) 01088 01089 elif nc > 1: 01090 # TODO: make tree run time exceptions hierarchy 01091 raise RuntimeError("more than one node as root") 01092 01093 # add oldRoot to newRoot; addChild takes care of case where oldRoot 01094 # is a flat list (i.e., nil-rooted tree). All children of oldRoot 01095 # are added to newRoot. 01096 newRoot.addChild(oldRoot) 01097 return newRoot 01098 01099 01100 ## 01101 # Transform ^(nil x) to x and nil to null 01102 def rulePostProcessing(self, root): 01103 01104 if root is not None and root.isNil(): 01105 if root.getChildCount() == 0: 01106 root = None 01107 01108 elif root.getChildCount() == 1: 01109 root = root.getChild(0) 01110 # whoever invokes rule will set parent and child index 01111 root.setParent(None) 01112 root.setChildIndex(-1) 01113 01114 return root 01115 01116 01117 def createFromToken(self, tokenType, fromToken, text=None): 01118 assert isinstance(tokenType, (int, long)), type(tokenType).__name__ 01119 assert isinstance(fromToken, Token), type(fromToken).__name__ 01120 assert text is None or isinstance(text, basestring), type(text).__name__ 01121 01122 fromToken = self.createToken(fromToken) 01123 fromToken.type = tokenType 01124 if text is not None: 01125 fromToken.text = text 01126 t = self.createWithPayload(fromToken) 01127 return t 01128 01129 01130 def createFromType(self, tokenType, text): 01131 assert isinstance(tokenType, (int, long)), type(tokenType).__name__ 01132 assert isinstance(text, basestring), type(text).__name__ 01133 01134 fromToken = self.createToken(tokenType=tokenType, text=text) 01135 t = self.createWithPayload(fromToken) 01136 return t 01137 01138 01139 def getType(self, t): 01140 return t.getType() 01141 01142 01143 def setType(self, t, type): 01144 raise RuntimeError("don't know enough about Tree node") 01145 01146 01147 def getText(self, t): 01148 return t.getText() 01149 01150 01151 def setText(self, t, text): 01152 raise RuntimeError("don't know enough about Tree node") 01153 01154 01155 def getChild(self, t, i): 01156 return t.getChild(i) 01157 01158 01159 def setChild(self, t, i, child): 01160 t.setChild(i, child) 01161 01162 01163 def deleteChild(self, t, i): 01164 return t.deleteChild(i) 01165 01166 01167 def getChildCount(self, t): 01168 return t.getChildCount() 01169 01170 01171 def getUniqueID(self, node): 01172 return hash(node) 01173 01174 01175 ## 01176 # 01177 # Tell me how to create a token for use with imaginary token nodes. 01178 # For example, there is probably no input symbol associated with imaginary 01179 # token DECL, but you need to create it as a payload or whatever for 01180 # the DECL node as in ^(DECL type ID). 01181 # 01182 # If you care what the token payload objects' type is, you should 01183 # override this method and any other createToken variant. 01184 # 01185 def createToken(self, fromToken=None, tokenType=None, text=None): 01186 01187 raise NotImplementedError 01188 01189 01190 ############################################################################ 01191 # 01192 # common tree implementation 01193 # 01194 # Tree 01195 # \- BaseTree 01196 # \- CommonTree 01197 # \- CommonErrorNode 01198 # 01199 # TreeAdaptor 01200 # \- BaseTreeAdaptor 01201 # \- CommonTreeAdaptor 01202 # 01203 ############################################################################ 01204 01205 01206 ## 01207 # @brief A tree node that is wrapper for a Token object. 01208 # 01209 # After 3.0 release 01210 # while building tree rewrite stuff, it became clear that computing 01211 # parent and child index is very difficult and cumbersome. Better to 01212 # spend the space in every tree node. If you don't want these extra 01213 # fields, it's easy to cut them out in your own BaseTree subclass. 01214 # 01215 # 01216 class CommonTree(BaseTree): 01217 01218 def __init__(self, payload): 01219 BaseTree.__init__(self) 01220 01221 # What token indexes bracket all tokens associated with this node 01222 # and below? 01223 self.startIndex = -1 01224 self.stopIndex = -1 01225 01226 # Who is the parent node of this node; if null, implies node is root 01227 self.parent = None 01228 01229 # What index is this node in the child list? Range: 0..n-1 01230 self.childIndex = -1 01231 01232 # A single token is the payload 01233 if payload is None: 01234 self.token