1
1
# -*- coding: utf-8 -*-
2
2
# Copyright © 2017 Kevin Thibedeau
3
3
# Distributed under the terms of the MIT license
4
+ """
5
+ VHDL documentation parser
6
+ """
4
7
import ast
5
8
import io
6
9
import os
7
10
import re
8
11
from pprint import pprint
9
- from typing import List , Optional
12
+ from typing import Any , Dict , List , Optional , Set
10
13
from .minilexer import MiniLexer
11
14
12
- """VHDL documentation parser"""
13
15
14
16
vhdl_tokens = {
15
17
'root' : [
@@ -172,13 +174,15 @@ def __init__(self, name, desc=None):
172
174
self .kind = 'unknown'
173
175
self .desc = desc
174
176
177
+
175
178
def remove_outer_parenthesis (s : Optional [str ]):
176
179
if s :
177
180
n = 1
178
181
while n :
179
182
s , n = re .subn (r'\([^()]*\)' , '' , s .strip ()) # remove non-nested/flat balanced parts
180
183
return s
181
184
185
+
182
186
class VhdlParameterType :
183
187
"""Parameter type definition
184
188
@@ -213,7 +217,7 @@ class VhdlParameter:
213
217
param_desc (optional str): Description of the parameter
214
218
"""
215
219
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 ):
217
221
self .name = name
218
222
self .mode = mode
219
223
self .data_type = data_type
@@ -356,6 +360,7 @@ def __repr__(self):
356
360
357
361
class VhdlEntity (VhdlObject ):
358
362
"""Entity declaration
363
+
359
364
Args:
360
365
name (str): Name of the entity
361
366
ports (list of VhdlParameter): Port parameters to the entity
@@ -364,20 +369,20 @@ class VhdlEntity(VhdlObject):
364
369
desc (str, optional): Description from object metacomments
365
370
"""
366
371
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 ):
368
373
VhdlObject .__init__ (self , name , desc )
369
374
self .kind = 'entity'
370
- self .generics = generics if generics is not None else []
375
+ self .generics = generics if generics else []
371
376
self .ports = ports
372
- self .sections = sections if sections is not None else {}
377
+ self .sections = sections if sections else {}
373
378
374
379
def __repr__ (self ):
375
380
return f"VhdlEntity('{ self .name } ')"
376
381
377
382
def dump (self ):
378
383
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 )} )" )
381
386
382
387
383
388
class VhdlComponent (VhdlObject ):
@@ -405,8 +410,8 @@ def __repr__(self):
405
410
406
411
def dump (self ):
407
412
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 )} )" )
410
415
411
416
412
417
def parse_vhdl_file (fname ):
@@ -417,7 +422,7 @@ def parse_vhdl_file(fname):
417
422
Returns:
418
423
Parsed objects.
419
424
"""
420
- with open (fname , 'rt' ) as fh :
425
+ with open (fname , 'rt' , encoding = 'UTF-8' ) as fh :
421
426
text = fh .read ()
422
427
return parse_vhdl (text )
423
428
@@ -540,9 +545,9 @@ def parse_vhdl(text):
540
545
ptype = groups [0 ]
541
546
last_items = []
542
547
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 )
546
551
547
552
param_items = []
548
553
@@ -559,9 +564,9 @@ def parse_vhdl(text):
559
564
560
565
last_items = []
561
566
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 )
565
570
566
571
param_items = []
567
572
@@ -581,9 +586,9 @@ def parse_vhdl(text):
581
586
582
587
last_items = []
583
588
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 )
587
592
588
593
param_items = []
589
594
@@ -666,6 +671,7 @@ def subprogram_signature(vo, fullname=None):
666
671
667
672
Args:
668
673
vo (VhdlFunction, VhdlProcedure): Subprogram object
674
+ fullname (None, str): Override object name
669
675
Returns:
670
676
Signature string.
671
677
"""
@@ -701,12 +707,12 @@ class VhdlExtractor:
701
707
array_types(set): Initial array types
702
708
"""
703
709
704
- def __init__ (self , array_types = set () ):
710
+ def __init__ (self , array_types : Set [ str ] = None ):
705
711
self .array_types = set (('std_ulogic_vector' , 'std_logic_vector' ,
706
712
'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
710
716
711
717
def extract_objects (self , fname , type_filter = None ):
712
718
"""Extract objects from a source file
@@ -730,9 +736,10 @@ def extract_objects(self, fname, type_filter=None):
730
736
if type_filter :
731
737
if not isinstance (type_filter , list ):
732
738
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 )]
736
743
737
744
return objects
738
745
@@ -779,7 +786,7 @@ def load_array_types(self, fname):
779
786
fname (str): Name of file to load array database from
780
787
"""
781
788
type_defs = ''
782
- with open (fname , 'rt' ) as fh :
789
+ with open (fname , 'rt' , encoding = 'UTF-8' ) as fh :
783
790
type_defs = fh .read ()
784
791
785
792
try :
@@ -796,7 +803,7 @@ def save_array_types(self, fname):
796
803
fname (str): Name of file to save array database to
797
804
"""
798
805
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 :
800
807
pprint (type_defs , stream = fh )
801
808
802
809
def _register_array_types (self , objects ):
0 commit comments