Skip to content

Add parser support for "extern port" and "extern frame" statements #37

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
6 changes: 6 additions & 0 deletions source/grammar/openpulseParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ openpulseStatement:
| endStatement
| expressionStatement
| externStatement
| externFrameStatement
| externPortStatement
| forStatement
| gateCallStatement
| ifStatement
Expand Down Expand Up @@ -59,3 +61,7 @@ scalarType:
| PORT
| FRAME
;


externFrameStatement: EXTERN FRAME Identifier SEMICOLON;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's overkill for this MR, but if we ever move towards allowing external linkage with other types it might make sense to have one statement type for this

externDataStatement: EXTERN (scalarType | arrayType) Identifier SEMICOLON;

Then the AST would be something like


@dataclass
class ExternDataStatement(QASMNode):
    """
    Node representing an extern data declaration.
    """

    name: Identifier
    type_: ClassicalType

externPortStatement: EXTERN PORT Identifier SEMICOLON;
18 changes: 18 additions & 0 deletions source/openpulse/openpulse/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
7 changes: 7 additions & 0 deletions source/openpulse/openpulse/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
span,
QASMNodeVisitor,
_raise_from_context,
_visit_identifier,
parse as parse_qasm3,
)
from openqasm3.visitor import QASMVisitor
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions source/openpulse/tests/test_openpulse_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down