Back to index

python3.2  3.2.2
Public Member Functions | Public Attributes
lib2to3.btm_matcher.BottomMatcher Class Reference
Inheritance diagram for lib2to3.btm_matcher.BottomMatcher:
Inheritance graph
[legend]
Collaboration diagram for lib2to3.btm_matcher.BottomMatcher:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def __init__
def add_fixer
def add
def run
def print_ac

Public Attributes

 match
 root
 nodes
 fixers
 logger
_PyObject_HEAD_EXTRA Py_ssize_t ob_refcnt
struct _typeobjectob_type

Detailed Description

The main matcher class. After instantiating the patterns should
be added using the add_fixer method

Definition at line 26 of file btm_matcher.py.


Constructor & Destructor Documentation

Definition at line 30 of file btm_matcher.py.

00030 
00031     def __init__(self):
00032         self.match = set()
00033         self.root = BMNode()
00034         self.nodes = [self.root]
00035         self.fixers = []
00036         self.logger = logging.getLogger("RefactoringTool")

Here is the caller graph for this function:


Member Function Documentation

def lib2to3.btm_matcher.BottomMatcher.add (   self,
  pattern,
  start 
)

Definition at line 49 of file btm_matcher.py.

00049 
00050     def add(self, pattern, start):
00051         "Recursively adds a linear pattern to the AC automaton"
00052         #print("adding pattern", pattern, "to", start)
00053         if not pattern:
00054             #print("empty pattern")
00055             return [start]
00056         if isinstance(pattern[0], tuple):
00057             #alternatives
00058             #print("alternatives")
00059             match_nodes = []
00060             for alternative in pattern[0]:
00061                 #add all alternatives, and add the rest of the pattern
00062                 #to each end node
00063                 end_nodes = self.add(alternative, start=start)
00064                 for end in end_nodes:
00065                     match_nodes.extend(self.add(pattern[1:], end))
00066             return match_nodes
00067         else:
00068             #single token
00069             #not last
00070             if pattern[0] not in start.transition_table:
00071                 #transition did not exist, create new
00072                 next_node = BMNode()
00073                 start.transition_table[pattern[0]] = next_node
00074             else:
00075                 #transition exists already, follow
00076                 next_node = start.transition_table[pattern[0]]
00077 
00078             if pattern[1:]:
00079                 end_nodes = self.add(pattern[1:], start=next_node)
00080             else:
00081                 end_nodes = [next_node]
00082             return end_nodes

Here is the call graph for this function:

Here is the caller graph for this function:

def lib2to3.btm_matcher.BottomMatcher.add_fixer (   self,
  fixer 
)
Reduces a fixer's pattern tree to a linear path and adds it
to the matcher(a common Aho-Corasick automaton). The fixer is
appended on the matching states and called when they are
reached

Definition at line 37 of file btm_matcher.py.

00037 
00038     def add_fixer(self, fixer):
00039         """Reduces a fixer's pattern tree to a linear path and adds it
00040         to the matcher(a common Aho-Corasick automaton). The fixer is
00041         appended on the matching states and called when they are
00042         reached"""
00043         self.fixers.append(fixer)
00044         tree = reduce_tree(fixer.pattern_tree)
00045         linear = tree.get_linear_subpattern()
00046         match_nodes = self.add(linear, start=self.root)
00047         for match_node in match_nodes:
00048             match_node.fixers.append(fixer)

Here is the call graph for this function:

Definition at line 144 of file btm_matcher.py.

00144 
00145     def print_ac(self):
00146         "Prints a graphviz diagram of the BM automaton(for debugging)"
00147         print("digraph g{")
00148         def print_node(node):
00149             for subnode_key in node.transition_table.keys():
00150                 subnode = node.transition_table[subnode_key]
00151                 print("%d -> %d [label=%s] //%s" %
00152                       (node.id, subnode.id, type_repr(subnode_key), str(subnode.fixers)))
00153                 if subnode_key == 1:
00154                     print(subnode.content)
00155                 print_node(subnode)
00156         print_node(self.root)
00157         print("}")
00158 
# taken from pytree.py for debugging; only used by print_ac

Here is the call graph for this function:

def lib2to3.btm_matcher.BottomMatcher.run (   self,
  leaves 
)
The main interface with the bottom matcher. The tree is
traversed from the bottom using the constructed
automaton. Nodes are only checked once as the tree is
retraversed. When the automaton fails, we give it one more
shot(in case the above tree matches as a whole with the
rejected leaf), then we break for the next leaf. There is the
special case of multiple arguments(see code comments) where we
recheck the nodes

Args:
   The leaves of the AST tree to be matched

Returns:
   A dictionary of node matches with fixers as the keys

Definition at line 83 of file btm_matcher.py.

00083 
00084     def run(self, leaves):
00085         """The main interface with the bottom matcher. The tree is
00086         traversed from the bottom using the constructed
00087         automaton. Nodes are only checked once as the tree is
00088         retraversed. When the automaton fails, we give it one more
00089         shot(in case the above tree matches as a whole with the
00090         rejected leaf), then we break for the next leaf. There is the
00091         special case of multiple arguments(see code comments) where we
00092         recheck the nodes
00093 
00094         Args:
00095            The leaves of the AST tree to be matched
00096 
00097         Returns:
00098            A dictionary of node matches with fixers as the keys
00099         """
00100         current_ac_node = self.root
00101         results = defaultdict(list)
00102         for leaf in leaves:
00103             current_ast_node = leaf
00104             while current_ast_node:
00105                 current_ast_node.was_checked = True
00106                 for child in current_ast_node.children:
00107                     # multiple statements, recheck
00108                     if isinstance(child, pytree.Leaf) and child.value == ";":
00109                         current_ast_node.was_checked = False
00110                         break
00111                 if current_ast_node.type == 1:
00112                     #name
00113                     node_token = current_ast_node.value
00114                 else:
00115                     node_token = current_ast_node.type
00116 
00117                 if node_token in current_ac_node.transition_table:
00118                     #token matches
00119                     current_ac_node = current_ac_node.transition_table[node_token]
00120                     for fixer in current_ac_node.fixers:
00121                         if not fixer in results:
00122                             results[fixer] = []
00123                         results[fixer].append(current_ast_node)
00124 
00125                 else:
00126                     #matching failed, reset automaton
00127                     current_ac_node = self.root
00128                     if (current_ast_node.parent is not None
00129                         and current_ast_node.parent.was_checked):
00130                         #the rest of the tree upwards has been checked, next leaf
00131                         break
00132 
00133                     #recheck the rejected node once from the root
00134                     if node_token in current_ac_node.transition_table:
00135                         #token matches
00136                         current_ac_node = current_ac_node.transition_table[node_token]
00137                         for fixer in current_ac_node.fixers:
00138                             if not fixer in results.keys():
00139                                 results[fixer] = []
00140                             results[fixer].append(current_ast_node)
00141 
00142                 current_ast_node = current_ast_node.parent
00143         return results

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 34 of file btm_matcher.py.

Definition at line 35 of file btm_matcher.py.

Definition at line 31 of file btm_matcher.py.

Definition at line 33 of file btm_matcher.py.

Definition at line 107 of file object.h.

struct _typeobject* _object::ob_type [inherited]

Definition at line 108 of file object.h.

Definition at line 32 of file btm_matcher.py.


The documentation for this class was generated from the following file: