def _test_ast_equivalent(self, a: ASTNode, b: ASTNode) -> None: assert a.attr_names == b.attr_names for name in a.attr_names: assert getattr(a, name) == getattr(b, name) for (name_a, child_a), (name_b, child_b) in zip(a.children(), b.children()): assert name_a == name_b self._test_ast_equivalent(child_a, child_b)
def traverse(node: ASTNode, depth: int = 0) -> JSONNode: klass = node.__class__ result = {} # Node type result[NODE_TYPE_ATTR] = klass.__name__ # Local node attributes for attr in klass.attr_names: result[attr] = getattr(node, attr) # Token position if tokens is not None: if node.coord is not None and node.coord.line > 0: # some nodes have invalid coordinate (0, 1) coord: Coord = node.coord pos = find_token(coord.line, coord.column) result[TOKEN_POS_ATTR] = pos else: result[TOKEN_POS_ATTR] = None # node_name = (" " * (2 * depth) + klass.__name__).ljust(35) # if node.coord is not None: # coord: Coord = node.coord # pos = result['coord'] # print(node_name, coord.line, coord.column, pos, (tokens[pos] if pos else None), sep='\t') # else: # print(node_name) # Children nodes children: Dict[str, Optional[MaybeList[JSONNode]]] = {} for child_name, child in node.children(): child_dict = traverse(child, depth + 1) # Child strings are either simple (e.g. 'value') or arrays (e.g. 'block_items[1]') match = RE_CHILD_ARRAY.match(child_name) if match: array_name, array_index = match.groups() array_index = int(array_index) # arrays come in order, so we verify and append. array: List[JSONNode] = children.setdefault(array_name, []) # type: ignore if array_index != len(array): raise ValueError(f"Internal ast error. Array {array_name} out of order. " f"Expected index {len(array)}, got {array_index}") array.append(child_dict) else: children[child_name] = child_dict # Missing children are filled with `None` values in the dictionary. for child_attr in child_attrs_of(klass): if child_attr not in children: children[child_attr] = None result[CHILDREN_ATTR] = children return result
def dfs(u: c_ast.Node): nonlocal node_parent for (v_name, v) in u.children(): node_parent[v] = u dfs(v)