Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#!/usr/bin/python
def remove_gaps(buf, delims, gap_chars, lower_strings=False):
da={}
for d in delims:
da[d]=False
prev_is_gap = False
buf2=""
lines=[]
for c in buf:
for d in delims:
if(c==d):
da[d]=not da[d]
within_string = any(da.values()) and not (c in delims)
if(not within_string):
if(c in gap_chars):
if(not prev_is_gap):
prev_is_gap = True
buf2+=" "
else:
prev_is_gap = False
buf2+=c
if(c==";" or c=="\n"):
lines.append(buf2);
buf2=""
else:
buf2+=c;
prev_is_gap = False
return lines
from dep_solver import DepParser, DepRelation, DepFile
class VHDLParser(DepParser):
def parse(self, f_deps, filename):
f = open(filename,"r")
buf = ""
# stage 1: strip comments
for l in f:
ci = l.find("--")
if(ci==0):
continue
while(ci>0):
nquotes = l[:ci].count('"') # ignore comments in strings
if(nquotes % 2 == 0):
l=l[:ci-1];
break
ci= l.find("--", ci+1)
buf+=l
# stage 2: remove spaces, crs, lfs, strip strings (we don't need them)
buf2=""
string_literal = char_literal = False
prev_is_gap = False
gap_chars = " \r\n\t"
lines=[]
for c in buf:
if(c == '"' and not char_literal):
string_literal = not string_literal
if(c == "'" and not string_literal):
char_literal = not char_literal
within_string = (string_literal or char_literal) and (c != '"') and (c != "'")
if(not within_string):
if(c in gap_chars):
if(not prev_is_gap):
prev_is_gap = True
buf2+=" "
else:
prev_is_gap = False
buf2+=c.lower()
if(c==";"):
lines.append(buf2);
buf2=""
else:
prev_is_gap = False
import re
patterns = {
"use" : "^ *use *(\w+) *\. *(\w+) *. *\w+ *;",
"entity" : "^ *entity +(\w+) +is +(port|generic)",
"package" : "^ *package +(\w+) +is",
"arch_begin" : "^ *architecture +(\w+) +of +(\w+) +is +",
"arch_end" : "^ *end +(\w+) +;",
"instance" : "^ *(\w+) *\: *(\w+) *(port|generic) *map"
}
compiled_patterns = map(lambda p: (p,re.compile(patterns[p])), patterns)
within_architecture = False
for l in lines:
matches = filter(lambda(k,v): v!=None, map(lambda (k,v): (k,re.match(v,l)), compiled_patterns))
if(not len(matches)):
continue
what,g=matches[0]
if(what == "use"):
f_deps.add_relation(DepRelation(g.group(1)+"."+g.group(2), DepRelation.USE, DepRelation.PACKAGE))
if(what == "package"):
f_deps.add_relation(DepRelation(g.group(1), DepRelation.PROVIDE, DepRelation.PACKAGE))
elif(what == "entity"):
f_deps.add_relation(DepRelation(g.group(1), DepRelation.PROVIDE, DepRelation.ENTITY))
elif(what == "package"):
f_deps.add_relation(DepRelation(g.group(1), DepRelation.PROVIDE, DepRelation.PACKAGE))
elif(what == "arch_begin"):
arch_name = g.group(1)
within_architecture = True
elif(what == "arch_end" and within_architecture and g.group(1) == arch_name):
within_architecture = False
elif(what == "instance" and within_architecture):
f_deps.add_relation(DepRelation(g.group(1), DepRelation.USE, DepRelation.ENTITY))