|
1 | 1 | import re |
2 | 2 | import xml.etree.ElementTree as ET |
| 3 | +from typing import Iterable |
3 | 4 | from typing import Set |
4 | 5 |
|
5 | 6 | from .schema import Action |
@@ -33,13 +34,20 @@ def strip_namespaces(tree: ET.Element): |
33 | 34 | attrib[new_name] = attrib.pop(name) |
34 | 35 |
|
35 | 36 |
|
| 37 | +def visit_states(states: Iterable[State], parents: list[State]): |
| 38 | + for state in states: |
| 39 | + yield state, parents |
| 40 | + if state.states: |
| 41 | + yield from visit_states(state.states.values(), parents + [state]) |
| 42 | + |
| 43 | + |
36 | 44 | def _parse_initial(initial_content: "str | None") -> Set[str]: |
37 | 45 | if initial_content is None: |
38 | 46 | return set() |
39 | 47 | return set(initial_content.split()) |
40 | 48 |
|
41 | 49 |
|
42 | | -def parse_scxml(scxml_content: str) -> StateMachineDefinition: |
| 50 | +def parse_scxml(scxml_content: str) -> StateMachineDefinition: # noqa: C901 |
43 | 51 | root = ET.fromstring(scxml_content) |
44 | 52 | strip_namespaces(root) |
45 | 53 |
|
@@ -75,6 +83,21 @@ def parse_scxml(scxml_content: str) -> StateMachineDefinition: |
75 | 83 | for s in definition.initial_states: |
76 | 84 | definition.states[s].initial = True |
77 | 85 |
|
| 86 | + # If the initial states definition does not contain any first level state, |
| 87 | + # we find the first level states that are ancestor of the initial states |
| 88 | + # and also set them as the initial states. |
| 89 | + if not set(definition.states.keys()) & definition.initial_states: |
| 90 | + not_found = set(definition.initial_states) |
| 91 | + for state, parents in visit_states(definition.states.values(), []): |
| 92 | + if state.id in definition.initial_states: |
| 93 | + not_found.remove(state.id) |
| 94 | + if parents: |
| 95 | + topmost_state = parents[0] |
| 96 | + topmost_state.initial = True |
| 97 | + definition.initial_states.add(topmost_state.id) |
| 98 | + if not not_found: |
| 99 | + break |
| 100 | + |
78 | 101 | return definition |
79 | 102 |
|
80 | 103 |
|
|
0 commit comments