Simatic_XML_Parser_to_SCL/ToUpload/processors/symbol_manager.py

58 lines
2.3 KiB
Python

# processors/symbol_manager.py
import sympy
import re
class SymbolManager:
def __init__(self):
# plc_name -> py_id (e.g., '"DB".Var' -> 'v0_')
self.plc_to_py_id = {}
# py_id -> Symbol object (e.g., 'v0_' -> sympy.Symbol('v0_'))
self.py_id_to_symbol = {}
# py_id -> plc_name (e.g., 'v0_' -> '"DB".Var') - Inverse mapping
self.py_id_to_plc = {}
self.counter = 0
# Pre-define common keywords/constants to avoid mapping them
self.reserved_names = {"TRUE", "FALSE"} # Add others if needed
def _generate_py_id(self):
py_id = f"v{self.counter}_"
self.counter += 1
# Extremely unlikely collision, but check anyway
while py_id in self.py_id_to_symbol:
py_id = f"v{self.counter}_"
self.counter += 1
return py_id
def get_symbol(self, plc_var_name):
"""Gets/Creates a SymPy Symbol for a PLC variable name."""
if plc_var_name is None:
print("Warning: Attempted to get symbol for None PLC name.")
return None # Or handle error appropriately
if plc_var_name.upper() in self.reserved_names:
print(f"Warning: Attempted to create symbol for reserved name: {plc_var_name}")
return None # Or handle differently (e.g., return sympy.true/false?)
if plc_var_name not in self.plc_to_py_id:
py_id = self._generate_py_id()
self.plc_to_py_id[plc_var_name] = py_id
self.py_id_to_plc[py_id] = plc_var_name
self.py_id_to_symbol[py_id] = sympy.symbols(py_id)
# print(f"DEBUG SymbolManager: Created {py_id} -> {plc_var_name}") # Debug
else:
py_id = self.plc_to_py_id[plc_var_name]
return self.py_id_to_symbol.get(py_id)
def get_plc_name(self, py_id):
"""Gets the original PLC name from a py_id."""
return self.py_id_to_plc.get(py_id)
def get_inverse_map(self):
"""Returns the map needed for postprocessing (py_id -> plc_name)."""
return self.py_id_to_plc.copy()
# Helper function to extract PLC variable name from JSON operand info
def extract_plc_variable_name(operand_info):
if operand_info and operand_info.get("type") == "variable":
return operand_info.get("name")
return None # Not a variable or info missing