Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance QASM parser to support multi-character register names #279

Merged
merged 2 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions pyzx/circuit/qasmparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from typing import List, Dict, Tuple, Optional

from . import Circuit
from .gates import Gate, qasm_gate_table
from .gates import Gate, qasm_gate_table, Measurement
from ..utils import settings


Expand Down Expand Up @@ -140,7 +140,18 @@ def extract_command_parts(self, c: str) -> Tuple[str,List[Fraction],List[str]]:
def parse_command(self, c: str, registers: Dict[str,Tuple[int,int]]) -> List[Gate]:
gates: List[Gate] = []
name, phases, args = self.extract_command_parts(c)
if name in ("barrier","creg","measure", "id"): return gates
if name in ("barrier","creg", "id"): return gates
if name == "measure":
target, result_bit = args[0].split(' -> ')
# Extract the register name and index separately for both target and result
_, target_idx = target.split('[')
_, result_idx = result_bit.split('[')
# Remove the trailing ']' and convert to int
target_qbit = int(target_idx[:-1])
result_register = int(result_idx[:-1])
gate = Measurement(target_qbit, result_register)
gates.append(gate)
return gates
if name in ("opaque", "if"):
raise TypeError("Unsupported operation {}".format(c))
if name == "qreg":
Expand All @@ -154,9 +165,12 @@ def parse_command(self, c: str, registers: Dict[str,Tuple[int,int]]) -> List[Gat
dim = 1
for a in args:
if "[" in a:
# Split at the first '[' to handle multi-character register names
regname, valp = a.split("[",1)
# Remove the trailing ']' before converting to int
val = int(valp[:-1])
if regname not in registers: raise TypeError("Invalid register {}".format(regname))
if regname not in registers:
raise TypeError("Invalid register {}".format(regname))
qubit_values.append([registers[regname][0]+val])
else:
if is_range:
Expand Down
17 changes: 17 additions & 0 deletions tests/test_qasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,23 @@ def test_parse_qasm3(self):
self.assertEqual(c.qubits, qasm3.qubits)
self.assertListEqual(c.gates, qasm3.gates)


def test_parse_qasm3_long_creg(self):
qasm3 = Circuit.from_qasm("""
OPENQASM 3;
include "stdgates.inc";
qubit[3] q1;
cx q1[0], q1[1];
s q1[2];
cx q1[2], q1[1];
""")
c = Circuit(3)
c.add_gate("CNOT", 0, 1)
c.add_gate("S", 2)
c.add_gate("CNOT", 2, 1)
self.assertEqual(c.qubits, qasm3.qubits)
self.assertListEqual(c.gates, qasm3.gates)

def test_load_qasm_from_file(self):
c = Circuit(1)
c.add_gate("YPhase", 0, Fraction(1, 4))
Expand Down
Loading