Skip to content

Commit

Permalink
Merge pull request #279 from contra-bit/fix/qasm-parser
Browse files Browse the repository at this point in the history
Enhance QASM parser to support multi-character register names
  • Loading branch information
jvdwetering authored Dec 19, 2024
2 parents d1ff358 + 48c8f5f commit c8b45b6
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
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

0 comments on commit c8b45b6

Please sign in to comment.