def _generate_pygraphviz( self, exclude_modules=None, exclude_states=None, include_test_module=False, ): if exclude_states is None: exclude_states = [] if exclude_modules is None: exclude_modules = [] graph = pygraphviz.AGraph(strict=True, directed=True, pad="4", rankdir="LR", ranksep="4", overlap=False, splines="true") for name, values in self._nodes.items(): # Populate the graph entirely (we need all original edges and nodes) state = self.get_state(name) color = States.state2color[state][1] fillcolor = States.state2color[state][0] group = States.state2group[state] add_node(graph, name, values, color, fillcolor, group) for name in graph.nodes(): if (name in exclude_modules or self.get_state(name) in exclude_states or (not include_test_module and name.startswith("test_"))): remove_node(graph, name) clean_graph(graph) # for name in graph.nodes(): # self._check_state_from_predecessors(graph, name) return graph
def visit_sequence(self, node, children) -> Any: if len(children) == 1: return children[0] graph = add_node('sequence', font=Font.ITALIC, shape=Shape.BOX, style=Style.ROUNDED) source = graph['top'] label, style = None, None for child in children: target = child['top'] root = child['nodes'][target] if root['label'] == 'atom': ident = next((k for k in child['edges'][target]), None) atom = child['nodes'][ident] if label is None: label = atom['label'] style = Style.FILLED if 'style' in atom else None else: label = label + atom['label'] style = style and (Style.FILLED if 'style' in atom else None) else: if label is not None: node = add_node(label, shape=Shape.BOX, style=style) tgt = node['top'] node = merge( node, add_node('atom', font=Font.ITALIC, shape=Shape.ELLIPSE)) src = node['top'] node = add_edge(src, tgt, node) graph = merge(graph, node) graph = add_edge(source, src, graph) label, style = None, None graph = merge(graph, child) graph = add_edge(source, target, graph) if label is not None: node = add_node(label, shape=Shape.BOX, style=style) tgt = node['top'] node = merge( node, add_node('atom', font=Font.ITALIC, shape=Shape.ELLIPSE)) src = node['top'] node = add_edge(src, tgt, node) graph = merge(graph, node) graph = add_edge(source, src, graph) # graph = merge(graph, child) # graph = add_edge(source, target, graph) return graph
def free(self, object_id): obj = self.objects.pop(object_id) add_node(self.free_list, FreeListNode(obj.heap_index, obj.size)) for p in obj.pointers: child = self.objects.get(p) if child: child.referenceCount = child.referenceCount-1 if child.referenceCount == 0: self.free(p)
def allocate(self, num_bytes): for index, node in enumerate(self.free_list): if node.num_bytes >= num_bytes: self.free_list.pop(index) if node.num_bytes > num_bytes: new_node = FreeListNode(node.heap_index + num_bytes, node.num_bytes - num_bytes) # target for future optimization, I know exactly where it goes add_node(self.free_list, new_node) return node.heap_index raise OutOfMemoryException
def allocate(self, num_bytes): for i in range(len(self.free_list)): index = (self.current_index + i) % len(self.free_list) node = self.free_list[index] if node.num_bytes >= num_bytes: self.free_list.pop(index) if node.num_bytes > num_bytes: new_node = FreeListNode(node.heap_index + num_bytes, node.num_bytes - num_bytes) add_node(self.free_list, new_node) self.current_index = index return node.heap_index raise OutOfMemoryException
def visit_group(self, node, children) -> Any: params = { 'label': f"group{children[1]['label'] if len(children) > 1 else ''}", 'font': Font.ITALIC, 'shape': Shape.ELLIPSE, } if len(children) > 1: for key, value in children[1].items(): if key not in ('label', 'line') and value is not None: params[key] = value graph = add_node(**params) if len(children) > 1 and 'line' in children[1]: params = { k: v for k, v in children[1].items() if k != 'style' and v is not None } graph = add_edge(graph['top'], graph['top'], graph, **params) source, target = graph['top'], children[0]['top'] graph = merge(graph, children[0]) graph = add_edge( source, target, graph, ) return graph
def visit_alternative(self, node, children) -> Any: if len(children) == 1: return children[0] graph = add_node('alternative', font=Font.ITALIC, shape=Shape.DIAMOND, style=Style.ROUNDED) for child in children: graph = merge(graph, child) graph = add_edge(graph['top'], child['top'], graph) return graph
def visit_escaped_in_range(self, node, children) -> Any: return add_node(node.value, shape=Shape.BOX)
def test_three_adjacent_nodes_are_merged(free_list): n = FreeListNode(3, 3) add_node(free_list, n) assert len(free_list) == 2 assert free_list[1].heap_index == 2 assert free_list[1].num_bytes == 5
def test_proceeding_adjacent_nodes_are_merged(free_list): n = FreeListNode(5, 1) add_node(free_list, n) assert len(free_list) == 3 assert free_list[2].heap_index == 5 assert free_list[2].num_bytes == 2
def test_maintains_ascending_heap_order(free_list): n = FreeListNode(4, 1) add_node(free_list, n) assert len(free_list) == 4 assert free_list[2] == n
def free(self, object_id): obj = self.objects.pop(object_id) add_node(self.free_list, FreeListNode(obj.heap_index, obj.size))
def visit_backref(self, node, children) -> Any: return add_node(node.value, shape=Shape.BOX, style=Style.FILLED)
def visit_character_set(self, node, children) -> Any: negated = children[0] == '^' if negated: children = children[1:] classes, values = set(), set() if children[0] in ['-', ']']: values.add(ord(children[0])) children = children[1:] for child in children: if isinstance(child, dict): ident = child['top'] label = child['nodes'][ident]['label'] try: values.update(order(label)) except TypeError: classes.add(label) else: values.update(child) graph = add_node( f"{'^' if negated else ''}charset", font=Font.ITALIC, shape=Shape.TRAPEZIUM, color=NEGATED if negated else None, ) source = graph['top'] for class_ in sorted(classes): child = add_node(class_, shape=Shape.BOX, style=Style.FILLED) graph = merge(graph, child) graph = add_edge(source, child['top'], graph) for group, symbol in [ (BUT_SPACE, '\\S'), (BUT_DIGIT, '\\D'), (BUT_WORD, '\\W'), (WORD, '\\w'), (DIGIT, '\\d'), (SPACE, '\\s'), ]: if group in values: child = add_node(symbol, shape=Shape.BOX, style=Style.FILLED) graph = merge(graph, child) graph = add_edge(source, child['top'], graph) values -= group start, last = None, None for value in sorted(values): if last is None: start, last = value, value elif value == last + 1: last = value else: label = normal( start ) if last == start else f"{normal(start)}-{normal(last)}" child = add_node(label, shape=Shape.BOX) graph = merge(graph, child) graph = add_edge(source, child['top'], graph) start, last = None, None if last is not None: label = normal( start) if last == start else f"{normal(start)}-{normal(last)}" child = add_node(label, shape=Shape.BOX) graph = merge(graph, child) graph = add_edge(source, child['top'], graph) return graph
def visit_unicode(self, node, children) -> Any: return add_node(normal(int(node.value[2:], 16)), shape=Shape.BOX)
def visit_character_class(self, node, children) -> Any: return add_node(node.value, shape=Shape.BOX, style=Style.FILLED)
def visit_symbol_in_range(self, node, children) -> Any: return add_node(normal(ord(node.value)), shape=Shape.BOX)