diff --git a/source/grammar/openpulseParser.g4 b/source/grammar/openpulseParser.g4 index 16c0fcd..2ba4f33 100644 --- a/source/grammar/openpulseParser.g4 +++ b/source/grammar/openpulseParser.g4 @@ -30,6 +30,8 @@ openpulseStatement: | endStatement | expressionStatement | externStatement + | externFrameStatement + | externPortStatement | forStatement | gateCallStatement | ifStatement @@ -59,3 +61,7 @@ scalarType: | PORT | FRAME ; + + +externFrameStatement: EXTERN FRAME Identifier SEMICOLON; +externPortStatement: EXTERN PORT Identifier SEMICOLON; diff --git a/source/openpulse/openpulse/ast.py b/source/openpulse/openpulse/ast.py index eca5cb3..6801ed2 100644 --- a/source/openpulse/openpulse/ast.py +++ b/source/openpulse/openpulse/ast.py @@ -131,6 +131,24 @@ class CalibrationBlock(QASMNode): body: List[Statement] +@dataclass +class ExternFrameStatement(QASMNode): + """ + Node representing an extern frame statement. + """ + + name: Identifier + + +@dataclass +class ExternPortStatement(QASMNode): + """ + Node representing an extern port statement. + """ + + name: Identifier + + # Override the class from openqasm3 @dataclass class CalibrationStatement(Statement): diff --git a/source/openpulse/openpulse/parser.py b/source/openpulse/openpulse/parser.py index 5f9c6d2..82e702f 100644 --- a/source/openpulse/openpulse/parser.py +++ b/source/openpulse/openpulse/parser.py @@ -43,6 +43,7 @@ span, QASMNodeVisitor, _raise_from_context, + _visit_identifier, parse as parse_qasm3, ) from openqasm3.visitor import QASMVisitor @@ -194,6 +195,12 @@ def visitCalibrationBlock(self, ctx: openpulseParser.CalibrationBlockContext): body=[self.visit(statement) for statement in ctx.openpulseStatement()] ) + def visitExternFrameStatement(self, ctx: openpulseParser.OpenpulseStatementContext): + return openpulse_ast.ExternFrameStatement(name=_visit_identifier(ctx.Identifier())) + + def visitExternPortStatement(self, ctx: openpulseParser.OpenpulseStatementContext): + return openpulse_ast.ExternPortStatement(name=_visit_identifier(ctx.Identifier())) + def visitScalarType(self, ctx: openpulseParser.ScalarTypeContext): if ctx.WAVEFORM() or ctx.PORT() or ctx.FRAME(): return self._visitPulseType(ctx) diff --git a/source/openpulse/tests/test_openpulse_parser.py b/source/openpulse/tests/test_openpulse_parser.py index b59836a..475f9e0 100644 --- a/source/openpulse/tests/test_openpulse_parser.py +++ b/source/openpulse/tests/test_openpulse_parser.py @@ -399,9 +399,11 @@ def test_permissive_parsing(capsys): port xy_port; port tx_port; port rx_port; + extern port cx_port; frame xy_frame = newframe(xy_port, 3714500000.0, 0); frame tx_frame = newframe(tx_port, 7883050000.0, 0); frame rx_frame = newframe(rx_port, 7883050000.0, 0); + extern frame cx_frame; waveform rabi_pulse_wf = gaussian(1e-07, 2.5e-08, 1.0, 0.0); waveform readout_waveform_wf = constant(5e-06, 0.03); waveform readout_kernel_wf = constant(5e-06, 1.0);