0
# Text Parsing
1
2
Parse OpenQASM 3 source code into the reference AST with full language support and error reporting. The parser converts textual OpenQASM 3 programs into structured AST representations that can be analyzed, manipulated, and converted back to text.
3
4
**Note**: Parsing functionality requires the `[parser]` extra installation: `pip install openqasm3[parser]`
5
6
## Capabilities
7
8
### Main Parsing Function
9
10
Parse complete OpenQASM 3 programs from text with comprehensive language support.
11
12
```python { .api }
13
def parse(input_: str, *, permissive: bool = False) -> ast.Program:
14
"""
15
Parse a complete OpenQASM 3 program from text into the reference AST.
16
17
Args:
18
input_: A string containing a complete OpenQASM 3 program
19
permissive: If True, enables ANTLR error recovery for partial parsing
20
If False (default), raises exceptions on syntax errors
21
22
Returns:
23
A complete ast.Program node representing the parsed program
24
25
Raises:
26
QASM3ParsingError: When the program cannot be correctly parsed
27
ImportError: If the [parser] extra is not installed
28
"""
29
```
30
31
### Span Management Functions
32
33
Functions for managing source location information in parsed AST nodes.
34
35
```python { .api }
36
def get_span(node: Union[ParserRuleContext, TerminalNode]) -> ast.Span:
37
"""
38
Extract source location span information from ANTLR parser nodes.
39
40
Args:
41
node: ANTLR parser node (ParserRuleContext or TerminalNode)
42
43
Returns:
44
ast.Span object with line/column information using ANTLR convention
45
(starting line number is 1, starting column number is 0)
46
"""
47
48
def add_span(node: _NodeT, span: ast.Span) -> _NodeT:
49
"""
50
Attach span information to an AST node.
51
52
Args:
53
node: Any AST node (must inherit from ast.QASMNode)
54
span: Source location span to attach
55
56
Returns:
57
The same node with span information attached
58
"""
59
60
def combine_span(first: ast.Span, second: ast.Span) -> ast.Span:
61
"""
62
Merge two spans into a single span covering both ranges.
63
64
Args:
65
first: First span to combine
66
second: Second span to combine
67
68
Returns:
69
Combined span covering the range from first.start to second.end
70
"""
71
72
def span(func):
73
"""
74
Function decorator that automatically attaches span information to AST nodes.
75
76
This decorator is used internally by visitor methods to automatically
77
attach source location information to AST nodes returned by the method.
78
79
Args:
80
func: Function to decorate (typically visitor methods)
81
82
Returns:
83
Decorated function with automatic span attachment
84
"""
85
```
86
87
### Parser Visitor Class
88
89
Advanced AST visitor for transforming ANTLR parse trees into OpenQASM 3 reference AST.
90
91
```python { .api }
92
class QASMNodeVisitor(qasm3ParserVisitor):
93
"""
94
Main AST visitor class that transforms ANTLR parse tree into OpenQASM3 reference AST.
95
96
This class extends the ANTLR-generated visitor and provides comprehensive
97
visitor methods for all OpenQASM 3 language constructs. It handles:
98
- Context and scope management with stack-based tracking
99
- Error handling and validation during AST generation
100
- Support for all statement types, expressions, and declarations
101
- Proper type checking and semantic validation
102
"""
103
104
def visitProgram(self, ctx) -> ast.Program:
105
"""Entry point for program AST generation"""
106
107
def _push_context(self, context_type: str) -> None:
108
"""Push a new context onto the context stack"""
109
110
def _push_scope(self, scope_type: str) -> None:
111
"""Push a new scope onto the scope stack"""
112
113
def _in_global_scope(self) -> bool:
114
"""Check if currently in global scope"""
115
116
def _in_gate(self) -> bool:
117
"""Check if currently inside a gate definition"""
118
119
def _in_subroutine(self) -> bool:
120
"""Check if currently inside a subroutine definition"""
121
122
def _in_loop(self) -> bool:
123
"""Check if currently inside a loop construct"""
124
125
# Visitor methods for all AST node types (50+ methods)
126
def visitQubitDeclaration(self, ctx) -> ast.QubitDeclaration: ...
127
def visitQuantumGateDefinition(self, ctx) -> ast.QuantumGateDefinition: ...
128
def visitClassicalDeclaration(self, ctx) -> ast.ClassicalDeclaration: ...
129
def visitSubroutineDefinition(self, ctx) -> ast.SubroutineDefinition: ...
130
def visitBranchingStatement(self, ctx) -> ast.BranchingStatement: ...
131
def visitWhileLoop(self, ctx) -> ast.WhileLoop: ...
132
def visitForInLoop(self, ctx) -> ast.ForInLoop: ...
133
# ... and many more visitor methods
134
```
135
136
### Error Handling
137
138
Exception classes for parsing error reporting.
139
140
```python { .api }
141
class QASM3ParsingError(Exception):
142
"""
143
Exception raised during AST generation phase when a program cannot be correctly parsed.
144
145
This exception is thrown for semantic errors during the AST visitor phase,
146
such as type mismatches, scope violations, or invalid language constructs.
147
Syntax errors from the ANTLR parser are converted to this exception type.
148
"""
149
```
150
151
## Usage Examples
152
153
### Basic Parsing
154
155
```python
156
import openqasm3
157
158
# Parse a simple OpenQASM 3 program
159
qasm_source = '''
160
OPENQASM 3.0;
161
qubit[2] q;
162
h q[0];
163
cx q[0], q[1];
164
measure q -> c;
165
'''
166
167
try:
168
program = openqasm3.parse(qasm_source)
169
print(f"Successfully parsed program with {len(program.statements)} statements")
170
print(f"Program version: {program.version}")
171
except openqasm3.parser.QASM3ParsingError as e:
172
print(f"Parsing failed: {e}")
173
```
174
175
### Error Recovery Mode
176
177
```python
178
import openqasm3
179
180
# Parse with permissive mode for error recovery
181
incomplete_source = '''
182
OPENQASM 3.0;
183
qubit[2] q;
184
h q[0];
185
// Missing semicolon and incomplete statement
186
cx q[0]
187
'''
188
189
try:
190
# Permissive mode attempts to recover from syntax errors
191
program = openqasm3.parse(incomplete_source, permissive=True)
192
print("Parsed with error recovery")
193
except openqasm3.parser.QASM3ParsingError as e:
194
print(f"Even permissive parsing failed: {e}")
195
```
196
197
### Advanced Usage with Span Information
198
199
```python
200
from openqasm3.parser import parse, get_span, add_span
201
202
# Parse with full span information
203
source = "qubit q;"
204
program = parse(source)
205
206
# Access span information for error reporting
207
for stmt in program.statements:
208
if stmt.span:
209
print(f"Statement at line {stmt.span.start_line}, "
210
f"columns {stmt.span.start_column}-{stmt.span.end_column}")
211
212
# Custom visitor with span handling
213
from openqasm3.parser import QASMNodeVisitor
214
from openqasm3 import ast
215
216
class CustomVisitor(QASMNodeVisitor):
217
def visitQubitDeclaration(self, ctx):
218
node = super().visitQubitDeclaration(ctx)
219
# Add custom processing with span information
220
if node.span:
221
print(f"Found qubit declaration at line {node.span.start_line}")
222
return node
223
```
224
225
### Working with Complex Programs
226
227
```python
228
import openqasm3
229
230
# Parse a complex program with multiple constructs
231
complex_source = '''
232
OPENQASM 3.0;
233
include "stdgates.inc";
234
235
// Declare qubits and classical bits
236
qubit[3] q;
237
bit[3] c;
238
239
// Define a custom gate
240
gate bell(angle[32] theta) q0, q1 {
241
h q0;
242
rx(theta) q1;
243
cx q0, q1;
244
}
245
246
// Use classical variables and control flow
247
int[32] shots = 1000;
248
for int i in [0:shots-1] {
249
// Apply the custom gate
250
bell(pi/4) q[0], q[1];
251
252
// Conditional measurement
253
if (measure q[0] -> c[0] == 1) {
254
x q[2];
255
}
256
}
257
'''
258
259
program = openqasm3.parse(complex_source)
260
261
# Analyze the parsed program
262
print(f"Program version: {program.version}")
263
print(f"Number of statements: {len(program.statements)}")
264
265
# Count different statement types
266
statement_counts = {}
267
for stmt in program.statements:
268
stmt_type = type(stmt).__name__
269
statement_counts[stmt_type] = statement_counts.get(stmt_type, 0) + 1
270
271
for stmt_type, count in statement_counts.items():
272
print(f"{stmt_type}: {count}")
273
```
274
275
## Installation Requirements
276
277
The parser functionality requires additional dependencies:
278
279
```bash
280
pip install openqasm3[parser]
281
```
282
283
This installs:
284
- `antlr4-python3-runtime`: ANTLR runtime for Python
285
- `importlib_metadata`: Metadata utilities (Python < 3.10)
286
287
The parser uses ANTLR-generated lexer and parser classes from the main OpenQASM repository grammar files.
288
289
## Supported Language Features
290
291
The parser supports the complete OpenQASM 3 specification including:
292
293
- **Quantum declarations**: qubits, quantum gates, gate modifiers
294
- **Classical types**: integers, floats, complex, angles, bits, booleans, arrays
295
- **Control flow**: if/else, while loops, for-in loops, switch statements
296
- **Subroutines**: classical functions with parameters and return types
297
- **Measurements**: quantum measurements with classical assignment
298
- **Timing**: delay instructions, boxes, duration literals
299
- **Calibration**: defcalgrammar, defcal, cal blocks
300
- **Advanced features**: include statements, pragmas, annotations
301
- **Type system**: full OpenQASM 3 type system with arrays and references
302
303
## Error Reporting
304
305
The parser provides detailed error reporting with:
306
307
- **Syntax errors**: Line and column information for invalid syntax
308
- **Semantic errors**: Context-aware errors for type mismatches and scope violations
309
- **Span information**: Source location tracking for all AST nodes
310
- **Error recovery**: Optional permissive mode for partial parsing