11# -*- coding: utf-8 -*-
22# Copyright © 2017 Kevin Thibedeau
33# Distributed under the terms of the MIT license
4+ """
5+ VHDL documentation parser
6+ """
47import ast
58import io
69import os
710import re
811from pprint import pprint
9- from typing import List , Optional
12+ from typing import Any , Dict , List , Optional , Set
1013from .minilexer import MiniLexer
1114
12- """VHDL documentation parser"""
1315
1416vhdl_tokens = {
1517 'root' : [
@@ -172,13 +174,15 @@ def __init__(self, name, desc=None):
172174 self .kind = 'unknown'
173175 self .desc = desc
174176
177+
175178def remove_outer_parenthesis (s : Optional [str ]):
176179 if s :
177180 n = 1
178181 while n :
179182 s , n = re .subn (r'\([^()]*\)' , '' , s .strip ()) # remove non-nested/flat balanced parts
180183 return s
181184
185+
182186class VhdlParameterType :
183187 """Parameter type definition
184188
@@ -213,7 +217,7 @@ class VhdlParameter:
213217 param_desc (optional str): Description of the parameter
214218 """
215219
216- 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 ):
220+ def __init__ (self , name , mode : Optional [str ] = None , data_type : Optional [VhdlParameterType ] = None , default_value : Optional [str ] = None , desc : Optional [str ] = None ):
217221 self .name = name
218222 self .mode = mode
219223 self .data_type = data_type
@@ -356,6 +360,7 @@ def __repr__(self):
356360
357361class VhdlEntity (VhdlObject ):
358362 """Entity declaration
363+
359364 Args:
360365 name (str): Name of the entity
361366 ports (list of VhdlParameter): Port parameters to the entity
@@ -364,20 +369,20 @@ class VhdlEntity(VhdlObject):
364369 desc (str, optional): Description from object metacomments
365370 """
366371
367- def __init__ (self , name : str , ports : List [VhdlParameter ], generics : List [VhdlParameter ] = [] , sections : List [str ] = [] , desc : Optional [str ] = None ):
372+ def __init__ (self , name : str , ports : List [VhdlParameter ], generics : Optional [ List [VhdlParameter ]] = None , sections : Optional [ List [str ]] = None , desc : Optional [str ] = None ):
368373 VhdlObject .__init__ (self , name , desc )
369374 self .kind = 'entity'
370- self .generics = generics if generics is not None else []
375+ self .generics = generics if generics else []
371376 self .ports = ports
372- self .sections = sections if sections is not None else {}
377+ self .sections = sections if sections else {}
373378
374379 def __repr__ (self ):
375380 return f"VhdlEntity('{ self .name } ')"
376381
377382 def dump (self ):
378383 print (f"VHDL entity: { self .name } " )
379- for p in self .ports :
380- print (f"\t { p .name } ({ type (p .name )} ), { p .data_type } ({ type (p .data_type )} )" )
384+ for port in self .ports :
385+ print (f"\t { port .name } ({ type (port .name )} ), { port .data_type } ({ type (port .data_type )} )" )
381386
382387
383388class VhdlComponent (VhdlObject ):
@@ -405,8 +410,8 @@ def __repr__(self):
405410
406411 def dump (self ):
407412 print (f"VHDL component: { self .name } " )
408- for p in self .ports :
409- print (f"\t { p .name } ({ type (p .name )} ), { p .data_type } ({ type (p .data_type )} )" )
413+ for port in self .ports :
414+ print (f"\t { port .name } ({ type (port .name )} ), { port .data_type } ({ type (port .data_type )} )" )
410415
411416
412417def parse_vhdl_file (fname ):
@@ -417,7 +422,7 @@ def parse_vhdl_file(fname):
417422 Returns:
418423 Parsed objects.
419424 """
420- with open (fname , 'rt' ) as fh :
425+ with open (fname , 'rt' , encoding = 'UTF-8' ) as fh :
421426 text = fh .read ()
422427 return parse_vhdl (text )
423428
@@ -540,9 +545,9 @@ def parse_vhdl(text):
540545 ptype = groups [0 ]
541546 last_items = []
542547 for i in param_items :
543- p = VhdlParameter (i , 'in' , VhdlParameterType (ptype ))
544- generics .append (p )
545- last_items .append (p )
548+ param = VhdlParameter (i , 'in' , VhdlParameterType (ptype ))
549+ generics .append (param )
550+ last_items .append (param )
546551
547552 param_items = []
548553
@@ -559,9 +564,9 @@ def parse_vhdl(text):
559564
560565 last_items = []
561566 for i in param_items :
562- p = VhdlParameter (i , mode , VhdlParameterType (ptype ))
563- ports .append (p )
564- last_items .append (p )
567+ param = VhdlParameter (i , mode , VhdlParameterType (ptype ))
568+ ports .append (param )
569+ last_items .append (param )
565570
566571 param_items = []
567572
@@ -581,9 +586,9 @@ def parse_vhdl(text):
581586
582587 last_items = []
583588 for i in param_items :
584- p = VhdlParameter (i , mode , VhdlParameterType (ptype , direction , r_bound , l_bound , arange ))
585- ports .append (p )
586- last_items .append (p )
589+ param = VhdlParameter (i , mode , VhdlParameterType (ptype , direction , r_bound , l_bound , arange ))
590+ ports .append (param )
591+ last_items .append (param )
587592
588593 param_items = []
589594
@@ -666,6 +671,7 @@ def subprogram_signature(vo, fullname=None):
666671
667672 Args:
668673 vo (VhdlFunction, VhdlProcedure): Subprogram object
674+ fullname (None, str): Override object name
669675 Returns:
670676 Signature string.
671677 """
@@ -701,12 +707,12 @@ class VhdlExtractor:
701707 array_types(set): Initial array types
702708 """
703709
704- def __init__ (self , array_types = set () ):
710+ def __init__ (self , array_types : Set [ str ] = None ):
705711 self .array_types = set (('std_ulogic_vector' , 'std_logic_vector' ,
706712 'signed' , 'unsigned' , 'bit_vector' ))
707-
708- self .array_types |= array_types
709- self .object_cache = {}
713+ if array_types :
714+ self .array_types |= array_types
715+ self .object_cache : Dict [ str , Any ] = {} # Any -> VhdlObject
710716
711717 def extract_objects (self , fname , type_filter = None ):
712718 """Extract objects from a source file
@@ -730,9 +736,10 @@ def extract_objects(self, fname, type_filter=None):
730736 if type_filter :
731737 if not isinstance (type_filter , list ):
732738 type_filter = [type_filter ]
733- objects = [
734- o for o in objects if any (map (lambda clz : isinstance (o , clz ), type_filter ))
735- ]
739+
740+ def type_is_in_filter (obj ):
741+ return any (map (lambda clz : isinstance (obj , clz ), type_filter ))
742+ objects = [o for o in objects if type_is_in_filter (o )]
736743
737744 return objects
738745
@@ -779,7 +786,7 @@ def load_array_types(self, fname):
779786 fname (str): Name of file to load array database from
780787 """
781788 type_defs = ''
782- with open (fname , 'rt' ) as fh :
789+ with open (fname , 'rt' , encoding = 'UTF-8' ) as fh :
783790 type_defs = fh .read ()
784791
785792 try :
@@ -796,7 +803,7 @@ def save_array_types(self, fname):
796803 fname (str): Name of file to save array database to
797804 """
798805 type_defs = {'arrays' : sorted (list (self .array_types ))}
799- with open (fname , 'wt' ) as fh :
806+ with open (fname , 'wt' , encoding = 'UTF-8' ) as fh :
800807 pprint (type_defs , stream = fh )
801808
802809 def _register_array_types (self , objects ):
0 commit comments