Exemplo n.º 1
0
 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)
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
 def dfs(u: c_ast.Node):
     nonlocal node_parent
     for (v_name, v) in u.children():
         node_parent[v] = u
         dfs(v)