phml.utilities.travel.travel

utilities.travel

Collection of utilities that hep with traversing an ast or node tree.

 1"""utilities.travel
 2
 3Collection of utilities that hep with traversing an ast or node tree.
 4"""
 5
 6from typing import Iterator
 7
 8from phml.core.nodes import NODE, Element, Root
 9
10__all__ = ["path", "path_names", "walk", "visit_children", "visit_all_after"]
11
12
13def path(node: NODE) -> list[NODE]:
14    """Get a list of nodes where each one is a child of
15    the other leading to the node passed in. This gives a
16    path to the node.
17
18    Does not include given node.
19
20    Args:
21        node (NODE): Node to find ancestors of.
22
23    Returns:
24        list[NODE]: List of nodes leading to the given node
25        starting from the root.
26    """
27    ancestors = []
28    while node.parent is not None:
29        ancestors = [node.parent, *ancestors]
30        node = node.parent
31
32    return ancestors
33
34def path_names(node: NODE) -> list[str]:
35    """Get a list of nodes where each one is a child of
36    the other leading to the node passed in. This gives a
37    path to the node.
38
39    Does not include given node.
40
41    Args:
42        node (NODE): Node to find ancestors of.
43
44    Returns:
45        list[str]: List of nodes leading to the given node
46        starting from the root.
47    """
48    ancestors = []
49    while node.parent is not None and node.parent.type != "root":
50        ancestors = [node.parent.tag, *ancestors]
51        node = node.parent
52
53    return ancestors
54
55
56def walk(node: Root | Element) -> Iterator:
57    """Recursively traverse the node and it's chidlren as an iterator.
58    Left to right depth first.
59    """
60
61    def get_children(parent) -> Iterator:
62        yield parent
63        if parent.type in ["root", "element"]:
64            for child in parent.children:
65                yield from get_children(child)
66
67    yield node
68    if node.type in ["root", "element"]:
69        for child in visit_children(node):
70            yield from get_children(child)
71
72
73def visit_children(parent: Root | Element) -> Iterator:
74    """Traverse the children of a Root or Element as an iterator."""
75    for child in parent.children:
76        yield child
77
78
79def visit_all_after(start: NODE) -> Iterator:
80    """Recursively traverse the tree starting at given node."""
81
82    def get_children(parent) -> Iterator:
83        yield parent
84        if parent.type in ["root", "element"]:
85            for child in parent.children:
86                yield from get_children(child)
87
88    parent = start.parent
89    idx = parent.children.index(start)
90    if idx < len(parent.children) - 1:
91        for child in parent.children[idx + 1 :]:
92            yield from get_children(child)
14def path(node: NODE) -> list[NODE]:
15    """Get a list of nodes where each one is a child of
16    the other leading to the node passed in. This gives a
17    path to the node.
18
19    Does not include given node.
20
21    Args:
22        node (NODE): Node to find ancestors of.
23
24    Returns:
25        list[NODE]: List of nodes leading to the given node
26        starting from the root.
27    """
28    ancestors = []
29    while node.parent is not None:
30        ancestors = [node.parent, *ancestors]
31        node = node.parent
32
33    return ancestors

Get a list of nodes where each one is a child of the other leading to the node passed in. This gives a path to the node.

Does not include given node.

Arguments:
  • node (NODE): Node to find ancestors of.
Returns:

list[NODE]: List of nodes leading to the given node starting from the root.

35def path_names(node: NODE) -> list[str]:
36    """Get a list of nodes where each one is a child of
37    the other leading to the node passed in. This gives a
38    path to the node.
39
40    Does not include given node.
41
42    Args:
43        node (NODE): Node to find ancestors of.
44
45    Returns:
46        list[str]: List of nodes leading to the given node
47        starting from the root.
48    """
49    ancestors = []
50    while node.parent is not None and node.parent.type != "root":
51        ancestors = [node.parent.tag, *ancestors]
52        node = node.parent
53
54    return ancestors

Get a list of nodes where each one is a child of the other leading to the node passed in. This gives a path to the node.

Does not include given node.

Arguments:
  • node (NODE): Node to find ancestors of.
Returns:

list[str]: List of nodes leading to the given node starting from the root.

def walk( node: phml.core.nodes.nodes.Root | phml.core.nodes.nodes.Element) -> Iterator:
57def walk(node: Root | Element) -> Iterator:
58    """Recursively traverse the node and it's chidlren as an iterator.
59    Left to right depth first.
60    """
61
62    def get_children(parent) -> Iterator:
63        yield parent
64        if parent.type in ["root", "element"]:
65            for child in parent.children:
66                yield from get_children(child)
67
68    yield node
69    if node.type in ["root", "element"]:
70        for child in visit_children(node):
71            yield from get_children(child)

Recursively traverse the node and it's chidlren as an iterator. Left to right depth first.

def visit_children( parent: phml.core.nodes.nodes.Root | phml.core.nodes.nodes.Element) -> Iterator:
74def visit_children(parent: Root | Element) -> Iterator:
75    """Traverse the children of a Root or Element as an iterator."""
76    for child in parent.children:
77        yield child

Traverse the children of a Root or Element as an iterator.

80def visit_all_after(start: NODE) -> Iterator:
81    """Recursively traverse the tree starting at given node."""
82
83    def get_children(parent) -> Iterator:
84        yield parent
85        if parent.type in ["root", "element"]:
86            for child in parent.children:
87                yield from get_children(child)
88
89    parent = start.parent
90    idx = parent.children.index(start)
91    if idx < len(parent.children) - 1:
92        for child in parent.children[idx + 1 :]:
93            yield from get_children(child)

Recursively traverse the tree starting at given node.