Skip to content

Commit

Permalink
Add reset to QasmParser
Browse files Browse the repository at this point in the history
Add a test which can serve as example including the modifications to
support the `reset` keyword in the import of QASM files in the PLY based
lexer/parser.
  • Loading branch information
rscircus committed Sep 14, 2024
1 parent 2adc218 commit 44689b7
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
5 changes: 5 additions & 0 deletions cirq-core/cirq/contrib/qasm_import/_lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def __init__(self):
reserved = {
'qreg': 'QREG',
'creg': 'CREG',
'reset': 'RESET',
'measure': 'MEASURE',
'if': 'IF',
'->': 'ARROW',
Expand Down Expand Up @@ -91,6 +92,10 @@ def t_CREG(self, t):
r"""creg"""
return t

def t_RESET(self, t):
r"""reset"""
return t

def t_MEASURE(self, t):
r"""measure"""
return t
Expand Down
24 changes: 21 additions & 3 deletions cirq-core/cirq/contrib/qasm_import/_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import sympy
from ply import yacc

from cirq import ops, Circuit, NamedQubit, CX
from cirq import ops, Circuit, NamedQubit, CX, R
from cirq.circuits.qasm_output import QasmUGate
from cirq.contrib.qasm_import._lexer import QasmLexer
from cirq.contrib.qasm_import.exception import QasmException
Expand Down Expand Up @@ -293,6 +293,7 @@ def p_format(self, p):
# circuit : new_reg circuit
# | gate_op circuit
# | measurement circuit
# | reset circuit
# | if circuit
# | empty

Expand All @@ -303,8 +304,13 @@ def p_circuit_reg(self, p):
def p_circuit_gate_or_measurement_or_if(self, p):
"""circuit : circuit gate_op
| circuit measurement
| circuit if"""
self.circuit.append(p[2])
| circuit reset
| circuit if
| circuit new_reg"""
if isinstance(p[2], list):
self.circuit.append(p[2])
else:
self.circuit.append([p[2]])
p[0] = self.circuit

def p_circuit_empty(self, p):
Expand All @@ -325,6 +331,7 @@ def p_new_reg(self, p):
self.qregs[name] = length
else:
self.cregs[name] = length
print("Calling qrags to create a qubit")
p[0] = (name, length)

# gate operations
Expand Down Expand Up @@ -499,6 +506,17 @@ def p_measurement(self, p):
ops.MeasurementGate(num_qubits=1, key=creg[i]).on(qreg[i]) for i in range(len(qreg))
]

# reset operations
# reset : RESET qarg

def p_reset(self, p):
"""reset : RESET qarg ';'"""
qreg = p[2]

p[0] = [
ops.ResetChannel().on(qreg[i]) for i in range(len(qreg))
]

# if operations
# if : IF '(' carg EQ NATURAL_NUMBER ')' ID qargs

Expand Down
28 changes: 28 additions & 0 deletions cirq-core/cirq/contrib/qasm_import/_parser_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,34 @@ def test_U_gate_too_much_params_error():
with pytest.raises(QasmException, match=r"U takes 3.*got.*4.*line 3"):
parser.parse(qasm)

def test_reset():
qasm ="""
OPENQASM 2.0;
include "qelib1.inc";
qreg q[1];
creg c[1];
x q[0];
reset q[0];
measure q[0] -> c[0];
"""

parser = QasmParser()

q_0 = cirq.NamedQubit('q_0')

expected_circuit = Circuit()
expected_circuit.append(cirq.X(q_0))
expected_circuit.append(cirq.ResetChannel().on(q_0))
expected_circuit.append(cirq.MeasurementGate(num_qubits=1, key='c_0').on(q_0))

parsed_qasm = parser.parse(qasm)

assert parsed_qasm.supportedFormat
assert parsed_qasm.qelib1Include

ct.assert_same_circuits(parsed_qasm.circuit, expected_circuit)
assert parsed_qasm.qregs == {'q': 1}
assert parsed_qasm.cregs == {'c': 1}

@pytest.mark.parametrize(
'expr',
Expand Down

0 comments on commit 44689b7

Please sign in to comment.