Skip to content

Commit c8b45b6

Browse files
authored
Merge pull request #279 from contra-bit/fix/qasm-parser
Enhance QASM parser to support multi-character register names
2 parents d1ff358 + 48c8f5f commit c8b45b6

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

pyzx/circuit/qasmparser.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from typing import List, Dict, Tuple, Optional
2222

2323
from . import Circuit
24-
from .gates import Gate, qasm_gate_table
24+
from .gates import Gate, qasm_gate_table, Measurement
2525
from ..utils import settings
2626

2727

@@ -140,7 +140,18 @@ def extract_command_parts(self, c: str) -> Tuple[str,List[Fraction],List[str]]:
140140
def parse_command(self, c: str, registers: Dict[str,Tuple[int,int]]) -> List[Gate]:
141141
gates: List[Gate] = []
142142
name, phases, args = self.extract_command_parts(c)
143-
if name in ("barrier","creg","measure", "id"): return gates
143+
if name in ("barrier","creg", "id"): return gates
144+
if name == "measure":
145+
target, result_bit = args[0].split(' -> ')
146+
# Extract the register name and index separately for both target and result
147+
_, target_idx = target.split('[')
148+
_, result_idx = result_bit.split('[')
149+
# Remove the trailing ']' and convert to int
150+
target_qbit = int(target_idx[:-1])
151+
result_register = int(result_idx[:-1])
152+
gate = Measurement(target_qbit, result_register)
153+
gates.append(gate)
154+
return gates
144155
if name in ("opaque", "if"):
145156
raise TypeError("Unsupported operation {}".format(c))
146157
if name == "qreg":
@@ -154,9 +165,12 @@ def parse_command(self, c: str, registers: Dict[str,Tuple[int,int]]) -> List[Gat
154165
dim = 1
155166
for a in args:
156167
if "[" in a:
168+
# Split at the first '[' to handle multi-character register names
157169
regname, valp = a.split("[",1)
170+
# Remove the trailing ']' before converting to int
158171
val = int(valp[:-1])
159-
if regname not in registers: raise TypeError("Invalid register {}".format(regname))
172+
if regname not in registers:
173+
raise TypeError("Invalid register {}".format(regname))
160174
qubit_values.append([registers[regname][0]+val])
161175
else:
162176
if is_range:

tests/test_qasm.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,23 @@ def test_parse_qasm3(self):
8080
self.assertEqual(c.qubits, qasm3.qubits)
8181
self.assertListEqual(c.gates, qasm3.gates)
8282

83+
84+
def test_parse_qasm3_long_creg(self):
85+
qasm3 = Circuit.from_qasm("""
86+
OPENQASM 3;
87+
include "stdgates.inc";
88+
qubit[3] q1;
89+
cx q1[0], q1[1];
90+
s q1[2];
91+
cx q1[2], q1[1];
92+
""")
93+
c = Circuit(3)
94+
c.add_gate("CNOT", 0, 1)
95+
c.add_gate("S", 2)
96+
c.add_gate("CNOT", 2, 1)
97+
self.assertEqual(c.qubits, qasm3.qubits)
98+
self.assertListEqual(c.gates, qasm3.gates)
99+
83100
def test_load_qasm_from_file(self):
84101
c = Circuit(1)
85102
c.add_gate("YPhase", 0, Fraction(1, 4))

0 commit comments

Comments
 (0)