DBsExcel_con_UDT/S7_DBParser.py

152 lines
5.9 KiB
Python
Raw Normal View History

2024-04-23 04:52:24 -03:00
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