""" @package antlr3.tree
@brief ANTLR3 runtime package, tree module

This module contains all support classes for AST construction and tree parsers.

"""

# begin[licence]
#
# [The "BSD licence"]
# Copyright (c) 2005-2012 Terence Parr
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
#    derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# end[licence]

# lot's of docstrings are missing, don't complain for now...
# pylint: disable-msg=C0111

import re

from antlr3.constants import UP, DOWN, EOF, INVALID_TOKEN_TYPE
from antlr3.recognizers import BaseRecognizer, RuleReturnScope
from antlr3.streams import IntStream
from antlr3.tokens import CommonToken, Token, INVALID_TOKEN
from antlr3.exceptions import MismatchedTreeNodeException, \
     MissingTokenException, UnwantedTokenException, MismatchedTokenException, \
     NoViableAltException


############################################################################
#
# tree related exceptions
#
############################################################################


class RewriteCardinalityException(RuntimeError):
    """
    @brief Base class for all exceptions thrown during AST rewrite construction.

    This signifies a case where the cardinality of two or more elements
    in a subrule are different: (ID INT)+ where |ID|!=|INT|
    """

    def __init__(self, elementDescription):
        RuntimeError.__init__(self, elementDescription)

        self.elementDescription = elementDescription


    def getMessage(self):
        return self.elementDescription


class RewriteEarlyExitException(RewriteCardinalityException):
    """@brief No elements within a (...)+ in a rewrite rule"""

    def __init__(self, elementDescription=None):
        RewriteCardinalityException.__init__(self, elementDescription)


class RewriteEmptyStreamException(RewriteCardinalityException):
    """
    @brief Ref to ID or expr but no tokens in ID stream or subtrees in expr stream
    """

    pass


############################################################################
#
# basic Tree and TreeAdaptor interfaces
#
############################################################################

class Tree(object):
    """
    @brief Abstract baseclass for tree nodes.

    What does a tree look like?  ANTLR has a number of support classes
    such as CommonTreeNodeStream that work on these kinds of trees.  You
    don't have to make your trees implement this interface, but if you do,
    you'll be able to use more support code.

    NOTE: When constructing trees, ANTLR can build any kind of tree; it can
    even use Token objects as trees if you add a child list to your tokens.

    This is a tree node without any payload; just navigation and factory stuff.
    """


    def getChild(self, i):
        raise NotImplementedError


    def getChildCount(self):
        raise NotImplementedError


    def getParent(self):
        """Tree tracks parent and child index now > 3.0"""

        raise NotImplementedError

    def setParent(self, t):
        """Tree tracks parent and child index now > 3.0"""

        raise NotImplementedError


    def hasAncestor(self, ttype):
        """Walk upwards looking for ancestor with this token type."""

        raise NotImplementedError

    def getAncestor(self, ttype):
        """Walk upwards and get first ancestor with this token type."""

        raise NotImplementedError

    def getAncestors(self):
        """Return a list of all ancestors of this node.

        The first node of list is the root and the last is the parent of
        this node.
        """

        raise NotImplementedError


    def getChildIndex(self):
        """This node is what child index? 0..n-1"""

        raise NotImplementedError

    def setChildIndex(self, index):
        """This node is what child index? 0..n-1"""

        raise NotImplementedError


    def freshenParentAndChildIndexes(self):
        """Set the parent and child index values for all children"""

        raise NotImplementedError


    def addChild(self, t):
        """
        Add t as a child to this node.  If t is null, do nothing.  If t
        is nil, add all children of t to this' children.
        """

        raise NotImplementedError


    def setChild(self, i, t):
        """Set ith child (0..n-1) to t; t must be non-null and non-nil node"""

        raise NotImplementedError


    def deleteChild(self, i):
        raise NotImplementedError


    def replaceChildren(self, startChildIndex, stopChildIndex, t):
        """
        Delete children from start to stop and replace with t even if t is
        a list (nil-root tree).  num of children can increase or decrease.
        For huge child lists, inserting children can force walking rest of
        children to set their childindex; could be slow.
        """

        raise NotImplementedError


    def isNil(self):
        """
        Indicates the node is a nil node but may still have children, meaning
        the tree is a flat list.
        """

        raise NotImplementedError


    def getTokenStartIndex(self):
        """
        What is the smallest token index (indexing from 0) for this node
           and its children?
        """

        raise NotImplementedError


    def setTokenStartIndex(self, index):
        raise NotImplementedError


    def getTokenStopIndex(self):
        """
        What is the largest token index (indexing from 0) for this node
        and its children?
        """

        raise NotImplementedError


    def setTokenStopIndex(self, index):
        raise NotImplementedError


    def dupNode(self):
        raise NotImplementedError


    def getType(self):
        """Return a token type; needed for tree parsing."""

        raise NotImplementedError


    def getText(self):
        raise NotImplementedError


    def getLine(self):
        """
        In case we don't have a token payload, what is the line for errors?
        """

        raise NotImplementedError


    def getCharPositionInLine(self):
        raise NotImplementedError


    def toStringTree(self):
        raise NotImplementedError


    def toString(self):
        raise NotImplementedError



class TreeAdaptor(object):
    """
    @brief Abstract baseclass for tree adaptors.

    How to create and navigate trees.  Rather than have a separate factory
    and adaptor, I've merged them.  Makes sense to encapsulate.

    This takes the place of the tree construction code generated in the
    generated code in 2.x and the ASTFactory.

    I do not need to know the type of a tree at all so they are all
    generic Objects.  This may increase the amount of typecasting needed. :(
    """

    # C o n s t r u c t i o n

    def createWithPayload(self, payload):
        """
        Create a tree node from Token object; for CommonTree type trees,
        then the token just becomes the payload.  This is the most
        common create call.

        Override if you want another kind of node to be built.
        """

        raise NotImplementedError


    def dupNode(self, treeNode):
        """Duplicate a single tree node.

        Override if you want another kind of node to be built."""

        raise NotImplementedError


    def dupTree(self, tree):
        """Duplicate tree recursively, using dupNode() for each node"""

        raise NotImplementedError


    def nil(self):
        """
        Return a nil node (an empty but non-null node) that can hold
        a list of element as the children.  If you want a flat tree (a list)
        use "t=adaptor.nil(); t.addChild(x); t.addChild(y);"
        """

        raise NotImplementedError


    def errorNode(self, input, start, stop, exc):
        """
        Return a tree node representing an error.  This node records the
        tokens consumed during error recovery.  The start token indicates the
        input symbol at which the error was detected.  The stop token indicates
        the last symbol consumed during recovery.

        You must specify the input stream so that the erroneous text can
        be packaged up in the error node.  The exception could be useful
        to some applications; default implementation stores ptr to it in
        the CommonErrorNode.

        This only makes sense during token parsing, not tree parsing.
        Tree parsing should happen only when parsing and tree construction
        succeed.
        """

        raise NotImplementedError


    def isNil(self, tree):
        """Is tree considered a nil node used to make lists of child nodes?"""

        raise NotImplementedError


    def addChild(self, t, child):
        """
        Add a child to the tree t.  If child is a flat tree (a list), make all
        in list children of t.  Warning: if t has no children, but child does
        and child isNil then you can decide it is ok to move children to t via
        t.children = child.children; i.e., without copying the array.  Just
        make sure that this is consistent with have the user will build
        ASTs. Do nothing if t or child is null.
        """

        raise NotImplementedError


    def becomeRoot(self, newRoot, oldRoot):
        """
        If oldRoot is a nil root, just copy or move the children to newRoot.
        If not a nil root, make oldRoot a child of newRoot.

           old=^(nil a b c), new=r yields ^(r a b c)
           old=^(a b c), new=r yields ^(r ^(a b c))

        If newRoot is a nil-rooted single child tree, use the single
        child as the new root node.

           old=^(nil a b c), new=^(nil r) yields ^(r a b c)
           old=^(a b c), new=^(nil r) yields ^(r ^(a b c))

        If oldRoot was null, it's ok, just return newRoot (even if isNil).

           old=null, new=r yields r
           old=null, new=^(nil r) yields ^(nil r)

        Return newRoot.  Throw an exception if newRoot is not a
        simple node or nil root with a single child node--it must be a root
        node.  If newRoot is ^(nil x) return x as newRoot.

        Be advised that it's ok for newRoot to point at oldRoot's
        children; i.e., you don't have to copy the list.  We are
        constructing these nodes so we should have this control for
        efficiency.
        """

        raise NotImplementedError


    def rulePostProcessing(self, root):
        """
        Given the root of the subtree created for this rule, post process
        it to do any simplifications or whatever you want.  A required
        behavior is to convert ^(nil singleSubtree) to singleSubtree
        as the setting of start/stop indexes relies on a single non-nil root
        for non-flat trees.

        Flat trees such as for lists like "idlist : ID+ ;" are left alone
        unless there is only one ID.  For a list, the start/stop indexes
        are set in the nil node.

        This method is executed after all rule tree construction and right
        before setTokenBoundaries().
        """

        raise NotImplementedError


    def getUniqueID(self, node):
        """For identifying trees.

        How to identify nodes so we can say "add node to a prior node"?
        Even becomeRoot is an issue.  Use System.identityHashCode(node)
        usually.
        """

        raise NotImplementedError


    # R e w r i t e  R u l e s

    def createFromToken(self, tokenType, fromToken, text=None):
        """
        Create a new node derived from a token, with a new token type and
        (optionally) new text.

        This is invoked from an imaginary node ref on right side of a
        rewrite rule as IMAG[$tokenLabel] or IMAG[$tokenLabel "IMAG"].

        This should invoke createToken(Token).
        """

        raise NotImplementedError


    def createFromType(self, tokenType, text):
        """Create a new node derived from a token, with a new token type.

        This is invoked from an imaginary node ref on right side of a
        rewrite rule as IMAG["IMAG"].

        This should invoke createToken(int,String).
        """

        raise NotImplementedError


    # C o n t e n t

    def getType(self, t):
        """For tree parsing, I need to know the token type of a node"""

        raise NotImplementedError


    def setType(self, t, type):
        """Node constructors can set the type of a node"""

        raise NotImplementedError


    def getText(self, t):
        raise NotImplementedError

    def setText(self, t, text):
        """Node constructors can set the text of a node"""

        raise NotImplementedError


    def getToken(self, t):
        """Return the token object from which this node was created.

        Currently used only for printing an error message.
        The error display routine in BaseRecognizer needs to
        display where the input the error occurred. If your
        tree of limitation does not store information that can
        lead you to the token, you can create a token filled with
        the appropriate information and pass that back.  See
        BaseRecognizer.getErrorMessage().
        """

        raise NotImplementedError


    def setTokenBoundaries(self, t, startToken, stopToken):
        """
        Where are the bounds in the input token stream for this node and
        all children?  Each rule that creates AST nodes will call this
        method right before returning.  Flat trees (i.e., lists) will
        still usually have a nil root node just to hold the children list.
        That node would contain the start/stop indexes then.
        """

        raise NotImplementedError


    def getTokenStartIndex(self, t):
        """
        Get the token start index for this subtree; return -1 if no such index
        """

        raise NotImplementedError


    def getTokenStopIndex(self, t):
        """
        Get the token stop index for this subtree; return -1 if no such index
        """

        raise NotImplementedError


    # N a v i g a t i o n  /  T r e e  P a r s i n g

    def getChild(self, t, i):
        """Get a child 0..n-1 node"""

        raise NotImplementedError


    def setChild(self, t, i, child):
        """Set ith child (0..n-1) to t; t must be non-null and non-nil node"""

        raise NotImplementedError


    def deleteChild(self, t, i):
        """Remove ith child and shift children down from right."""

        raise NotImplementedError


    def getChildCount(self, t):
        """How many children?  If 0, then this is a leaf node"""

        raise NotImplementedError


    def getParent(self, t):
        """
        Who is the parent node of this node; if null, implies node is root.
        If your node type doesn't handle this, it's ok but the tree rewrites
        in tree parsers need this functionality.
        """

        raise NotImplementedError


    def setParent(self, t, parent):
        """
        Who is the parent node of this node; if null, implies node is root.
        If your node type doesn't handle this, it's ok but the tree rewrites
        in tree parsers need this functionality.
        """

        raise NotImplementedError


    def getChildIndex(self, t):
        """
        What index is this node in the child list? Range: 0..n-1
        If your node type doesn't handle this, it's ok but the tree rewrites
        in tree parsers need this functionality.
        """

        raise NotImplementedError


    def setChildIndex(self, t, index):
        """
        What index is this node in the child list? Range: 0..n-1
        If your node type doesn't handle this, it's ok but the tree rewrites
        in tree parsers need this functionality.
        """

        raise NotImplementedError


    def replaceChildren(self, parent, startChildIndex, stopChildIndex, t):
        """
        Replace from start to stop child index of parent with t, which might
        be a list.  Number of children may be different
        after this call.

        If parent is null, don't do anything; must be at root of overall tree.
        Can't replace whatever points to the parent externally.  Do nothing.
        """

        raise NotImplementedError


    # Misc

    def create(self, *args):
        """
        Deprecated, use createWithPayload, createFromToken or createFromType.

        This method only exists to mimic the Java interface of TreeAdaptor.

        """

        if len(args) == 1 and isinstance(args[0], Token):
            # Object create(Token payload);
##             warnings.warn(
##                 "Using create() is deprecated, use createWithPayload()",
##                 DeprecationWarning,
##                 stacklevel=2
##                 )
            return self.createWithPayload(args[0])

        if (len(args) == 2
            and isinstance(args[0], int)
            and isinstance(args[1], Token)):
            # Object create(int tokenType, Token fromToken);
##             warnings.warn(
##                 "Using create() is deprecated, use createFromToken()",
##                 DeprecationWarning,
##                 stacklevel=2
##                 )
            return self.createFromToken(args[0], args[1])

        if (len(args) == 3
            and isinstance(args[0], int)
            and isinstance(args[1], Token)
            and isinstance(args[2], str)):
            # Object create(int tokenType, Token fromToken, String text);
##             warnings.warn(
##                 "Using create() is deprecated, use createFromToken()",
##                 DeprecationWarning,
##                 stacklevel=2
##                 )
            return self.createFromToken(args[0], args[1], args[2])

        if (len(args) == 2
            and isinstance(args[0], int)
            and isinstance(args[1], str)):
            # Object create(int tokenType, String text);
##             warnings.warn(
##                 "Using create() is deprecated, use createFromType()",
##                 DeprecationWarning,
##                 stacklevel=2
##                 )
            return self.createFromType(args[0], args[1])

        raise TypeError(
            "No create method with this signature found: {}"
            .format(', '.join(type(v).__name__ for v in args)))


############################################################################
#
# base implementation of Tree and TreeAdaptor
#
# Tree
# \- BaseTree
#
# TreeAdaptor
# \- BaseTreeAdaptor
#
############################################################################


class BaseTree(Tree):
    """
    @brief A generic tree implementation with no payload.

    You must subclass to
    actually have any user data.  ANTLR v3 uses a list of children approach
    instead of the child-sibling approach in v2.  A flat tree (a list) is
    an empty node whose children represent the list.  An empty, but
    non-null node is called "nil".
    """

    # BaseTree is abstract, no need to complain about not implemented abstract
    # methods
    # pylint: disable-msg=W0223

    def __init__(self, node=None):
        """
        Create a new node from an existing node does nothing for BaseTree
        as there are no fields other than the children list, which cannot
        be copied as the children are not considered part of this node.
        """

        super().__init__()
        self.children = []
        self.parent = None
        self.childIndex = 0


    def getChild(self, i):
        try:
            return self.children[i]
        except IndexError:
            return None


    def getChildren(self):
        """@brief Get the children internal List

        Note that if you directly mess with
        the list, do so at your own risk.
        """

        # FIXME: mark as deprecated
        return self.children


    def getFirstChildWithType(self, treeType):
        for child in self.children:
            if child.getType() == treeType:
                return child

        return None


    def getChildCount(self):
        return len(self.children)


    def addChild(self, childTree):
        """Add t as child of this node.

        Warning: if t has no children, but child does
        and child isNil then this routine moves children to t via
        t.children = child.children; i.e., without copying the array.
        """

        # this implementation is much simpler and probably less efficient
        # than the mumbo-jumbo that Ter did for the Java runtime.

        if childTree is None:
            return

        if childTree.isNil():
            # t is an empty node possibly with children

            if self.children is childTree.children:
                raise ValueError("attempt to add child list to itself")

            # fix parent pointer and childIndex for new children
            for idx, child in enumerate(childTree.children):
                child.parent = self
                child.childIndex = len(self.children) + idx

            self.children += childTree.children

        else:
            # child is not nil (don't care about children)
            self.children.append(childTree)
            childTree.parent = self
            childTree.childIndex = len(self.children) - 1


    def addChildren(self, children):
        """Add all elements of kids list as children of this node"""

        self.children += children


    def setChild(self, i, t):
        if t is None:
            return

        if t.isNil():
            raise ValueError("Can't set single child to a list")

        self.children[i] = t
        t.parent = self
        t.childIndex = i


    def deleteChild(self, i):
        killed = self.children[i]

        del self.children[i]

        # walk rest and decrement their child indexes
        for idx, child in enumerate(self.children[i:]):
            child.childIndex = i + idx

        return killed


    def replaceChildren(self, startChildIndex, stopChildIndex, newTree):
        """
        Delete children from start to stop and replace with t even if t is
        a list (nil-root tree).  num of children can increase or decrease.
        For huge child lists, inserting children can force walking rest of
        children to set their childindex; could be slow.
        """

        if (startChildIndex >= len(self.children)
            or stopChildIndex >= len(self.children)):
            raise IndexError("indexes invalid")

        replacingHowMany = stopChildIndex - startChildIndex + 1

        # normalize to a list of children to add: newChildren
        if newTree.isNil():
            newChildren = newTree.children

        else:
            newChildren = [newTree]

        replacingWithHowMany = len(newChildren)
        delta = replacingHowMany - replacingWithHowMany


        if delta == 0:
            # if same number of nodes, do direct replace
            for idx, child in enumerate(newChildren):
                self.children[idx + startChildIndex] = child
                child.parent = self
                child.childIndex = idx + startChildIndex

        else:
            # length of children changes...

            # ...delete replaced segment...
            del self.children[startChildIndex:stopChildIndex+1]

            # ...insert new segment...
            self.children[startChildIndex:startChildIndex] = newChildren

            # ...and fix indeces
            self.freshenParentAndChildIndexes(startChildIndex)


    def isNil(self):
        return False


    def freshenParentAndChildIndexes(self, offset=0):
        for idx, child in enumerate(self.children[offset:]):
            child.childIndex = idx + offset
            child.parent = self


    def sanityCheckParentAndChildIndexes(self, parent=None, i=-1):
        if parent != self.parent:
            raise ValueError(
                "parents don't match; expected {!r} found {!r}"
                .format(parent, self.parent))

        if i != self.childIndex:
            raise ValueError(
                "child indexes don't match; expected {} found {}"
                .format(i, self.childIndex))

        for idx, child in enumerate(self.children):
            child.sanityCheckParentAndChildIndexes(self, idx)


    def getChildIndex(self):
        """BaseTree doesn't track child indexes."""

        return 0


    def setChildIndex(self, index):
        """BaseTree doesn't track child indexes."""

        pass


    def getParent(self):
        """BaseTree doesn't track parent pointers."""

        return None

    def setParent(self, t):
        """BaseTree doesn't track parent pointers."""

        pass


    def hasAncestor(self, ttype):
        """Walk upwards looking for ancestor with this token type."""
        return self.getAncestor(ttype) is not None

    def getAncestor(self, ttype):
        """Walk upwards and get first ancestor with this token type."""
        t = self.getParent()
        while t is not None:
            if t.getType() == ttype:
                return t
            t = t.getParent()

        return None

    def getAncestors(self):
        """Return a list of all ancestors of this node.

        The first node of list is the root and the last is the parent of
        this node.
        """
        if self.getParent() is None:
            return None

        ancestors = []
        t = self.getParent()
        while t is not None:
            ancestors.insert(0, t) # insert at start
            t = t.getParent()

        return ancestors


    def toStringTree(self):
        """Print out a whole tree not just a node"""

        if len(self.children) == 0:
            return self.toString()

        buf = []
        if not self.isNil():
            buf.append('(')
            buf.append(self.toString())
            buf.append(' ')

        for i, child in enumerate(self.children):
            if i > 0:
                buf.append(' ')
            buf.append(child.toStringTree())

        if not self.isNil():
            buf.append(')')

        return ''.join(buf)


    def getLine(self):
        return 0


    def getCharPositionInLine(self):
        return 0


    def toString(self):
        """Override to say how a node (not a tree) should look as text"""

        raise NotImplementedError



class BaseTreeAdaptor(TreeAdaptor):
    """
    @brief A TreeAdaptor that works with any Tree implementation.
    """

    # BaseTreeAdaptor is abstract, no need to complain about not implemented
    # abstract methods
    # pylint: disable-msg=W0223

    def nil(self):
        return self.createWithPayload(None)


    def errorNode(self, input, start, stop, exc):
        """
        create tree node that holds the start and stop tokens associated
        with an error.

        If you specify your own kind of tree nodes, you will likely have to
        override this method. CommonTree returns Token.INVALID_TOKEN_TYPE
        if no token payload but you might have to set token type for diff
        node type.

        You don't have to subclass CommonErrorNode; you will likely need to
        subclass your own tree node class to avoid class cast exception.
        """

        return CommonErrorNode(input, start, stop, exc)


    def isNil(self, tree):
        return tree.isNil()


    def dupTree(self, t, parent=None):
        """
        This is generic in the sense that it will work with any kind of
        tree (not just Tree interface).  It invokes the adaptor routines
        not the tree node routines to do the construction.
        """

        if t is None:
            return None

        newTree = self.dupNode(t)

        # ensure new subtree root has parent/child index set

        # same index in new tree
        self.setChildIndex(newTree, self.getChildIndex(t))

        self.setParent(newTree, parent)

        for i in range(self.getChildCount(t)):
            child = self.getChild(t, i)
            newSubTree = self.dupTree(child, t)
            self.addChild(newTree, newSubTree)

        return newTree


    def addChild(self, tree, child):
        """
        Add a child to the tree t.  If child is a flat tree (a list), make all
        in list children of t.  Warning: if t has no children, but child does
        and child isNil then you can decide it is ok to move children to t via
        t.children = child.children; i.e., without copying the array.  Just
        make sure that this is consistent with have the user will build
        ASTs.
        """

        #if isinstance(child, Token):
        #    child = self.createWithPayload(child)

        if tree is not None and child is not None:
            tree.addChild(child)


    def becomeRoot(self, newRoot, oldRoot):
        """
        If oldRoot is a nil root, just copy or move the children to newRoot.
        If not a nil root, make oldRoot a child of newRoot.

          old=^(nil a b c), new=r yields ^(r a b c)
          old=^(a b c), new=r yields ^(r ^(a b c))

        If newRoot is a nil-rooted single child tree, use the single
        child as the new root node.

          old=^(nil a b c), new=^(nil r) yields ^(r a b c)
          old=^(a b c), new=^(nil r) yields ^(r ^(a b c))

        If oldRoot was null, it's ok, just return newRoot (even if isNil).

          old=null, new=r yields r
          old=null, new=^(nil r) yields ^(nil r)

        Return newRoot.  Throw an exception if newRoot is not a
        simple node or nil root with a single child node--it must be a root
        node.  If newRoot is ^(nil x) return x as newRoot.

        Be advised that it's ok for newRoot to point at oldRoot's
        children; i.e., you don't have to copy the list.  We are
        constructing these nodes so we should have this control for
        efficiency.
        """

        if isinstance(newRoot, Token):
            newRoot = self.create(newRoot)

        if oldRoot is None:
            return newRoot

        if not isinstance(newRoot, CommonTree):
            newRoot = self.createWithPayload(newRoot)

        # handle ^(nil real-node)
        if newRoot.isNil():
            nc = newRoot.getChildCount()
            if nc == 1:
                newRoot = newRoot.getChild(0)

            elif nc > 1:
                # TODO: make tree run time exceptions hierarchy
                raise RuntimeError("more than one node as root")

        # add oldRoot to newRoot; addChild takes care of case where oldRoot
        # is a flat list (i.e., nil-rooted tree).  All children of oldRoot
        # are added to newRoot.
        newRoot.addChild(oldRoot)
        return newRoot


    def rulePostProcessing(self, root):
        """Transform ^(nil x) to x and nil to null"""

        if root is not None and root.isNil():
            if root.getChildCount() == 0:
                root = None

            elif root.getChildCount() == 1:
                root = root.getChild(0)
                # whoever invokes rule will set parent and child index
                root.setParent(None)
                root.setChildIndex(-1)

        return root


    def createFromToken(self, tokenType, fromToken, text=None):
        if fromToken is None:
            return self.createFromType(tokenType, text)

        assert isinstance(tokenType, int), type(tokenType).__name__
        assert isinstance(fromToken, Token), type(fromToken).__name__
        assert text is None or isinstance(text, str), type(text).__name__

        fromToken = self.createToken(fromToken)
        fromToken.type = tokenType
        if text is not None:
            fromToken.text = text
        t = self.createWithPayload(fromToken)
        return t


    def createFromType(self, tokenType, text):
        assert isinstance(tokenType, int), type(tokenType).__name__
        assert isinstance(text, str) or text is None, type(text).__name__

        fromToken = self.createToken(tokenType=tokenType, text=text)
        t = self.createWithPayload(fromToken)
        return t


    def getType(self, t):
        return t.getType()


    def setType(self, t, type):
        raise RuntimeError("don't know enough about Tree node")


    def getText(self, t):
        return t.getText()


    def setText(self, t, text):
        raise RuntimeError("don't know enough about Tree node")


    def getChild(self, t, i):
        return t.getChild(i)


    def setChild(self, t, i, child):
        t.setChild(i, child)


    def deleteChild(self, t, i):
        return t.deleteChild(i)


    def getChildCount(self, t):
        return t.getChildCount()


    def getUniqueID(self, node):
        return hash(node)


    def createToken(self, fromToken=None, tokenType=None, text=None):
        """
        Tell me how to create a token for use with imaginary token nodes.
        For example, there is probably no input symbol associated with imaginary
        token DECL, but you need to create it as a payload or whatever for
        the DECL node as in ^(DECL type ID).

        If you care what the token payload objects' type is, you should
        override this method and any other createToken variant.
        """

        raise NotImplementedError


############################################################################
#
# common tree implementation
#
# Tree
# \- BaseTree
#    \- CommonTree
#       \- CommonErrorNode
#
# TreeAdaptor
# \- BaseTreeAdaptor
#    \- CommonTreeAdaptor
#
############################################################################


class CommonTree(BaseTree):
    """@brief A tree node that is wrapper for a Token object.

    After 3.0 release
    while building tree rewrite stuff, it became clear that computing
    parent and child index is very difficult and cumbersome.  Better to
    spend the space in every tree node.  If you don't want these extra
    fields, it's easy to cut them out in your own BaseTree subclass.

    """

    def __init__(self, payload):
        BaseTree.__init__(self)

        # What token indexes bracket all tokens associated with this node
        # and below?
        self.startIndex = -1
        self.stopIndex = -1

        # Who is the parent node of this node; if null, implies node is root
        self.parent = None

        # What index is this node in the child list? Range: 0..n-1
        self.childIndex = -1

        # A single token is the payload
        if payload is None:
            self.token = None

        elif isinstance(payload, CommonTree):
            self.token = payload.token
            self.startIndex = payload.startIndex
            self.stopIndex = payload.stopIndex

        elif payload is None or isinstance(payload, Token):
            self.token = payload

        else:
            raise TypeError(type(payload).__name__)



    def getToken(self):
        return self.token


    def dupNode(self):
        return CommonTree(self)


    def isNil(self):
        return self.token is None


    def getType(self):
        if self.token is None:
            return INVALID_TOKEN_TYPE

        return self.token.type

    type = property(getType)


    def getText(self):
        if self.token is None:
            return None

        return self.token.text

    text = property(getText)


    def getLine(self):
        if self.token is None or self.token.line == 0:
            if self.getChildCount():
                return self.getChild(0).getLine()
            else:
                return 0

        return self.token.line

    line = property(getLine)


    def getCharPositionInLine(self):
        if self.token is None or self.token.charPositionInLine == -1:
            if self.getChildCount():
                return self.getChild(0).getCharPositionInLine()
            else:
                return 0

        else:
            return self.token.charPositionInLine

    charPositionInLine = property(getCharPositionInLine)


    def getTokenStartIndex(self):
        if self.startIndex == -1 and self.token:
            return self.token.index

        return self.startIndex

    def setTokenStartIndex(self, index):
        self.startIndex = index

    tokenStartIndex = property(getTokenStartIndex, setTokenStartIndex)


    def getTokenStopIndex(self):
        if self.stopIndex == -1 and self.token:
            return self.token.index

        return self.stopIndex

    def setTokenStopIndex(self, index):
        self.stopIndex = index

    tokenStopIndex = property(getTokenStopIndex, setTokenStopIndex)


    def setUnknownTokenBoundaries(self):
        """For every node in this subtree, make sure it's start/stop token's
        are set.  Walk depth first, visit bottom up.  Only updates nodes
        with at least one token index < 0.
        """

        if self.children is None:
            if self.startIndex < 0 or self.stopIndex < 0:
                self.startIndex = self.stopIndex = self.token.index

            return

        for child in self.children:
            child.setUnknownTokenBoundaries()

        if self.startIndex >= 0 and self.stopIndex >= 0:
            # already set
            return

        if self.children:
            firstChild = self.children[0]
            lastChild = self.children[-1]
            self.startIndex = firstChild.getTokenStartIndex()
            self.stopIndex = lastChild.getTokenStopIndex()


    def getChildIndex(self):
        #FIXME: mark as deprecated
        return self.childIndex


    def setChildIndex(self, idx):
        #FIXME: mark as deprecated
        self.childIndex = idx


    def getParent(self):
        #FIXME: mark as deprecated
        return self.parent


    def setParent(self, t):
        #FIXME: mark as deprecated
        self.parent = t


    def toString(self):
        if self.isNil():
            return "nil"

        if self.getType() == INVALID_TOKEN_TYPE:
            return "<errornode>"

        return self.token.text

    __str__ = toString



    def toStringTree(self):
        if not self.children:
            return self.toString()

        ret = ''
        if not self.isNil():
            ret += '({!s} '.format(self)

        ret += ' '.join([child.toStringTree() for child in self.children])

        if not self.isNil():
            ret += ')'

        return ret


INVALID_NODE = CommonTree(INVALID_TOKEN)


class CommonErrorNode(CommonTree):
    """A node representing erroneous token range in token stream"""

    def __init__(self, input, start, stop, exc):
        CommonTree.__init__(self, None)

        if (stop is None or (stop.index < start.index and stop.type != EOF)):
            # sometimes resync does not consume a token (when LT(1) is
            # in follow set.  So, stop will be 1 to left to start. adjust.
            # Also handle case where start is the first token and no token
            # is consumed during recovery; LT(-1) will return null.
            stop = start

        self.input = input
        self.start = start
        self.stop = stop
        self.trappedException = exc


    def isNil(self):
        return False


    def getType(self):
        return INVALID_TOKEN_TYPE


    def getText(self):
        if isinstance(self.start, Token):
            i = self.start.index
            j = self.stop.index
            if self.stop.type == EOF:
                j = self.input.size()

            badText = self.input.toString(i, j)

        elif isinstance(self.start, Tree):
            badText = self.input.toString(self.start, self.stop)

        else:
            # people should subclass if they alter the tree type so this
            # next one is for sure correct.
            badText = "<unknown>"

        return badText


    def toString(self):
        if isinstance(self.trappedException, MissingTokenException):
            return ("<missing type: "
                    + str(self.trappedException.getMissingType())
                    + ">")

        elif isinstance(self.trappedException, UnwantedTokenException):
            return ("<extraneous: "
                    + str(self.trappedException.getUnexpectedToken())
                    + ", resync=" + self.getText() + ">")

        elif isinstance(self.trappedException, MismatchedTokenException):
            return ("<mismatched token: "
                    + str(self.trappedException.token)
                    + ", resync=" + self.getText() + ">")

        elif isinstance(self.trappedException, NoViableAltException):
            return ("<unexpected: "
                    + str(self.trappedException.token)
                    + ", resync=" + self.getText() + ">")

        return "<error: "+self.getText()+">"

    __str__ = toString


class CommonTreeAdaptor(BaseTreeAdaptor):
    """
    @brief A TreeAdaptor that works with any Tree implementation.

    It provides
    really just factory methods; all the work is done by BaseTreeAdaptor.
    If you would like to have different tokens created than ClassicToken
    objects, you need to override this and then set the parser tree adaptor to
    use your subclass.

    To get your parser to build nodes of a different type, override
    create(Token), errorNode(), and to be safe, YourTreeClass.dupNode().
    dupNode is called to duplicate nodes during rewrite operations.
    """

    def dupNode(self, treeNode):
        """
        Duplicate a node.  This is part of the factory;
        override if you want another kind of node to be built.

        I could use reflection to prevent having to override this
        but reflection is slow.
        """

        if treeNode is None:
            return None

        return treeNode.dupNode()


    def createWithPayload(self, payload):
        return CommonTree(payload)


    def createToken(self, fromToken=None, tokenType=None, text=None):
        """
        Tell me how to create a token for use with imaginary token nodes.
        For example, there is probably no input symbol associated with imaginary
        token DECL, but you need to create it as a payload or whatever for
        the DECL node as in ^(DECL type ID).

        If you care what the token payload objects' type is, you should
        override this method and any other createToken variant.
        """

        if fromToken is not None:
            return CommonToken(oldToken=fromToken)

        return CommonToken(type=tokenType, text=text)


    def setTokenBoundaries(self, t, startToken, stopToken):
        """
        Track start/stop token for subtree root created for a rule.
        Only works with Tree nodes.  For rules that match nothing,
        seems like this will yield start=i and stop=i-1 in a nil node.
        Might be useful info so I'll not force to be i..i.
        """

        if t is None:
            return

        start = 0
        stop = 0

        if startToken is not None:
            start = startToken.index

        if stopToken is not None:
            stop = stopToken.index

        t.setTokenStartIndex(start)
        t.setTokenStopIndex(stop)


    def getTokenStartIndex(self, t):
        if t is None:
            return -1
        return t.getTokenStartIndex()


    def getTokenStopIndex(self, t):
        if t is None:
            return -1
        return t.getTokenStopIndex()


    def getText(self, t):
        if t is None:
            return None
        return t.text


    def getType(self, t):
        if t is None:
            return INVALID_TOKEN_TYPE

        return t.type


    def getToken(self, t):
        """
        What is the Token associated with this node?  If
        you are not using CommonTree, then you must
        override this in your own adaptor.
        """

        if isinstance(t, CommonTree):
            return t.getToken()

        return None # no idea what to do


    def getChild(self, t, i):
        if t is None:
            return None
        return t.getChild(i)


    def getChildCount(self, t):
        if t is None:
            return 0
        return t.getChildCount()


    def getParent(self, t):
        return t.getParent()


    def setParent(self, t, parent):
        t.setParent(parent)


    def getChildIndex(self, t):
        if t is None:
            return 0
        return t.getChildIndex()


    def setChildIndex(self, t, index):
        t.setChildIndex(index)


    def replaceChildren(self, parent, startChildIndex, stopChildIndex, t):
        if parent is not None:
            parent.replaceChildren(startChildIndex, stopChildIndex, t)


############################################################################
#
# streams
#
# TreeNodeStream
# \- BaseTree
#    \- CommonTree
#
# TreeAdaptor
# \- BaseTreeAdaptor
#    \- CommonTreeAdaptor
#
############################################################################



class TreeNodeStream(IntStream):
    """@brief A stream of tree nodes

    It accessing nodes from a tree of some kind.
    """

    # TreeNodeStream is abstract, no need to complain about not implemented
    # abstract methods
    # pylint: disable-msg=W0223

    def get(self, i):
        """Get a tree node at an absolute index i; 0..n-1.
        If you don't want to buffer up nodes, then this method makes no
        sense for you.
        """

        raise NotImplementedError


    def LT(self, k):
        """
        Get tree node at current input pointer + i ahead where i=1 is next node.
        i<0 indicates nodes in the past.  So LT(-1) is previous node, but
        implementations are not required to provide results for k < -1.
        LT(0) is undefined.  For i>=n, return null.
        Return null for LT(0) and any index that results in an absolute address
        that is negative.

        This is analogus to the LT() method of the TokenStream, but this
        returns a tree node instead of a token.  Makes code gen identical
        for both parser and tree grammars. :)
        """

        raise NotImplementedError


    def getTreeSource(self):
        """
        Where is this stream pulling nodes from?  This is not the name, but
        the object that provides node objects.
        """

        raise NotImplementedError


    def getTokenStream(self):
        """
        If the tree associated with this stream was created from a TokenStream,
        you can specify it here.  Used to do rule $text attribute in tree
        parser.  Optional unless you use tree parser rule text attribute
        or output=template and rewrite=true options.
        """

        raise NotImplementedError


    def getTreeAdaptor(self):
        """
        What adaptor can tell me how to interpret/navigate nodes and
        trees.  E.g., get text of a node.
        """

        raise NotImplementedError


    def setUniqueNavigationNodes(self, uniqueNavigationNodes):
        """
        As we flatten the tree, we use UP, DOWN nodes to represent
        the tree structure.  When debugging we need unique nodes
        so we have to instantiate new ones.  When doing normal tree
        parsing, it's slow and a waste of memory to create unique
        navigation nodes.  Default should be false;
        """

        raise NotImplementedError


    def reset(self):
        """
        Reset the tree node stream in such a way that it acts like
        a freshly constructed stream.
        """

        raise NotImplementedError


    def toString(self, start, stop):
        """
        Return the text of all nodes from start to stop, inclusive.
        If the stream does not buffer all the nodes then it can still
        walk recursively from start until stop.  You can always return
        null or "" too, but users should not access $ruleLabel.text in
        an action of course in that case.
        """

        raise NotImplementedError


    # REWRITING TREES (used by tree parser)
    def replaceChildren(self, parent, startChildIndex, stopChildIndex, t):
        """
 	Replace from start to stop child index of parent with t, which might
        be a list.  Number of children may be different
        after this call.  The stream is notified because it is walking the
        tree and might need to know you are monkeying with the underlying
        tree.  Also, it might be able to modify the node stream to avoid
        restreaming for future phases.

        If parent is null, don't do anything; must be at root of overall tree.
        Can't replace whatever points to the parent externally.  Do nothing.
        """

        raise NotImplementedError


class CommonTreeNodeStream(TreeNodeStream):
    """@brief A buffered stream of tree nodes.

    Nodes can be from a tree of ANY kind.

    This node stream sucks all nodes out of the tree specified in
    the constructor during construction and makes pointers into
    the tree using an array of Object pointers. The stream necessarily
    includes pointers to DOWN and UP and EOF nodes.

    This stream knows how to mark/release for backtracking.

    This stream is most suitable for tree interpreters that need to
    jump around a lot or for tree parsers requiring speed (at cost of memory).
    There is some duplicated functionality here with UnBufferedTreeNodeStream
    but just in bookkeeping, not tree walking etc...

    @see UnBufferedTreeNodeStream
    """

    def __init__(self, *args):
        TreeNodeStream.__init__(self)

        if len(args) == 1:
            adaptor = CommonTreeAdaptor()
            tree = args[0]

            nodes = None
            down = None
            up = None
            eof = None

        elif len(args) == 2:
            adaptor = args[0]
            tree = args[1]

            nodes = None
            down = None
            up = None
            eof = None

        elif len(args) == 3:
            parent = args[0]
            start = args[1]
            stop = args[2]

            adaptor = parent.adaptor
            tree = parent.root

            nodes = parent.nodes[start:stop]
            down = parent.down
            up = parent.up
            eof = parent.eof

        else:
            raise TypeError("Invalid arguments")

        # all these navigation nodes are shared and hence they
        # cannot contain any line/column info
        if down is not None:
            self.down = down
        else:
            self.down = adaptor.createFromType(DOWN, "DOWN")

        if up is not None:
            self.up = up
        else:
            self.up = adaptor.createFromType(UP, "UP")

        if eof is not None:
            self.eof = eof
        else:
            self.eof = adaptor.createFromType(EOF, "EOF")

        # The complete mapping from stream index to tree node.
        # This buffer includes pointers to DOWN, UP, and EOF nodes.
        # It is built upon ctor invocation.  The elements are type
        #  Object as we don't what the trees look like.

        # Load upon first need of the buffer so we can set token types
        # of interest for reverseIndexing.  Slows us down a wee bit to
        # do all of the if p==-1 testing everywhere though.
        if nodes is not None:
            self.nodes = nodes
        else:
            self.nodes = []

        # Pull nodes from which tree?
        self.root = tree

        # IF this tree (root) was created from a token stream, track it.
        self.tokens = None

        # What tree adaptor was used to build these trees
        self.adaptor = adaptor

        # Reuse same DOWN, UP navigation nodes unless this is true
        self.uniqueNavigationNodes = False

        # The index into the nodes list of the current node (next node
        # to consume).  If -1, nodes array not filled yet.
        self.p = -1

        # Track the last mark() call result value for use in rewind().
        self.lastMarker = None

        # Stack of indexes used for push/pop calls
        self.calls = []


    def fillBuffer(self):
        """Walk tree with depth-first-search and fill nodes buffer.
        Don't do DOWN, UP nodes if its a list (t is isNil).
        """

        self._fillBuffer(self.root)
        self.p = 0 # buffer of nodes intialized now


    def _fillBuffer(self, t):
        nil = self.adaptor.isNil(t)

        if not nil:
            self.nodes.append(t) # add this node

        # add DOWN node if t has children
        n = self.adaptor.getChildCount(t)
        if not nil and n > 0:
            self.addNavigationNode(DOWN)

        # and now add all its children
        for c in range(n):
            self._fillBuffer(self.adaptor.getChild(t, c))

        # add UP node if t has children
        if not nil and n > 0:
            self.addNavigationNode(UP)


    def getNodeIndex(self, node):
        """What is the stream index for node? 0..n-1
        Return -1 if node not found.
        """

        if self.p == -1:
            self.fillBuffer()

        for i, t in enumerate(self.nodes):
            if t == node:
                return i

        return -1


    def addNavigationNode(self, ttype):
        """
        As we flatten the tree, we use UP, DOWN nodes to represent
        the tree structure.  When debugging we need unique nodes
        so instantiate new ones when uniqueNavigationNodes is true.
        """

        navNode = None

        if ttype == DOWN:
            if self.hasUniqueNavigationNodes():
                navNode = self.adaptor.createFromType(DOWN, "DOWN")

            else:
                navNode = self.down

        else:
            if self.hasUniqueNavigationNodes():
                navNode = self.adaptor.createFromType(UP, "UP")

            else:
                navNode = self.up

        self.nodes.append(navNode)


    def get(self, i):
        if self.p == -1:
            self.fillBuffer()

        return self.nodes[i]


    def LT(self, k):
        if self.p == -1:
            self.fillBuffer()

        if k == 0:
            return None

        if k < 0:
            return self.LB(-k)

        if self.p + k - 1 >= len(self.nodes):
            return self.eof

        return self.nodes[self.p + k - 1]


    def getCurrentSymbol(self):
        return self.LT(1)


    def LB(self, k):
        """Look backwards k nodes"""

        if k == 0:
            return None

        if self.p - k < 0:
            return None

        return self.nodes[self.p - k]


    def isEOF(self, obj):
        return self.adaptor.getType(obj) == EOF


    def getTreeSource(self):
        return self.root


    def getSourceName(self):
        return self.getTokenStream().getSourceName()


    def getTokenStream(self):
        return self.tokens


    def setTokenStream(self, tokens):
        self.tokens = tokens


    def getTreeAdaptor(self):
        return self.adaptor


    def hasUniqueNavigationNodes(self):
        return self.uniqueNavigationNodes


    def setUniqueNavigationNodes(self, uniqueNavigationNodes):
        self.uniqueNavigationNodes = uniqueNavigationNodes


    def consume(self):
        if self.p == -1:
            self.fillBuffer()

        self.p += 1


    def LA(self, i):
        return self.adaptor.getType(self.LT(i))


    def mark(self):
        if self.p == -1:
            self.fillBuffer()


        self.lastMarker = self.index()
        return self.lastMarker


    def release(self, marker=None):
        # no resources to release

        pass


    def index(self):
        return self.p


    def rewind(self, marker=None):
        if marker is None:
            marker = self.lastMarker

        self.seek(marker)


    def seek(self, index):
        if self.p == -1:
            self.fillBuffer()

        self.p = index


    def push(self, index):
        """
        Make stream jump to a new location, saving old location.
        Switch back with pop().
        """

        self.calls.append(self.p) # save current index
        self.seek(index)


    def pop(self):
        """
        Seek back to previous index saved during last push() call.
        Return top of stack (return index).
        """

        ret = self.calls.pop(-1)
        self.seek(ret)
        return ret


    def reset(self):
        self.p = 0
        self.lastMarker = 0
        self.calls = []


    def size(self):
        if self.p == -1:
            self.fillBuffer()

        return len(self.nodes)


    # TREE REWRITE INTERFACE

    def replaceChildren(self, parent, startChildIndex, stopChildIndex, t):
        if parent is not None:
            self.adaptor.replaceChildren(
                parent, startChildIndex, stopChildIndex, t
                )


    def __str__(self):
        """Used for testing, just return the token type stream"""

        if self.p == -1:
            self.fillBuffer()

        return ' '.join([str(self.adaptor.getType(node))
                         for node in self.nodes
                         ])


    def toString(self, start, stop):
        if start is None or stop is None:
            return None

        if self.p == -1:
            self.fillBuffer()

        #System.out.println("stop: "+stop);
        #if ( start instanceof CommonTree )
        #    System.out.print("toString: "+((CommonTree)start).getToken()+", ");
        #else
        #    System.out.println(start);
        #if ( stop instanceof CommonTree )
        #    System.out.println(((CommonTree)stop).getToken());
        #else
        #    System.out.println(stop);

        # if we have the token stream, use that to dump text in order
        if self.tokens is not None:
            beginTokenIndex = self.adaptor.getTokenStartIndex(start)
            endTokenIndex = self.adaptor.getTokenStopIndex(stop)

            # if it's a tree, use start/stop index from start node
            # else use token range from start/stop nodes
            if self.adaptor.getType(stop) == UP:
                endTokenIndex = self.adaptor.getTokenStopIndex(start)

            elif self.adaptor.getType(stop) == EOF:
                endTokenIndex = self.size() -2 # don't use EOF

            return self.tokens.toString(beginTokenIndex, endTokenIndex)

        # walk nodes looking for start
        i, t = 0, None
        for i, t in enumerate(self.nodes):
            if t == start:
                break

        # now walk until we see stop, filling string buffer with text
        buf = []
        t = self.nodes[i]
        while t != stop:
            text = self.adaptor.getText(t)
            if text is None:
                text = " " + self.adaptor.getType(t)

            buf.append(text)
            i += 1
            t = self.nodes[i]

        # include stop node too
        text = self.adaptor.getText(stop)
        if text is None:
            text = " " +self.adaptor.getType(stop)

        buf.append(text)

        return ''.join(buf)


    ## iterator interface
    def __iter__(self):
        if self.p == -1:
            self.fillBuffer()

        for node in self.nodes:
            yield node


#############################################################################
#
# tree parser
#
#############################################################################

class TreeParser(BaseRecognizer):
    """@brief Baseclass for generated tree parsers.

    A parser for a stream of tree nodes.  "tree grammars" result in a subclass
    of this.  All the error reporting and recovery is shared with Parser via
    the BaseRecognizer superclass.
    """

    def __init__(self, input, state=None):
        BaseRecognizer.__init__(self, state)

        self.input = None
        self.setTreeNodeStream(input)


    def reset(self):
        BaseRecognizer.reset(self) # reset all recognizer state variables
        if self.input is not None:
            self.input.seek(0) # rewind the input


    def setTreeNodeStream(self, input):
        """Set the input stream"""

        self.input = input


    def getTreeNodeStream(self):
        return self.input


    def getSourceName(self):
        return self.input.getSourceName()


    def getCurrentInputSymbol(self, input):
        return input.LT(1)


    def getMissingSymbol(self, input, e, expectedTokenType, follow):
        tokenText = "<missing " + self.tokenNames[expectedTokenType] + ">"
        adaptor = input.adaptor
        return adaptor.createToken(
            CommonToken(type=expectedTokenType, text=tokenText))


    # precompiled regex used by inContext
    dotdot = ".*[^.]\\.\\.[^.].*"
    doubleEtc = ".*\\.\\.\\.\\s+\\.\\.\\..*"
    dotdotPattern = re.compile(dotdot)
    doubleEtcPattern = re.compile(doubleEtc)

    def inContext(self, context, adaptor=None, tokenName=None, t=None):
        """Check if current node in input has a context.

        Context means sequence of nodes towards root of tree.  For example,
        you might say context is "MULT" which means my parent must be MULT.
        "CLASS VARDEF" says current node must be child of a VARDEF and whose
        parent is a CLASS node.  You can use "..." to mean zero-or-more nodes.
        "METHOD ... VARDEF" means my parent is VARDEF and somewhere above
        that is a METHOD node.  The first node in the context is not
        necessarily the root.  The context matcher stops matching and returns
        true when it runs out of context.  There is no way to force the first
        node to be the root.
        """

        return self._inContext(
            self.input.getTreeAdaptor(), self.tokenNames,
            self.input.LT(1), context)

    @classmethod
    def _inContext(cls, adaptor, tokenNames, t, context):
        """The worker for inContext.

        It's static and full of parameters for testing purposes.
        """

        if cls.dotdotPattern.match(context):
            # don't allow "..", must be "..."
            raise ValueError("invalid syntax: ..")

        if cls.doubleEtcPattern.match(context):
            # don't allow double "..."
            raise ValueError("invalid syntax: ... ...")

        # ensure spaces around ...
        context = context.replace("...", " ... ")
        context = context.strip()
        nodes = context.split()

        ni = len(nodes) - 1
        t = adaptor.getParent(t)
        while ni >= 0 and t is not None:
            if nodes[ni] == "...":
                # walk upwards until we see nodes[ni-1] then continue walking
                if ni == 0:
                    # ... at start is no-op
                    return True
                goal = nodes[ni-1]
                ancestor = cls._getAncestor(adaptor, tokenNames, t, goal)
                if ancestor is None:
                    return False
                t = ancestor
                ni -= 1

            name = tokenNames[adaptor.getType(t)]
            if name != nodes[ni]:
                return False

            # advance to parent and to previous element in context node list
            ni -= 1
            t = adaptor.getParent(t)

        # at root but more nodes to match
        if t is None and ni >= 0:
            return False

        return True

    @staticmethod
    def _getAncestor(adaptor, tokenNames, t, goal):
        """Helper for static inContext."""
        while t is not None:
            name = tokenNames[adaptor.getType(t)]
            if name == goal:
                return t
            t = adaptor.getParent(t)

        return None


    def matchAny(self):
        """
        Match '.' in tree parser has special meaning.  Skip node or
        entire tree if node has children.  If children, scan until
        corresponding UP node.
        """

        self._state.errorRecovery = False

        look = self.input.LT(1)
        if self.input.getTreeAdaptor().getChildCount(look) == 0:
            self.input.consume() # not subtree, consume 1 node and return
            return

        # current node is a subtree, skip to corresponding UP.
        # must count nesting level to get right UP
        level = 0
        tokenType = self.input.getTreeAdaptor().getType(look)
        while tokenType != EOF and not (tokenType == UP and level==0):
            self.input.consume()
            look = self.input.LT(1)
            tokenType = self.input.getTreeAdaptor().getType(look)
            if tokenType == DOWN:
                level += 1

            elif tokenType == UP:
                level -= 1

        self.input.consume() # consume UP


    def mismatch(self, input, ttype, follow):
        """
        We have DOWN/UP nodes in the stream that have no line info; override.
        plus we want to alter the exception type. Don't try to recover
        from tree parser errors inline...
        """

        raise MismatchedTreeNodeException(ttype, input)


    def getErrorHeader(self, e):
        """
        Prefix error message with the grammar name because message is
        always intended for the programmer because the parser built
        the input tree not the user.
        """

        return (self.getGrammarFileName() +
                ": node from {}line {}:{}".format(
                    "after " if e.approximateLineInfo else '',
                    e.line,
                    e.charPositionInLine))

    def getErrorMessage(self, e):
        """
        Tree parsers parse nodes they usually have a token object as
        payload. Set the exception token and do the default behavior.
        """

        if isinstance(self, TreeParser):
            adaptor = e.input.getTreeAdaptor()
            e.token = adaptor.getToken(e.node)
            if e.token is not None: # could be an UP/DOWN node
                e.token = CommonToken(
                    type=adaptor.getType(e.node),
                    text=adaptor.getText(e.node)
                    )

        return BaseRecognizer.getErrorMessage(self, e)


    def traceIn(self, ruleName, ruleIndex):
        BaseRecognizer.traceIn(self, ruleName, ruleIndex, self.input.LT(1))


    def traceOut(self, ruleName, ruleIndex):
        BaseRecognizer.traceOut(self, ruleName, ruleIndex, self.input.LT(1))


#############################################################################
#
# tree visitor
#
#############################################################################

class TreeVisitor(object):
    """Do a depth first walk of a tree, applying pre() and post() actions
    we go.
    """

    def __init__(self, adaptor=None):
        if adaptor is not None:
            self.adaptor = adaptor
        else:
            self.adaptor = CommonTreeAdaptor()

    def visit(self, t, pre_action=None, post_action=None):
        """Visit every node in tree t and trigger an action for each node
        before/after having visited all of its children.  Bottom up walk.
        Execute both actions even if t has no children.  Ignore return
        results from transforming children since they will have altered
        the child list of this node (their parent).  Return result of
        applying post action to this node.

        The Python version differs from the Java version by taking two
        callables 'pre_action' and 'post_action' instead of a class instance
        that wraps those methods. Those callables must accept a TreeNode as
        their single argument and return the (potentially transformed or
        replaced) TreeNode.
        """

        isNil = self.adaptor.isNil(t)
        if pre_action is not None and not isNil:
            # if rewritten, walk children of new t
            t = pre_action(t)

        idx = 0
        while idx < self.adaptor.getChildCount(t):
            child = self.adaptor.getChild(t, idx)
            self.visit(child, pre_action, post_action)
            idx += 1

        if post_action is not None and not isNil:
            t = post_action(t)

        return t

#############################################################################
#
# tree iterator
#
#############################################################################

class TreeIterator(object):
    """
    Return a node stream from a doubly-linked tree whose nodes
    know what child index they are.

    Emit navigation nodes (DOWN, UP, and EOF) to let show tree structure.
    """

    def __init__(self, tree, adaptor=None):
        if adaptor is None:
            adaptor = CommonTreeAdaptor()

        self.root = tree
        self.adaptor = adaptor

        self.first_time = True
        self.tree = tree

        # If we emit UP/DOWN nodes, we need to spit out multiple nodes per
        # next() call.
        self.nodes = []

        # navigation nodes to return during walk and at end
        self.down = adaptor.createFromType(DOWN, "DOWN")
        self.up = adaptor.createFromType(UP, "UP")
        self.eof = adaptor.createFromType(EOF, "EOF")


    def reset(self):
        self.first_time = True
        self.tree = self.root
        self.nodes = []


    def __iter__(self):
        return self


    def has_next(self):
        if self.first_time:
            return self.root is not None

        if len(self.nodes) > 0:
            return True

        if self.tree is None:
            return False

        if self.adaptor.getChildCount(self.tree) > 0:
            return True

        # back at root?
        return self.adaptor.getParent(self.tree) is not None


    def __next__(self):
        if not self.has_next():
            raise StopIteration

        if self.first_time:
            # initial condition
            self.first_time = False
            if self.adaptor.getChildCount(self.tree) == 0:
                # single node tree (special)
                self.nodes.append(self.eof)
                return self.tree

            return self.tree

        # if any queued up, use those first
        if len(self.nodes) > 0:
            return self.nodes.pop(0)

        # no nodes left?
        if self.tree is None:
            return self.eof

        # next node will be child 0 if any children
        if self.adaptor.getChildCount(self.tree) > 0:
            self.tree = self.adaptor.getChild(self.tree, 0)
            # real node is next after DOWN
            self.nodes.append(self.tree)
            return self.down

        # if no children, look for next sibling of tree or ancestor
        parent = self.adaptor.getParent(self.tree)
        # while we're out of siblings, keep popping back up towards root
        while (parent is not None
               and self.adaptor.getChildIndex(self.tree)+1 >= self.adaptor.getChildCount(parent)):
            # we're moving back up
            self.nodes.append(self.up)
            self.tree = parent
            parent = self.adaptor.getParent(self.tree)

        # no nodes left?
        if parent is None:
            self.tree = None # back at root? nothing left then
            self.nodes.append(self.eof) # add to queue, might have UP nodes in there
            return self.nodes.pop(0)

        # must have found a node with an unvisited sibling
        # move to it and return it
        nextSiblingIndex = self.adaptor.getChildIndex(self.tree) + 1
        self.tree = self.adaptor.getChild(parent, nextSiblingIndex)
        self.nodes.append(self.tree) # add to queue, might have UP nodes in there
        return self.nodes.pop(0)



#############################################################################
#
# streams for rule rewriting
#
#############################################################################

class RewriteRuleElementStream(object):
    """@brief Internal helper class.

    A generic list of elements tracked in an alternative to be used in
    a -> rewrite rule.  We need to subclass to fill in the next() method,
    which returns either an AST node wrapped around a token payload or
    an existing subtree.

    Once you start next()ing, do not try to add more elements.  It will
    break the cursor tracking I believe.

    @see org.antlr.runtime.tree.RewriteRuleSubtreeStream
    @see org.antlr.runtime.tree.RewriteRuleTokenStream

    TODO: add mechanism to detect/puke on modification after reading from
    stream
    """

    def __init__(self, adaptor, elementDescription, elements=None):
        # Cursor 0..n-1.  If singleElement!=null, cursor is 0 until you next(),
        # which bumps it to 1 meaning no more elements.
        self.cursor = 0

        # Track single elements w/o creating a list.  Upon 2nd add, alloc list
        self.singleElement = None

        # The list of tokens or subtrees we are tracking
        self.elements = None

        # Once a node / subtree has been used in a stream, it must be dup'd
        # from then on.  Streams are reset after subrules so that the streams
        # can be reused in future subrules.  So, reset must set a dirty bit.
        # If dirty, then next() always returns a dup.
        self.dirty = False

        # The element or stream description; usually has name of the token or
        # rule reference that this list tracks.  Can include rulename too, but
        # the exception would track that info.
        self.elementDescription = elementDescription

        self.adaptor = adaptor

        if isinstance(elements, (list, tuple)):
            # Create a stream, but feed off an existing list
            self.singleElement = None
            self.elements = elements

        else:
            # Create a stream with one element
            self.add(elements)


    def reset(self):
        """
        Reset the condition of this stream so that it appears we have
        not consumed any of its elements.  Elements themselves are untouched.
        Once we reset the stream, any future use will need duplicates.  Set
        the dirty bit.
        """

        self.cursor = 0
        self.dirty = True


    def add(self, el):
        if el is None:
            return

        if self.elements is not None: # if in list, just add
            self.elements.append(el)
            return

        if self.singleElement is None: # no elements yet, track w/o list
            self.singleElement = el
            return

        # adding 2nd element, move to list
        self.elements = []
        self.elements.append(self.singleElement)
        self.singleElement = None
        self.elements.append(el)


    def nextTree(self):
        """
        Return the next element in the stream.  If out of elements, throw
        an exception unless size()==1.  If size is 1, then return elements[0].

        Return a duplicate node/subtree if stream is out of elements and
        size==1. If we've already used the element, dup (dirty bit set).
        """

        if (self.dirty
            or (self.cursor >= len(self) and len(self) == 1)
            ):
            # if out of elements and size is 1, dup
            el = self._next()
            return self.dup(el)

        # test size above then fetch
        el = self._next()
        return el


    def _next(self):
        """
        do the work of getting the next element, making sure that it's
        a tree node or subtree.  Deal with the optimization of single-
        element list versus list of size > 1.  Throw an exception
        if the stream is empty or we're out of elements and size>1.
        protected so you can override in a subclass if necessary.
        """

        if len(self) == 0:
            raise RewriteEmptyStreamException(self.elementDescription)

        if self.cursor >= len(self): # out of elements?
            if len(self) == 1: # if size is 1, it's ok; return and we'll dup
                return self.toTree(self.singleElement)

            # out of elements and size was not 1, so we can't dup
            raise RewriteCardinalityException(self.elementDescription)

        # we have elements
        if self.singleElement is not None:
            self.cursor += 1 # move cursor even for single element list
            return self.toTree(self.singleElement)

        # must have more than one in list, pull from elements
        o = self.toTree(self.elements[self.cursor])
        self.cursor += 1
        return o


    def dup(self, el):
        """
        When constructing trees, sometimes we need to dup a token or AST
        subtree.  Dup'ing a token means just creating another AST node
        around it.  For trees, you must call the adaptor.dupTree() unless
        the element is for a tree root; then it must be a node dup.
        """

        raise NotImplementedError


    def toTree(self, el):
        """
        Ensure stream emits trees; tokens must be converted to AST nodes.
        AST nodes can be passed through unmolested.
        """

        return el


    def hasNext(self):
        return ( (self.singleElement is not None and self.cursor < 1)
                 or (self.elements is not None
                     and self.cursor < len(self.elements)
                     )
                 )


    def size(self):
        if self.singleElement is not None:
            return 1

        if self.elements is not None:
            return len(self.elements)

        return 0

    __len__ = size


    def getDescription(self):
        """Deprecated. Directly access elementDescription attribute"""

        return self.elementDescription


class RewriteRuleTokenStream(RewriteRuleElementStream):
    """@brief Internal helper class."""

    def toTree(self, el):
        # Don't convert to a tree unless they explicitly call nextTree.
        # This way we can do hetero tree nodes in rewrite.
        return el


    def nextNode(self):
        t = self._next()
        return self.adaptor.createWithPayload(t)


    def nextToken(self):
        return self._next()


    def dup(self, el):
        raise TypeError("dup can't be called for a token stream.")


class RewriteRuleSubtreeStream(RewriteRuleElementStream):
    """@brief Internal helper class."""

    def nextNode(self):
        """
        Treat next element as a single node even if it's a subtree.
        This is used instead of next() when the result has to be a
        tree root node.  Also prevents us from duplicating recently-added
        children; e.g., ^(type ID)+ adds ID to type and then 2nd iteration
        must dup the type node, but ID has been added.

        Referencing a rule result twice is ok; dup entire tree as
        we can't be adding trees as root; e.g., expr expr.

        Hideous code duplication here with super.next().  Can't think of
        a proper way to refactor.  This needs to always call dup node
        and super.next() doesn't know which to call: dup node or dup tree.
        """

        if (self.dirty
            or (self.cursor >= len(self) and len(self) == 1)
            ):
            # if out of elements and size is 1, dup (at most a single node
            # since this is for making root nodes).
            el = self._next()
            return self.adaptor.dupNode(el)

        # test size above then fetch
        el = self._next()
        while self.adaptor.isNil(el) and self.adaptor.getChildCount(el) == 1:
            el = self.adaptor.getChild(el, 0)

        # dup just the root (want node here)
        return self.adaptor.dupNode(el)


    def dup(self, el):
        return self.adaptor.dupTree(el)



class RewriteRuleNodeStream(RewriteRuleElementStream):
    """
    Queues up nodes matched on left side of -> in a tree parser. This is
    the analog of RewriteRuleTokenStream for normal parsers.
    """

    def nextNode(self):
        return self._next()


    def toTree(self, el):
        return self.adaptor.dupNode(el)


    def dup(self, el):
        # we dup every node, so don't have to worry about calling dup; short-
        #circuited next() so it doesn't call.
        raise TypeError("dup can't be called for a node stream.")


class TreeRuleReturnScope(RuleReturnScope):
    """
    This is identical to the ParserRuleReturnScope except that
    the start property is a tree nodes not Token object
    when you are parsing trees.  To be generic the tree node types
    have to be Object.
    """

    def __init__(self):
        super().__init__()
        self.start = None
        self.tree = None


    def getStart(self):
        return self.start


    def getTree(self):
        return self.tree
