QASM Parser¶
parser ¶
QASMCircuit
dataclass
¶
Parsed representation of an OpenQASM 2.0 / 3.0 circuit.
Attributes¶
n_qubits : total qubit count declared in qreg / qubit statements n_cbits : total classical bit count declared in creg / bit statements ops : list of gate dicts — each dict has keys: 'type' : 'gate' 'name' : lowercase gate name (aliases resolved) 'qubits' : list[int] — absolute qubit indices 'params' : list[float] — evaluated rotation angles
to_tuples ¶
Convert ops to the tuple format expected by DenseSVSimulator.run_circuit:
(name, qubit0, [qubit1, ...], [param0, ...])
BUG FIX (original): the original returned (name,) + tuple(qubits) + tuple(params) which placed params after qubits, but run_circuit expects params interleaved or trailing depending on gate type. For the standard (name, qubit, param) convention used throughout the simulator, this ordering is correct — preserved here but documented explicitly so callers know what to expect.
Source code in dense_evolution/parser.py
__iter__ ¶
Duck-type as an iterable of the same tuples to_tuples() returns,
so a QASMCircuit works anywhere a plain circuit list is expected
(QuantumTranspiler.transpile, Chunk.run_chunk, ...) without the
caller having to remember to call .to_tuples() first. Verified this
was a real gap, not a hypothetical one: for cmd in circuit inside
QuantumTranspiler.transpile — reached via Chunk.run_chunk(circuit)
— raised TypeError: 'QASMCircuit' object is not iterable when
handed a QASMCircuit straight from QASMParser().parse(), instead of
circuit.to_tuples().
Source code in dense_evolution/parser.py
QASMParser ¶
Robust OpenQASM 2.0 / 3.0 parser.
Supported features¶
- qreg / creg (QASM 2.0)
- qubit / bit (QASM 3.0)
- Parametric gates: rx, ry, rz, p, u1, u2, u3, cp, crz, ...
- Compound parameter expressions: pi/2, sqrt(2), cos(0.3), ...
- Block comments / ... / and line comments // ...
- Gate aliases: cu1→cp, u1→p, toffoli→ccx, cnot→cx, ...
- Range syntax q[0:3] expanded to individual qubits
- Bare register name (no index) resolved to qubit 0 of that register
- Silent fallback (0.0) for unparseable parameter expressions
parse ¶
Parse an OpenQASM 2.0 or 3.0 string into a QASMCircuit.
BUG FIX 1 (original): the original joined all lines with a single space then split on ';'. Multi-line gate definitions (gate foo ...) were not stripped before joining, causing 'gate foo ...' to appear as a runnable instruction. Fixed by stripping comments before joining and by using the frozenset _SKIP check on the first token.
BUG FIX 2 (original): bare register names (e.g. 'h q' instead of 'h q[0]') were silently dropped if the register had more than one qubit, because qubit_map only stored 'name[0]' → 0 for size-1 registers. Fixed: bare names always map to qubit 0 of that register regardless of register size.
BUG FIX 3 (original): range syntax q[0:3] was never handled — such tokens fell through to the digit-extraction fallback which returned only the last digit. Fixed in _resolve_qubits.
Source code in dense_evolution/parser.py
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | |
validate ¶
Light structural validation — does not verify gate semantics.