1# Lint as: python2, python3
2""" @package antlr3.tree
3@brief ANTLR3 runtime package, tree module
4
5This module contains all support classes for AST construction and tree parsers.
6
7"""
8
9# begin[licence]
10#
11# [The "BSD licence"]
12# Copyright (c) 2005-2008 Terence Parr
13# All rights reserved.
14#
15# Redistribution and use in source and binary forms, with or without
16# modification, are permitted provided that the following conditions
17# are met:
18# 1. Redistributions of source code must retain the above copyright
19#    notice, this list of conditions and the following disclaimer.
20# 2. Redistributions in binary form must reproduce the above copyright
21#    notice, this list of conditions and the following disclaimer in the
22#    documentation and/or other materials provided with the distribution.
23# 3. The name of the author may not be used to endorse or promote products
24#    derived from this software without specific prior written permission.
25#
26# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36#
37# end[licence]
38
39# lot's of docstrings are missing, don't complain for now...
40# pylint: disable-msg=C0111
41
42from __future__ import absolute_import
43from __future__ import division
44from __future__ import print_function
45
46from antlr3.constants import UP, DOWN, EOF, INVALID_TOKEN_TYPE
47from antlr3.exceptions import MismatchedTreeNodeException, \
48     MissingTokenException, UnwantedTokenException, MismatchedTokenException, \
49     NoViableAltException
50from antlr3.recognizers import BaseRecognizer, RuleReturnScope
51from antlr3.streams import IntStream
52from antlr3.tokens import CommonToken, Token, INVALID_TOKEN
53import six
54from six.moves import range
55
56
57############################################################################
58#
59# tree related exceptions
60#
61############################################################################
62
63
64class RewriteCardinalityException(RuntimeError):
65  """
66    @brief Base class for all exceptions thrown during AST rewrite construction.
67
68    This signifies a case where the cardinality of two or more elements
69    in a subrule are different: (ID INT)+ where |ID|!=|INT|
70    """
71
72  def __init__(self, elementDescription):
73    RuntimeError.__init__(self, elementDescription)
74
75    self.elementDescription = elementDescription
76
77  def getMessage(self):
78    return self.elementDescription
79
80
81class RewriteEarlyExitException(RewriteCardinalityException):
82  """@brief No elements within a (...)+ in a rewrite rule"""
83
84  def __init__(self, elementDescription=None):
85    RewriteCardinalityException.__init__(self, elementDescription)
86
87
88class RewriteEmptyStreamException(RewriteCardinalityException):
89  """
90    @brief Ref to ID or expr but no tokens in ID stream or subtrees in expr
91    stream
92    """
93
94  pass
95
96
97############################################################################
98#
99# basic Tree and TreeAdaptor interfaces
100#
101############################################################################
102
103class Tree(object):
104  """
105    @brief Abstract baseclass for tree nodes.
106
107    What does a tree look like?  ANTLR has a number of support classes
108    such as CommonTreeNodeStream that work on these kinds of trees.  You
109    don't have to make your trees implement this interface, but if you do,
110    you'll be able to use more support code.
111
112    NOTE: When constructing trees, ANTLR can build any kind of tree; it can
113    even use Token objects as trees if you add a child list to your tokens.
114
115    This is a tree node without any payload; just navigation and factory stuff.
116    """
117
118  def getChild(self, i):
119    raise NotImplementedError
120
121  def getChildCount(self):
122    raise NotImplementedError
123
124  def getParent(self):
125    """Tree tracks parent and child index now > 3.0"""
126
127    raise NotImplementedError
128
129  def setParent(self, t):
130    """Tree tracks parent and child index now > 3.0"""
131
132    raise NotImplementedError
133
134  def getChildIndex(self):
135    """This node is what child index? 0..n-1"""
136
137    raise NotImplementedError
138
139  def setChildIndex(self, index):
140    """This node is what child index? 0..n-1"""
141
142    raise NotImplementedError
143
144  def freshenParentAndChildIndexes(self):
145    """Set the parent and child index values for all children"""
146
147    raise NotImplementedError
148
149  def addChild(self, t):
150    """
151        Add t as a child to this node.  If t is null, do nothing.  If t
152        is nil, add all children of t to this' children.
153        """
154
155    raise NotImplementedError
156
157  def setChild(self, i, t):
158    """Set ith child (0..n-1) to t; t must be non-null and non-nil node"""
159
160    raise NotImplementedError
161
162  def deleteChild(self, i):
163    raise NotImplementedError
164
165  def replaceChildren(self, startChildIndex, stopChildIndex, t):
166    """
167        Delete children from start to stop and replace with t even if t is
168        a list (nil-root tree).  num of children can increase or decrease.
169        For huge child lists, inserting children can force walking rest of
170        children to set their childindex; could be slow.
171        """
172
173    raise NotImplementedError
174
175  def isNil(self):
176    """
177        Indicates the node is a nil node but may still have children, meaning
178        the tree is a flat list.
179        """
180
181    raise NotImplementedError
182
183  def getTokenStartIndex(self):
184    """
185        What is the smallest token index (indexing from 0) for this node
186           and its children?
187        """
188
189    raise NotImplementedError
190
191  def setTokenStartIndex(self, index):
192    raise NotImplementedError
193
194  def getTokenStopIndex(self):
195    """
196        What is the largest token index (indexing from 0) for this node
197        and its children?
198        """
199
200    raise NotImplementedError
201
202  def setTokenStopIndex(self, index):
203    raise NotImplementedError
204
205  def dupNode(self):
206    raise NotImplementedError
207
208  def getType(self):
209    """Return a token type; needed for tree parsing."""
210
211    raise NotImplementedError
212
213  def getText(self):
214    raise NotImplementedError
215
216  def getLine(self):
217    """
218        In case we don't have a token payload, what is the line for errors?
219        """
220
221    raise NotImplementedError
222
223  def getCharPositionInLine(self):
224    raise NotImplementedError
225
226  def toStringTree(self):
227    raise NotImplementedError
228
229  def toString(self):
230    raise NotImplementedError
231
232
233
234class TreeAdaptor(object):
235  """
236    @brief Abstract baseclass for tree adaptors.
237
238    How to create and navigate trees.  Rather than have a separate factory
239    and adaptor, I've merged them.  Makes sense to encapsulate.
240
241    This takes the place of the tree construction code generated in the
242    generated code in 2.x and the ASTFactory.
243
244    I do not need to know the type of a tree at all so they are all
245    generic Objects.  This may increase the amount of typecasting needed. :(
246    """
247
248  # C o n s t r u c t i o n
249
250  def createWithPayload(self, payload):
251    """
252        Create a tree node from Token object; for CommonTree type trees,
253        then the token just becomes the payload.  This is the most
254        common create call.
255
256        Override if you want another kind of node to be built.
257        """
258
259    raise NotImplementedError
260
261  def dupNode(self, treeNode):
262    """Duplicate a single tree node.
263
264        Override if you want another kind of node to be built.
265    """
266
267    raise NotImplementedError
268
269  def dupTree(self, tree):
270    """Duplicate tree recursively, using dupNode() for each node"""
271
272    raise NotImplementedError
273
274  def nil(self):
275    """
276        Return a nil node (an empty but non-null node) that can hold
277        a list of element as the children.  If you want a flat tree (a list)
278        use "t=adaptor.nil(); t.addChild(x); t.addChild(y);"
279        """
280
281    raise NotImplementedError
282
283  def errorNode(self, input, start, stop, exc):
284    """
285        Return a tree node representing an error.  This node records the
286        tokens consumed during error recovery.  The start token indicates the
287        input symbol at which the error was detected.  The stop token indicates
288        the last symbol consumed during recovery.
289
290        You must specify the input stream so that the erroneous text can
291        be packaged up in the error node.  The exception could be useful
292        to some applications; default implementation stores ptr to it in
293        the CommonErrorNode.
294
295        This only makes sense during token parsing, not tree parsing.
296        Tree parsing should happen only when parsing and tree construction
297        succeed.
298        """
299
300    raise NotImplementedError
301
302  def isNil(self, tree):
303    """Is tree considered a nil node used to make lists of child nodes?"""
304
305    raise NotImplementedError
306
307  def addChild(self, t, child):
308    """
309        Add a child to the tree t.  If child is a flat tree (a list), make all
310        in list children of t.  Warning: if t has no children, but child does
311        and child isNil then you can decide it is ok to move children to t via
312        t.children = child.children; i.e., without copying the array.  Just
313        make sure that this is consistent with have the user will build
314        ASTs. Do nothing if t or child is null.
315        """
316
317    raise NotImplementedError
318
319  def becomeRoot(self, newRoot, oldRoot):
320    """
321        If oldRoot is a nil root, just copy or move the children to newRoot.
322        If not a nil root, make oldRoot a child of newRoot.
323
324           old=^(nil a b c), new=r yields ^(r a b c)
325           old=^(a b c), new=r yields ^(r ^(a b c))
326
327        If newRoot is a nil-rooted single child tree, use the single
328        child as the new root node.
329
330           old=^(nil a b c), new=^(nil r) yields ^(r a b c)
331           old=^(a b c), new=^(nil r) yields ^(r ^(a b c))
332
333        If oldRoot was null, it's ok, just return newRoot (even if isNil).
334
335           old=null, new=r yields r
336           old=null, new=^(nil r) yields ^(nil r)
337
338        Return newRoot.  Throw an exception if newRoot is not a
339        simple node or nil root with a single child node--it must be a root
340        node.  If newRoot is ^(nil x) return x as newRoot.
341
342        Be advised that it's ok for newRoot to point at oldRoot's
343        children; i.e., you don't have to copy the list.  We are
344        constructing these nodes so we should have this control for
345        efficiency.
346        """
347
348    raise NotImplementedError
349
350  def rulePostProcessing(self, root):
351    """
352        Given the root of the subtree created for this rule, post process
353        it to do any simplifications or whatever you want.  A required
354        behavior is to convert ^(nil singleSubtree) to singleSubtree
355        as the setting of start/stop indexes relies on a single non-nil root
356        for non-flat trees.
357
358        Flat trees such as for lists like "idlist : ID+ ;" are left alone
359        unless there is only one ID.  For a list, the start/stop indexes
360        are set in the nil node.
361
362        This method is executed after all rule tree construction and right
363        before setTokenBoundaries().
364        """
365
366    raise NotImplementedError
367
368  def getUniqueID(self, node):
369    """For identifying trees.
370
371        How to identify nodes so we can say "add node to a prior node"?
372        Even becomeRoot is an issue.  Use System.identityHashCode(node)
373        usually.
374        """
375
376    raise NotImplementedError
377
378  # R e w r i t e  R u l e s
379
380  def createFromToken(self, tokenType, fromToken, text=None):
381    """
382        Create a new node derived from a token, with a new token type and
383        (optionally) new text.
384
385        This is invoked from an imaginary node ref on right side of a
386        rewrite rule as IMAG[$tokenLabel] or IMAG[$tokenLabel "IMAG"].
387
388        This should invoke createToken(Token).
389        """
390
391    raise NotImplementedError
392
393  def createFromType(self, tokenType, text):
394    """Create a new node derived from a token, with a new token type.
395
396        This is invoked from an imaginary node ref on right side of a
397        rewrite rule as IMAG["IMAG"].
398
399        This should invoke createToken(int,String).
400        """
401
402    raise NotImplementedError
403
404  # C o n t e n t
405
406  def getType(self, t):
407    """For tree parsing, I need to know the token type of a node"""
408
409    raise NotImplementedError
410
411  def setType(self, t, type):
412    """Node constructors can set the type of a node"""
413
414    raise NotImplementedError
415
416  def getText(self, t):
417    raise NotImplementedError
418
419  def setText(self, t, text):
420    """Node constructors can set the text of a node"""
421
422    raise NotImplementedError
423
424  def getToken(self, t):
425    """Return the token object from which this node was created.
426
427        Currently used only for printing an error message.
428        The error display routine in BaseRecognizer needs to
429        display where the input the error occurred. If your
430        tree of limitation does not store information that can
431        lead you to the token, you can create a token filled with
432        the appropriate information and pass that back.  See
433        BaseRecognizer.getErrorMessage().
434        """
435
436    raise NotImplementedError
437
438  def setTokenBoundaries(self, t, startToken, stopToken):
439    """
440        Where are the bounds in the input token stream for this node and
441        all children?  Each rule that creates AST nodes will call this
442        method right before returning.  Flat trees (i.e., lists) will
443        still usually have a nil root node just to hold the children list.
444        That node would contain the start/stop indexes then.
445        """
446
447    raise NotImplementedError
448
449  def getTokenStartIndex(self, t):
450    """
451        Get the token start index for this subtree; return -1 if no such index
452        """
453
454    raise NotImplementedError
455
456  def getTokenStopIndex(self, t):
457    """
458        Get the token stop index for this subtree; return -1 if no such index
459        """
460
461    raise NotImplementedError
462
463  # N a v i g a t i o n  /  T r e e  P a r s i n g
464
465  def getChild(self, t, i):
466    """Get a child 0..n-1 node"""
467
468    raise NotImplementedError
469
470  def setChild(self, t, i, child):
471    """Set ith child (0..n-1) to t; t must be non-null and non-nil node"""
472
473    raise NotImplementedError
474
475  def deleteChild(self, t, i):
476    """Remove ith child and shift children down from right."""
477
478    raise NotImplementedError
479
480  def getChildCount(self, t):
481    """How many children?  If 0, then this is a leaf node"""
482
483    raise NotImplementedError
484
485  def getParent(self, t):
486    """
487        Who is the parent node of this node; if null, implies node is root.
488        If your node type doesn't handle this, it's ok but the tree rewrites
489        in tree parsers need this functionality.
490        """
491
492    raise NotImplementedError
493
494  def setParent(self, t, parent):
495    """
496        Who is the parent node of this node; if null, implies node is root.
497        If your node type doesn't handle this, it's ok but the tree rewrites
498        in tree parsers need this functionality.
499        """
500
501    raise NotImplementedError
502
503  def getChildIndex(self, t):
504    """
505        What index is this node in the child list? Range: 0..n-1
506        If your node type doesn't handle this, it's ok but the tree rewrites
507        in tree parsers need this functionality.
508        """
509
510    raise NotImplementedError
511
512  def setChildIndex(self, t, index):
513    """
514        What index is this node in the child list? Range: 0..n-1
515        If your node type doesn't handle this, it's ok but the tree rewrites
516        in tree parsers need this functionality.
517        """
518
519    raise NotImplementedError
520
521  def replaceChildren(self, parent, startChildIndex, stopChildIndex, t):
522    """
523        Replace from start to stop child index of parent with t, which might
524        be a list.  Number of children may be different
525        after this call.
526
527        If parent is null, don't do anything; must be at root of overall tree.
528        Can't replace whatever points to the parent externally.  Do nothing.
529        """
530
531    raise NotImplementedError
532
533  # Misc
534
535  def create(self, *args):
536    """
537        Deprecated, use createWithPayload, createFromToken or createFromType.
538
539        This method only exists to mimic the Java interface of TreeAdaptor.
540
541        """
542
543    if len(args) == 1 and isinstance(args[0], Token):
544      # Object create(Token payload);
545      ##             warnings.warn(
546      ##                 "Using create() is deprecated, use createWithPayload()",
547      ##                 DeprecationWarning,
548      ##                 stacklevel=2
549      ##                 )
550      return self.createWithPayload(args[0])
551
552    if (len(args) == 2 and isinstance(args[0], six.integer_types) and
553        isinstance(args[1], Token)):
554      # Object create(int tokenType, Token fromToken);
555      ##             warnings.warn(
556      ##                 "Using create() is deprecated, use createFromToken()",
557      ##                 DeprecationWarning,
558      ##                 stacklevel=2
559      ##                 )
560      return self.createFromToken(args[0], args[1])
561
562    if (len(args) == 3 and isinstance(args[0], six.integer_types) and
563        isinstance(args[1], Token) and isinstance(args[2], six.string_types)):
564      # Object create(int tokenType, Token fromToken, String text);
565      ##             warnings.warn(
566      ##                 "Using create() is deprecated, use createFromToken()",
567      ##                 DeprecationWarning,
568      ##                 stacklevel=2
569      ##                 )
570      return self.createFromToken(args[0], args[1], args[2])
571
572    if (len(args) == 2 and isinstance(args[0], six.integer_types) and
573        isinstance(args[1], six.string_types)):
574      # Object create(int tokenType, String text);
575      ##             warnings.warn(
576      ##                 "Using create() is deprecated, use createFromType()",
577      ##                 DeprecationWarning,
578      ##                 stacklevel=2
579      ##                 )
580      return self.createFromType(args[0], args[1])
581
582    raise TypeError("No create method with this signature found: %s" %
583                    (", ".join(type(v).__name__ for v in args)))
584
585
586############################################################################
587#
588# base implementation of Tree and TreeAdaptor
589#
590# Tree
591# \- BaseTree
592#
593# TreeAdaptor
594# \- BaseTreeAdaptor
595#
596############################################################################
597
598
599class BaseTree(Tree):
600  """
601    @brief A generic tree implementation with no payload.
602
603    You must subclass to
604    actually have any user data.  ANTLR v3 uses a list of children approach
605    instead of the child-sibling approach in v2.  A flat tree (a list) is
606    an empty node whose children represent the list.  An empty, but
607    non-null node is called "nil".
608    """
609
610  # BaseTree is abstract, no need to complain about not implemented abstract
611  # methods
612  # pylint: disable-msg=W0223
613
614  def __init__(self, node=None):
615    """
616        Create a new node from an existing node does nothing for BaseTree
617        as there are no fields other than the children list, which cannot
618        be copied as the children are not considered part of this node.
619        """
620
621    Tree.__init__(self)
622    self.children = []
623    self.parent = None
624    self.childIndex = 0
625
626  def getChild(self, i):
627    try:
628      return self.children[i]
629    except IndexError:
630      return None
631
632  def getChildren(self):
633    """@brief Get the children internal List
634
635        Note that if you directly mess with
636        the list, do so at your own risk.
637        """
638
639    # FIXME: mark as deprecated
640    return self.children
641
642  def getFirstChildWithType(self, treeType):
643    for child in self.children:
644      if child.getType() == treeType:
645        return child
646
647    return None
648
649  def getChildCount(self):
650    return len(self.children)
651
652  def addChild(self, childTree):
653    """Add t as child of this node.
654
655        Warning: if t has no children, but child does
656        and child isNil then this routine moves children to t via
657        t.children = child.children; i.e., without copying the array.
658        """
659
660    # this implementation is much simpler and probably less efficient
661    # than the mumbo-jumbo that Ter did for the Java runtime.
662
663    if childTree is None:
664      return
665
666    if childTree.isNil():
667      # t is an empty node possibly with children
668
669      if self.children is childTree.children:
670        raise ValueError("attempt to add child list to itself")
671
672      # fix parent pointer and childIndex for new children
673      for idx, child in enumerate(childTree.children):
674        child.parent = self
675        child.childIndex = len(self.children) + idx
676
677      self.children += childTree.children
678
679    else:
680      # child is not nil (don't care about children)
681      self.children.append(childTree)
682      childTree.parent = self
683      childTree.childIndex = len(self.children) - 1
684
685  def addChildren(self, children):
686    """Add all elements of kids list as children of this node"""
687
688    self.children += children
689
690  def setChild(self, i, t):
691    if t is None:
692      return
693
694    if t.isNil():
695      raise ValueError("Can't set single child to a list")
696
697    self.children[i] = t
698    t.parent = self
699    t.childIndex = i
700
701  def deleteChild(self, i):
702    killed = self.children[i]
703
704    del self.children[i]
705
706    # walk rest and decrement their child indexes
707    for idx, child in enumerate(self.children[i:]):
708      child.childIndex = i + idx
709
710    return killed
711
712  def replaceChildren(self, startChildIndex, stopChildIndex, newTree):
713    """
714        Delete children from start to stop and replace with t even if t is
715        a list (nil-root tree).  num of children can increase or decrease.
716        For huge child lists, inserting children can force walking rest of
717        children to set their childindex; could be slow.
718        """
719
720    if (startChildIndex >= len(self.children) or
721        stopChildIndex >= len(self.children)):
722      raise IndexError("indexes invalid")
723
724    replacingHowMany = stopChildIndex - startChildIndex + 1
725
726    # normalize to a list of children to add: newChildren
727    if newTree.isNil():
728      newChildren = newTree.children
729
730    else:
731      newChildren = [newTree]
732
733    replacingWithHowMany = len(newChildren)
734    delta = replacingHowMany - replacingWithHowMany
735
736    if delta == 0:
737      # if same number of nodes, do direct replace
738      for idx, child in enumerate(newChildren):
739        self.children[idx + startChildIndex] = child
740        child.parent = self
741        child.childIndex = idx + startChildIndex
742
743    else:
744      # length of children changes...
745
746      # ...delete replaced segment...
747      del self.children[startChildIndex:stopChildIndex + 1]
748
749      # ...insert new segment...
750      self.children[startChildIndex:startChildIndex] = newChildren
751
752      # ...and fix indeces
753      self.freshenParentAndChildIndexes(startChildIndex)
754
755  def isNil(self):
756    return False
757
758  def freshenParentAndChildIndexes(self, offset=0):
759    for idx, child in enumerate(self.children[offset:]):
760      child.childIndex = idx + offset
761      child.parent = self
762
763  def sanityCheckParentAndChildIndexes(self, parent=None, i=-1):
764    if parent != self.parent:
765      raise ValueError("parents don't match; expected %r found %r" %
766                       (parent, self.parent))
767
768    if i != self.childIndex:
769      raise ValueError("child indexes don't match; expected %d found %d" %
770                       (i, self.childIndex))
771
772    for idx, child in enumerate(self.children):
773      child.sanityCheckParentAndChildIndexes(self, idx)
774
775  def getChildIndex(self):
776    """BaseTree doesn't track child indexes."""
777
778    return 0
779
780  def setChildIndex(self, index):
781    """BaseTree doesn't track child indexes."""
782
783    pass
784
785  def getParent(self):
786    """BaseTree doesn't track parent pointers."""
787
788    return None
789
790  def setParent(self, t):
791    """BaseTree doesn't track parent pointers."""
792
793    pass
794
795  def toStringTree(self):
796    """Print out a whole tree not just a node"""
797
798    if len(self.children) == 0:
799      return self.toString()
800
801    buf = []
802    if not self.isNil():
803      buf.append("(")
804      buf.append(self.toString())
805      buf.append(" ")
806
807    for i, child in enumerate(self.children):
808      if i > 0:
809        buf.append(" ")
810      buf.append(child.toStringTree())
811
812    if not self.isNil():
813      buf.append(")")
814
815    return "".join(buf)
816
817  def getLine(self):
818    return 0
819
820  def getCharPositionInLine(self):
821    return 0
822
823  def toString(self):
824    """Override to say how a node (not a tree) should look as text"""
825
826    raise NotImplementedError
827
828
829
830class BaseTreeAdaptor(TreeAdaptor):
831  """
832    @brief A TreeAdaptor that works with any Tree implementation.
833    """
834
835  # BaseTreeAdaptor is abstract, no need to complain about not implemented
836  # abstract methods
837  # pylint: disable-msg=W0223
838
839  def nil(self):
840    return self.createWithPayload(None)
841
842  def errorNode(self, input, start, stop, exc):
843    """
844        create tree node that holds the start and stop tokens associated
845        with an error.
846
847        If you specify your own kind of tree nodes, you will likely have to
848        override this method. CommonTree returns Token.INVALID_TOKEN_TYPE
849        if no token payload but you might have to set token type for diff
850        node type.
851        """
852
853    return CommonErrorNode(input, start, stop, exc)
854
855  def isNil(self, tree):
856    return tree.isNil()
857
858  def dupTree(self, t, parent=None):
859    """
860        This is generic in the sense that it will work with any kind of
861        tree (not just Tree interface).  It invokes the adaptor routines
862        not the tree node routines to do the construction.
863        """
864
865    if t is None:
866      return None
867
868    newTree = self.dupNode(t)
869
870    # ensure new subtree root has parent/child index set
871
872    # same index in new tree
873    self.setChildIndex(newTree, self.getChildIndex(t))
874
875    self.setParent(newTree, parent)
876
877    for i in range(self.getChildCount(t)):
878      child = self.getChild(t, i)
879      newSubTree = self.dupTree(child, t)
880      self.addChild(newTree, newSubTree)
881
882    return newTree
883
884  def addChild(self, tree, child):
885    """
886        Add a child to the tree t.  If child is a flat tree (a list), make all
887        in list children of t.  Warning: if t has no children, but child does
888        and child isNil then you can decide it is ok to move children to t via
889        t.children = child.children; i.e., without copying the array.  Just
890        make sure that this is consistent with have the user will build
891        ASTs.
892        """
893
894    #if isinstance(child, Token):
895    #    child = self.createWithPayload(child)
896
897    if tree is not None and child is not None:
898      tree.addChild(child)
899
900  def becomeRoot(self, newRoot, oldRoot):
901    """
902        If oldRoot is a nil root, just copy or move the children to newRoot.
903        If not a nil root, make oldRoot a child of newRoot.
904
905          old=^(nil a b c), new=r yields ^(r a b c)
906          old=^(a b c), new=r yields ^(r ^(a b c))
907
908        If newRoot is a nil-rooted single child tree, use the single
909        child as the new root node.
910
911          old=^(nil a b c), new=^(nil r) yields ^(r a b c)
912          old=^(a b c), new=^(nil r) yields ^(r ^(a b c))
913
914        If oldRoot was null, it's ok, just return newRoot (even if isNil).
915
916          old=null, new=r yields r
917          old=null, new=^(nil r) yields ^(nil r)
918
919        Return newRoot.  Throw an exception if newRoot is not a
920        simple node or nil root with a single child node--it must be a root
921        node.  If newRoot is ^(nil x) return x as newRoot.
922
923        Be advised that it's ok for newRoot to point at oldRoot's
924        children; i.e., you don't have to copy the list.  We are
925        constructing these nodes so we should have this control for
926        efficiency.
927        """
928
929    if isinstance(newRoot, Token):
930      newRoot = self.create(newRoot)
931
932    if oldRoot is None:
933      return newRoot
934
935    if not isinstance(newRoot, CommonTree):
936      newRoot = self.createWithPayload(newRoot)
937
938    # handle ^(nil real-node)
939    if newRoot.isNil():
940      nc = newRoot.getChildCount()
941      if nc == 1:
942        newRoot = newRoot.getChild(0)
943
944      elif nc > 1:
945        # TODO: make tree run time exceptions hierarchy
946        raise RuntimeError("more than one node as root")
947
948    # add oldRoot to newRoot; addChild takes care of case where oldRoot
949    # is a flat list (i.e., nil-rooted tree).  All children of oldRoot
950    # are added to newRoot.
951    newRoot.addChild(oldRoot)
952    return newRoot
953
954  def rulePostProcessing(self, root):
955    """Transform ^(nil x) to x and nil to null"""
956
957    if root is not None and root.isNil():
958      if root.getChildCount() == 0:
959        root = None
960
961      elif root.getChildCount() == 1:
962        root = root.getChild(0)
963        # whoever invokes rule will set parent and child index
964        root.setParent(None)
965        root.setChildIndex(-1)
966
967    return root
968
969  def createFromToken(self, tokenType, fromToken, text=None):
970    assert isinstance(tokenType, six.integer_types), type(tokenType).__name__
971    assert isinstance(fromToken, Token), type(fromToken).__name__
972    assert text is None or isinstance(text,
973                                      six.string_types), type(text).__name__
974
975    fromToken = self.createToken(fromToken)
976    fromToken.type = tokenType
977    if text is not None:
978      fromToken.text = text
979    t = self.createWithPayload(fromToken)
980    return t
981
982  def createFromType(self, tokenType, text):
983    assert isinstance(tokenType, six.integer_types), type(tokenType).__name__
984    assert isinstance(text, six.string_types), type(text).__name__
985
986    fromToken = self.createToken(tokenType=tokenType, text=text)
987    t = self.createWithPayload(fromToken)
988    return t
989
990  def getType(self, t):
991    return t.getType()
992
993  def setType(self, t, type):
994    raise RuntimeError("don't know enough about Tree node")
995
996  def getText(self, t):
997    return t.getText()
998
999  def setText(self, t, text):
1000    raise RuntimeError("don't know enough about Tree node")
1001
1002  def getChild(self, t, i):
1003    return t.getChild(i)
1004
1005  def setChild(self, t, i, child):
1006    t.setChild(i, child)
1007
1008  def deleteChild(self, t, i):
1009    return t.deleteChild(i)
1010
1011  def getChildCount(self, t):
1012    return t.getChildCount()
1013
1014  def getUniqueID(self, node):
1015    return hash(node)
1016
1017  def createToken(self, fromToken=None, tokenType=None, text=None):
1018    """
1019        Tell me how to create a token for use with imaginary token nodes.
1020        For example, there is probably no input symbol associated with imaginary
1021        token DECL, but you need to create it as a payload or whatever for
1022        the DECL node as in ^(DECL type ID).
1023
1024        If you care what the token payload objects' type is, you should
1025        override this method and any other createToken variant.
1026        """
1027
1028    raise NotImplementedError
1029
1030
1031############################################################################
1032#
1033# common tree implementation
1034#
1035# Tree
1036# \- BaseTree
1037#    \- CommonTree
1038#       \- CommonErrorNode
1039#
1040# TreeAdaptor
1041# \- BaseTreeAdaptor
1042#    \- CommonTreeAdaptor
1043#
1044############################################################################
1045
1046
1047class CommonTree(BaseTree):
1048  """@brief A tree node that is wrapper for a Token object.
1049
1050    After 3.0 release
1051    while building tree rewrite stuff, it became clear that computing
1052    parent and child index is very difficult and cumbersome.  Better to
1053    spend the space in every tree node.  If you don't want these extra
1054    fields, it's easy to cut them out in your own BaseTree subclass.
1055
1056    """
1057
1058  def __init__(self, payload):
1059    BaseTree.__init__(self)
1060
1061    # What token indexes bracket all tokens associated with this node
1062    # and below?
1063    self.startIndex = -1
1064    self.stopIndex = -1
1065
1066    # Who is the parent node of this node; if null, implies node is root
1067    self.parent = None
1068
1069    # What index is this node in the child list? Range: 0..n-1
1070    self.childIndex = -1
1071
1072    # A single token is the payload
1073    if payload is None:
1074      self.token = None
1075
1076    elif isinstance(payload, CommonTree):
1077      self.token = payload.token
1078      self.startIndex = payload.startIndex
1079      self.stopIndex = payload.stopIndex
1080
1081    elif payload is None or isinstance(payload, Token):
1082      self.token = payload
1083
1084    else:
1085      raise TypeError(type(payload).__name__)
1086
1087  def getToken(self):
1088    return self.token
1089
1090  def dupNode(self):
1091    return CommonTree(self)
1092
1093  def isNil(self):
1094    return self.token is None
1095
1096  def getType(self):
1097    if self.token is None:
1098      return INVALID_TOKEN_TYPE
1099
1100    return self.token.getType()
1101
1102  type = property(getType)
1103
1104  def getText(self):
1105    if self.token is None:
1106      return None
1107
1108    return self.token.text
1109
1110  text = property(getText)
1111
1112  def getLine(self):
1113    if self.token is None or self.token.getLine() == 0:
1114      if self.getChildCount():
1115        return self.getChild(0).getLine()
1116      else:
1117        return 0
1118
1119    return self.token.getLine()
1120
1121  line = property(getLine)
1122
1123  def getCharPositionInLine(self):
1124    if self.token is None or self.token.getCharPositionInLine() == -1:
1125      if self.getChildCount():
1126        return self.getChild(0).getCharPositionInLine()
1127      else:
1128        return 0
1129
1130    else:
1131      return self.token.getCharPositionInLine()
1132
1133  charPositionInLine = property(getCharPositionInLine)
1134
1135  def getTokenStartIndex(self):
1136    if self.startIndex == -1 and self.token is not None:
1137      return self.token.getTokenIndex()
1138
1139    return self.startIndex
1140
1141  def setTokenStartIndex(self, index):
1142    self.startIndex = index
1143
1144  tokenStartIndex = property(getTokenStartIndex, setTokenStartIndex)
1145
1146  def getTokenStopIndex(self):
1147    if self.stopIndex == -1 and self.token is not None:
1148      return self.token.getTokenIndex()
1149
1150    return self.stopIndex
1151
1152  def setTokenStopIndex(self, index):
1153    self.stopIndex = index
1154
1155  tokenStopIndex = property(getTokenStopIndex, setTokenStopIndex)
1156
1157  def getChildIndex(self):
1158    #FIXME: mark as deprecated
1159    return self.childIndex
1160
1161  def setChildIndex(self, idx):
1162    #FIXME: mark as deprecated
1163    self.childIndex = idx
1164
1165  def getParent(self):
1166    #FIXME: mark as deprecated
1167    return self.parent
1168
1169  def setParent(self, t):
1170    #FIXME: mark as deprecated
1171    self.parent = t
1172
1173  def toString(self):
1174    if self.isNil():
1175      return "nil"
1176
1177    if self.getType() == INVALID_TOKEN_TYPE:
1178      return "<errornode>"
1179
1180    return self.token.text
1181
1182  __str__ = toString
1183
1184  def toStringTree(self):
1185    if not self.children:
1186      return self.toString()
1187
1188    ret = ""
1189    if not self.isNil():
1190      ret += "(%s " % (self.toString())
1191
1192    ret += " ".join([child.toStringTree() for child in self.children])
1193
1194    if not self.isNil():
1195      ret += ")"
1196
1197    return ret
1198
1199
1200INVALID_NODE = CommonTree(INVALID_TOKEN)
1201
1202
1203class CommonErrorNode(CommonTree):
1204  """A node representing erroneous token range in token stream"""
1205
1206  def __init__(self, input, start, stop, exc):
1207    CommonTree.__init__(self, None)
1208
1209    if (stop is None or (stop.getTokenIndex() < start.getTokenIndex() and
1210                         stop.getType() != EOF)):
1211      # sometimes resync does not consume a token (when LT(1) is
1212      # in follow set.  So, stop will be 1 to left to start. adjust.
1213      # Also handle case where start is the first token and no token
1214      # is consumed during recovery; LT(-1) will return null.
1215      stop = start
1216
1217    self.input = input
1218    self.start = start
1219    self.stop = stop
1220    self.trappedException = exc
1221
1222  def isNil(self):
1223    return False
1224
1225  def getType(self):
1226    return INVALID_TOKEN_TYPE
1227
1228  def getText(self):
1229    if isinstance(self.start, Token):
1230      i = self.start.getTokenIndex()
1231      j = self.stop.getTokenIndex()
1232      if self.stop.getType() == EOF:
1233        j = self.input.size()
1234
1235      badText = self.input.toString(i, j)
1236
1237    elif isinstance(self.start, Tree):
1238      badText = self.input.toString(self.start, self.stop)
1239
1240    else:
1241      # people should subclass if they alter the tree type so this
1242      # next one is for sure correct.
1243      badText = "<unknown>"
1244
1245    return badText
1246
1247  def toString(self):
1248    if isinstance(self.trappedException, MissingTokenException):
1249      return ("<missing type: " + str(self.trappedException.getMissingType()) +
1250              ">")
1251
1252    elif isinstance(self.trappedException, UnwantedTokenException):
1253      return ("<extraneous: " +
1254              str(self.trappedException.getUnexpectedToken()) + ", resync=" +
1255              self.getText() + ">")
1256
1257    elif isinstance(self.trappedException, MismatchedTokenException):
1258      return ("<mismatched token: " + str(self.trappedException.token) +
1259              ", resync=" + self.getText() + ">")
1260
1261    elif isinstance(self.trappedException, NoViableAltException):
1262      return ("<unexpected: " + str(self.trappedException.token) + ", resync=" +
1263              self.getText() + ">")
1264
1265    return "<error: " + self.getText() + ">"
1266
1267
1268class CommonTreeAdaptor(BaseTreeAdaptor):
1269  """
1270    @brief A TreeAdaptor that works with any Tree implementation.
1271
1272    It provides
1273    really just factory methods; all the work is done by BaseTreeAdaptor.
1274    If you would like to have different tokens created than ClassicToken
1275    objects, you need to override this and then set the parser tree adaptor to
1276    use your subclass.
1277
1278    To get your parser to build nodes of a different type, override
1279    create(Token).
1280    """
1281
1282  def dupNode(self, treeNode):
1283    """
1284        Duplicate a node.  This is part of the factory;
1285        override if you want another kind of node to be built.
1286
1287        I could use reflection to prevent having to override this
1288        but reflection is slow.
1289        """
1290
1291    if treeNode is None:
1292      return None
1293
1294    return treeNode.dupNode()
1295
1296  def createWithPayload(self, payload):
1297    return CommonTree(payload)
1298
1299  def createToken(self, fromToken=None, tokenType=None, text=None):
1300    """
1301        Tell me how to create a token for use with imaginary token nodes.
1302        For example, there is probably no input symbol associated with imaginary
1303        token DECL, but you need to create it as a payload or whatever for
1304        the DECL node as in ^(DECL type ID).
1305
1306        If you care what the token payload objects' type is, you should
1307        override this method and any other createToken variant.
1308        """
1309
1310    if fromToken is not None:
1311      return CommonToken(oldToken=fromToken)
1312
1313    return CommonToken(type=tokenType, text=text)
1314
1315  def setTokenBoundaries(self, t, startToken, stopToken):
1316    """
1317        Track start/stop token for subtree root created for a rule.
1318        Only works with Tree nodes.  For rules that match nothing,
1319        seems like this will yield start=i and stop=i-1 in a nil node.
1320        Might be useful info so I'll not force to be i..i.
1321        """
1322
1323    if t is None:
1324      return
1325
1326    start = 0
1327    stop = 0
1328
1329    if startToken is not None:
1330      start = startToken.index
1331
1332    if stopToken is not None:
1333      stop = stopToken.index
1334
1335    t.setTokenStartIndex(start)
1336    t.setTokenStopIndex(stop)
1337
1338  def getTokenStartIndex(self, t):
1339    if t is None:
1340      return -1
1341    return t.getTokenStartIndex()
1342
1343  def getTokenStopIndex(self, t):
1344    if t is None:
1345      return -1
1346    return t.getTokenStopIndex()
1347
1348  def getText(self, t):
1349    if t is None:
1350      return None
1351    return t.getText()
1352
1353  def getType(self, t):
1354    if t is None:
1355      return INVALID_TOKEN_TYPE
1356
1357    return t.getType()
1358
1359  def getToken(self, t):
1360    """
1361        What is the Token associated with this node?  If
1362        you are not using CommonTree, then you must
1363        override this in your own adaptor.
1364        """
1365
1366    if isinstance(t, CommonTree):
1367      return t.getToken()
1368
1369    return None  # no idea what to do
1370
1371  def getChild(self, t, i):
1372    if t is None:
1373      return None
1374    return t.getChild(i)
1375
1376  def getChildCount(self, t):
1377    if t is None:
1378      return 0
1379    return t.getChildCount()
1380
1381  def getParent(self, t):
1382    return t.getParent()
1383
1384  def setParent(self, t, parent):
1385    t.setParent(parent)
1386
1387  def getChildIndex(self, t):
1388    return t.getChildIndex()
1389
1390  def setChildIndex(self, t, index):
1391    t.setChildIndex(index)
1392
1393  def replaceChildren(self, parent, startChildIndex, stopChildIndex, t):
1394    if parent is not None:
1395      parent.replaceChildren(startChildIndex, stopChildIndex, t)
1396
1397
1398############################################################################
1399#
1400# streams
1401#
1402# TreeNodeStream
1403# \- BaseTree
1404#    \- CommonTree
1405#
1406# TreeAdaptor
1407# \- BaseTreeAdaptor
1408#    \- CommonTreeAdaptor
1409#
1410############################################################################
1411
1412
1413
1414class TreeNodeStream(IntStream):
1415  """@brief A stream of tree nodes
1416
1417    It accessing nodes from a tree of some kind.
1418    """
1419
1420  # TreeNodeStream is abstract, no need to complain about not implemented
1421  # abstract methods
1422  # pylint: disable-msg=W0223
1423
1424  def get(self, i):
1425    """Get a tree node at an absolute index i; 0..n-1.
1426
1427        If you don't want to buffer up nodes, then this method makes no
1428        sense for you.
1429        """
1430
1431    raise NotImplementedError
1432
1433  def LT(self, k):
1434    """
1435        Get tree node at current input pointer + i ahead where i=1 is next node.
1436        i<0 indicates nodes in the past.  So LT(-1) is previous node, but
1437        implementations are not required to provide results for k < -1.
1438        LT(0) is undefined.  For i>=n, return null.
1439        Return null for LT(0) and any index that results in an absolute address
1440        that is negative.
1441
1442        This is analogus to the LT() method of the TokenStream, but this
1443        returns a tree node instead of a token.  Makes code gen identical
1444        for both parser and tree grammars. :)
1445        """
1446
1447    raise NotImplementedError
1448
1449  def getTreeSource(self):
1450    """
1451        Where is this stream pulling nodes from?  This is not the name, but
1452        the object that provides node objects.
1453        """
1454
1455    raise NotImplementedError
1456
1457  def getTokenStream(self):
1458    """
1459        If the tree associated with this stream was created from a TokenStream,
1460        you can specify it here.  Used to do rule $text attribute in tree
1461        parser.  Optional unless you use tree parser rule text attribute
1462        or output=template and rewrite=true options.
1463        """
1464
1465    raise NotImplementedError
1466
1467  def getTreeAdaptor(self):
1468    """
1469        What adaptor can tell me how to interpret/navigate nodes and
1470        trees.  E.g., get text of a node.
1471        """
1472
1473    raise NotImplementedError
1474
1475  def setUniqueNavigationNodes(self, uniqueNavigationNodes):
1476    """
1477        As we flatten the tree, we use UP, DOWN nodes to represent
1478        the tree structure.  When debugging we need unique nodes
1479        so we have to instantiate new ones.  When doing normal tree
1480        parsing, it's slow and a waste of memory to create unique
1481        navigation nodes.  Default should be false;
1482        """
1483
1484    raise NotImplementedError
1485
1486  def toString(self, start, stop):
1487    """
1488        Return the text of all nodes from start to stop, inclusive.
1489        If the stream does not buffer all the nodes then it can still
1490        walk recursively from start until stop.  You can always return
1491        null or "" too, but users should not access $ruleLabel.text in
1492        an action of course in that case.
1493        """
1494
1495    raise NotImplementedError
1496
1497  # REWRITING TREES (used by tree parser)
1498  def replaceChildren(self, parent, startChildIndex, stopChildIndex, t):
1499    """
1500        Replace from start to stop child index of parent with t, which might
1501        be a list.  Number of children may be different
1502        after this call.  The stream is notified because it is walking the
1503        tree and might need to know you are monkeying with the underlying
1504        tree.  Also, it might be able to modify the node stream to avoid
1505        restreaming for future phases.
1506
1507        If parent is null, don't do anything; must be at root of overall tree.
1508        Can't replace whatever points to the parent externally.  Do nothing.
1509        """
1510
1511    raise NotImplementedError
1512
1513
1514class CommonTreeNodeStream(TreeNodeStream):
1515  """@brief A buffered stream of tree nodes.
1516
1517    Nodes can be from a tree of ANY kind.
1518
1519    This node stream sucks all nodes out of the tree specified in
1520    the constructor during construction and makes pointers into
1521    the tree using an array of Object pointers. The stream necessarily
1522    includes pointers to DOWN and UP and EOF nodes.
1523
1524    This stream knows how to mark/release for backtracking.
1525
1526    This stream is most suitable for tree interpreters that need to
1527    jump around a lot or for tree parsers requiring speed (at cost of memory).
1528    There is some duplicated functionality here with UnBufferedTreeNodeStream
1529    but just in bookkeeping, not tree walking etc...
1530
1531    @see UnBufferedTreeNodeStream
1532    """
1533
1534  def __init__(self, *args):
1535    TreeNodeStream.__init__(self)
1536
1537    if len(args) == 1:
1538      adaptor = CommonTreeAdaptor()
1539      tree = args[0]
1540
1541    elif len(args) == 2:
1542      adaptor = args[0]
1543      tree = args[1]
1544
1545    else:
1546      raise TypeError("Invalid arguments")
1547
1548    # all these navigation nodes are shared and hence they
1549    # cannot contain any line/column info
1550    self.down = adaptor.createFromType(DOWN, "DOWN")
1551    self.up = adaptor.createFromType(UP, "UP")
1552    self.eof = adaptor.createFromType(EOF, "EOF")
1553
1554    # The complete mapping from stream index to tree node.
1555    # This buffer includes pointers to DOWN, UP, and EOF nodes.
1556    # It is built upon ctor invocation.  The elements are type
1557    #  Object as we don't what the trees look like.
1558
1559    # Load upon first need of the buffer so we can set token types
1560    # of interest for reverseIndexing.  Slows us down a wee bit to
1561    # do all of the if p==-1 testing everywhere though.
1562    self.nodes = []
1563
1564    # Pull nodes from which tree?
1565    self.root = tree
1566
1567    # IF this tree (root) was created from a token stream, track it.
1568    self.tokens = None
1569
1570    # What tree adaptor was used to build these trees
1571    self.adaptor = adaptor
1572
1573    # Reuse same DOWN, UP navigation nodes unless this is true
1574    self.uniqueNavigationNodes = False
1575
1576    # The index into the nodes list of the current node (next node
1577    # to consume).  If -1, nodes array not filled yet.
1578    self.p = -1
1579
1580    # Track the last mark() call result value for use in rewind().
1581    self.lastMarker = None
1582
1583    # Stack of indexes used for push/pop calls
1584    self.calls = []
1585
1586  def fillBuffer(self):
1587    """Walk tree with depth-first-search and fill nodes buffer.
1588
1589        Don't do DOWN, UP nodes if its a list (t is isNil).
1590        """
1591
1592    self._fillBuffer(self.root)
1593    self.p = 0  # buffer of nodes intialized now
1594
1595  def _fillBuffer(self, t):
1596    nil = self.adaptor.isNil(t)
1597
1598    if not nil:
1599      self.nodes.append(t)  # add this node
1600
1601    # add DOWN node if t has children
1602    n = self.adaptor.getChildCount(t)
1603    if not nil and n > 0:
1604      self.addNavigationNode(DOWN)
1605
1606    # and now add all its children
1607    for c in range(n):
1608      self._fillBuffer(self.adaptor.getChild(t, c))
1609
1610    # add UP node if t has children
1611    if not nil and n > 0:
1612      self.addNavigationNode(UP)
1613
1614  def getNodeIndex(self, node):
1615    """What is the stream index for node?
1616
1617    0..n-1
1618        Return -1 if node not found.
1619        """
1620
1621    if self.p == -1:
1622      self.fillBuffer()
1623
1624    for i, t in enumerate(self.nodes):
1625      if t == node:
1626        return i
1627
1628    return -1
1629
1630  def addNavigationNode(self, ttype):
1631    """
1632        As we flatten the tree, we use UP, DOWN nodes to represent
1633        the tree structure.  When debugging we need unique nodes
1634        so instantiate new ones when uniqueNavigationNodes is true.
1635        """
1636
1637    navNode = None
1638
1639    if ttype == DOWN:
1640      if self.hasUniqueNavigationNodes():
1641        navNode = self.adaptor.createFromType(DOWN, "DOWN")
1642
1643      else:
1644        navNode = self.down
1645
1646    else:
1647      if self.hasUniqueNavigationNodes():
1648        navNode = self.adaptor.createFromType(UP, "UP")
1649
1650      else:
1651        navNode = self.up
1652
1653    self.nodes.append(navNode)
1654
1655  def get(self, i):
1656    if self.p == -1:
1657      self.fillBuffer()
1658
1659    return self.nodes[i]
1660
1661  def LT(self, k):
1662    if self.p == -1:
1663      self.fillBuffer()
1664
1665    if k == 0:
1666      return None
1667
1668    if k < 0:
1669      return self.LB(-k)
1670
1671    #System.out.print("LT(p="+p+","+k+")=");
1672    if self.p + k - 1 >= len(self.nodes):
1673      return self.eof
1674
1675    return self.nodes[self.p + k - 1]
1676
1677  def getCurrentSymbol(self):
1678    return self.LT(1)
1679
1680  def LB(self, k):
1681    """Look backwards k nodes"""
1682
1683    if k == 0:
1684      return None
1685
1686    if self.p - k < 0:
1687      return None
1688
1689    return self.nodes[self.p - k]
1690
1691  def getTreeSource(self):
1692    return self.root
1693
1694  def getSourceName(self):
1695    return self.getTokenStream().getSourceName()
1696
1697  def getTokenStream(self):
1698    return self.tokens
1699
1700  def setTokenStream(self, tokens):
1701    self.tokens = tokens
1702
1703  def getTreeAdaptor(self):
1704    return self.adaptor
1705
1706  def hasUniqueNavigationNodes(self):
1707    return self.uniqueNavigationNodes
1708
1709  def setUniqueNavigationNodes(self, uniqueNavigationNodes):
1710    self.uniqueNavigationNodes = uniqueNavigationNodes
1711
1712  def consume(self):
1713    if self.p == -1:
1714      self.fillBuffer()
1715
1716    self.p += 1
1717
1718  def LA(self, i):
1719    return self.adaptor.getType(self.LT(i))
1720
1721  def mark(self):
1722    if self.p == -1:
1723      self.fillBuffer()
1724
1725    self.lastMarker = self.index()
1726    return self.lastMarker
1727
1728  def release(self, marker=None):
1729    # no resources to release
1730
1731    pass
1732
1733  def index(self):
1734    return self.p
1735
1736  def rewind(self, marker=None):
1737    if marker is None:
1738      marker = self.lastMarker
1739
1740    self.seek(marker)
1741
1742  def seek(self, index):
1743    if self.p == -1:
1744      self.fillBuffer()
1745
1746    self.p = index
1747
1748  def push(self, index):
1749    """
1750        Make stream jump to a new location, saving old location.
1751        Switch back with pop().
1752        """
1753
1754    self.calls.append(self.p)  # save current index
1755    self.seek(index)
1756
1757  def pop(self):
1758    """
1759        Seek back to previous index saved during last push() call.
1760        Return top of stack (return index).
1761        """
1762
1763    ret = self.calls.pop(-1)
1764    self.seek(ret)
1765    return ret
1766
1767  def reset(self):
1768    self.p = 0
1769    self.lastMarker = 0
1770    self.calls = []
1771
1772  def size(self):
1773    if self.p == -1:
1774      self.fillBuffer()
1775
1776    return len(self.nodes)
1777
1778  # TREE REWRITE INTERFACE
1779
1780  def replaceChildren(self, parent, startChildIndex, stopChildIndex, t):
1781    if parent is not None:
1782      self.adaptor.replaceChildren(parent, startChildIndex, stopChildIndex, t)
1783
1784  def __str__(self):
1785    """Used for testing, just return the token type stream"""
1786
1787    if self.p == -1:
1788      self.fillBuffer()
1789
1790    return " ".join([str(self.adaptor.getType(node)) for node in self.nodes])
1791
1792  def toString(self, start, stop):
1793    if start is None or stop is None:
1794      return None
1795
1796    if self.p == -1:
1797      self.fillBuffer()
1798
1799    #System.out.println("stop: "+stop);
1800    #if ( start instanceof CommonTree )
1801    #    System.out.print("toString: "+((CommonTree)start).getToken()+", ");
1802    #else
1803    #    System.out.println(start);
1804    #if ( stop instanceof CommonTree )
1805    #    System.out.println(((CommonTree)stop).getToken());
1806    #else
1807    #    System.out.println(stop);
1808
1809    # if we have the token stream, use that to dump text in order
1810    if self.tokens is not None:
1811      beginTokenIndex = self.adaptor.getTokenStartIndex(start)
1812      endTokenIndex = self.adaptor.getTokenStopIndex(stop)
1813
1814      # if it's a tree, use start/stop index from start node
1815      # else use token range from start/stop nodes
1816      if self.adaptor.getType(stop) == UP:
1817        endTokenIndex = self.adaptor.getTokenStopIndex(start)
1818
1819      elif self.adaptor.getType(stop) == EOF:
1820        endTokenIndex = self.size() - 2  # don't use EOF
1821
1822      return self.tokens.toString(beginTokenIndex, endTokenIndex)
1823
1824    # walk nodes looking for start
1825    i, t = 0, None
1826    for i, t in enumerate(self.nodes):
1827      if t == start:
1828        break
1829
1830    # now walk until we see stop, filling string buffer with text
1831    buf = []
1832    t = self.nodes[i]
1833    while t != stop:
1834      text = self.adaptor.getText(t)
1835      if text is None:
1836        text = " " + self.adaptor.getType(t)
1837
1838      buf.append(text)
1839      i += 1
1840      t = self.nodes[i]
1841
1842    # include stop node too
1843    text = self.adaptor.getText(stop)
1844    if text is None:
1845      text = " " + self.adaptor.getType(stop)
1846
1847    buf.append(text)
1848
1849    return "".join(buf)
1850
1851  ## iterator interface
1852  def __iter__(self):
1853    if self.p == -1:
1854      self.fillBuffer()
1855
1856    for node in self.nodes:
1857      yield node
1858
1859
1860#############################################################################
1861#
1862# tree parser
1863#
1864#############################################################################
1865
1866class TreeParser(BaseRecognizer):
1867  """@brief Baseclass for generated tree parsers.
1868
1869    A parser for a stream of tree nodes.  "tree grammars" result in a subclass
1870    of this.  All the error reporting and recovery is shared with Parser via
1871    the BaseRecognizer superclass.
1872    """
1873
1874  def __init__(self, input, state=None):
1875    BaseRecognizer.__init__(self, state)
1876
1877    self.input = None
1878    self.setTreeNodeStream(input)
1879
1880  def reset(self):
1881    BaseRecognizer.reset(self)  # reset all recognizer state variables
1882    if self.input is not None:
1883      self.input.seek(0)  # rewind the input
1884
1885  def setTreeNodeStream(self, input):
1886    """Set the input stream"""
1887
1888    self.input = input
1889
1890  def getTreeNodeStream(self):
1891    return self.input
1892
1893  def getSourceName(self):
1894    return self.input.getSourceName()
1895
1896  def getCurrentInputSymbol(self, input):
1897    return input.LT(1)
1898
1899  def getMissingSymbol(self, input, e, expectedTokenType, follow):
1900    tokenText = "<missing " + self.tokenNames[expectedTokenType] + ">"
1901    return CommonTree(CommonToken(type=expectedTokenType, text=tokenText))
1902
1903  def matchAny(self, ignore):  # ignore stream, copy of this.input
1904    """
1905        Match '.' in tree parser has special meaning.  Skip node or
1906        entire tree if node has children.  If children, scan until
1907        corresponding UP node.
1908        """
1909
1910    self._state.errorRecovery = False
1911
1912    look = self.input.LT(1)
1913    if self.input.getTreeAdaptor().getChildCount(look) == 0:
1914      self.input.consume()  # not subtree, consume 1 node and return
1915      return
1916
1917    # current node is a subtree, skip to corresponding UP.
1918    # must count nesting level to get right UP
1919    level = 0
1920    tokenType = self.input.getTreeAdaptor().getType(look)
1921    while tokenType != EOF and not (tokenType == UP and level == 0):
1922      self.input.consume()
1923      look = self.input.LT(1)
1924      tokenType = self.input.getTreeAdaptor().getType(look)
1925      if tokenType == DOWN:
1926        level += 1
1927
1928      elif tokenType == UP:
1929        level -= 1
1930
1931    self.input.consume()  # consume UP
1932
1933  def mismatch(self, input, ttype, follow):
1934    """
1935        We have DOWN/UP nodes in the stream that have no line info; override.
1936        plus we want to alter the exception type. Don't try to recover
1937        from tree parser errors inline...
1938        """
1939
1940    raise MismatchedTreeNodeException(ttype, input)
1941
1942  def getErrorHeader(self, e):
1943    """
1944        Prefix error message with the grammar name because message is
1945        always intended for the programmer because the parser built
1946        the input tree not the user.
1947        """
1948
1949    return (
1950        self.getGrammarFileName() + ": node from %sline %s:%s" %
1951        (["", "after "][e.approximateLineInfo], e.line, e.charPositionInLine))
1952
1953  def getErrorMessage(self, e, tokenNames):
1954    """
1955        Tree parsers parse nodes they usually have a token object as
1956        payload. Set the exception token and do the default behavior.
1957        """
1958
1959    if isinstance(self, TreeParser):
1960      adaptor = e.input.getTreeAdaptor()
1961      e.token = adaptor.getToken(e.node)
1962      if e.token is not None:  # could be an UP/DOWN node
1963        e.token = CommonToken(
1964            type=adaptor.getType(e.node), text=adaptor.getText(e.node))
1965
1966    return BaseRecognizer.getErrorMessage(self, e, tokenNames)
1967
1968  def traceIn(self, ruleName, ruleIndex):
1969    BaseRecognizer.traceIn(self, ruleName, ruleIndex, self.input.LT(1))
1970
1971  def traceOut(self, ruleName, ruleIndex):
1972    BaseRecognizer.traceOut(self, ruleName, ruleIndex, self.input.LT(1))
1973
1974
1975#############################################################################
1976#
1977# streams for rule rewriting
1978#
1979#############################################################################
1980
1981class RewriteRuleElementStream(object):
1982  """@brief Internal helper class.
1983
1984    A generic list of elements tracked in an alternative to be used in
1985    a -> rewrite rule.  We need to subclass to fill in the next() method,
1986    which returns either an AST node wrapped around a token payload or
1987    an existing subtree.
1988
1989    Once you start next()ing, do not try to add more elements.  It will
1990    break the cursor tracking I believe.
1991
1992    @see org.antlr.runtime.tree.RewriteRuleSubtreeStream
1993    @see org.antlr.runtime.tree.RewriteRuleTokenStream
1994
1995    TODO: add mechanism to detect/puke on modification after reading from
1996    stream
1997    """
1998
1999  def __init__(self, adaptor, elementDescription, elements=None):
2000    # Cursor 0..n-1.  If singleElement!=null, cursor is 0 until you next(),
2001    # which bumps it to 1 meaning no more elements.
2002    self.cursor = 0
2003
2004    # Track single elements w/o creating a list.  Upon 2nd add, alloc list
2005    self.singleElement = None
2006
2007    # The list of tokens or subtrees we are tracking
2008    self.elements = None
2009
2010    # Once a node / subtree has been used in a stream, it must be dup'd
2011    # from then on.  Streams are reset after subrules so that the streams
2012    # can be reused in future subrules.  So, reset must set a dirty bit.
2013    # If dirty, then next() always returns a dup.
2014    self.dirty = False
2015
2016    # The element or stream description; usually has name of the token or
2017    # rule reference that this list tracks.  Can include rulename too, but
2018    # the exception would track that info.
2019    self.elementDescription = elementDescription
2020
2021    self.adaptor = adaptor
2022
2023    if isinstance(elements, (list, tuple)):
2024      # Create a stream, but feed off an existing list
2025      self.singleElement = None
2026      self.elements = elements
2027
2028    else:
2029      # Create a stream with one element
2030      self.add(elements)
2031
2032  def reset(self):
2033    """
2034        Reset the condition of this stream so that it appears we have
2035        not consumed any of its elements.  Elements themselves are untouched.
2036        Once we reset the stream, any future use will need duplicates.  Set
2037        the dirty bit.
2038        """
2039
2040    self.cursor = 0
2041    self.dirty = True
2042
2043  def add(self, el):
2044    if el is None:
2045      return
2046
2047    if self.elements is not None:  # if in list, just add
2048      self.elements.append(el)
2049      return
2050
2051    if self.singleElement is None:  # no elements yet, track w/o list
2052      self.singleElement = el
2053      return
2054
2055    # adding 2nd element, move to list
2056    self.elements = []
2057    self.elements.append(self.singleElement)
2058    self.singleElement = None
2059    self.elements.append(el)
2060
2061  def nextTree(self):
2062    """
2063        Return the next element in the stream.  If out of elements, throw
2064        an exception unless size()==1.  If size is 1, then return elements[0].
2065
2066        Return a duplicate node/subtree if stream is out of elements and
2067        size==1. If we've already used the element, dup (dirty bit set).
2068        """
2069
2070    if (self.dirty or (self.cursor >= len(self) and len(self) == 1)):
2071      # if out of elements and size is 1, dup
2072      el = self._next()
2073      return self.dup(el)
2074
2075    # test size above then fetch
2076    el = self._next()
2077    return el
2078
2079  def _next(self):
2080    """
2081        do the work of getting the next element, making sure that it's
2082        a tree node or subtree.  Deal with the optimization of single-
2083        element list versus list of size > 1.  Throw an exception
2084        if the stream is empty or we're out of elements and size>1.
2085        protected so you can override in a subclass if necessary.
2086        """
2087
2088    if len(self) == 0:
2089      raise RewriteEmptyStreamException(self.elementDescription)
2090
2091    if self.cursor >= len(self):  # out of elements?
2092      if len(self) == 1:  # if size is 1, it's ok; return and we'll dup
2093        return self.toTree(self.singleElement)
2094
2095      # out of elements and size was not 1, so we can't dup
2096      raise RewriteCardinalityException(self.elementDescription)
2097
2098    # we have elements
2099    if self.singleElement is not None:
2100      self.cursor += 1  # move cursor even for single element list
2101      return self.toTree(self.singleElement)
2102
2103    # must have more than one in list, pull from elements
2104    o = self.toTree(self.elements[self.cursor])
2105    self.cursor += 1
2106    return o
2107
2108  def dup(self, el):
2109    """
2110        When constructing trees, sometimes we need to dup a token or AST
2111        subtree.  Dup'ing a token means just creating another AST node
2112        around it.  For trees, you must call the adaptor.dupTree() unless
2113        the element is for a tree root; then it must be a node dup.
2114        """
2115
2116    raise NotImplementedError
2117
2118  def toTree(self, el):
2119    """
2120        Ensure stream emits trees; tokens must be converted to AST nodes.
2121        AST nodes can be passed through unmolested.
2122        """
2123
2124    return el
2125
2126  def hasNext(self):
2127    return ((self.singleElement is not None and self.cursor < 1) or
2128            (self.elements is not None and self.cursor < len(self.elements)))
2129
2130  def size(self):
2131    if self.singleElement is not None:
2132      return 1
2133
2134    if self.elements is not None:
2135      return len(self.elements)
2136
2137    return 0
2138
2139  __len__ = size
2140
2141  def getDescription(self):
2142    """Deprecated. Directly access elementDescription attribute"""
2143
2144    return self.elementDescription
2145
2146
2147class RewriteRuleTokenStream(RewriteRuleElementStream):
2148  """@brief Internal helper class."""
2149
2150  def toTree(self, el):
2151    # Don't convert to a tree unless they explicitly call nextTree.
2152    # This way we can do hetero tree nodes in rewrite.
2153    return el
2154
2155  def nextNode(self):
2156    t = self._next()
2157    return self.adaptor.createWithPayload(t)
2158
2159  def nextToken(self):
2160    return self._next()
2161
2162  def dup(self, el):
2163    raise TypeError("dup can't be called for a token stream.")
2164
2165
2166class RewriteRuleSubtreeStream(RewriteRuleElementStream):
2167  """@brief Internal helper class."""
2168
2169  def nextNode(self):
2170    """
2171        Treat next element as a single node even if it's a subtree.
2172        This is used instead of next() when the result has to be a
2173        tree root node.  Also prevents us from duplicating recently-added
2174        children; e.g., ^(type ID)+ adds ID to type and then 2nd iteration
2175        must dup the type node, but ID has been added.
2176
2177        Referencing a rule result twice is ok; dup entire tree as
2178        we can't be adding trees as root; e.g., expr expr.
2179
2180        Hideous code duplication here with super.next().  Can't think of
2181        a proper way to refactor.  This needs to always call dup node
2182        and super.next() doesn't know which to call: dup node or dup tree.
2183        """
2184
2185    if (self.dirty or (self.cursor >= len(self) and len(self) == 1)):
2186      # if out of elements and size is 1, dup (at most a single node
2187      # since this is for making root nodes).
2188      el = self._next()
2189      return self.adaptor.dupNode(el)
2190
2191    # test size above then fetch
2192    el = self._next()
2193    return el
2194
2195  def dup(self, el):
2196    return self.adaptor.dupTree(el)
2197
2198
2199
2200class RewriteRuleNodeStream(RewriteRuleElementStream):
2201  """
2202    Queues up nodes matched on left side of -> in a tree parser. This is
2203    the analog of RewriteRuleTokenStream for normal parsers.
2204    """
2205
2206  def nextNode(self):
2207    return self._next()
2208
2209  def toTree(self, el):
2210    return self.adaptor.dupNode(el)
2211
2212  def dup(self, el):
2213    # we dup every node, so don't have to worry about calling dup; short-
2214    #circuited next() so it doesn't call.
2215    raise TypeError("dup can't be called for a node stream.")
2216
2217
2218class TreeRuleReturnScope(RuleReturnScope):
2219  """
2220    This is identical to the ParserRuleReturnScope except that
2221    the start property is a tree nodes not Token object
2222    when you are parsing trees.  To be generic the tree node types
2223    have to be Object.
2224    """
2225
2226  def __init__(self):
2227    self.start = None
2228    self.tree = None
2229
2230  def getStart(self):
2231    return self.start
2232
2233  def getTree(self):
2234    return self.tree
2235