Skip to content

Commit 0f8aaeb

Browse files
Merge pull request #24 from hodgestar/feature/update-to-openqasm-3-1
Update the included OpenQASM grammar to OpenQASM 3.1.0
2 parents 615abd8 + ca57dbf commit 0f8aaeb

File tree

13 files changed

+156
-18
lines changed

13 files changed

+156
-18
lines changed

.github/workflows/tests-ast.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ jobs:
1414
fail-fast: false
1515
matrix:
1616
# Just using minimum and maximum to avoid exploding the matrix.
17-
python-version: ['3.7', '3.10']
18-
antlr-version: ['4.7', '4.11']
17+
python-version: ['3.7', '3.12']
18+
antlr-version: ['4.7', '4.13']
1919
defaults:
2020
run:
2121
working-directory: source/openpulse

source/grammar/openpulseParser.g4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ openpulseStatement:
3838
| quantumDeclarationStatement
3939
| resetStatement
4040
| returnStatement
41+
| switchStatement
4142
| whileStatement
4243
)
4344
;

source/grammar/qasm3Lexer.g4

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ lexer grammar qasm3Lexer;
1414
/* Language keywords. */
1515

1616
OPENQASM: 'OPENQASM' -> pushMode(VERSION_IDENTIFIER);
17-
INCLUDE: 'include';
18-
DEFCALGRAMMAR: 'defcalgrammar';
17+
INCLUDE: 'include' -> pushMode(ARBITRARY_STRING);
18+
DEFCALGRAMMAR: 'defcalgrammar' -> pushMode(ARBITRARY_STRING);
1919
DEF: 'def';
2020
CAL: 'cal' -> mode(CAL_PRELUDE);
2121
DEFCAL: 'defcal' -> mode(DEFCAL_PRELUDE);
@@ -33,6 +33,9 @@ RETURN: 'return';
3333
FOR: 'for';
3434
WHILE: 'while';
3535
IN: 'in';
36+
SWITCH: 'switch';
37+
CASE: 'case';
38+
DEFAULT: 'default';
3639

3740
PRAGMA: '#'? 'pragma' -> pushMode(EAT_TO_LINE_END);
3841
AnnotationKeyword: '@' Identifier -> pushMode(EAT_TO_LINE_END);
@@ -123,7 +126,7 @@ ComparisonOperator: '>' | '<' | '>=' | '<=';
123126
BitshiftOperator: '>>' | '<<';
124127

125128
IMAG: 'im';
126-
ImaginaryLiteral: (DecimalIntegerLiteral | FloatLiteral) ' '* IMAG;
129+
ImaginaryLiteral: (DecimalIntegerLiteral | FloatLiteral) [ \t]* IMAG;
127130

128131
BinaryIntegerLiteral: ('0b' | '0B') ([01] '_'?)* [01];
129132
OctalIntegerLiteral: '0o' ([0-7] '_'?)* [0-7];
@@ -149,15 +152,9 @@ FloatLiteral:
149152

150153
fragment TimeUnit: 'dt' | 'ns' | 'us' | 'µs' | 'ms' | 's';
151154
// represents explicit time value in SI or backend units
152-
TimingLiteral: (DecimalIntegerLiteral | FloatLiteral) TimeUnit;
153-
155+
TimingLiteral: (DecimalIntegerLiteral | FloatLiteral) [ \t]* TimeUnit;
154156

155157
BitstringLiteral: '"' ([01] '_'?)* [01] '"';
156-
// allow ``"str"`` and ``'str'``
157-
StringLiteral
158-
: '"' ~["\r\t\n]+? '"'
159-
| '\'' ~['\r\t\n]+? '\''
160-
;
161158

162159
// Ignore whitespace between tokens, and define C++-style comments.
163160
Whitespace: [ \t]+ -> skip ;
@@ -173,6 +170,13 @@ mode VERSION_IDENTIFIER;
173170
VERSION_IDENTIFER_WHITESPACE: [ \t\r\n]+ -> skip;
174171
VersionSpecifier: [0-9]+ ('.' [0-9]+)? -> popMode;
175172

173+
// An include statement's path or defcalgrammar target is potentially ambiguous
174+
// with `BitstringLiteral`.
175+
mode ARBITRARY_STRING;
176+
ARBITRARY_STRING_WHITESPACE: [ \t\r\n]+ -> skip;
177+
// allow ``"str"`` and ``'str'``;
178+
StringLiteral: ('"' ~["\r\t\n]+? '"' | '\'' ~['\r\t\n]+? '\'') -> popMode;
179+
176180

177181
// A different lexer mode to swap to when we need handle tokens on a line basis
178182
// rather than the default arbitrary-whitespace-based tokenisation. This is

source/grammar/qasm3Parser.g4

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ options {
44
tokenVocab = qasm3Lexer;
55
}
66

7-
program: version? statement* EOF;
7+
program: version? statementOrScope* EOF;
88
version: OPENQASM VersionSpecifier SEMICOLON;
99

1010
// A statement is any valid single statement of an OpenQASM 3 program, with the
@@ -43,11 +43,12 @@ statement:
4343
| quantumDeclarationStatement
4444
| resetStatement
4545
| returnStatement
46+
| switchStatement
4647
| whileStatement
4748
)
4849
;
4950
annotation: AnnotationKeyword RemainingLineContent?;
50-
scope: LBRACE statement* RBRACE;
51+
scope: LBRACE statementOrScope* RBRACE;
5152
pragma: PRAGMA RemainingLineContent;
5253

5354
statementOrScope: statement | scope;
@@ -67,6 +68,11 @@ forStatement: FOR scalarType Identifier IN (setExpression | LBRACKET rangeExpres
6768
ifStatement: IF LPAREN expression RPAREN if_body=statementOrScope (ELSE else_body=statementOrScope)?;
6869
returnStatement: RETURN (expression | measureExpression)? SEMICOLON;
6970
whileStatement: WHILE LPAREN expression RPAREN body=statementOrScope;
71+
switchStatement: SWITCH LPAREN expression RPAREN LBRACE switchCaseItem* RBRACE;
72+
switchCaseItem:
73+
CASE expressionList scope
74+
| DEFAULT scope
75+
;
7076

7177
// Quantum directive statements.
7278
barrierStatement: BARRIER gateOperandList? SEMICOLON;

source/openpulse/ANTLR_VERSIONS.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
4.9.2
44
4.10.1
55
4.11.1
6+
4.12.0
7+
4.13.0

source/openpulse/openpulse/__init__.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,14 @@
1414
the :obj:`~parser.parse` function.
1515
"""
1616

17+
__all__ = [
18+
"ast",
19+
"parser",
20+
"spec",
21+
"parse",
22+
]
23+
1724
__version__ = "0.5.0"
1825

19-
from . import ast, parser
26+
from . import ast, parser, spec
2027
from .parser import parse

source/openpulse/openpulse/parser.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
]
2525

2626
from contextlib import contextmanager
27-
from typing import List
27+
from typing import List, Union
2828

2929
try:
3030
from antlr4 import CommonTokenStream, InputStream, ParserRuleContext
@@ -129,6 +129,13 @@ def _in_loop(self):
129129
for scope in reversed(self._current_context())
130130
)
131131

132+
def _parse_scoped_statements(
133+
self, node: Union[qasm3Parser.ScopeContext, qasm3Parser.StatementOrScopeContext]
134+
) -> List[ast.Statement]:
135+
with self._push_scope(node.parentCtx):
136+
block = self.visit(node)
137+
return block.statements if isinstance(block, ast.CompoundStatement) else [block]
138+
132139
@span
133140
def _visitPulseType(self, ctx: openpulseParser.ScalarTypeContext):
134141
if ctx.WAVEFORM():
@@ -305,6 +312,7 @@ def visitOpenpulseStatement(self, ctx: openpulseParser.OpenpulseStatementContext
305312
OpenPulseNodeVisitor.visitStatementOrScope = QASMNodeVisitor.visitStatementOrScope
306313
OpenPulseNodeVisitor.visitUnaryExpression = QASMNodeVisitor.visitUnaryExpression
307314
OpenPulseNodeVisitor.visitWhileStatement = QASMNodeVisitor.visitWhileStatement
315+
OpenPulseNodeVisitor.visitSwitchStatement = QASMNodeVisitor.visitSwitchStatement
308316

309317

310318
class CalParser(QASMVisitor[None]):

source/openpulse/openpulse/spec.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
"""
2+
=====================================================
3+
Supported Specification Metadata (``openpulse.spec``)
4+
=====================================================
5+
6+
.. currentmodule:: openpulse.spec
7+
8+
Metadata on the specifications supported by this package.
9+
10+
.. autodata:: supported_versions
11+
"""
12+
13+
__all__ = ["supported_versions"]
14+
15+
#: A list of specification versions supported by this
16+
#: package. Each version is a :code:`str`, e.g. :code:`'3.0'`.
17+
supported_versions = [
18+
"3.0",
19+
"3.1",
20+
]

source/openpulse/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
antlr4-python3-runtime
2-
openqasm3>=0.5,<1.0
2+
openqasm3>=1.0.0,<2.0

source/openpulse/setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ include_package_data = True
2727
install_requires =
2828
antlr4-python3-runtime # __ANTLR_VERSIONS__
2929
importlib_metadata; python_version<'3.10'
30-
openqasm3[parser]>=0.5,<1.0
30+
openqasm3[parser]>=1.0.0,<2.0
3131

3232
[options.packages.find]
3333
exclude = tests*

0 commit comments

Comments
 (0)