From 98c5116f102d42671b1c3fc44683f0a7349013b0 Mon Sep 17 00:00:00 2001 From: Kamyar Mohajerani Date: Wed, 9 Mar 2022 15:16:03 -0500 Subject: [PATCH 1/5] fix VhdlExtractor.is_array + use setup.cfg + clean --- hdlparse/__init__.py | 1 + hdlparse/minilexer.py | 9 +++-- hdlparse/verilog_parser.py | 7 ++-- hdlparse/vhdl_parser.py | 83 +++++++++++++++++++++----------------- setup.cfg | 31 ++++++++++++++ setup.py | 43 +------------------- 6 files changed, 86 insertions(+), 88 deletions(-) create mode 100644 setup.cfg diff --git a/hdlparse/__init__.py b/hdlparse/__init__.py index e69de29..6df8ed0 100644 --- a/hdlparse/__init__.py +++ b/hdlparse/__init__.py @@ -0,0 +1 @@ +__version__ = '1.1.0' \ No newline at end of file diff --git a/hdlparse/minilexer.py b/hdlparse/minilexer.py index 00936e9..dda7019 100644 --- a/hdlparse/minilexer.py +++ b/hdlparse/minilexer.py @@ -6,12 +6,13 @@ """Minimalistic lexer engine inspired by the PyPigments RegexLexer""" -__version__ = '1.0.7' log = logging.getLogger(__name__) -handler = logging.StreamHandler() -handler.setFormatter(logging.Formatter('%(name)s - %(levelname)s - %(message)s')) -log.addHandler(handler) + +if not log.handlers: # only add the handler if no handlers are already registered + handler = logging.StreamHandler() + handler.setFormatter(logging.Formatter('%(name)s - %(levelname)s - %(message)s')) + log.addHandler(handler) class MiniLexer(object): diff --git a/hdlparse/verilog_parser.py b/hdlparse/verilog_parser.py index 1add1d8..a1f8f36 100644 --- a/hdlparse/verilog_parser.py +++ b/hdlparse/verilog_parser.py @@ -4,8 +4,7 @@ import io import os from collections import OrderedDict - -from hdlparse.minilexer import MiniLexer +from .minilexer import MiniLexer """Verilog documentation parser""" @@ -25,7 +24,7 @@ r'^[\(\s]*(input|inout|output)\s+(reg|supply0|supply1|tri|triand|trior|tri0|tri1|wire|wand|wor)?' r'\s*(signed)?\s*((\[[^]]+\])+)?', 'module_port_start', 'module_port'), - (r'endmodule', 'end_module', '#pop'), + (r'\bendmodule\b', 'end_module', '#pop'), (r'/\*', 'block_comment', 'block_comment'), (r'//#\s*{{(.*)}}\n', 'section_meta'), (r'//.*\n', None), @@ -226,7 +225,7 @@ def is_verilog(fname): Returns: True when file has a Verilog extension. """ - return os.path.splitext(fname)[1].lower() in ('.vlog', '.v') + return os.path.splitext(fname)[1].lower() in ('.vlog', '.v', '.sv') class VerilogExtractor: diff --git a/hdlparse/vhdl_parser.py b/hdlparse/vhdl_parser.py index 1e11eb9..1f9ca2f 100644 --- a/hdlparse/vhdl_parser.py +++ b/hdlparse/vhdl_parser.py @@ -6,7 +6,8 @@ import os import re from pprint import pprint -from hdlparse.minilexer import MiniLexer +from typing import List, Optional +from .minilexer import MiniLexer """VHDL documentation parser""" @@ -171,20 +172,48 @@ def __init__(self, name, desc=None): self.kind = 'unknown' self.desc = desc +def remove_outer_parenthesis(s: Optional[str]): + if s: + n = 1 + while n: + s, n = re.subn(r'\([^()]*\)', '', s.strip()) # remove non-nested/flat balanced parts + return s + +class VhdlParameterType: + """Parameter type definition + + Args: + name (str): Name of the type + direction(str): "to" or "downto" + r_bound (str): A simple expression based on digits or variable names + l_bound (str): A simple expression based on digits or variable names + arange (str): Original array range string + """ + + def __init__(self, name, direction="", r_bound="", l_bound="", arange=""): + self.name = name + self.direction = direction.lower().strip() + self.r_bound = r_bound.strip() + self.l_bound = l_bound.strip() + self.arange = arange + + def __repr__(self): + return f"VhdlParameterType('{self.name}','{self.arange}')" + class VhdlParameter: """Parameter to subprograms, ports, and generics Args: name (str): Name of the object - mode (str): Direction mode for the parameter - data_type (str): Type name for the parameter - default_value (str): Default value of the parameter - desc (str): Description from object metacomments - param_desc (str): Description of the parameter + mode (optional str): Direction mode for the parameter + data_type (optional VhdlParameterType): Type name for the parameter + default_value (optional str): Default value of the parameter + desc (optional str): Description from object metacomments + param_desc (optional str): Description of the parameter """ - def __init__(self, name, mode=None, data_type=None, default_value=None, desc=None, param_desc=None): + def __init__(self, name, mode: Optional[str] = None, data_type: Optional[VhdlParameterType] = None, default_value: Optional[str] = None, desc: Optional[str] = None, param_desc: Optional[str] = None): self.name = name self.mode = mode self.data_type = data_type @@ -210,28 +239,6 @@ def __repr__(self): return f"VhdlParameter('{self.name}', '{self.mode}', '{self.data_type.name + self.data_type.arange}')" -class VhdlParameterType: - """Parameter type definition - - Args: - name (str): Name of the type - direction(str): "to" or "downto" - r_bound (str): A simple expression based on digits or variable names - l_bound (str): A simple expression based on digits or variable names - arange (str): Original array range string - """ - - def __init__(self, name, direction="", r_bound="", l_bound="", arange=""): - self.name = name - self.direction = direction.strip() - self.r_bound = r_bound.strip() - self.l_bound = l_bound.strip() - self.arange = arange - - def __repr__(self): - return f"VhdlParameterType('{self.name}','{self.arange}')" - - class VhdlPackage(VhdlObject): """Package declaration @@ -357,7 +364,7 @@ class VhdlEntity(VhdlObject): desc (str, optional): Description from object metacomments """ - def __init__(self, name, ports, generics=None, sections=None, desc=None): + def __init__(self, name: str, ports: List[VhdlParameter], generics: List[VhdlParameter] = [], sections: List[str] = [], desc: Optional[str] = None): VhdlObject.__init__(self, name, desc) self.kind = 'entity' self.generics = generics if generics is not None else [] @@ -602,7 +609,7 @@ def parse_vhdl(text): saved_type = groups[0] elif action in ( - 'array_type', 'file_type', 'access_type', 'record_type', 'range_type', 'enum_type', 'incomplete_type'): + 'array_type', 'file_type', 'access_type', 'record_type', 'range_type', 'enum_type', 'incomplete_type'): vobj = VhdlType(saved_type, cur_package, action, metacomments) objects.append(vobj) kind = None @@ -684,7 +691,7 @@ def is_vhdl(fname): Returns: True when file has a VHDL extension. """ - return os.path.splitext(fname)[1].lower() in ('.vhdl', '.vhd') + return os.path.splitext(fname)[-1].lower() in ('.vhdl', '.vhd') class VhdlExtractor: @@ -721,7 +728,11 @@ def extract_objects(self, fname, type_filter=None): self._register_array_types(objects) if type_filter: - objects = [o for o in objects if isinstance(o, type_filter)] + if not isinstance(type_filter, list): + type_filter = [type_filter] + objects = [ + o for o in objects if any(map(lambda clz: isinstance(o, clz), type_filter)) + ] return objects @@ -750,11 +761,7 @@ def is_array(self, data_type): Returns: True if ``data_type`` is a known array type. """ - - # Split off any brackets - data_type = data_type.split('[')[0].strip() - - return data_type.lower() in self.array_types + return data_type.name.lower() in self.array_types def _add_array_types(self, type_defs): """Add array data types to internal registry diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..2cb2386 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,31 @@ +[metadata] +name = hdlparse +author = Kevin Thibedeau +author_email = kevin.thibedeau@gmail.com +url = http://kevinpt.github.io/hdlparse +download_url = http://kevinpt.github.io/hdlparse +description = HDL parser +long_description = file: README.rst +description_file = README.rst +version = attr: hdlparse.__version__ +license = MIT +keywords = HDL parser +classifiers = + Development Status :: 5 - Production/Stable + Operating System :: OS Independent + Intended Audience :: Developers + Topic :: Text Processing :: General + Natural Language :: English + Programming Language :: Python :: 3 + License :: OSI Approved :: MIT License + +[options] +packages = hdlparse +py_modules = +install_requires = +include_package_data = True + + +[pycodestyle] +max_line_length = 120 +ignore = E501 \ No newline at end of file diff --git a/setup.py b/setup.py index 29e2e86..6068493 100755 --- a/setup.py +++ b/setup.py @@ -1,44 +1,3 @@ from setuptools import setup -# Use README.rst for the long description -with open('README.rst') as fh: - long_description = fh.read() - -# Scan the script for the version string -version_file = 'hdlparse/minilexer.py' -version = None -with open(version_file) as fh: - try: - version = [line.split('=')[1].strip().strip("'") for line in fh if - line.startswith('__version__')][0] - except IndexError: - pass - -if version is None: - raise RuntimeError('Unable to find version string in file: {0}'.format(version_file)) - -setup(name='hdlparse', - version=version, - author='Kevin Thibedeau', - author_email='kevin.thibedeau@gmail.com', - url='http://kevinpt.github.io/hdlparse', - download_url='http://kevinpt.github.io/hdlparse', - description='HDL parser', - long_description=long_description, - platforms=['Any'], - install_requires=[], - packages=['hdlparse'], - py_modules=[], - include_package_data=True, - - keywords='HDL parser', - license='MIT', - classifiers=['Development Status :: 5 - Production/Stable', - 'Operating System :: OS Independent', - 'Intended Audience :: Developers', - 'Topic :: Text Processing :: General', - 'Natural Language :: English', - 'Programming Language :: Python :: 3', - 'License :: OSI Approved :: MIT License' - ] - ) +setup() From c3b4cdf8014a78a9caf41755aed9496a98b31c18 Mon Sep 17 00:00:00 2001 From: Kamyar Mohajerani Date: Wed, 9 Mar 2022 16:41:10 -0500 Subject: [PATCH 2/5] +is_verilog --- hdlparse/verilog_parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hdlparse/verilog_parser.py b/hdlparse/verilog_parser.py index a1f8f36..73aec0e 100644 --- a/hdlparse/verilog_parser.py +++ b/hdlparse/verilog_parser.py @@ -225,7 +225,7 @@ def is_verilog(fname): Returns: True when file has a Verilog extension. """ - return os.path.splitext(fname)[1].lower() in ('.vlog', '.v', '.sv') + return os.path.splitext(fname)[-1].lower() in ('.vlog', '.v', '.sv') class VerilogExtractor: From c3b8a07fadc8186faebe9abe382ea3e12d5beed5 Mon Sep 17 00:00:00 2001 From: Kamyar Mohajerani Date: Thu, 10 Mar 2022 12:49:53 -0500 Subject: [PATCH 3/5] pylint fixes --- doc/conf.py | 2 +- hdlparse/__init__.py | 5 ++- hdlparse/minilexer.py | 10 +++--- hdlparse/verilog_parser.py | 18 +++++------ hdlparse/vhdl_parser.py | 65 +++++++++++++++++++++----------------- setup.cfg | 12 +++++-- 6 files changed, 65 insertions(+), 47 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index 10af14c..82a2984 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -55,7 +55,7 @@ # def get_package_version(verfile): - '''Scan the script for the version string''' + """Scan the script for the version string""" version = None with open(verfile) as fh: try: diff --git a/hdlparse/__init__.py b/hdlparse/__init__.py index 6df8ed0..70ccacf 100644 --- a/hdlparse/__init__.py +++ b/hdlparse/__init__.py @@ -1 +1,4 @@ -__version__ = '1.1.0' \ No newline at end of file +""" +Parse Verilog and VHDL files +""" +__version__ = '1.1.0' diff --git a/hdlparse/minilexer.py b/hdlparse/minilexer.py index dda7019..04c4a80 100644 --- a/hdlparse/minilexer.py +++ b/hdlparse/minilexer.py @@ -1,10 +1,12 @@ # -*- coding: utf-8 -*- # Copyright © 2017 Kevin Thibedeau # Distributed under the terms of the MIT license +""" +Minimalistic lexer engine inspired by the PyPigments RegexLexer +""" import re import logging -"""Minimalistic lexer engine inspired by the PyPigments RegexLexer""" log = logging.getLogger(__name__) @@ -15,7 +17,7 @@ log.addHandler(handler) -class MiniLexer(object): +class MiniLexer(): """Simple lexer state machine with regex matching rules""" def __init__(self, tokens, flags=re.MULTILINE): @@ -54,7 +56,7 @@ def run(self, text): text (str): Text to apply lexer to Yields: - A sequence of lexer matches. + A sequence of lexer matches """ stack = ['root'] @@ -67,7 +69,7 @@ def run(self, text): m = pat.match(text, pos) if m: if action: - log.debug(f"Match: {m.group().strip()} -> {action}") + log.debug("Match: %s -> %s", m.group().strip(), action) yield (pos, m.end() - 1), action, m.groups() diff --git a/hdlparse/verilog_parser.py b/hdlparse/verilog_parser.py index 73aec0e..590de24 100644 --- a/hdlparse/verilog_parser.py +++ b/hdlparse/verilog_parser.py @@ -1,12 +1,14 @@ # -*- coding: utf-8 -*- # Copyright © 2017 Kevin Thibedeau # Distributed under the terms of the MIT license +""" +Verilog documentation parser +""" import io import os from collections import OrderedDict from .minilexer import MiniLexer -"""Verilog documentation parser""" verilog_tokens = { # state @@ -109,11 +111,12 @@ def parse_verilog_file(fname): """Parse a named Verilog file Args: - fname (str): File to parse. + fname (str): File to parse + Returns: - List of parsed objects. + List of parsed objects """ - with open(fname, 'rt') as fh: + with open(fname, 'rt', encoding='UTF-8') as fh: text = fh.read() return parse_verilog(text) @@ -129,25 +132,21 @@ def parse_verilog(text): lex = VerilogLexer name = None - kind = None - saved_type = None mode = 'input' port_type = 'wire' param_type = '' metacomments = [] - parameters = [] generics = [] ports = OrderedDict() sections = [] port_param_index = 0 last_item = None - array_range_start_pos = 0 objects = [] - for pos, action, groups in lex.run(text): + for _, action, groups in lex.run(text): if action == 'metacomment': comment = groups[0].strip() if last_item is None: @@ -159,7 +158,6 @@ def parse_verilog(text): sections.append((port_param_index, groups[0])) elif action == 'module': - kind = 'module' name = groups[0] generics = [] ports = OrderedDict() diff --git a/hdlparse/vhdl_parser.py b/hdlparse/vhdl_parser.py index 1f9ca2f..9330be3 100644 --- a/hdlparse/vhdl_parser.py +++ b/hdlparse/vhdl_parser.py @@ -1,15 +1,17 @@ # -*- coding: utf-8 -*- # Copyright © 2017 Kevin Thibedeau # Distributed under the terms of the MIT license +""" +VHDL documentation parser +""" import ast import io import os import re from pprint import pprint -from typing import List, Optional +from typing import Any, Dict, List, Optional, Set from .minilexer import MiniLexer -"""VHDL documentation parser""" vhdl_tokens = { 'root': [ @@ -172,6 +174,7 @@ def __init__(self, name, desc=None): self.kind = 'unknown' self.desc = desc + def remove_outer_parenthesis(s: Optional[str]): if s: n = 1 @@ -179,6 +182,7 @@ def remove_outer_parenthesis(s: Optional[str]): s, n = re.subn(r'\([^()]*\)', '', s.strip()) # remove non-nested/flat balanced parts return s + class VhdlParameterType: """Parameter type definition @@ -213,7 +217,7 @@ class VhdlParameter: param_desc (optional str): Description of the parameter """ - def __init__(self, name, mode: Optional[str] = None, data_type: Optional[VhdlParameterType] = None, default_value: Optional[str] = None, desc: Optional[str] = None, param_desc: Optional[str] = None): + def __init__(self, name, mode: Optional[str] = None, data_type: Optional[VhdlParameterType] = None, default_value: Optional[str] = None, desc: Optional[str] = None): self.name = name self.mode = mode self.data_type = data_type @@ -356,6 +360,7 @@ def __repr__(self): class VhdlEntity(VhdlObject): """Entity declaration + Args: name (str): Name of the entity ports (list of VhdlParameter): Port parameters to the entity @@ -364,20 +369,20 @@ class VhdlEntity(VhdlObject): desc (str, optional): Description from object metacomments """ - def __init__(self, name: str, ports: List[VhdlParameter], generics: List[VhdlParameter] = [], sections: List[str] = [], desc: Optional[str] = None): + def __init__(self, name: str, ports: List[VhdlParameter], generics: Optional[List[VhdlParameter]] = None, sections: Optional[List[str]] = None, desc: Optional[str] = None): VhdlObject.__init__(self, name, desc) self.kind = 'entity' - self.generics = generics if generics is not None else [] + self.generics = generics if generics else [] self.ports = ports - self.sections = sections if sections is not None else {} + self.sections = sections if sections else {} def __repr__(self): return f"VhdlEntity('{self.name}')" def dump(self): print(f"VHDL entity: {self.name}") - for p in self.ports: - print(f"\t{p.name} ({type(p.name)}), {p.data_type} ({type(p.data_type)})") + for port in self.ports: + print(f"\t{port.name} ({type(port.name)}), {port.data_type} ({type(port.data_type)})") class VhdlComponent(VhdlObject): @@ -405,8 +410,8 @@ def __repr__(self): def dump(self): print(f"VHDL component: {self.name}") - for p in self.ports: - print(f"\t{p.name} ({type(p.name)}), {p.data_type} ({type(p.data_type)})") + for port in self.ports: + print(f"\t{port.name} ({type(port.name)}), {port.data_type} ({type(port.data_type)})") def parse_vhdl_file(fname): @@ -417,7 +422,7 @@ def parse_vhdl_file(fname): Returns: Parsed objects. """ - with open(fname, 'rt') as fh: + with open(fname, 'rt', encoding='UTF-8') as fh: text = fh.read() return parse_vhdl(text) @@ -540,9 +545,9 @@ def parse_vhdl(text): ptype = groups[0] last_items = [] for i in param_items: - p = VhdlParameter(i, 'in', VhdlParameterType(ptype)) - generics.append(p) - last_items.append(p) + param = VhdlParameter(i, 'in', VhdlParameterType(ptype)) + generics.append(param) + last_items.append(param) param_items = [] @@ -559,9 +564,9 @@ def parse_vhdl(text): last_items = [] for i in param_items: - p = VhdlParameter(i, mode, VhdlParameterType(ptype)) - ports.append(p) - last_items.append(p) + param = VhdlParameter(i, mode, VhdlParameterType(ptype)) + ports.append(param) + last_items.append(param) param_items = [] @@ -581,9 +586,9 @@ def parse_vhdl(text): last_items = [] for i in param_items: - p = VhdlParameter(i, mode, VhdlParameterType(ptype, direction, r_bound, l_bound, arange)) - ports.append(p) - last_items.append(p) + param = VhdlParameter(i, mode, VhdlParameterType(ptype, direction, r_bound, l_bound, arange)) + ports.append(param) + last_items.append(param) param_items = [] @@ -666,6 +671,7 @@ def subprogram_signature(vo, fullname=None): Args: vo (VhdlFunction, VhdlProcedure): Subprogram object + fullname (None, str): Override object name Returns: Signature string. """ @@ -701,12 +707,12 @@ class VhdlExtractor: array_types(set): Initial array types """ - def __init__(self, array_types=set()): + def __init__(self, array_types: Set[str] = None): self.array_types = set(('std_ulogic_vector', 'std_logic_vector', 'signed', 'unsigned', 'bit_vector')) - - self.array_types |= array_types - self.object_cache = {} + if array_types: + self.array_types |= array_types + self.object_cache: Dict[str, Any] = {} # Any -> VhdlObject def extract_objects(self, fname, type_filter=None): """Extract objects from a source file @@ -730,9 +736,10 @@ def extract_objects(self, fname, type_filter=None): if type_filter: if not isinstance(type_filter, list): type_filter = [type_filter] - objects = [ - o for o in objects if any(map(lambda clz: isinstance(o, clz), type_filter)) - ] + + def type_is_in_filter(obj): + return any(map(lambda clz: isinstance(obj, clz), type_filter)) + objects = [o for o in objects if type_is_in_filter(o)] return objects @@ -779,7 +786,7 @@ def load_array_types(self, fname): fname (str): Name of file to load array database from """ type_defs = '' - with open(fname, 'rt') as fh: + with open(fname, 'rt', encoding='UTF-8') as fh: type_defs = fh.read() try: @@ -796,7 +803,7 @@ def save_array_types(self, fname): fname (str): Name of file to save array database to """ type_defs = {'arrays': sorted(list(self.array_types))} - with open(fname, 'wt') as fh: + with open(fname, 'wt', encoding='UTF-8') as fh: pprint(type_defs, stream=fh) def _register_array_types(self, objects): diff --git a/setup.cfg b/setup.cfg index 2cb2386..23b5041 100644 --- a/setup.cfg +++ b/setup.cfg @@ -25,7 +25,15 @@ py_modules = install_requires = include_package_data = True - [pycodestyle] max_line_length = 120 -ignore = E501 \ No newline at end of file +ignore = E501 + +[pydocstyle] +ignore = D100,D102,D103,D105,D107,D202,D203,D213,D400,D405,D406,D407,D413,D415 + +[pylint] +disable = + C0103,C0301,C0103,C0116,R0201,R0801,R0903,R0912,R0913,R0914,R0915,W0702 +ignore-docstrings = yes +output-format = colorized \ No newline at end of file From d05c5ca288277e696cae70cf5d6f5d39219c5562 Mon Sep 17 00:00:00 2001 From: Kamyar Mohajerani Date: Thu, 10 Mar 2022 13:00:42 -0500 Subject: [PATCH 4/5] more lint/formating fixes --- doc/conf.py | 48 ++++++++++++++++++-------------------- hdlparse/__init__.py | 4 +--- hdlparse/minilexer.py | 5 +--- hdlparse/verilog_parser.py | 4 +--- hdlparse/vhdl_parser.py | 12 ++++------ setup.cfg | 2 +- 6 files changed, 32 insertions(+), 43 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index 82a2984..4bd7dcb 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -45,25 +45,26 @@ master_doc = 'index' # General information about the project. -project = u'Hdlparse' -copyright = u'2017, Kevin Thibedeau' -author = u'Kevin Thibedeau' +project = 'Hdlparse' +copyright = '2017, Kevin Thibedeau' +author = 'Kevin Thibedeau' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. -# + def get_package_version(verfile): - """Scan the script for the version string""" - version = None - with open(verfile) as fh: - try: - version = [line.split('=')[1].strip().strip("'") for line in fh if \ - line.startswith('__version__')][0] - except IndexError: - pass - return version + """Scan the script for the version string""" + version = None + with open(verfile) as fh: + try: + version = [line.split('=')[1].strip().strip("'") for line in fh if + line.startswith('__version__')][0] + except IndexError: + pass + return version + # The short X.Y version. version = get_package_version('../hdlparse/minilexer.py') @@ -102,13 +103,13 @@ def get_package_version(verfile): # # html_theme_options = {} html_theme_options = { - 'description': 'HDL parsing library', - 'show_powered_by': False, - 'logo_text_align': 'center', - 'font_family': 'Verdana, Geneva, sans-serif', - 'github_user': 'kevinpt', - 'github_repo': 'hdlparse', - 'github_button': True + 'description': 'HDL parsing library', + 'show_powered_by': False, + 'logo_text_align': 'center', + 'font_family': 'Verdana, Geneva, sans-serif', + 'github_user': 'kevinpt', + 'github_repo': 'hdlparse', + 'github_button': True } # Add any paths that contain custom static files (such as style sheets) here, @@ -124,12 +125,12 @@ def get_package_version(verfile): html_sidebars = { '**': [ 'about.html', - 'relations.html', # needs 'show_related': True theme option to display + 'relations.html', # needs 'show_related': True theme option to display 'localtoc.html', 'projects.html', 'searchbox.html' ], - + 'index': [ 'about.html', 'download.html', @@ -196,6 +197,3 @@ def get_package_version(verfile): author, 'HdlParse', 'One line description of project.', 'Miscellaneous'), ] - - - diff --git a/hdlparse/__init__.py b/hdlparse/__init__.py index 70ccacf..571a96d 100644 --- a/hdlparse/__init__.py +++ b/hdlparse/__init__.py @@ -1,4 +1,2 @@ -""" -Parse Verilog and VHDL files -""" +"""Parse Verilog and VHDL files""" __version__ = '1.1.0' diff --git a/hdlparse/minilexer.py b/hdlparse/minilexer.py index 04c4a80..c36f6fd 100644 --- a/hdlparse/minilexer.py +++ b/hdlparse/minilexer.py @@ -1,14 +1,11 @@ # -*- coding: utf-8 -*- # Copyright © 2017 Kevin Thibedeau # Distributed under the terms of the MIT license -""" -Minimalistic lexer engine inspired by the PyPigments RegexLexer -""" +"""Minimalistic lexer engine inspired by the PyPigments RegexLexer""" import re import logging - log = logging.getLogger(__name__) if not log.handlers: # only add the handler if no handlers are already registered diff --git a/hdlparse/verilog_parser.py b/hdlparse/verilog_parser.py index 590de24..eac14cb 100644 --- a/hdlparse/verilog_parser.py +++ b/hdlparse/verilog_parser.py @@ -1,9 +1,7 @@ # -*- coding: utf-8 -*- # Copyright © 2017 Kevin Thibedeau # Distributed under the terms of the MIT license -""" -Verilog documentation parser -""" +"""Verilog documentation parser""" import io import os from collections import OrderedDict diff --git a/hdlparse/vhdl_parser.py b/hdlparse/vhdl_parser.py index 9330be3..dac8f85 100644 --- a/hdlparse/vhdl_parser.py +++ b/hdlparse/vhdl_parser.py @@ -1,9 +1,7 @@ # -*- coding: utf-8 -*- # Copyright © 2017 Kevin Thibedeau # Distributed under the terms of the MIT license -""" -VHDL documentation parser -""" +"""VHDL documentation parser""" import ast import io import os @@ -848,10 +846,10 @@ def register_array_types_from_sources(self, source_files): component acomp is port ( a,b,c : in std_ulogic; -- no default value - f,g,h : inout bit := '1'; -- bit ports + f,g,h : inout bit := '1'; -- bit ports v : in std_logic_vector(lBound -1 downto 0) -- array range ); -- port list comment - + end component; end package; @@ -864,11 +862,11 @@ def register_array_types_from_sources(self, source_files): try: for p in o.parameters: print(p) - except: + except AttributeError: pass try: for p in o.ports: print(p) - except: + except AttributeError: pass diff --git a/setup.cfg b/setup.cfg index 23b5041..2d60df6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -30,7 +30,7 @@ max_line_length = 120 ignore = E501 [pydocstyle] -ignore = D100,D102,D103,D105,D107,D202,D203,D213,D400,D405,D406,D407,D413,D415 +ignore = D100,D102,D103,D105,D202,D203,D213,D400,D405,D406,D407,D413,D415 [pylint] disable = From 7c1dcd23bd10ecf81c824591e3c73167ec790424 Mon Sep 17 00:00:00 2001 From: Kamyar Mohajerani Date: Wed, 2 Nov 2022 16:42:52 -0400 Subject: [PATCH 5/5] eval array bounds if possible --- hdlparse/vhdl_parser.py | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/hdlparse/vhdl_parser.py b/hdlparse/vhdl_parser.py index dac8f85..9f9f0f2 100644 --- a/hdlparse/vhdl_parser.py +++ b/hdlparse/vhdl_parser.py @@ -195,8 +195,8 @@ class VhdlParameterType: def __init__(self, name, direction="", r_bound="", l_bound="", arange=""): self.name = name self.direction = direction.lower().strip() - self.r_bound = r_bound.strip() - self.l_bound = l_bound.strip() + self.r_bound = r_bound + self.l_bound = l_bound self.arange = arange def __repr__(self): @@ -578,9 +578,32 @@ def parse_vhdl(text): elif action == 'array_range_val': l_bound, direction, r_bound = groups + if direction: + direction = direction.strip() + if l_bound: + try: + l_bound = l_bound.replace("/", "//") + l_bound = eval(l_bound) + except Exception: + pass + if r_bound: + try: + r_bound = r_bound.replace("/", "//") + r_bound = eval(r_bound) + except Exception: + pass elif action == 'array_range_end': - arange = text[array_range_start_pos:pos[0] + 1] + if l_bound and r_bound and direction: + arange = " ".join([l_bound, direction, r_bound]) + print("arange -> ", arange) + else: + arange = text[array_range_start_pos:pos[0] + 1] + # arange = arange.strip().lstrip("(") + # match = re.match("\s*\(?\s*(.*)\s+(downto|to)\s+(.*)\s*\)\s*", arange, re.IGNORECASE) + # if match: + # print("------", match.groups()) + # arange = " ".join(match.groups()) last_items = [] for i in param_items: @@ -731,6 +754,8 @@ def extract_objects(self, fname, type_filter=None): self.object_cache[fname] = objects self._register_array_types(objects) + print("objects=", objects) + if type_filter: if not isinstance(type_filter, list): type_filter = [type_filter]