mal-toolbox 1.2.1__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mal_toolbox-1.2.1.dist-info → mal_toolbox-2.0.0.dist-info}/METADATA +8 -75
- {mal_toolbox-1.2.1.dist-info → mal_toolbox-2.0.0.dist-info}/RECORD +16 -13
- maltoolbox/__init__.py +2 -2
- maltoolbox/attackgraph/node.py +1 -0
- maltoolbox/language/compiler/__init__.py +4 -499
- maltoolbox/language/compiler/distributions.py +158 -0
- maltoolbox/language/compiler/exceptions.py +37 -0
- maltoolbox/language/compiler/lang.py +5 -0
- maltoolbox/language/compiler/mal_analyzer.py +920 -0
- maltoolbox/language/compiler/mal_compiler.py +1070 -0
- maltoolbox/language/languagegraph.py +6 -5
- maltoolbox/language/compiler/mal_lexer.py +0 -232
- maltoolbox/language/compiler/mal_parser.py +0 -3159
- {mal_toolbox-1.2.1.dist-info → mal_toolbox-2.0.0.dist-info}/WHEEL +0 -0
- {mal_toolbox-1.2.1.dist-info → mal_toolbox-2.0.0.dist-info}/entry_points.txt +0 -0
- {mal_toolbox-1.2.1.dist-info → mal_toolbox-2.0.0.dist-info}/licenses/AUTHORS +0 -0
- {mal_toolbox-1.2.1.dist-info → mal_toolbox-2.0.0.dist-info}/licenses/LICENSE +0 -0
- {mal_toolbox-1.2.1.dist-info → mal_toolbox-2.0.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
class DistributionsException(Exception):
|
|
2
|
+
def __init__(self, error_message):
|
|
3
|
+
self._error_message = error_message
|
|
4
|
+
super().__init__(self._error_message)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Distributions:
|
|
8
|
+
@staticmethod
|
|
9
|
+
def validate(distribution_name: str, params: list) -> None:
|
|
10
|
+
match distribution_name:
|
|
11
|
+
case 'Bernoulli':
|
|
12
|
+
Bernoulli.validate(params)
|
|
13
|
+
case 'Binomial':
|
|
14
|
+
Binomial.validate(params)
|
|
15
|
+
case 'Exponential':
|
|
16
|
+
Exponential.validate(params)
|
|
17
|
+
case 'Gamma':
|
|
18
|
+
Gamma.validate(params)
|
|
19
|
+
case 'LogNormal':
|
|
20
|
+
LogNormal.validate(params)
|
|
21
|
+
case 'Pareto':
|
|
22
|
+
Pareto.validate(params)
|
|
23
|
+
case 'TruncatedNormal':
|
|
24
|
+
TruncatedNormal.validate(params)
|
|
25
|
+
case 'Uniform':
|
|
26
|
+
Uniform.validate(params)
|
|
27
|
+
case (
|
|
28
|
+
'Enabled'
|
|
29
|
+
| 'Disabled'
|
|
30
|
+
| 'Zero'
|
|
31
|
+
| 'Infinity'
|
|
32
|
+
| 'EasyAndCertain'
|
|
33
|
+
| 'EasyAndUncertain'
|
|
34
|
+
| 'HardAndCertain'
|
|
35
|
+
| 'HardAndUncertain'
|
|
36
|
+
| 'VeryHardAndCertain'
|
|
37
|
+
| 'VeryHardAndUncertain'
|
|
38
|
+
):
|
|
39
|
+
Combination.validate(params)
|
|
40
|
+
case _:
|
|
41
|
+
err_msg = f'Distribution {distribution_name} is not supported'
|
|
42
|
+
raise (DistributionsException(err_msg))
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class Bernoulli:
|
|
46
|
+
@staticmethod
|
|
47
|
+
def validate(params: list) -> None:
|
|
48
|
+
if not params or len(params) != 1:
|
|
49
|
+
err_msg = 'Expected exactly one parameter (probability), for Bernoulli distribution'
|
|
50
|
+
raise (DistributionsException(err_msg))
|
|
51
|
+
if not 0 <= params[0] <= 1:
|
|
52
|
+
err_msg = f"{params[0]} is not in valid range '0 <= probability <= 1', for Bernoulli distribution"
|
|
53
|
+
raise (DistributionsException(err_msg))
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class Binomial:
|
|
57
|
+
@staticmethod
|
|
58
|
+
def validate(params: list) -> None:
|
|
59
|
+
if not params or len(params) != 2:
|
|
60
|
+
err_msg = 'Expected exactly two parameters (trials, probability), for Binomial distribution'
|
|
61
|
+
raise (DistributionsException(err_msg))
|
|
62
|
+
if not 0 <= params[1] <= 1:
|
|
63
|
+
err_msg = f"{params[1]} is not in valid range '0 <= probability <= 1', for Binomial distribution"
|
|
64
|
+
raise (DistributionsException(err_msg))
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class Exponential:
|
|
68
|
+
@staticmethod
|
|
69
|
+
def validate(params: list) -> None:
|
|
70
|
+
if not params or len(params) != 1:
|
|
71
|
+
err_msg = (
|
|
72
|
+
'Expected exactly one parameter (lambda), for Exponential distribution'
|
|
73
|
+
)
|
|
74
|
+
raise (DistributionsException(err_msg))
|
|
75
|
+
if params[0] <= 0:
|
|
76
|
+
err_msg = f"{params[0]} is not in valid range 'lambda > 0', for Exponential distribution"
|
|
77
|
+
raise (DistributionsException(err_msg))
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class Gamma:
|
|
81
|
+
@staticmethod
|
|
82
|
+
def validate(params: list) -> None:
|
|
83
|
+
if not params or len(params) != 2:
|
|
84
|
+
err_msg = (
|
|
85
|
+
'Expected exactly two parameters (shape, scale), for Gamma distribution'
|
|
86
|
+
)
|
|
87
|
+
raise (DistributionsException(err_msg))
|
|
88
|
+
if params[0] <= 0:
|
|
89
|
+
err_msg = (
|
|
90
|
+
f"{params[0]} is not in valid range 'shape > 0', for Gamma distribution"
|
|
91
|
+
)
|
|
92
|
+
raise (DistributionsException(err_msg))
|
|
93
|
+
if params[1] <= 0:
|
|
94
|
+
err_msg = (
|
|
95
|
+
f"{params[1]} is not in valid range 'scale > 0', for Gamma distribution"
|
|
96
|
+
)
|
|
97
|
+
raise (DistributionsException(err_msg))
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class LogNormal:
|
|
101
|
+
@staticmethod
|
|
102
|
+
def validate(params: list) -> None:
|
|
103
|
+
if not params or len(params) != 2:
|
|
104
|
+
err_msg = 'Expected exactly two parameters (mean, standardDeviation), for LogNormal distribution'
|
|
105
|
+
raise (DistributionsException(err_msg))
|
|
106
|
+
if params[1] <= 0:
|
|
107
|
+
err_msg = f"{params[1]} is not in valid range 'standardDeviation > 0', for LogNormal distribution"
|
|
108
|
+
raise (DistributionsException(err_msg))
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class Pareto:
|
|
112
|
+
@staticmethod
|
|
113
|
+
def validate(params: list) -> None:
|
|
114
|
+
if not params or len(params) != 2:
|
|
115
|
+
err_msg = (
|
|
116
|
+
'Expected exactly two parameters (min, shape), for Pareto distribution'
|
|
117
|
+
)
|
|
118
|
+
raise (DistributionsException(err_msg))
|
|
119
|
+
if params[0] <= 0:
|
|
120
|
+
err_msg = (
|
|
121
|
+
f"{params[0]} is not in valid range 'min > 0', for Pareto distribution"
|
|
122
|
+
)
|
|
123
|
+
raise (DistributionsException(err_msg))
|
|
124
|
+
if params[1] <= 0:
|
|
125
|
+
err_msg = f"{params[1]} is not in valid range 'shape > 0', for Pareto distribution"
|
|
126
|
+
raise (DistributionsException(err_msg))
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class TruncatedNormal:
|
|
130
|
+
@staticmethod
|
|
131
|
+
def validate(params: list) -> None:
|
|
132
|
+
if not params or len(params) != 2:
|
|
133
|
+
err_msg = 'Expected exactly two parameters (mean, standardDeviation), for TruncatedNormal distribution'
|
|
134
|
+
raise (DistributionsException(err_msg))
|
|
135
|
+
if params[1] <= 0:
|
|
136
|
+
err_msg = f"{params[1]} is not in valid range 'standardDeviation > 0', for TruncatedNormal distribution"
|
|
137
|
+
raise (DistributionsException(err_msg))
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class Uniform:
|
|
141
|
+
@staticmethod
|
|
142
|
+
def validate(params: list) -> None:
|
|
143
|
+
if not params or len(params) != 2:
|
|
144
|
+
err_msg = (
|
|
145
|
+
'Expected exactly two parameters (min, max), for Uniform distribution'
|
|
146
|
+
)
|
|
147
|
+
raise (DistributionsException(err_msg))
|
|
148
|
+
if params[0] > params[1]:
|
|
149
|
+
err_msg = f"({params[0]}, {params[1]}) does not meet requirement 'min <= max', for Uniform distribution"
|
|
150
|
+
raise (DistributionsException(err_msg))
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class Combination:
|
|
154
|
+
@staticmethod
|
|
155
|
+
def validate(params: list) -> None:
|
|
156
|
+
if params and len(params) != 0:
|
|
157
|
+
err_msg = 'Expected exactly zero parameters, for combination distributions'
|
|
158
|
+
raise (DistributionsException(err_msg))
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
class MalCompilerError(Exception):
|
|
2
|
+
"""Base exception for MalCompiler errors."""
|
|
3
|
+
|
|
4
|
+
pass
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class MalSyntaxError(MalCompilerError):
|
|
8
|
+
"""Raised when syntax error is encountered during compilation."""
|
|
9
|
+
|
|
10
|
+
def __init__(self, message, line=None, column=None):
|
|
11
|
+
self.line = line
|
|
12
|
+
self.column = column
|
|
13
|
+
super().__init__(message)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class MalParseError(MalCompilerError):
|
|
17
|
+
"""Raised when parsing fails."""
|
|
18
|
+
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class MalTypeError(MalCompilerError):
|
|
23
|
+
"""Raised when type checking fails."""
|
|
24
|
+
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class MalNameError(MalCompilerError):
|
|
29
|
+
"""Raised when an undefined name is referenced."""
|
|
30
|
+
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class MalCompilationError(MalCompilerError):
|
|
35
|
+
"""Raised when code generation fails."""
|
|
36
|
+
|
|
37
|
+
pass
|