152 lines
5.9 KiB
Python
152 lines
5.9 KiB
Python
import re
|
|
import os
|
|
import json
|
|
|
|
def clean_line(line):
|
|
"""Clean line from BOM and extra spaces or quotes."""
|
|
# Remove UTF-8 BOM if exists and strip trailing/leading whitespace
|
|
line = line.replace("\ufeff", "").strip()
|
|
# Standardize TYPE and DATA_BLOCK definitions to ensure they're properly captured
|
|
line = re.sub(r'\s*TYPE\s+"?', 'TYPE "', line)
|
|
line = re.sub(r'\s*DATA_BLOCK\s+"?', 'DATA_BLOCK "', line)
|
|
line = remove_text_inside_brackets(line)
|
|
return line
|
|
|
|
def remove_text_inside_brackets(text):
|
|
# Define the pattern to find text inside brackets
|
|
pattern = r"\{.*?\}"
|
|
# Use re.sub to replace the found text with an empty string
|
|
cleaned_text = re.sub(pattern, '', text)
|
|
return cleaned_text
|
|
|
|
def extract_name(line):
|
|
"""Extract the name from TYPE or DATA_BLOCK definition line."""
|
|
# Attempt to find a quoted name first
|
|
match = re.search(r'(TYPE|DATA_BLOCK)\s+"([^"]+)"', line)
|
|
if match:
|
|
return match.group(2).strip() # The name is within quotes
|
|
|
|
# If no quoted name, find an unquoted name
|
|
match = re.search(r"(TYPE|DATA_BLOCK)\s+(\S+)", line)
|
|
if match:
|
|
return match.group(2).strip() # The name is without quotes
|
|
|
|
|
|
def parse_udts(lines):
|
|
udt_json = {}
|
|
udt_name = None
|
|
nested_structs = []
|
|
current_struct = None
|
|
is_within_struct = False
|
|
|
|
for line in lines:
|
|
line = clean_line(line)
|
|
if "TYPE" in line and "END_TYPE" not in line:
|
|
udt_name = extract_name(line)
|
|
udt_json[udt_name] = {}
|
|
current_struct = udt_json[udt_name]
|
|
print(f"Created UDT: {udt_name}")
|
|
elif "END_TYPE" in line:
|
|
print(f"Completed UDT: {udt_name}")
|
|
udt_name = None
|
|
nested_structs = []
|
|
current_struct = None
|
|
is_within_struct = False
|
|
elif "STRUCT" in line and "END_STRUCT" not in line and udt_name is not None:
|
|
struct_name = (
|
|
"Struct" if "STRUCT" == line.strip() else line.split(":")[0].strip()
|
|
)
|
|
new_struct = {}
|
|
current_struct[struct_name] = new_struct
|
|
nested_structs.append(current_struct)
|
|
current_struct = new_struct
|
|
is_within_struct = True
|
|
print(f"Created STRUCT: {struct_name}")
|
|
elif "END_STRUCT" in line and udt_name is not None:
|
|
current_struct = nested_structs.pop() if nested_structs else None
|
|
is_within_struct = bool(nested_structs)
|
|
print(f"Closed STRUCT in UDT '{udt_name}'")
|
|
elif udt_name and ":" in line and is_within_struct:
|
|
parts = line.split(":")
|
|
field_name = parts[0].strip()
|
|
field_details = parts[1].strip().split("//")
|
|
field_type = (
|
|
field_details[0].replace(";", "").strip()
|
|
) # Removing ';' from field type
|
|
field_comment = parts[1].split("//")[1].strip() if "//" in parts[1] else ""
|
|
if "Struct" in field_type:
|
|
new_struct = {}
|
|
current_struct[field_name] = new_struct
|
|
nested_structs.append(current_struct)
|
|
current_struct = new_struct
|
|
print(f"Opened inline STRUCT at field '{field_name}'")
|
|
else:
|
|
current_struct[field_name] = {
|
|
"type": field_type,
|
|
"comment": field_comment,
|
|
}
|
|
print(
|
|
f"Added field '{field_name}' to STRUCT: Type={field_type}, Comment={field_comment}"
|
|
)
|
|
|
|
return udt_json
|
|
|
|
|
|
def parse_dbs(lines, udts):
|
|
db_json = {}
|
|
db_name = None
|
|
nested_structs = []
|
|
current_struct = None
|
|
is_within_struct = False
|
|
|
|
for line in lines:
|
|
line = clean_line(line)
|
|
if "DATA_BLOCK" in line and "END_DATA_BLOCK" not in line:
|
|
db_name = extract_name(line)
|
|
db_json[db_name] = {}
|
|
current_struct = db_json[db_name]
|
|
print(f"Created DATA_BLOCK: {db_name}")
|
|
elif "END_DATA_BLOCK" in line:
|
|
print(f"Completed DATA_BLOCK: {db_name}")
|
|
db_name = None
|
|
nested_structs = []
|
|
current_struct = None
|
|
is_within_struct = False
|
|
elif "STRUCT" in line and "END_STRUCT" not in line and db_name is not None:
|
|
struct_name = (
|
|
"Struct" if "STRUCT" == line.strip() else line.split(":")[0].strip()
|
|
)
|
|
new_struct = {}
|
|
current_struct[struct_name] = new_struct
|
|
nested_structs.append(current_struct)
|
|
current_struct = new_struct
|
|
is_within_struct = True
|
|
print(f"Created STRUCT in DB '{db_name}': {struct_name}")
|
|
elif "END_STRUCT" in line and db_name is not None:
|
|
current_struct = nested_structs.pop() if nested_structs else None
|
|
is_within_struct = bool(nested_structs)
|
|
print(f"Closed STRUCT in DB '{db_name}'")
|
|
elif db_name and ":" in line and is_within_struct:
|
|
parts = line.split(":")
|
|
field_name = parts[0].strip()
|
|
field_details = parts[1].strip().split("//")
|
|
field_type = (
|
|
field_details[0].replace(";", "").strip()
|
|
) # Removing ';' from field type
|
|
field_comment = parts[1].split("//")[1].strip() if "//" in parts[1] else ""
|
|
if "Struct" in field_type:
|
|
new_struct = {}
|
|
current_struct[field_name] = new_struct
|
|
nested_structs.append(current_struct)
|
|
current_struct = new_struct
|
|
print(f"Opened inline STRUCT at field '{field_name}' in DB '{db_name}'")
|
|
else:
|
|
current_struct[field_name] = {
|
|
"type": field_type,
|
|
"comment": field_comment,
|
|
}
|
|
print(
|
|
f"Added field '{field_name}' to STRUCT in DB '{db_name}': Type={field_type}, Comment={field_comment}"
|
|
)
|
|
|
|
return db_json |