diff --git a/cirq-core/cirq/contrib/qasm_import/_lexer.py b/cirq-core/cirq/contrib/qasm_import/_lexer.py index 206d9e88d74f..a62ee52f84e8 100644 --- a/cirq-core/cirq/contrib/qasm_import/_lexer.py +++ b/cirq-core/cirq/contrib/qasm_import/_lexer.py @@ -29,6 +29,7 @@ def __init__(self): reserved = { 'qreg': 'QREG', 'creg': 'CREG', + 'reset': 'RESET', 'measure': 'MEASURE', 'if': 'IF', '->': 'ARROW', @@ -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 diff --git a/cirq-core/cirq/contrib/qasm_import/_parser.py b/cirq-core/cirq/contrib/qasm_import/_parser.py index e7bcdae06db2..6673ca137ca0 100644 --- a/cirq-core/cirq/contrib/qasm_import/_parser.py +++ b/cirq-core/cirq/contrib/qasm_import/_parser.py @@ -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 @@ -293,6 +293,7 @@ def p_format(self, p): # circuit : new_reg circuit # | gate_op circuit # | measurement circuit + # | reset circuit # | if circuit # | empty @@ -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): @@ -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 @@ -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 diff --git a/cirq-core/cirq/contrib/qasm_import/_parser_test.py b/cirq-core/cirq/contrib/qasm_import/_parser_test.py index 4b0ca8e50f1e..e334f2ccb856 100644 --- a/cirq-core/cirq/contrib/qasm_import/_parser_test.py +++ b/cirq-core/cirq/contrib/qasm_import/_parser_test.py @@ -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',