The goal of this code is to print the entity tree of a VHDL project. There are a readme and very minimal tests on the github repo.
I am trying to refactor the code to use generators in order to familiarize myself with yield, and to think in terms of iterators, not raw data structures. Here is my current attempt at doing so:
import re
from sys import argv
from os import walk
from os.path import join as pjoin
EXCLUDES = ["implementation", "testbench"]
BASIC_ID_REGEX = "[a-z][a-z0-9]*(?:_[a-z0-9]+)*"
def _vhdltree(level, filepath, pattern, vhd_files):
for entity, component in find_entities(filepath, pattern):
"""Codereview: I am not specifically interested in feedbacks for the
following snippet (except about the recursive design), but if you
have a particularly elegant
solution which keeps the "UI" part very minimal, suggestions
are welcome"""
path = vhd_files.get(component.lower(), "Not Found")
print(" "*level + entity + " : " + path)
if path != "Not Found":#Probably ugly, but lazy
_vhdltree(level+1, path, pattern, vhd_files)
def find_entities(filepath, pattern):
with open(filepath) as f:
for l in f:
m = pattern.match(l)
if m:
yield m.group('entity'), m.group('component').split(".")[-1]
def find_vhd(proot):
for (dirpath, dirnames, filenames) in walk(proot):
if not isexcluded(dirpath.lower()):
for fn in filenames:
if fn[-4:].lower() == ".vhd":
yield fn[:-4].lower(), pjoin(dirpath, fn)
def isexcluded(path):
for excluder in EXCLUDES:
if excluder in path:
return True
return False
def vhdltree(filepath, proot):
instantiation_regex = ("\s*(?P<entity>{0})\s*:\s*entity\s*(?P<component>{0}(?:\.{0})*)" # NOQA
.format(BASIC_ID_REGEX))
p = re.compile(instantiation_regex, re.IGNORECASE)
vhd_files = dict(find_vhd(proot))
_vhdltree(0, filepath, p, vhd_files)
if __name__ == "__main__":
#Codereview: user is trusted, don't care about this part
vhdltree(argv[1], argv[2])
Any feedback about the use of generators is welcome. Specifically, I wonder if it would be possible to avoid "realizing" the vhd_files generator as a dict while keeping the search in _vhdltree as simple as a get? Are there more pythonic alternatives or more efficient solutions for a structure designed to be one-wa searchable (I know this is probably never where the program spends its time, but I'd like to know for my general culture). I looked in itertools but didn't find an immediate solution.
I am interested in modern, Python3 solutions for my general knowledge. From a practical point of view however, the code is supposed to be 2-compatible.