annotate Lib/lib2to3/pytree.py @ 54294:dba767bc3155 legacy-trunk

remove mention of old ctypes version
author Benjamin Peterson <benjamin@python.org>
date Sat, 23 May 2009 20:59:09 +0000
parents 119e4323400d
children 7700408f65fc
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
1 # Copyright 2006 Google, Inc. All Rights Reserved.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
2 # Licensed to PSF under a Contributor Agreement.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
3
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
4 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
5 Python parse tree definitions.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
6
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
7 This is a very concrete parse tree; we need to keep every token and
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
8 even the comments and whitespace between tokens.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
9
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
10 There's also a pattern matching implementation here.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
11 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
12
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
13 __author__ = "Guido van Rossum <guido@python.org>"
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
14
49885
0607c97a8124 Merged revisions 67428 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 49431
diff changeset
15 import sys
0607c97a8124 Merged revisions 67428 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 49431
diff changeset
16 from StringIO import StringIO
0607c97a8124 Merged revisions 67428 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 49431
diff changeset
17
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
18
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
19 HUGE = 0x7FFFFFFF # maximum repeat count, default max
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
20
45992
e47c3c7bbddc Merged revisions 61602-61723 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45906
diff changeset
21 _type_reprs = {}
e47c3c7bbddc Merged revisions 61602-61723 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45906
diff changeset
22 def type_repr(type_num):
e47c3c7bbddc Merged revisions 61602-61723 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45906
diff changeset
23 global _type_reprs
e47c3c7bbddc Merged revisions 61602-61723 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45906
diff changeset
24 if not _type_reprs:
e47c3c7bbddc Merged revisions 61602-61723 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45906
diff changeset
25 from .pygram import python_symbols
e47c3c7bbddc Merged revisions 61602-61723 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45906
diff changeset
26 # printing tokens is possible but not as useful
e47c3c7bbddc Merged revisions 61602-61723 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45906
diff changeset
27 # from .pgen2 import token // token.__dict__.items():
e47c3c7bbddc Merged revisions 61602-61723 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45906
diff changeset
28 for name, val in python_symbols.__dict__.items():
e47c3c7bbddc Merged revisions 61602-61723 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45906
diff changeset
29 if type(val) == int: _type_reprs[val] = name
e47c3c7bbddc Merged revisions 61602-61723 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45906
diff changeset
30 return _type_reprs.setdefault(type_num, type_num)
e47c3c7bbddc Merged revisions 61602-61723 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45906
diff changeset
31
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
32
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
33 class Base(object):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
34
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
35 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
36 Abstract base class for Node and Leaf.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
37
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
38 This provides some default functionality and boilerplate using the
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
39 template pattern.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
40
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
41 A node may be a subnode of at most one parent.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
42 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
43
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
44 # Default values for instance variables
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
45 type = None # int: token number (< 256) or symbol number (>= 256)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
46 parent = None # Parent node pointer, or None
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
47 children = () # Tuple of subnodes
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
48 was_changed = False
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
49
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
50 def __new__(cls, *args, **kwds):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
51 """Constructor that prevents Base from being instantiated."""
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
52 assert cls is not Base, "Cannot instantiate Base"
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
53 return object.__new__(cls)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
54
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
55 def __eq__(self, other):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
56 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
57 Compare two nodes for equality.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
58
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
59 This calls the method _eq().
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
60 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
61 if self.__class__ is not other.__class__:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
62 return NotImplemented
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
63 return self._eq(other)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
64
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
65 def __ne__(self, other):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
66 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
67 Compare two nodes for inequality.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
68
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
69 This calls the method _eq().
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
70 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
71 if self.__class__ is not other.__class__:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
72 return NotImplemented
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
73 return not self._eq(other)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
74
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
75 def _eq(self, other):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
76 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
77 Compare two nodes for equality.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
78
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
79 This is called by __eq__ and __ne__. It is only called if the two nodes
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
80 have the same type. This must be implemented by the concrete subclass.
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
81 Nodes should be considered equal if they have the same structure,
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
82 ignoring the prefix string and other context information.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
83 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
84 raise NotImplementedError
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
85
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
86 def clone(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
87 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
88 Return a cloned (deep) copy of self.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
89
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
90 This must be implemented by the concrete subclass.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
91 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
92 raise NotImplementedError
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
93
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
94 def post_order(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
95 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
96 Return a post-order iterator for the tree.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
97
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
98 This must be implemented by the concrete subclass.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
99 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
100 raise NotImplementedError
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
101
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
102 def pre_order(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
103 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
104 Return a pre-order iterator for the tree.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
105
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
106 This must be implemented by the concrete subclass.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
107 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
108 raise NotImplementedError
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
109
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
110 def set_prefix(self, prefix):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
111 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
112 Set the prefix for the node (see Leaf class).
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
113
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
114 This must be implemented by the concrete subclass.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
115 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
116 raise NotImplementedError
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
117
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
118 def get_prefix(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
119 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
120 Return the prefix for the node (see Leaf class).
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
121
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
122 This must be implemented by the concrete subclass.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
123 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
124 raise NotImplementedError
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
125
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
126 def replace(self, new):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
127 """Replace this node with a new one in the parent."""
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
128 assert self.parent is not None, str(self)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
129 assert new is not None
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
130 if not isinstance(new, list):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
131 new = [new]
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
132 l_children = []
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
133 found = False
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
134 for ch in self.parent.children:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
135 if ch is self:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
136 assert not found, (self.parent.children, self, new)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
137 if new is not None:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
138 l_children.extend(new)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
139 found = True
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
140 else:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
141 l_children.append(ch)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
142 assert found, (self.children, self, new)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
143 self.parent.changed()
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
144 self.parent.children = l_children
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
145 for x in new:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
146 x.parent = self.parent
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
147 self.parent = None
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
148
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
149 def get_lineno(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
150 """Return the line number which generated the invocant node."""
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
151 node = self
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
152 while not isinstance(node, Leaf):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
153 if not node.children:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
154 return
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
155 node = node.children[0]
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
156 return node.lineno
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
157
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
158 def changed(self):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
159 if self.parent:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
160 self.parent.changed()
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
161 self.was_changed = True
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
162
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
163 def remove(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
164 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
165 Remove the node from the tree. Returns the position of the node in its
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
166 parent's children before it was removed.
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
167 """
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
168 if self.parent:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
169 for i, node in enumerate(self.parent.children):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
170 if node is self:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
171 self.parent.changed()
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
172 del self.parent.children[i]
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
173 self.parent = None
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
174 return i
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
175
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
176 @property
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
177 def next_sibling(self):
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
178 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
179 The node immediately following the invocant in their parent's children
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
180 list. If the invocant does not have a next sibling, it is None
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
181 """
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
182 if self.parent is None:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
183 return None
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
184
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
185 # Can't use index(); we need to test by identity
46385
842a6c2c9bcd Merged revisions 62080-62262 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45992
diff changeset
186 for i, child in enumerate(self.parent.children):
842a6c2c9bcd Merged revisions 62080-62262 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45992
diff changeset
187 if child is self:
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
188 try:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
189 return self.parent.children[i+1]
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
190 except IndexError:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
191 return None
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
192
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
193 @property
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
194 def prev_sibling(self):
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
195 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
196 The node immediately preceding the invocant in their parent's children
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
197 list. If the invocant does not have a previous sibling, it is None.
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
198 """
46385
842a6c2c9bcd Merged revisions 62080-62262 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45992
diff changeset
199 if self.parent is None:
842a6c2c9bcd Merged revisions 62080-62262 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45992
diff changeset
200 return None
842a6c2c9bcd Merged revisions 62080-62262 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45992
diff changeset
201
842a6c2c9bcd Merged revisions 62080-62262 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45992
diff changeset
202 # Can't use index(); we need to test by identity
842a6c2c9bcd Merged revisions 62080-62262 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45992
diff changeset
203 for i, child in enumerate(self.parent.children):
842a6c2c9bcd Merged revisions 62080-62262 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45992
diff changeset
204 if child is self:
842a6c2c9bcd Merged revisions 62080-62262 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45992
diff changeset
205 if i == 0:
842a6c2c9bcd Merged revisions 62080-62262 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45992
diff changeset
206 return None
842a6c2c9bcd Merged revisions 62080-62262 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45992
diff changeset
207 return self.parent.children[i-1]
842a6c2c9bcd Merged revisions 62080-62262 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45992
diff changeset
208
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
209 def get_suffix(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
210 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
211 Return the string immediately following the invocant node. This is
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
212 effectively equivalent to node.next_sibling.get_prefix()
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
213 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
214 next_sib = self.next_sibling
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
215 if next_sib is None:
53934
119e4323400d Merged revisions 72491-72493 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 53821
diff changeset
216 return u""
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
217 return next_sib.get_prefix()
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
218
53934
119e4323400d Merged revisions 72491-72493 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 53821
diff changeset
219 if sys.version_info < (3, 0):
119e4323400d Merged revisions 72491-72493 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 53821
diff changeset
220 def __str__(self):
119e4323400d Merged revisions 72491-72493 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 53821
diff changeset
221 return unicode(self).encode("ascii")
119e4323400d Merged revisions 72491-72493 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 53821
diff changeset
222
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
223
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
224 class Node(Base):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
225
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
226 """Concrete implementation for interior nodes."""
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
227
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
228 def __init__(self, type, children, context=None, prefix=None):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
229 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
230 Initializer.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
231
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
232 Takes a type constant (a symbol number >= 256), a sequence of
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
233 child nodes, and an optional context keyword argument.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
234
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
235 As a side effect, the parent pointers of the children are updated.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
236 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
237 assert type >= 256, type
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
238 self.type = type
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
239 self.children = list(children)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
240 for ch in self.children:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
241 assert ch.parent is None, repr(ch)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
242 ch.parent = self
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
243 if prefix is not None:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
244 self.set_prefix(prefix)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
245
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
246 def __repr__(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
247 """Return a canonical string representation."""
45992
e47c3c7bbddc Merged revisions 61602-61723 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45906
diff changeset
248 return "%s(%s, %r)" % (self.__class__.__name__,
e47c3c7bbddc Merged revisions 61602-61723 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45906
diff changeset
249 type_repr(self.type),
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
250 self.children)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
251
53934
119e4323400d Merged revisions 72491-72493 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 53821
diff changeset
252 def __unicode__(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
253 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
254 Return a pretty string representation.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
255
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
256 This reproduces the input source exactly.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
257 """
53934
119e4323400d Merged revisions 72491-72493 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 53821
diff changeset
258 return u"".join(map(unicode, self.children))
119e4323400d Merged revisions 72491-72493 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 53821
diff changeset
259
119e4323400d Merged revisions 72491-72493 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 53821
diff changeset
260 if sys.version_info > (3, 0):
119e4323400d Merged revisions 72491-72493 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 53821
diff changeset
261 __str__ = __unicode__
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
262
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
263 def _eq(self, other):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
264 """Compare two nodes for equality."""
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
265 return (self.type, self.children) == (other.type, other.children)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
266
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
267 def clone(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
268 """Return a cloned (deep) copy of self."""
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
269 return Node(self.type, [ch.clone() for ch in self.children])
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
270
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
271 def post_order(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
272 """Return a post-order iterator for the tree."""
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
273 for child in self.children:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
274 for node in child.post_order():
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
275 yield node
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
276 yield self
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
277
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
278 def pre_order(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
279 """Return a pre-order iterator for the tree."""
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
280 yield self
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
281 for child in self.children:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
282 for node in child.post_order():
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
283 yield node
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
284
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
285 def set_prefix(self, prefix):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
286 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
287 Set the prefix for the node.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
288
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
289 This passes the responsibility on to the first child.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
290 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
291 if self.children:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
292 self.children[0].set_prefix(prefix)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
293
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
294 def get_prefix(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
295 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
296 Return the prefix for the node.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
297
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
298 This passes the call on to the first child.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
299 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
300 if not self.children:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
301 return ""
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
302 return self.children[0].get_prefix()
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
303
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
304 def set_child(self, i, child):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
305 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
306 Equivalent to 'node.children[i] = child'. This method also sets the
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
307 child's parent attribute appropriately.
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
308 """
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
309 child.parent = self
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
310 self.children[i].parent = None
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
311 self.children[i] = child
50198
21d3357dcbec Merged revisions 67806 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 49885
diff changeset
312 self.changed()
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
313
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
314 def insert_child(self, i, child):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
315 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
316 Equivalent to 'node.children.insert(i, child)'. This method also sets
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
317 the child's parent attribute appropriately.
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
318 """
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
319 child.parent = self
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
320 self.children.insert(i, child)
50198
21d3357dcbec Merged revisions 67806 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 49885
diff changeset
321 self.changed()
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
322
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
323 def append_child(self, child):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
324 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
325 Equivalent to 'node.children.append(child)'. This method also sets the
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
326 child's parent attribute appropriately.
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
327 """
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
328 child.parent = self
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
329 self.children.append(child)
50198
21d3357dcbec Merged revisions 67806 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 49885
diff changeset
330 self.changed()
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
331
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
332
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
333 class Leaf(Base):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
334
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
335 """Concrete implementation for leaf nodes."""
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
336
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
337 # Default values for instance variables
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
338 prefix = "" # Whitespace and comments preceding this token in the input
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
339 lineno = 0 # Line where this token starts in the input
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
340 column = 0 # Column where this token tarts in the input
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
341
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
342 def __init__(self, type, value, context=None, prefix=None):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
343 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
344 Initializer.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
345
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
346 Takes a type constant (a token number < 256), a string value, and an
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
347 optional context keyword argument.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
348 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
349 assert 0 <= type < 256, type
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
350 if context is not None:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
351 self.prefix, (self.lineno, self.column) = context
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
352 self.type = type
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
353 self.value = value
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
354 if prefix is not None:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
355 self.prefix = prefix
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
356
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
357 def __repr__(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
358 """Return a canonical string representation."""
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
359 return "%s(%r, %r)" % (self.__class__.__name__,
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
360 self.type,
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
361 self.value)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
362
53934
119e4323400d Merged revisions 72491-72493 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 53821
diff changeset
363 def __unicode__(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
364 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
365 Return a pretty string representation.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
366
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
367 This reproduces the input source exactly.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
368 """
53934
119e4323400d Merged revisions 72491-72493 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 53821
diff changeset
369 return self.prefix + unicode(self.value)
119e4323400d Merged revisions 72491-72493 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 53821
diff changeset
370
119e4323400d Merged revisions 72491-72493 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 53821
diff changeset
371 if sys.version_info > (3, 0):
119e4323400d Merged revisions 72491-72493 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 53821
diff changeset
372 __str__ = __unicode__
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
373
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
374 def _eq(self, other):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
375 """Compare two nodes for equality."""
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
376 return (self.type, self.value) == (other.type, other.value)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
377
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
378 def clone(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
379 """Return a cloned (deep) copy of self."""
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
380 return Leaf(self.type, self.value,
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
381 (self.prefix, (self.lineno, self.column)))
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
382
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
383 def post_order(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
384 """Return a post-order iterator for the tree."""
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
385 yield self
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
386
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
387 def pre_order(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
388 """Return a pre-order iterator for the tree."""
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
389 yield self
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
390
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
391 def set_prefix(self, prefix):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
392 """Set the prefix for the node."""
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
393 self.changed()
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
394 self.prefix = prefix
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
395
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
396 def get_prefix(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
397 """Return the prefix for the node."""
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
398 return self.prefix
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
399
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
400
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
401 def convert(gr, raw_node):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
402 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
403 Convert raw node information to a Node or Leaf instance.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
404
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
405 This is passed to the parser driver which calls it whenever a reduction of a
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
406 grammar rule produces a new complete node, so that the tree is build
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
407 strictly bottom-up.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
408 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
409 type, value, context, children = raw_node
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
410 if children or type in gr.number2symbol:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
411 # If there's exactly one child, return that child instead of
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
412 # creating a new node.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
413 if len(children) == 1:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
414 return children[0]
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
415 return Node(type, children, context=context)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
416 else:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
417 return Leaf(type, value, context=context)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
418
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
419
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
420 class BasePattern(object):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
421
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
422 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
423 A pattern is a tree matching pattern.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
424
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
425 It looks for a specific node type (token or symbol), and
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
426 optionally for a specific content.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
427
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
428 This is an abstract base class. There are three concrete
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
429 subclasses:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
430
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
431 - LeafPattern matches a single leaf node;
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
432 - NodePattern matches a single node (usually non-leaf);
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
433 - WildcardPattern matches a sequence of nodes of variable length.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
434 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
435
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
436 # Defaults for instance variables
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
437 type = None # Node type (token if < 256, symbol if >= 256)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
438 content = None # Optional content matching pattern
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
439 name = None # Optional name used to store match in results dict
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
440
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
441 def __new__(cls, *args, **kwds):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
442 """Constructor that prevents BasePattern from being instantiated."""
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
443 assert cls is not BasePattern, "Cannot instantiate BasePattern"
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
444 return object.__new__(cls)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
445
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
446 def __repr__(self):
45992
e47c3c7bbddc Merged revisions 61602-61723 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45906
diff changeset
447 args = [type_repr(self.type), self.content, self.name]
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
448 while args and args[-1] is None:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
449 del args[-1]
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
450 return "%s(%s)" % (self.__class__.__name__, ", ".join(map(repr, args)))
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
451
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
452 def optimize(self):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
453 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
454 A subclass can define this as a hook for optimizations.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
455
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
456 Returns either self or another node with the same effect.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
457 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
458 return self
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
459
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
460 def match(self, node, results=None):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
461 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
462 Does this pattern exactly match a node?
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
463
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
464 Returns True if it matches, False if not.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
465
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
466 If results is not None, it must be a dict which will be
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
467 updated with the nodes matching named subpatterns.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
468
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
469 Default implementation for non-wildcard patterns.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
470 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
471 if self.type is not None and node.type != self.type:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
472 return False
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
473 if self.content is not None:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
474 r = None
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
475 if results is not None:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
476 r = {}
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
477 if not self._submatch(node, r):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
478 return False
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
479 if r:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
480 results.update(r)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
481 if results is not None and self.name:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
482 results[self.name] = node
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
483 return True
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
484
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
485 def match_seq(self, nodes, results=None):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
486 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
487 Does this pattern exactly match a sequence of nodes?
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
488
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
489 Default implementation for non-wildcard patterns.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
490 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
491 if len(nodes) != 1:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
492 return False
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
493 return self.match(nodes[0], results)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
494
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
495 def generate_matches(self, nodes):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
496 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
497 Generator yielding all matches for this pattern.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
498
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
499 Default implementation for non-wildcard patterns.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
500 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
501 r = {}
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
502 if nodes and self.match(nodes[0], r):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
503 yield 1, r
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
504
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
505
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
506 class LeafPattern(BasePattern):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
507
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
508 def __init__(self, type=None, content=None, name=None):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
509 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
510 Initializer. Takes optional type, content, and name.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
511
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
512 The type, if given must be a token type (< 256). If not given,
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
513 this matches any *leaf* node; the content may still be required.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
514
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
515 The content, if given, must be a string.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
516
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
517 If a name is given, the matching node is stored in the results
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
518 dict under that key.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
519 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
520 if type is not None:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
521 assert 0 <= type < 256, type
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
522 if content is not None:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
523 assert isinstance(content, basestring), repr(content)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
524 self.type = type
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
525 self.content = content
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
526 self.name = name
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
527
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
528 def match(self, node, results=None):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
529 """Override match() to insist on a leaf node."""
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
530 if not isinstance(node, Leaf):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
531 return False
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
532 return BasePattern.match(self, node, results)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
533
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
534 def _submatch(self, node, results=None):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
535 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
536 Match the pattern's content to the node's children.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
537
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
538 This assumes the node type matches and self.content is not None.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
539
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
540 Returns True if it matches, False if not.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
541
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
542 If results is not None, it must be a dict which will be
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
543 updated with the nodes matching named subpatterns.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
544
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
545 When returning False, the results dict may still be updated.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
546 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
547 return self.content == node.value
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
548
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
549
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
550 class NodePattern(BasePattern):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
551
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
552 wildcards = False
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
553
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
554 def __init__(self, type=None, content=None, name=None):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
555 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
556 Initializer. Takes optional type, content, and name.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
557
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
558 The type, if given, must be a symbol type (>= 256). If the
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
559 type is None this matches *any* single node (leaf or not),
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
560 except if content is not None, in which it only matches
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
561 non-leaf nodes that also match the content pattern.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
562
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
563 The content, if not None, must be a sequence of Patterns that
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
564 must match the node's children exactly. If the content is
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
565 given, the type must not be None.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
566
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
567 If a name is given, the matching node is stored in the results
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
568 dict under that key.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
569 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
570 if type is not None:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
571 assert type >= 256, type
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
572 if content is not None:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
573 assert not isinstance(content, basestring), repr(content)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
574 content = list(content)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
575 for i, item in enumerate(content):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
576 assert isinstance(item, BasePattern), (i, item)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
577 if isinstance(item, WildcardPattern):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
578 self.wildcards = True
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
579 self.type = type
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
580 self.content = content
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
581 self.name = name
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
582
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
583 def _submatch(self, node, results=None):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
584 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
585 Match the pattern's content to the node's children.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
586
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
587 This assumes the node type matches and self.content is not None.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
588
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
589 Returns True if it matches, False if not.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
590
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
591 If results is not None, it must be a dict which will be
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
592 updated with the nodes matching named subpatterns.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
593
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
594 When returning False, the results dict may still be updated.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
595 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
596 if self.wildcards:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
597 for c, r in generate_matches(self.content, node.children):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
598 if c == len(node.children):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
599 if results is not None:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
600 results.update(r)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
601 return True
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
602 return False
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
603 if len(self.content) != len(node.children):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
604 return False
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
605 for subpattern, child in zip(self.content, node.children):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
606 if not subpattern.match(child, results):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
607 return False
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
608 return True
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
609
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
610
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
611 class WildcardPattern(BasePattern):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
612
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
613 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
614 A wildcard pattern can match zero or more nodes.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
615
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
616 This has all the flexibility needed to implement patterns like:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
617
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
618 .* .+ .? .{m,n}
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
619 (a b c | d e | f)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
620 (...)* (...)+ (...)? (...){m,n}
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
621
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
622 except it always uses non-greedy matching.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
623 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
624
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
625 def __init__(self, content=None, min=0, max=HUGE, name=None):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
626 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
627 Initializer.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
628
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
629 Args:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
630 content: optional sequence of subsequences of patterns;
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
631 if absent, matches one node;
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
632 if present, each subsequence is an alternative [*]
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
633 min: optinal minumum number of times to match, default 0
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
634 max: optional maximum number of times tro match, default HUGE
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
635 name: optional name assigned to this match
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
636
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
637 [*] Thus, if content is [[a, b, c], [d, e], [f, g, h]] this is
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
638 equivalent to (a b c | d e | f g h); if content is None,
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
639 this is equivalent to '.' in regular expression terms.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
640 The min and max parameters work as follows:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
641 min=0, max=maxint: .*
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
642 min=1, max=maxint: .+
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
643 min=0, max=1: .?
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
644 min=1, max=1: .
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
645 If content is not None, replace the dot with the parenthesized
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
646 list of alternatives, e.g. (a b c | d e | f g h)*
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
647 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
648 assert 0 <= min <= max <= HUGE, (min, max)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
649 if content is not None:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
650 content = tuple(map(tuple, content)) # Protect against alterations
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
651 # Check sanity of alternatives
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
652 assert len(content), repr(content) # Can't have zero alternatives
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
653 for alt in content:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
654 assert len(alt), repr(alt) # Can have empty alternatives
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
655 self.content = content
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
656 self.min = min
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
657 self.max = max
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
658 self.name = name
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
659
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
660 def optimize(self):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
661 """Optimize certain stacked wildcard patterns."""
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
662 subpattern = None
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
663 if (self.content is not None and
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
664 len(self.content) == 1 and len(self.content[0]) == 1):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
665 subpattern = self.content[0][0]
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
666 if self.min == 1 and self.max == 1:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
667 if self.content is None:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
668 return NodePattern(name=self.name)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
669 if subpattern is not None and self.name == subpattern.name:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
670 return subpattern.optimize()
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
671 if (self.min <= 1 and isinstance(subpattern, WildcardPattern) and
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
672 subpattern.min <= 1 and self.name == subpattern.name):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
673 return WildcardPattern(subpattern.content,
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
674 self.min*subpattern.min,
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
675 self.max*subpattern.max,
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
676 subpattern.name)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
677 return self
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
678
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
679 def match(self, node, results=None):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
680 """Does this pattern exactly match a node?"""
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
681 return self.match_seq([node], results)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
682
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
683 def match_seq(self, nodes, results=None):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
684 """Does this pattern exactly match a sequence of nodes?"""
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
685 for c, r in self.generate_matches(nodes):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
686 if c == len(nodes):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
687 if results is not None:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
688 results.update(r)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
689 if self.name:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
690 results[self.name] = list(nodes)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
691 return True
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
692 return False
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
693
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
694 def generate_matches(self, nodes):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
695 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
696 Generator yielding matches for a sequence of nodes.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
697
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
698 Args:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
699 nodes: sequence of nodes
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
700
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
701 Yields:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
702 (count, results) tuples where:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
703 count: the match comprises nodes[:count];
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
704 results: dict containing named submatches.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
705 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
706 if self.content is None:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
707 # Shortcut for special case (see __init__.__doc__)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
708 for count in xrange(self.min, 1 + min(len(nodes), self.max)):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
709 r = {}
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
710 if self.name:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
711 r[self.name] = nodes[:count]
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
712 yield count, r
47997
30fdd0c3b6de Merged revisions 65053-65054 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 46385
diff changeset
713 elif self.name == "bare_name":
30fdd0c3b6de Merged revisions 65053-65054 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 46385
diff changeset
714 yield self._bare_name_matches(nodes)
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
715 else:
49885
0607c97a8124 Merged revisions 67428 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 49431
diff changeset
716 # The reason for this is that hitting the recursion limit usually
0607c97a8124 Merged revisions 67428 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 49431
diff changeset
717 # results in some ugly messages about how RuntimeErrors are being
0607c97a8124 Merged revisions 67428 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 49431
diff changeset
718 # ignored.
0607c97a8124 Merged revisions 67428 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 49431
diff changeset
719 save_stderr = sys.stderr
0607c97a8124 Merged revisions 67428 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 49431
diff changeset
720 sys.stderr = StringIO()
49431
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
721 try:
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
722 for count, r in self._recursive_matches(nodes, 0):
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
723 if self.name:
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
724 r[self.name] = nodes[:count]
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
725 yield count, r
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
726 except RuntimeError:
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
727 # We fall back to the iterative pattern matching scheme if the recursive
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
728 # scheme hits the recursion limit.
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
729 for count, r in self._iterative_matches(nodes):
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
730 if self.name:
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
731 r[self.name] = nodes[:count]
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
732 yield count, r
49885
0607c97a8124 Merged revisions 67428 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 49431
diff changeset
733 finally:
0607c97a8124 Merged revisions 67428 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 49431
diff changeset
734 sys.stderr = save_stderr
49431
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
735
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
736 def _iterative_matches(self, nodes):
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
737 """Helper to iteratively yield the matches."""
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
738 nodelen = len(nodes)
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
739 if 0 >= self.min:
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
740 yield 0, {}
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
741
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
742 results = []
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
743 # generate matches that use just one alt from self.content
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
744 for alt in self.content:
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
745 for c, r in generate_matches(alt, nodes):
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
746 yield c, r
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
747 results.append((c, r))
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
748
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
749 # for each match, iterate down the nodes
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
750 while results:
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
751 new_results = []
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
752 for c0, r0 in results:
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
753 # stop if the entire set of nodes has been matched
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
754 if c0 < nodelen and c0 <= self.max:
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
755 for alt in self.content:
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
756 for c1, r1 in generate_matches(alt, nodes[c0:]):
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
757 if c1 > 0:
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
758 r = {}
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
759 r.update(r0)
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
760 r.update(r1)
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
761 yield c0 + c1, r
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
762 new_results.append((c0 + c1, r))
2e794757bdc8 Merged revisions 66766-66767,66771-66772,66774,66776,66783-66787,66790,66793,66797 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 47997
diff changeset
763 results = new_results
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
764
47997
30fdd0c3b6de Merged revisions 65053-65054 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 46385
diff changeset
765 def _bare_name_matches(self, nodes):
30fdd0c3b6de Merged revisions 65053-65054 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 46385
diff changeset
766 """Special optimized matcher for bare_name."""
30fdd0c3b6de Merged revisions 65053-65054 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 46385
diff changeset
767 count = 0
30fdd0c3b6de Merged revisions 65053-65054 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 46385
diff changeset
768 r = {}
30fdd0c3b6de Merged revisions 65053-65054 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 46385
diff changeset
769 done = False
30fdd0c3b6de Merged revisions 65053-65054 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 46385
diff changeset
770 max = len(nodes)
30fdd0c3b6de Merged revisions 65053-65054 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 46385
diff changeset
771 while not done and count < max:
30fdd0c3b6de Merged revisions 65053-65054 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 46385
diff changeset
772 done = True
30fdd0c3b6de Merged revisions 65053-65054 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 46385
diff changeset
773 for leaf in self.content:
30fdd0c3b6de Merged revisions 65053-65054 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 46385
diff changeset
774 if leaf[0].match(nodes[count], r):
30fdd0c3b6de Merged revisions 65053-65054 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 46385
diff changeset
775 count += 1
30fdd0c3b6de Merged revisions 65053-65054 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 46385
diff changeset
776 done = False
30fdd0c3b6de Merged revisions 65053-65054 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 46385
diff changeset
777 break
30fdd0c3b6de Merged revisions 65053-65054 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 46385
diff changeset
778 r[self.name] = nodes[:count]
30fdd0c3b6de Merged revisions 65053-65054 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 46385
diff changeset
779 return count, r
30fdd0c3b6de Merged revisions 65053-65054 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 46385
diff changeset
780
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
781 def _recursive_matches(self, nodes, count):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
782 """Helper to recursively yield the matches."""
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
783 assert self.content is not None
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
784 if count >= self.min:
47997
30fdd0c3b6de Merged revisions 65053-65054 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 46385
diff changeset
785 yield 0, {}
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
786 if count < self.max:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
787 for alt in self.content:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
788 for c0, r0 in generate_matches(alt, nodes):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
789 for c1, r1 in self._recursive_matches(nodes[c0:], count+1):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
790 r = {}
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
791 r.update(r0)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
792 r.update(r1)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
793 yield c0 + c1, r
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
794
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
795
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
796 class NegatedPattern(BasePattern):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
797
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
798 def __init__(self, content=None):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
799 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
800 Initializer.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
801
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
802 The argument is either a pattern or None. If it is None, this
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
803 only matches an empty sequence (effectively '$' in regex
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
804 lingo). If it is not None, this matches whenever the argument
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
805 pattern doesn't have any matches.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
806 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
807 if content is not None:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
808 assert isinstance(content, BasePattern), repr(content)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
809 self.content = content
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
810
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
811 def match(self, node):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
812 # We never match a node in its entirety
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
813 return False
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
814
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
815 def match_seq(self, nodes):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
816 # We only match an empty sequence of nodes in its entirety
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
817 return len(nodes) == 0
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
818
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
819 def generate_matches(self, nodes):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
820 if self.content is None:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
821 # Return a match if there is an empty sequence
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
822 if len(nodes) == 0:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
823 yield 0, {}
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
824 else:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
825 # Return a match if the argument pattern has no matches
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
826 for c, r in self.content.generate_matches(nodes):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
827 return
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
828 yield 0, {}
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
829
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
830
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
831 def generate_matches(patterns, nodes):
53821
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
832 """
fb10b88afd40 Merged revisions 68503,68507,68694,69054,69673,69679-69681,70991,70999,71003,71695 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 50198
diff changeset
833 Generator yielding matches for a sequence of patterns and nodes.
45906
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
834
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
835 Args:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
836 patterns: a sequence of patterns
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
837 nodes: a sequence of nodes
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
838
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
839 Yields:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
840 (count, results) tuples where:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
841 count: the entire sequence of patterns matches nodes[:count];
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
842 results: dict containing named submatches.
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
843 """
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
844 if not patterns:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
845 yield 0, {}
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
846 else:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
847 p, rest = patterns[0], patterns[1:]
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
848 for c0, r0 in p.generate_matches(nodes):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
849 if not rest:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
850 yield c0, r0
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
851 else:
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
852 for c1, r1 in generate_matches(rest, nodes[c0:]):
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
853 r = {}
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
854 r.update(r0)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
855 r.update(r1)
302625fa6a2a Import lib2to3.
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
856 yield c0 + c1, r