improved the file connector algorithm
This commit is contained in:
parent
9c412ace74
commit
fd9838bcba
@ -1,7 +1,8 @@
|
|||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Tuple, Optional, Dict
|
from typing import List, Tuple, Optional, Dict, Union
|
||||||
|
|
||||||
from fsfwgen.parserbase.parser import FileParser, VerbosityLevels
|
from fsfwgen.parserbase.parser import FileParser, VerbosityLevels
|
||||||
from fsfwgen.utility.printer import PrettyPrinter
|
from fsfwgen.utility.printer import PrettyPrinter
|
||||||
@ -20,14 +21,34 @@ DEFAULT_MOVING_WINDOWS_SIZE = 7
|
|||||||
INVALID_IF_ID = -1
|
INVALID_IF_ID = -1
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class FileStartHelper:
|
||||||
|
start_name: str
|
||||||
|
start_name_or_value: str
|
||||||
|
count: int
|
||||||
|
cumulative_start_index: Optional[int] = None
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class FileEndHelper:
|
||||||
|
end_name: str
|
||||||
|
cumulative_end_value: Optional[int] = None
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class FileConnHelper:
|
||||||
|
file_name: str
|
||||||
|
sh: Optional[FileStartHelper]
|
||||||
|
eh: Optional[FileEndHelper]
|
||||||
|
|
||||||
|
|
||||||
class InterfaceParser(FileParser):
|
class InterfaceParser(FileParser):
|
||||||
def __init__(self, file_list: list, print_table: bool = False):
|
def __init__(self, file_list: list, print_table: bool = False):
|
||||||
super().__init__(file_list)
|
super().__init__(file_list)
|
||||||
self.print_table = print_table
|
self.print_table = print_table
|
||||||
self.file_table_list = []
|
self.file_table_list = []
|
||||||
self.file_name_table = []
|
self.file_name_table = []
|
||||||
self.start_name_list = []
|
self.file_conn_helpers: Optional[List[FileConnHelper]] = None
|
||||||
self.end_name_list = []
|
|
||||||
self._debug_mode = False
|
self._debug_mode = False
|
||||||
|
|
||||||
def enable_debug_mode(self, enable: bool):
|
def enable_debug_mode(self, enable: bool):
|
||||||
@ -60,23 +81,28 @@ class InterfaceParser(FileParser):
|
|||||||
start_matched = False
|
start_matched = False
|
||||||
end_matched = False
|
end_matched = False
|
||||||
start_name = ""
|
start_name = ""
|
||||||
target_end_name = ""
|
first_entry_name_or_index = ""
|
||||||
|
file_conn_entry = FileConnHelper(file_name, None, None)
|
||||||
for line in all_lines:
|
for line in all_lines:
|
||||||
if not start_matched:
|
if not start_matched:
|
||||||
match = re.search(r"[\s]*([\w]*) = [\s]*([\w]*)", line)
|
match = re.search(r"[\s]*([\w]*) = [\s]*([\w]*)", line)
|
||||||
if match:
|
if match:
|
||||||
# current_file_table.update({count: [match.group(1), match.group(2)]})
|
# current_file_table.update({count: [match.group(1), match.group(2)]})
|
||||||
start_name = match.group(1)
|
start_name = match.group(1)
|
||||||
target_end_name = match.group(2)
|
first_entry_name_or_index = match.group(2)
|
||||||
start_matched = True
|
start_matched = True
|
||||||
else:
|
else:
|
||||||
match = re.search(r"[\s]*([\w]*),?(?:[\s]*//)?([^\n]*)?", line)
|
match = re.search(r"[\s]*([\w]*),?(?:[\s]*//)?([^\n]*)?", line)
|
||||||
if match:
|
if match:
|
||||||
count += 1
|
count += 1
|
||||||
|
# It is expected that the last entry is explicitely marked like this.
|
||||||
|
# TODO: Could also simply remember last entry and then designate that as end
|
||||||
|
# entry as soon as "}" is found. Requires moving window mode though
|
||||||
if re.search(r"\[EXPORT][\s]*:[\s]*\[END]", match.group(2)):
|
if re.search(r"\[EXPORT][\s]*:[\s]*\[END]", match.group(2)):
|
||||||
last_entry_name = match.group(1)
|
last_entry_name = match.group(1)
|
||||||
end_matched = True
|
end_matched = True
|
||||||
self.end_name_list.append([last_entry_name, None])
|
file_conn_entry.eh = FileEndHelper(last_entry_name, None)
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
short_name = match.group(2)
|
short_name = match.group(2)
|
||||||
if short_name == "":
|
if short_name == "":
|
||||||
@ -94,50 +120,68 @@ class InterfaceParser(FileParser):
|
|||||||
"Make sure to use [EXPORT] : [END]"
|
"Make sure to use [EXPORT] : [END]"
|
||||||
)
|
)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
self.start_name_list.append([start_name, target_end_name, None, count])
|
file_conn_entry.sh = FileStartHelper(
|
||||||
|
start_name, first_entry_name_or_index, count, None
|
||||||
|
)
|
||||||
|
if self.file_conn_helpers is None:
|
||||||
|
self.file_conn_helpers = []
|
||||||
|
self.file_conn_helpers.append(file_conn_entry)
|
||||||
self.file_name_table.append(file_name)
|
self.file_name_table.append(file_name)
|
||||||
self.file_table_list.append(current_file_table)
|
self.file_table_list.append(current_file_table)
|
||||||
|
|
||||||
def _post_parsing_operation(self):
|
def _post_parsing_operation(self):
|
||||||
self.start_name_list, self.end_name_list = self.__assign_start_end_indexes(
|
self.__assign_start_end_indexes()
|
||||||
self.start_name_list, self.end_name_list
|
self._print_start_end_info()
|
||||||
)
|
|
||||||
for idx, file_table in enumerate(self.file_table_list):
|
for idx, file_table in enumerate(self.file_table_list):
|
||||||
self.__build_mod_interface_table(self.start_name_list[idx][2], file_table)
|
self.__build_mod_interface_table(
|
||||||
|
self.file_conn_helpers[idx].sh.count, file_table
|
||||||
|
)
|
||||||
if self.print_table:
|
if self.print_table:
|
||||||
PrettyPrinter.pprint(self.mib_table)
|
PrettyPrinter.pprint(self.mib_table)
|
||||||
|
|
||||||
@staticmethod
|
def _print_start_end_info(self):
|
||||||
def __assign_start_end_indexes(
|
for conn_helper in self.file_conn_helpers:
|
||||||
start_name_list_list, end_name_list_list
|
print(
|
||||||
) -> Tuple[List, List]:
|
f"Detected {conn_helper.sh.count} entries in {conn_helper.file_name}, "
|
||||||
# TODO: Clean up this mess. Use a wrapper/helper class instead of wild list/indexes
|
f"end index {conn_helper.eh.cumulative_end_value}"
|
||||||
# Also, the complexity of this algorithm warrants a unittest..
|
)
|
||||||
start_list_list_completed = start_name_list_list
|
|
||||||
end_list_list_completed = end_name_list_list
|
def __assign_start_end_indexes(self):
|
||||||
|
conn_helpers_old = self.file_conn_helpers.copy()
|
||||||
all_indexes_filled = False
|
all_indexes_filled = False
|
||||||
max_outer_iterations = 15
|
max_outer_iterations = 15
|
||||||
current_iteration = 0
|
current_iteration = 0
|
||||||
while not all_indexes_filled:
|
while not all_indexes_filled:
|
||||||
for idx, start_name_list in enumerate(start_list_list_completed):
|
for idx, conn_helper in enumerate(conn_helpers_old):
|
||||||
if start_name_list[1].isdigit():
|
sh = conn_helper.sh
|
||||||
start_list_list_completed[idx][2] = int(start_name_list[1])
|
# In the very first file, the first index might/will be a number
|
||||||
end_list_list_completed[idx][1] = (
|
if sh.start_name_or_value.isdigit():
|
||||||
start_list_list_completed[idx][2]
|
sh.cumulative_start_index = int(sh.start_name_or_value)
|
||||||
+ start_list_list_completed[idx][3]
|
conn_helpers_old[idx].eh.cumulative_end_value = (
|
||||||
|
sh.cumulative_start_index + sh.count
|
||||||
)
|
)
|
||||||
target_end_name = start_name_list[1]
|
# Now, we try to connect the start and end of the files using the start and end
|
||||||
for end_name_list in end_list_list_completed:
|
# names respectively
|
||||||
end_name = end_name_list[0]
|
end_name_to_search = conn_helper.sh.start_name_or_value
|
||||||
end_value = end_name_list[1]
|
for end_name_helper in conn_helpers_old:
|
||||||
if end_name == target_end_name and end_value is not None:
|
eh = end_name_helper.eh
|
||||||
start_list_list_completed[idx][2] = end_value
|
if (
|
||||||
end_list_list_completed[idx][1] = (
|
eh.end_name == end_name_to_search
|
||||||
end_value + start_list_list_completed[idx][3]
|
and eh.cumulative_end_value is not None
|
||||||
|
):
|
||||||
|
self.file_conn_helpers[
|
||||||
|
idx
|
||||||
|
].sh.cumulative_start_index = eh.cumulative_end_value
|
||||||
|
self.file_conn_helpers[idx].eh.cumulative_end_value = (
|
||||||
|
eh.cumulative_end_value
|
||||||
|
+ self.file_conn_helpers[idx].sh.count
|
||||||
)
|
)
|
||||||
all_indexes_filled = True
|
all_indexes_filled = True
|
||||||
for idx, start_name_list in enumerate(start_list_list_completed):
|
for idx, conn_helper in enumerate(conn_helpers_old):
|
||||||
if start_name_list[2] is None or end_name_list_list[idx][1] is None:
|
if (
|
||||||
|
conn_helper.sh.cumulative_start_index is None
|
||||||
|
or conn_helper.eh.cumulative_end_value is None
|
||||||
|
):
|
||||||
all_indexes_filled = False
|
all_indexes_filled = False
|
||||||
current_iteration += 1
|
current_iteration += 1
|
||||||
if current_iteration >= max_outer_iterations:
|
if current_iteration >= max_outer_iterations:
|
||||||
@ -146,7 +190,6 @@ class InterfaceParser(FileParser):
|
|||||||
"given number of maximum outer iterations!"
|
"given number of maximum outer iterations!"
|
||||||
)
|
)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
return start_list_list_completed, end_list_list_completed
|
|
||||||
|
|
||||||
def __build_mod_interface_table(self, count_start: int, interface_dict: dict):
|
def __build_mod_interface_table(self, count_start: int, interface_dict: dict):
|
||||||
dict_to_build = dict()
|
dict_to_build = dict()
|
||||||
|
Loading…
Reference in New Issue
Block a user