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.