Reference OpenQASM AST in Python - contains the reference abstract syntax tree (AST) for representing OpenQASM 3 programs, tools to parse text into this AST, and tools to manipulate the AST
npx @tessl/cli install tessl/pypi-openqasm3@1.0.00
# OpenQASM 3 Python Reference
1
2
A comprehensive Python library that provides the reference abstract syntax tree (AST) for representing OpenQASM 3 programs, tools to parse text into this AST, and tools to manipulate the AST. This package enables developers to build OpenQASM 3 compiler passes, quantum circuit analyzers, and other quantum language processing tools in Python.
3
4
## Package Information
5
6
- **Package Name**: openqasm3
7
- **Language**: Python
8
- **Installation**:
9
- Base package: `pip install openqasm3` (AST, visitors, code generation only)
10
- With parsing: `pip install openqasm3[parser]` (includes text-to-AST parsing)
11
- **License**: Apache 2.0
12
- **Supported Python**: ≥3.7
13
14
## Core Imports
15
16
```python
17
import openqasm3
18
```
19
20
Common imports for working with AST nodes:
21
22
```python
23
from openqasm3 import ast
24
```
25
26
For parsing (requires `[parser]` extra):
27
28
```python
29
from openqasm3 import parse
30
# or
31
import openqasm3
32
program = openqasm3.parse(qasm_source)
33
```
34
35
For AST manipulation:
36
37
```python
38
from openqasm3 import visitor
39
```
40
41
For code generation:
42
43
```python
44
from openqasm3 import dump, dumps
45
```
46
47
## Basic Usage
48
49
```python
50
import openqasm3
51
from openqasm3 import ast
52
53
# Parse OpenQASM 3 source code into AST (requires [parser] extra)
54
qasm_source = '''
55
OPENQASM 3.0;
56
qubit[2] q;
57
h q[0];
58
cx q[0], q[1];
59
'''
60
61
program = openqasm3.parse(qasm_source)
62
print(f"Program has {len(program.statements)} statements")
63
64
# Create AST nodes programmatically
65
qubit_decl = ast.QubitDeclaration(
66
qubit=ast.Identifier("q"),
67
size=ast.IntegerLiteral(2)
68
)
69
70
# Convert AST back to OpenQASM 3 text
71
qasm_text = openqasm3.dumps(program)
72
print(qasm_text)
73
74
# Walk and analyze AST using visitor pattern
75
class GateCounter(openqasm3.visitor.QASMVisitor):
76
def __init__(self):
77
self.gate_count = 0
78
79
def visit_QuantumGate(self, node):
80
self.gate_count += 1
81
self.generic_visit(node)
82
83
counter = GateCounter()
84
counter.visit(program)
85
print(f"Found {counter.gate_count} quantum gates")
86
```
87
88
## Architecture
89
90
The OpenQASM 3 Python reference follows a layered architecture:
91
92
- **AST Layer**: Complete node hierarchy representing all OpenQASM 3 language constructs
93
- **Parser Layer**: ANTLR-based parser for converting text to AST (optional)
94
- **Visitor Layer**: Visitor and transformer patterns for AST traversal and manipulation
95
- **Printer Layer**: AST-to-text conversion with configurable formatting
96
- **Utilities**: Expression precedence, specification metadata, and type helpers
97
98
This design enables maximum reusability across quantum compiler toolchains, development environments, and language processing applications.
99
100
## Capabilities
101
102
### AST Node Hierarchy
103
104
Complete abstract syntax tree representing all OpenQASM 3 language constructs including quantum gates, classical code, control flow, type system, and calibration blocks.
105
106
```python { .api }
107
# Base classes
108
@dataclass
109
class QASMNode:
110
span: Optional[Span] = field(init=False, default=None, compare=False)
111
112
@dataclass
113
class Statement(QASMNode):
114
annotations: List[Annotation] = field(init=False, default_factory=list)
115
116
class Expression(QASMNode):
117
pass
118
119
class ClassicalType(QASMNode):
120
pass
121
122
# Program structure
123
@dataclass
124
class Program(QASMNode):
125
statements: List[Union[Statement, Pragma]]
126
version: Optional[str] = None
127
128
# Key statement types
129
@dataclass
130
class QubitDeclaration(Statement):
131
qubit: Identifier
132
size: Optional[Expression] = None
133
134
@dataclass
135
class QuantumGateDefinition(Statement):
136
name: Identifier
137
arguments: List[Identifier]
138
qubits: List[Identifier]
139
body: List[QuantumStatement]
140
141
@dataclass
142
class ClassicalDeclaration(Statement):
143
type: ClassicalType
144
identifier: Identifier
145
init_expression: Optional[Union[Expression, QuantumMeasurement]] = None
146
147
@dataclass
148
class SubroutineDefinition(Statement):
149
name: Identifier
150
arguments: List[Union[ClassicalArgument, QuantumArgument]]
151
body: List[Statement]
152
return_type: Optional[ClassicalType] = None
153
```
154
155
[AST Nodes](./ast-nodes.md)
156
157
### Text Parsing
158
159
Parse OpenQASM 3 source code into the reference AST with full language support and error reporting. Requires the `[parser]` extra installation.
160
161
```python { .api }
162
def parse(input_: str, *, permissive: bool = False) -> ast.Program:
163
"""
164
Parse a complete OpenQASM 3 program from text into the reference AST.
165
166
Args:
167
input_: A string containing a complete OpenQASM 3 program
168
permissive: If True, enables ANTLR error recovery for partial parsing
169
If False (default), raises exceptions on syntax errors
170
171
Returns:
172
A complete ast.Program node representing the parsed program
173
174
Raises:
175
QASM3ParsingError: When the program cannot be correctly parsed
176
ImportError: If the [parser] extra is not installed
177
"""
178
```
179
180
[Parser](./parser.md)
181
182
### AST Visitors and Transformers
183
184
Visitor and transformer patterns for systematic AST traversal, analysis, and modification with optional context support.
185
186
```python { .api }
187
class QASMVisitor(Generic[T]):
188
def visit(self, node: QASMNode, context: Optional[T] = None):
189
"""Visit a node and dispatch to the appropriate visitor method"""
190
191
def generic_visit(self, node: QASMNode, context: Optional[T] = None):
192
"""Called if no explicit visitor function exists for a node"""
193
194
class QASMTransformer(QASMVisitor[T]):
195
def generic_visit(self, node: QASMNode, context: Optional[T] = None) -> QASMNode:
196
"""Visit and potentially modify nodes and their children"""
197
```
198
199
[Visitors](./visitors.md)
200
201
### Code Generation
202
203
Convert AST nodes back to valid OpenQASM 3 text with configurable formatting and complete language support.
204
205
```python { .api }
206
def dump(node: ast.QASMNode, file: io.TextIOBase, **kwargs) -> None:
207
"""Write textual OpenQASM 3 code representing an AST node to an open stream"""
208
209
def dumps(node: ast.QASMNode, **kwargs) -> str:
210
"""Get a string representation of OpenQASM 3 code from an AST node"""
211
212
class Printer(QASMVisitor[PrinterState]):
213
def __init__(self, stream: io.TextIOBase, indent: str = " ",
214
chain_else_if: bool = True, old_measurement: bool = False):
215
"""Initialize the printer with formatting options"""
216
217
def visit(self, node: ast.QASMNode, context: Optional[PrinterState] = None) -> None:
218
"""Main entry point for visiting nodes and generating code"""
219
```
220
221
[Code Generation](./code-generation.md)
222
223
### Utilities and Metadata
224
225
Expression precedence handling, specification version metadata, and other utility functions for working with OpenQASM 3 ASTs.
226
227
```python { .api }
228
# Specification metadata
229
supported_versions: List[str] # ["3.0", "3.1"]
230
231
# Expression precedence
232
def precedence(node_type: type) -> int:
233
"""
234
Get the precedence level for an expression node type.
235
Higher numbers indicate higher precedence (tighter binding).
236
"""
237
```
238
239
[Utilities](./utilities.md)
240
241
## Types
242
243
```python { .api }
244
# Core enums
245
class AccessControl(Enum):
246
readonly = "readonly"
247
mutable = "mutable"
248
249
class TimeUnit(Enum):
250
dt = "dt"
251
ns = "ns"
252
us = "us"
253
ms = "ms"
254
s = "s"
255
256
class BinaryOperator(Enum):
257
# Comparison operators
258
GT = ">"
259
LT = "<"
260
GTE = ">="
261
LTE = "<="
262
EQ = "=="
263
NE = "!="
264
# Logical operators
265
LOGICAL_AND = "&&"
266
LOGICAL_OR = "||"
267
# Bitwise operators
268
BITWISE_OR = "|"
269
BITWISE_XOR = "^"
270
BITWISE_AND = "&"
271
LSHIFT = "<<"
272
RSHIFT = ">>"
273
# Arithmetic operators
274
PLUS = "+"
275
MINUS = "-"
276
TIMES = "*"
277
DIVIDE = "/"
278
MODULO = "%"
279
POWER = "**"
280
281
class UnaryOperator(Enum):
282
BITWISE_NOT = "~"
283
LOGICAL_NOT = "!"
284
MINUS = "-"
285
286
class AssignmentOperator(Enum):
287
EQUALS = "="
288
PLUS_EQUALS = "+="
289
MINUS_EQUALS = "-="
290
TIMES_EQUALS = "*="
291
DIVIDE_EQUALS = "/="
292
BITWISE_AND_EQUALS = "&="
293
BITWISE_OR_EQUALS = "|="
294
BITWISE_NOT_EQUALS = "~="
295
BITWISE_XOR_EQUALS = "^="
296
LSHIFT_EQUALS = "<<="
297
RSHIFT_EQUALS = ">>="
298
MODULO_EQUALS = "%="
299
POWER_EQUALS = "**="
300
301
class GateModifierName(Enum):
302
inv = "inv"
303
pow = "pow"
304
ctrl = "ctrl"
305
negctrl = "negctrl"
306
307
class IOKeyword(Enum):
308
input = "input"
309
output = "output"
310
311
# Location information
312
@dataclass
313
class Span:
314
start_line: int
315
start_column: int
316
end_line: int
317
end_column: int
318
319
# Type aliases
320
IndexElement = Union[DiscreteSet, List[Union[Expression, RangeDefinition]]]
321
```