QThink / quyaml_parser.py
Ahmed Samir Nagy Mohammed
init
18d21ca
import yaml
from qiskit import QuantumCircuit
import re
import numpy as np
def parse_quyaml_to_qiskit(quyaml_string: str) -> QuantumCircuit:
"""
Parses a QuYAML string into a Qiskit QuantumCircuit object.
"""
try:
data = yaml.safe_load(quyaml_string)
except yaml.YAMLError as e:
raise ValueError(f"Invalid QuYAML format: {e}")
circuit_name = data.get('circuit', 'my_circuit')
def get_reg_size(reg_str):
match = re.search(r'\[(\d+)\]', reg_str)
return int(match.group(1)) if match else 0
q_size = get_reg_size(data.get('qreg', 'q[0]'))
c_size = get_reg_size(data.get('creg', 'c[0]'))
if q_size == 0:
raise ValueError("QuYAML must define at least one quantum register (e.g., qreg: q[1])")
qc = QuantumCircuit(q_size, c_size, name=circuit_name)
instructions = data.get('instructions', [])
for inst_str in instructions:
apply_instruction(qc, inst_str)
return qc
def apply_instruction(qc: QuantumCircuit, inst_str: str):
"""
Parses a single QuYAML instruction string and applies it to the circuit.
"""
parts = inst_str.split()
gate = parts[0].lower()
def get_indices(target_strings):
indices = []
for s in target_strings:
match = re.search(r'\[(\d+)\]', s)
if match:
indices.append(int(match.group(1)))
return indices
targets = [p.replace(',', '') for p in parts[1:]]
q_indices = get_indices(targets)
try:
if gate == 'h':
qc.h(q_indices[0])
elif gate == 'x':
qc.x(q_indices[0])
elif gate == 'cx':
qc.cx(q_indices[0], q_indices[1])
elif gate == 'swap':
qc.swap(q_indices[0], q_indices[1])
elif gate.startswith('cphase'):
angle_str = re.search(r'\((.*?)\)', gate).group(1)
angle_map = {'pi/2': np.pi / 2, 'pi/4': np.pi / 4, 'pi': np.pi}
angle = angle_map.get(angle_str, float(angle_str))
qc.cp(angle, q_indices[0], q_indices[1])
elif gate == 'measure':
qc.measure(range(qc.num_qubits), range(qc.num_clbits))
except Exception as e:
raise ValueError(f"Could not parse instruction '{inst_str}'. Error: {e}")