-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmatcher.py
137 lines (124 loc) · 5.2 KB
/
matcher.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
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
from typing import List, Optional
from data_types import ISA51BaseComponents, ISA51BaseComponentsMatch
from static_source import id_letters, ACTIVE_FUNCTIONS, FUNCTION_MODIFIERS, \
PASSIVE_FUNCTIONS, VARIABLE_MODIFIERS
class ISA51CodeMatcher:
def match_variable_in_combinations(
self, comb: dict, variable: str, code: str,
headers_letters: List[str]) -> List[ISA51BaseComponentsMatch]:
tf_list = comb["f"]
match_list = []
for i, target_func in enumerate(tf_list):
is_allowed, target_func = self._determine_target_function(
variable, headers_letters[i], target_func
)
if not self._is_code_length_valid(code, target_func):
continue
code_fm = self._extract_code_function_modifier(code)
if self._is_valid_match(code, target_func, code_fm):
bc = self._extract_base_components(
variable, target_func, code
)
match_list.append(ISA51BaseComponentsMatch(
index=i,
bc=bc,
var_name=comb["v"],
is_allowed=is_allowed
))
return match_list
@staticmethod
def _determine_target_function(variable: str, header_letter: str,
target_func: str) -> tuple:
is_allowed = True
if target_func == "-":
is_allowed = False
target_func = variable + header_letter
return is_allowed, target_func
@staticmethod
def _is_code_length_valid(code: str, target_func: str) -> bool:
target_have_fm = target_func.endswith("*")
if ((not target_have_fm and len(code) != len(target_func))
or (target_have_fm and len(code) > len(target_func))):
return False
return True
@staticmethod
def _extract_code_function_modifier(code: str) -> str:
code_fm = code[len(code) - 1]
if code_fm not in id_letters[FUNCTION_MODIFIERS]:
code_fm = ""
return code_fm
@staticmethod
def _is_valid_match(code: str, target_func: str,
code_fm: str) -> bool:
target_have_fm = target_func.endswith("*")
if target_have_fm:
code_without_fm = code[:len(target_func) - len(code_fm)]
target_without_fm = target_func.replace("*", "")
if code_without_fm == target_without_fm:
return True
return code == target_func
@staticmethod
def _extract_base_components(
variable: str, target_func: str, code: str) -> Optional[
ISA51BaseComponents]:
bc = ISA51BaseComponents(
variable_letter=variable[0],
variable_modifiers_letters=[],
passive_function_letters=[],
active_function_letter=None,
function_modifier_letters=[],
)
if len(variable) == 2:
bc.variable_modifiers_letters = [variable[1]]
elif len(variable) == 3:
bc.variable_modifiers_letters = [variable[1], variable[2]]
elif len(variable) == 4:
bc.variable_modifiers_letters = [variable[1], variable[2],
variable[3]]
final_vm = []
for i, vm in enumerate(bc.variable_modifiers_letters):
if vm in id_letters[VARIABLE_MODIFIERS]:
final_vm.append(vm)
else:
if vm in id_letters[PASSIVE_FUNCTIONS]:
bc.passive_function_letters.append(vm)
else:
bc.append_invalid_reason(
f"Invalid character found "
f"(must be variable modifier): '{vm}'"
)
bc.variable_modifiers_letters = final_vm
funcs = target_func[len(variable):]
if len(funcs) == 0:
bc.append_invalid_reason("no functions found")
return bc
code = code[len(variable):]
for f in funcs:
if (f in id_letters[ACTIVE_FUNCTIONS]
and bc.active_function_letter is None):
bc.active_function_letter = f
code = code[1:]
elif (f in id_letters[PASSIVE_FUNCTIONS]
and (bc.passive_function_letters is not None and len(bc.passive_function_letters) < 2)):
bc.passive_function_letters.append(f)
code = code[1:]
if not target_func.endswith("*") and len(code) > 0:
bc.append_invalid_reason(
f"The match code is longer than expected "
f"and not supposed to have a function modifier: "
f"{code} | {target_func}"
)
if len(code) > 2:
bc.append_invalid_reason(
f"Too many function modifiers characters "
f"found: {code}"
)
for fm in code:
if fm in id_letters[FUNCTION_MODIFIERS]:
bc.function_modifier_letters.append(fm)
else:
bc.append_invalid_reason(
f"Invalid character found "
f"(must be function modifier): '{fm}'"
)
return bc