or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ast-nodes.mdcode-generation.mdindex.mdparser.mdutilities.mdvisitors.md

parser.mddocs/

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