In [72]:
from collections import deque
from goetia import libgoetia

In [40]:
test = 'goetia::hashing::KmerIterator< goetia::hashing::HashShifter <goetia::hashing::Hash< uint64_t, size_t > >, DNA_SIMPLE >'

In [41]:
class Node:
    def __init__(self, string):
        tokens = string.strip().split('::')
        self.namespace = tuple(tokens[:-1])
        self.name = tokens[-1]
        self.children = []
        self.parent = None

    def __str__(self):
        return '::'.join(self.namespace + (self.name,))

    def __repr__(self):
        return str(self)

In [55]:
def parse_template(string):
    buffer = []
    stack = []
    root = None
    
    for c in string:
        if c == '<':
            n = Node(''.join(buffer))
            if root is not None:
                root.children.append(n)
                n.parent = root
            root = n
            print(n)
            stack.append(c)
            buffer = []
        elif c == '>':
            stack.pop()
            if buffer:
                n = Node(''.join(buffer))
                n.parent = root
                root.children.append(n)
                print(n)
                buffer = []
            if root.parent is not None:
                root = root.parent
        elif c == ',' and buffer:
            n = Node(''.join(buffer))
            root.children.append(n)
            n.parent = root
            buffer = []
            print(n)
        elif c not in '<> ,;':
            buffer.append(c)
    assert stack == []
    return root

In [56]:
root = parse_template(test)


goetia::hashing::KmerIterator
goetia::hashing::HashShifter
goetia::hashing::Hash
uint64_t
size_t
DNA_SIMPLE

In [71]:
cursor = root
seen = set()
process = deque([(1, n) for n in root.children])
print(0, root)
while process:
    level , node = process.popleft()
    process.extend([(level + 1, n) for n in node.children])
    print(level, node)


0 goetia::hashing::KmerIterator
1 goetia::hashing::HashShifter
1 DNA_SIMPLE
2 goetia::hashing::Hash
3 uint64_t
3 size_t

In [61]:
process = deque()

In [62]:
?process


Type:        deque
String form: deque([])
Length:      0
File:        ~/miniconda/envs/goetia-sourmash/lib/python3.7/collections/__init__.py
Docstring:  
deque([iterable[, maxlen]]) --> deque object

A list-like sequence optimized for data accesses near its endpoints.

In [77]:
parse_template(libgoetia.hashing.FwdLemireShifter.__name__).children[0].name


HashShifter
goetia::hashing::LemireShifterPolicy
goetia::hashing::Hash
unsignedlong
goetia::DNA_SIMPLE
Out[77]:
'LemireShifterPolicy'

In [81]:
libgoetia.hashing.FwdLemireShifter.NAME


Out[81]:
'goetia::hashing::HashShifter<goetia::hashing::LemireShifterPol'

In [ ]: