• Main Page
  • Packages
  • Classes
  • Files

antlr3/tree.py

Go to the documentation of this file.
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