cyberark-tpc-plugin-parser 0.4.0__tar.gz → 0.4.2__tar.gz
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.
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/PKG-INFO +6 -6
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/README.md +3 -3
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/cyberark_tpc_plugin_parser.egg-info/PKG-INFO +6 -6
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/cyberark_tpc_plugin_parser.egg-info/SOURCES.txt +1 -1
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/pyproject.toml +15 -10
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/tests/test_lexer.py +7 -4
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/tests/test_parser.py +2 -1
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/tpc_plugin_parser/lexer/lexer.py +49 -39
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/tpc_plugin_parser/lexer/tokens/assignment.py +1 -1
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/tpc_plugin_parser/lexer/tokens/comment.py +1 -1
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/tpc_plugin_parser/lexer/tokens/cpm_parameter_validation.py +1 -1
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/tpc_plugin_parser/lexer/tokens/fail_state.py +1 -1
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/tpc_plugin_parser/lexer/tokens/parse_error.py +1 -1
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/tpc_plugin_parser/lexer/tokens/section_header.py +1 -1
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/tpc_plugin_parser/lexer/tokens/transition.py +1 -1
- cyberark_tpc_plugin_parser-0.4.2/tpc_plugin_parser/lexer/utilities/regex.py +12 -0
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/tpc_plugin_parser/lexer/utilities/types.py +2 -1
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/tpc_plugin_parser/parser.py +1 -1
- cyberark_tpc_plugin_parser-0.4.0/tpc_plugin_parser/lexer/utilities/regex.py +0 -17
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/LICENSE +0 -0
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/cyberark_tpc_plugin_parser.egg-info/dependency_links.txt +0 -0
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/cyberark_tpc_plugin_parser.egg-info/top_level.txt +0 -0
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/setup.cfg +0 -0
- {cyberark_tpc_plugin_parser-0.4.0/tpc_plugin_parser/lexer → cyberark_tpc_plugin_parser-0.4.2/tpc_plugin_parser}/__init__.py +0 -0
- {cyberark_tpc_plugin_parser-0.4.0/tpc_plugin_parser/lexer/tokens → cyberark_tpc_plugin_parser-0.4.2/tpc_plugin_parser/lexer}/__init__.py +0 -0
- {cyberark_tpc_plugin_parser-0.4.0/tpc_plugin_parser/lexer/utilities → cyberark_tpc_plugin_parser-0.4.2/tpc_plugin_parser/lexer/tokens}/__init__.py +0 -0
- /cyberark_tpc_plugin_parser-0.4.0/tpc_plugin_parser/__init__..py → /cyberark_tpc_plugin_parser-0.4.2/tpc_plugin_parser/lexer/utilities/__init__.py +0 -0
- {cyberark_tpc_plugin_parser-0.4.0 → cyberark_tpc_plugin_parser-0.4.2}/tpc_plugin_parser/lexer/utilities/token_name.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cyberark-tpc-plugin-parser
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: A package to help parse CyberArk TPC plugin prompts and process files.
|
|
5
5
|
Author-email: Peter McDonald <git@petermcdonald.co.uk>
|
|
6
6
|
License: MIT License
|
|
@@ -31,14 +31,14 @@ Project-URL: issues, https://github.com/petermcd/CyberArk-TPC-Plugin-Parser/issu
|
|
|
31
31
|
Keywords: cyberark,parser,tpc
|
|
32
32
|
Classifier: Intended Audience :: Developers
|
|
33
33
|
Classifier: Programming Language :: Python
|
|
34
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
35
34
|
Classifier: Programming Language :: Python :: 3.12
|
|
36
35
|
Classifier: Programming Language :: Python :: 3.13
|
|
37
36
|
Classifier: Programming Language :: Python :: 3.14
|
|
38
37
|
Classifier: Programming Language :: Python :: 3.15
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.16
|
|
39
39
|
Classifier: Topic :: Software Development :: Testing
|
|
40
40
|
Classifier: Typing :: Typed
|
|
41
|
-
Requires-Python: >=3.
|
|
41
|
+
Requires-Python: >=3.12
|
|
42
42
|
Description-Content-Type: text/markdown
|
|
43
43
|
License-File: LICENSE
|
|
44
44
|
Dynamic: license-file
|
|
@@ -67,10 +67,10 @@ files as arguments:
|
|
|
67
67
|
```python
|
|
68
68
|
from tpc_plugin_parser.parser import Parser
|
|
69
69
|
|
|
70
|
-
with open(
|
|
70
|
+
with open("/path/to/files/process.ini") as process_fh:
|
|
71
71
|
process_content: str = process_fh.read()
|
|
72
|
-
|
|
73
|
-
with open(
|
|
72
|
+
|
|
73
|
+
with open("/path/to/files/prompts.ini") as prompts_fh:
|
|
74
74
|
prompts_content: str = prompts_fh.read()
|
|
75
75
|
|
|
76
76
|
parser: Parser = Parser(process_file=process_content, prompts_file=prompts_content)
|
|
@@ -22,10 +22,10 @@ files as arguments:
|
|
|
22
22
|
```python
|
|
23
23
|
from tpc_plugin_parser.parser import Parser
|
|
24
24
|
|
|
25
|
-
with open(
|
|
25
|
+
with open("/path/to/files/process.ini") as process_fh:
|
|
26
26
|
process_content: str = process_fh.read()
|
|
27
|
-
|
|
28
|
-
with open(
|
|
27
|
+
|
|
28
|
+
with open("/path/to/files/prompts.ini") as prompts_fh:
|
|
29
29
|
prompts_content: str = prompts_fh.read()
|
|
30
30
|
|
|
31
31
|
parser: Parser = Parser(process_file=process_content, prompts_file=prompts_content)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cyberark-tpc-plugin-parser
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: A package to help parse CyberArk TPC plugin prompts and process files.
|
|
5
5
|
Author-email: Peter McDonald <git@petermcdonald.co.uk>
|
|
6
6
|
License: MIT License
|
|
@@ -31,14 +31,14 @@ Project-URL: issues, https://github.com/petermcd/CyberArk-TPC-Plugin-Parser/issu
|
|
|
31
31
|
Keywords: cyberark,parser,tpc
|
|
32
32
|
Classifier: Intended Audience :: Developers
|
|
33
33
|
Classifier: Programming Language :: Python
|
|
34
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
35
34
|
Classifier: Programming Language :: Python :: 3.12
|
|
36
35
|
Classifier: Programming Language :: Python :: 3.13
|
|
37
36
|
Classifier: Programming Language :: Python :: 3.14
|
|
38
37
|
Classifier: Programming Language :: Python :: 3.15
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.16
|
|
39
39
|
Classifier: Topic :: Software Development :: Testing
|
|
40
40
|
Classifier: Typing :: Typed
|
|
41
|
-
Requires-Python: >=3.
|
|
41
|
+
Requires-Python: >=3.12
|
|
42
42
|
Description-Content-Type: text/markdown
|
|
43
43
|
License-File: LICENSE
|
|
44
44
|
Dynamic: license-file
|
|
@@ -67,10 +67,10 @@ files as arguments:
|
|
|
67
67
|
```python
|
|
68
68
|
from tpc_plugin_parser.parser import Parser
|
|
69
69
|
|
|
70
|
-
with open(
|
|
70
|
+
with open("/path/to/files/process.ini") as process_fh:
|
|
71
71
|
process_content: str = process_fh.read()
|
|
72
|
-
|
|
73
|
-
with open(
|
|
72
|
+
|
|
73
|
+
with open("/path/to/files/prompts.ini") as prompts_fh:
|
|
74
74
|
prompts_content: str = prompts_fh.read()
|
|
75
75
|
|
|
76
76
|
parser: Parser = Parser(process_file=process_content, prompts_file=prompts_content)
|
|
@@ -7,7 +7,7 @@ cyberark_tpc_plugin_parser.egg-info/dependency_links.txt
|
|
|
7
7
|
cyberark_tpc_plugin_parser.egg-info/top_level.txt
|
|
8
8
|
tests/test_lexer.py
|
|
9
9
|
tests/test_parser.py
|
|
10
|
-
tpc_plugin_parser/__init__
|
|
10
|
+
tpc_plugin_parser/__init__.py
|
|
11
11
|
tpc_plugin_parser/parser.py
|
|
12
12
|
tpc_plugin_parser/lexer/__init__.py
|
|
13
13
|
tpc_plugin_parser/lexer/lexer.py
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "cyberark-tpc-plugin-parser"
|
|
3
|
-
version = "0.4.
|
|
3
|
+
version = "0.4.2"
|
|
4
4
|
description = "A package to help parse CyberArk TPC plugin prompts and process files."
|
|
5
5
|
keywords = ["cyberark", "parser", "tpc"]
|
|
6
6
|
authors = [{ name = "Peter McDonald", email = "git@petermcdonald.co.uk"}]
|
|
7
7
|
readme = "README.md"
|
|
8
8
|
license = { file = "LICENSE" }
|
|
9
|
-
requires-python = ">=3.
|
|
9
|
+
requires-python = ">=3.12"
|
|
10
10
|
|
|
11
11
|
classifiers = [
|
|
12
12
|
"Intended Audience :: Developers",
|
|
13
13
|
"Programming Language :: Python",
|
|
14
|
-
"Programming Language :: Python :: 3.11",
|
|
15
14
|
"Programming Language :: Python :: 3.12",
|
|
16
15
|
"Programming Language :: Python :: 3.13",
|
|
17
16
|
"Programming Language :: Python :: 3.14",
|
|
18
17
|
"Programming Language :: Python :: 3.15",
|
|
18
|
+
"Programming Language :: Python :: 3.16",
|
|
19
19
|
"Topic :: Software Development :: Testing",
|
|
20
20
|
"Typing :: Typed",
|
|
21
21
|
]
|
|
@@ -29,13 +29,9 @@ issues = "https://github.com/petermcd/CyberArk-TPC-Plugin-Parser/issues"
|
|
|
29
29
|
|
|
30
30
|
[dependency-groups]
|
|
31
31
|
dev = [
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"pytest>=
|
|
35
|
-
"pytest-cov>=7.0.0",
|
|
36
|
-
"ruff>=0.13.0",
|
|
37
|
-
"troml>=0.4.1",
|
|
38
|
-
"ty>=0.0.1a20",
|
|
32
|
+
"pygments>=2.21.0",
|
|
33
|
+
"pytest>=9.1.1",
|
|
34
|
+
"pytest-cov>=7.1.0",
|
|
39
35
|
]
|
|
40
36
|
|
|
41
37
|
[tool.pytest.ini_options]
|
|
@@ -43,3 +39,12 @@ addopts = "--cov=tpc_plugin_parser --cov-report term-missing --cov-report xml:co
|
|
|
43
39
|
|
|
44
40
|
[tool.ruff]
|
|
45
41
|
line-length = 120
|
|
42
|
+
|
|
43
|
+
[cosmic-ray]
|
|
44
|
+
module-path = "tpc_plugin_parser"
|
|
45
|
+
timeout = 10.0
|
|
46
|
+
excluded-modules = []
|
|
47
|
+
test-command = "uv run pytest"
|
|
48
|
+
|
|
49
|
+
[cosmic-ray.distributor]
|
|
50
|
+
name = "local"
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"""Test the lexer."""
|
|
2
2
|
|
|
3
3
|
import pytest
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
from tpc_plugin_parser.lexer.lexer import _MAX_SOURCE_BYTES, Lexer
|
|
5
6
|
from tpc_plugin_parser.lexer.tokens.assignment import Assignment
|
|
6
7
|
from tpc_plugin_parser.lexer.tokens.comment import Comment
|
|
7
8
|
from tpc_plugin_parser.lexer.tokens.cpm_parameter_validation import CPMParameterValidation
|
|
@@ -10,9 +11,10 @@ from tpc_plugin_parser.lexer.tokens.parse_error import ParseError
|
|
|
10
11
|
from tpc_plugin_parser.lexer.tokens.section_header import SectionHeader
|
|
11
12
|
from tpc_plugin_parser.lexer.tokens.transition import Transition
|
|
12
13
|
from tpc_plugin_parser.lexer.utilities.token_name import TokenName
|
|
14
|
+
from tpc_plugin_parser.lexer.utilities.types import ALL_TOKEN_TYPES
|
|
13
15
|
|
|
14
16
|
|
|
15
|
-
class TestLexer
|
|
17
|
+
class TestLexer:
|
|
16
18
|
"""Test the lexer."""
|
|
17
19
|
|
|
18
20
|
@pytest.mark.parametrize(
|
|
@@ -257,8 +259,9 @@ class TestLexer(object):
|
|
|
257
259
|
"""
|
|
258
260
|
lex: Lexer = Lexer(source=line)
|
|
259
261
|
lex.process()
|
|
260
|
-
found_tokens = lex.tokens
|
|
262
|
+
found_tokens: list[tuple[TokenName, ALL_TOKEN_TYPES]] = lex.tokens
|
|
261
263
|
assert len(found_tokens) == len(expected_tokens)
|
|
264
|
+
assert isinstance(found_tokens[0][1], ParseError)
|
|
262
265
|
assert found_tokens[0][1].content == expected_tokens[0].content
|
|
263
266
|
assert found_tokens[0][1].line_number == expected_tokens[0].line_number
|
|
264
267
|
|
|
@@ -271,4 +274,4 @@ class TestLexer(object):
|
|
|
271
274
|
def test_fail_state_code_out_of_range_raises(self) -> None:
|
|
272
275
|
"""Test that a fail-state error code outside 0–65535 raises ValueError."""
|
|
273
276
|
with pytest.raises(ValueError, match="valid range"):
|
|
274
|
-
Lexer(source="state=fail(message, 65536)").tokens
|
|
277
|
+
_ = Lexer(source="state=fail(message, 65536)").tokens
|
|
@@ -26,14 +26,21 @@ from tpc_plugin_parser.lexer.utilities.types import ALL_TOKEN_TYPES, TokenSpecs
|
|
|
26
26
|
_MAX_SOURCE_BYTES: int = 1 * 1024 * 1024 # 1 MiB
|
|
27
27
|
_log = logging.getLogger(__name__)
|
|
28
28
|
|
|
29
|
+
_ASSIGNMENT_RE = re.compile(ASSIGNMENT, re.IGNORECASE)
|
|
30
|
+
_COMMENT_RE = re.compile(COMMENT, re.IGNORECASE)
|
|
31
|
+
_CPM_PARAMETER_VALIDATION_RE = re.compile(CPM_PARAMETER_VALIDATION, re.IGNORECASE)
|
|
32
|
+
_FAIL_STATE_RE = re.compile(FAIL_STATE, re.IGNORECASE)
|
|
33
|
+
_SECTION_HEADER_RE = re.compile(SECTION_HEADER, re.IGNORECASE)
|
|
34
|
+
_TRANSITION_RE = re.compile(TRANSITION, re.IGNORECASE)
|
|
29
35
|
|
|
30
|
-
|
|
36
|
+
|
|
37
|
+
class Lexer:
|
|
31
38
|
"""Object to handle processing the ini files."""
|
|
32
39
|
|
|
33
40
|
__slots__ = (
|
|
34
|
-
"_tokens",
|
|
35
41
|
"_source",
|
|
36
42
|
"_token_specs",
|
|
43
|
+
"_tokens",
|
|
37
44
|
)
|
|
38
45
|
|
|
39
46
|
def __init__(self, source: str) -> None:
|
|
@@ -51,35 +58,37 @@ class Lexer(object):
|
|
|
51
58
|
self._source: str = source
|
|
52
59
|
self._token_specs: list[TokenSpecs] = [
|
|
53
60
|
{
|
|
54
|
-
|
|
61
|
+
# Must precede ASSIGNMENT: "name = fail(...)" also matches the
|
|
62
|
+
# more general assignment pattern.
|
|
63
|
+
"pattern": _FAIL_STATE_RE,
|
|
64
|
+
"token_name": TokenName.FAIL_STATE,
|
|
65
|
+
"processor": self._process_fail_state,
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"pattern": _ASSIGNMENT_RE,
|
|
69
|
+
"token_name": TokenName.ASSIGNMENT,
|
|
70
|
+
"processor": self._process_assignment,
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"pattern": _COMMENT_RE,
|
|
55
74
|
"token_name": TokenName.COMMENT,
|
|
56
75
|
"processor": self._process_comment,
|
|
57
76
|
},
|
|
58
77
|
{
|
|
59
|
-
"pattern":
|
|
78
|
+
"pattern": _CPM_PARAMETER_VALIDATION_RE,
|
|
60
79
|
"token_name": TokenName.CPM_PARAMETER_VALIDATION,
|
|
61
80
|
"processor": self._process_cpm_parameter_validation,
|
|
62
81
|
},
|
|
63
82
|
{
|
|
64
|
-
"pattern":
|
|
65
|
-
"token_name": TokenName.FAIL_STATE,
|
|
66
|
-
"processor": self._process_fail_state,
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
"pattern": re.compile(SECTION_HEADER, re.IGNORECASE),
|
|
83
|
+
"pattern": _SECTION_HEADER_RE,
|
|
70
84
|
"token_name": TokenName.SECTION_HEADER,
|
|
71
85
|
"processor": self._process_section_header,
|
|
72
86
|
},
|
|
73
87
|
{
|
|
74
|
-
"pattern":
|
|
88
|
+
"pattern": _TRANSITION_RE,
|
|
75
89
|
"token_name": TokenName.TRANSITION,
|
|
76
90
|
"processor": self._process_transitions,
|
|
77
91
|
},
|
|
78
|
-
{
|
|
79
|
-
"pattern": re.compile(ASSIGNMENT, re.IGNORECASE),
|
|
80
|
-
"token_name": TokenName.ASSIGNMENT,
|
|
81
|
-
"processor": self._process_assignment,
|
|
82
|
-
},
|
|
83
92
|
]
|
|
84
93
|
|
|
85
94
|
def process(self) -> None:
|
|
@@ -94,7 +103,7 @@ class Lexer(object):
|
|
|
94
103
|
for line_number, line in enumerate(self._source.splitlines(), start=1):
|
|
95
104
|
for token_spec in self._token_specs:
|
|
96
105
|
if match := token_spec["pattern"].match(line):
|
|
97
|
-
token_spec["processor"](match
|
|
106
|
+
token_spec["processor"](match, line_number)
|
|
98
107
|
break
|
|
99
108
|
else:
|
|
100
109
|
if line.strip():
|
|
@@ -104,11 +113,11 @@ class Lexer(object):
|
|
|
104
113
|
"""
|
|
105
114
|
Process a variable assignment line
|
|
106
115
|
|
|
107
|
-
:param match: Regex
|
|
116
|
+
:param match: Regex matches of the assignment.
|
|
108
117
|
"""
|
|
109
|
-
name: str = str(match
|
|
110
|
-
equals = str(match
|
|
111
|
-
assigned_stripped = str(match
|
|
118
|
+
name: str = str(match["name"]).strip()
|
|
119
|
+
equals = str(match["equals"]).strip() if match.groupdict().get("equals", None) else None
|
|
120
|
+
assigned_stripped = str(match["value"]).strip() if match.groupdict().get("value", None) else None
|
|
112
121
|
assigned = assigned_stripped or None
|
|
113
122
|
self._tokens.append(
|
|
114
123
|
(
|
|
@@ -126,7 +135,7 @@ class Lexer(object):
|
|
|
126
135
|
"""
|
|
127
136
|
Process the provided comment.
|
|
128
137
|
|
|
129
|
-
:param match: Regex
|
|
138
|
+
:param match: Regex matches of the comment.
|
|
130
139
|
"""
|
|
131
140
|
self._tokens.append(
|
|
132
141
|
(
|
|
@@ -137,21 +146,21 @@ class Lexer(object):
|
|
|
137
146
|
|
|
138
147
|
def _process_cpm_parameter_validation(self, match: re.Match, line_number: int) -> None:
|
|
139
148
|
"""
|
|
140
|
-
Process
|
|
149
|
+
Process provided parameter validation.
|
|
141
150
|
|
|
142
|
-
:param match: Regex
|
|
151
|
+
:param match: Regex matches of the parameter validation.
|
|
143
152
|
"""
|
|
144
153
|
allow_characters: str | None = None
|
|
145
|
-
if match
|
|
146
|
-
allow_characters = str(match
|
|
154
|
+
if match["allowcharacters"]:
|
|
155
|
+
allow_characters = str(match["allowcharacters"]).strip()
|
|
147
156
|
|
|
148
157
|
self._tokens.append(
|
|
149
158
|
(
|
|
150
159
|
TokenName.CPM_PARAMETER_VALIDATION,
|
|
151
160
|
CPMParameterValidation(
|
|
152
|
-
name=str(match
|
|
153
|
-
source=str(match
|
|
154
|
-
mandatory=str(match
|
|
161
|
+
name=str(match["name"]),
|
|
162
|
+
source=str(match["source"]),
|
|
163
|
+
mandatory=str(match["mandatory"]),
|
|
155
164
|
allow_characters=allow_characters,
|
|
156
165
|
line_number=line_number,
|
|
157
166
|
),
|
|
@@ -160,19 +169,20 @@ class Lexer(object):
|
|
|
160
169
|
|
|
161
170
|
def _process_fail_state(self, match: re.Match, line_number: int) -> None:
|
|
162
171
|
"""
|
|
163
|
-
Process the provided fail state
|
|
172
|
+
Process the provided fail state.
|
|
164
173
|
|
|
165
174
|
:param match: Regex match of the fail state.
|
|
166
175
|
"""
|
|
167
|
-
code = int(match
|
|
176
|
+
code = int(match["code"])
|
|
168
177
|
if not (0 <= code <= 65535):
|
|
178
|
+
_log.warning("Fail-state error code %d at line %d", code, line_number)
|
|
169
179
|
raise ValueError(f"Fail-state error code {code} is outside the valid range 0–65535")
|
|
170
180
|
self._tokens.append(
|
|
171
181
|
(
|
|
172
182
|
TokenName.FAIL_STATE,
|
|
173
183
|
FailState(
|
|
174
|
-
name=str(match
|
|
175
|
-
message=str(match
|
|
184
|
+
name=str(match["name"]).strip(),
|
|
185
|
+
message=str(match["message"]).strip(),
|
|
176
186
|
code=code,
|
|
177
187
|
line_number=line_number,
|
|
178
188
|
),
|
|
@@ -201,13 +211,13 @@ class Lexer(object):
|
|
|
201
211
|
"""
|
|
202
212
|
Process the provided section header.
|
|
203
213
|
|
|
204
|
-
:param match: Regex
|
|
214
|
+
:param match: Regex matches of the section header.
|
|
205
215
|
"""
|
|
206
216
|
self._tokens.append(
|
|
207
217
|
(
|
|
208
218
|
TokenName.SECTION_HEADER,
|
|
209
219
|
SectionHeader(
|
|
210
|
-
name=str(match
|
|
220
|
+
name=str(match["name"].strip()),
|
|
211
221
|
line_number=line_number,
|
|
212
222
|
),
|
|
213
223
|
)
|
|
@@ -217,15 +227,15 @@ class Lexer(object):
|
|
|
217
227
|
"""
|
|
218
228
|
Process the provided transitions.
|
|
219
229
|
|
|
220
|
-
:param match: Regex
|
|
230
|
+
:param match: Regex matches of the transitions.
|
|
221
231
|
"""
|
|
222
232
|
self._tokens.append(
|
|
223
233
|
(
|
|
224
234
|
TokenName.TRANSITION,
|
|
225
235
|
Transition(
|
|
226
|
-
current_state=str(match
|
|
227
|
-
condition=str(match
|
|
228
|
-
next_state=str(match
|
|
236
|
+
current_state=str(match["current"]).strip(),
|
|
237
|
+
condition=str(match["condition"]).strip(),
|
|
238
|
+
next_state=str(match["next"]).strip(),
|
|
229
239
|
line_number=line_number,
|
|
230
240
|
),
|
|
231
241
|
)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""List of regex the lexer uses."""
|
|
2
|
+
|
|
3
|
+
ASSIGNMENT: str = r"^\s*(?P<name>\w+)(?:\s*(?P<equals>=)(?:\s*(?P<value>[^\r\n]*))?)?\s*$"
|
|
4
|
+
COMMENT: str = r"^\s*(?P<comment>[#;]+.*)\s*$"
|
|
5
|
+
CPM_PARAMETER_VALIDATION: str = (
|
|
6
|
+
r"^\s*(?P<name>[\w\\]+)(?:\s*,\s*source\s*=\s*(?P<source>[^, ]*))"
|
|
7
|
+
r"(?:\s*,\s*mandatory\s*=\s*(?P<mandatory>[^,]*))?"
|
|
8
|
+
r"(?:\s*,\s*allowcharacters\s*=\s*(?P<allowcharacters>.*))?$"
|
|
9
|
+
)
|
|
10
|
+
FAIL_STATE: str = r"^\s*(?P<name>\w+)\s*=\s*fail\s*\(\s*(?P<message>.*),\s*(?P<code>[0-9]+)\)\s*$"
|
|
11
|
+
SECTION_HEADER: str = r"^\s*\[(?P<name>\w+(?:\s+\w+)*)]\s*$"
|
|
12
|
+
TRANSITION: str = r"^\s*(?P<current>\w+)\s*,\s*(?P<condition>\w+)\s*,\s*(?P<next>\w+)\s*$"
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"""Module for aggregating all token types used in the lexer."""
|
|
2
2
|
|
|
3
|
-
from typing import Callable, TypedDict
|
|
4
3
|
import re
|
|
4
|
+
from collections.abc import Callable
|
|
5
|
+
from typing import TypedDict
|
|
5
6
|
|
|
6
7
|
from tpc_plugin_parser.lexer.tokens.assignment import Assignment
|
|
7
8
|
from tpc_plugin_parser.lexer.tokens.comment import Comment
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"""List of regex the lexer uses."""
|
|
2
|
-
|
|
3
|
-
ASSIGNMENT: str = r"^(?:[\s]*)(?P<name>[\w]+)(?:(?:[\s]*)(?P<equals>=)(?:(?:[\s]*)(?P<value>[^\r\n]*))?)?(?:[\s]*)$"
|
|
4
|
-
COMMENT: str = r"^(?:[\s]*)(?P<comment>(?:[#;]+)(?:.*))(?:[\s]*)$"
|
|
5
|
-
CPM_PARAMETER_VALIDATION: str = (
|
|
6
|
-
r"^(?:[\s]*)(?P<name>[\w\\]+)(?:(?:[\s]*,[\s]*)(?:source)(?:[\s]*)=(?:[\s]*)"
|
|
7
|
-
r"(?P<source>[^, ]*))(?:(?:[\s]*,[\s]*)(?:mandatory)(?:[\s]*)=(?:[\s]*)"
|
|
8
|
-
r"(?P<mandatory>[^,]*))?(?:(?:[\s]*,[\s]*)(?:allowcharacters)(?:[\s]*)=(?:[\s]*)(?P<allowcharacters>.*))?$"
|
|
9
|
-
)
|
|
10
|
-
FAIL_STATE: str = (
|
|
11
|
-
r"^(?:[\s]*)(?P<name>[\w]+)(?:[\s]*)=(?:[\s]*)(?:fail)(?:[\s]*)\((?:[\s]*)"
|
|
12
|
-
r"(?P<message>.*),(?:[\s]*)(?P<code>[0-9]+)\)(?:[\s]*)$"
|
|
13
|
-
)
|
|
14
|
-
SECTION_HEADER: str = r"^(?:[\s]*)\[(?P<name>[\w]+(?:[\s]+[\w]+)*)](?:[\s]*)$"
|
|
15
|
-
TRANSITION: str = (
|
|
16
|
-
r"^(?:[\s]*)(?P<current>[\w]+)(?:[\s]*,[\s]*)(?P<condition>[\w]+)(?:[\s]*,[\s]*)(?P<next>[\w]+)(?:[\s]*)$"
|
|
17
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|