-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtypeDef.py
85 lines (71 loc) · 2.62 KB
/
typeDef.py
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
class TypeDefinition:
r"""
To create type definition, use TypeDefinition.load(fileName).
For each line, the type definition should contain three elements,
divided by space:
1. name that will be used in program
2. regular expression
3. (optional) display name
For example:
minus \-{1} -
int_constant \b(-?)(0|[1-9]\d*)\b int_const
int \bint\b int
"""
@staticmethod
def load(fileName):
"""
Load type definition from given file.
"""
with open(fileName, "r") as f:
src = f.read()
return TypeDefinition.loadFromString(src)
@staticmethod
def loadFromString(string):
"""
Load type definition from given string.
"""
td = TypeDefinition()
for line in string.split('\n'):
a, b, *rest = line.split()
assert len(rest) <= 1
td.addDefinition(a, b, *rest)
return td
def __init__(self):
self.__d = {} # map name to RE and displayName
self.__toInt = {} # map name to integer
self.__toName = {} # map integer to name
self.__displayNameToInt = {} # map display name to integer
self.__toDisplayName = {}
self.re = None
def __str__(self):
return str(self.__d) + "\n" + str(self.__toInt)
def addDefinition(self, name, expression, displayName=None):
self.__d[name] = (expression, displayName)
# in order to take less memory and have faster process speed,
# map string to int.
if name not in self.__toInt:
self.__toInt[name] = len(self.__toInt)
self.__toName[len(self.__toInt) - 1] = name
if displayName is not None:
self.__displayNameToInt[displayName] = \
len(self.__toInt) - 1
self.__toDisplayName[len(self.__toInt) - 1] = \
displayName
def getRE(self):
if self.re is None:
self.re = '|'.join('(?P<%s>%s)' % (k, v[0])
for k, v in self.__d.items())
return self.re
def getID(self, name):
assert name in self.__toInt
return self.__toInt[name]
def getIDByDisplayName(self, displayName):
assert displayName in self.__displayNameToInt
return self.__displayNameToInt[displayName]
def getName(self, id_):
assert id_ in self.__toName
return self.__toName[id_]
def getDisplayName(self, id_):
if id_ not in self.__toDisplayName:
return ""
return self.__toDisplayName[id_]