Some checks failed
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 7s
wai-audit collector and player integration / does this change touch it (pull_request) Successful in 9s
WAI energy receipts / does this change touch it (pull_request) Successful in 13s
WAI conformance / does this change touch it (pull_request) Successful in 14s
WAI examples / WAI examples · does this change touch them (pull_request) Successful in 6s
wai-quantum command line / does this change touch it (pull_request) Successful in 7s
wai-quantum dataflow member / does this change touch it (pull_request) Successful in 8s
wai-quantum CUDA member / does this change touch it (pull_request) Successful in 9s
wai-quantum signal processor / does this change touch it (pull_request) Successful in 8s
wai-quantum editors / does this change touch it (pull_request) Successful in 6s
wai-quantum FPGA member / does this change touch it (pull_request) Successful in 7s
wai-quantum HIP member / does this change touch it (pull_request) Successful in 8s
wai-quantum Metal member / does this change touch it (pull_request) Successful in 7s
wai-quantum OpenQASM reader / does this change touch it (pull_request) Successful in 8s
wai-quantum npu-cores member / does this change touch it (pull_request) Successful in 6s
wai-quantum neural-processor member / does this change touch it (pull_request) Successful in 8s
wai-quantum OpenCL member / does this change touch it (pull_request) Successful in 9s
wai-quantum for Python / does this change touch it (pull_request) Successful in 10s
wai-quantum-qpu / does this change touch it (pull_request) Successful in 7s
wai-quantum matrix-extension member / does this change touch it (pull_request) Successful in 7s
wai-quantum service / does this change touch it (pull_request) Successful in 9s
wai-quantum studio and desktop / does this change touch it (pull_request) Successful in 8s
wai-quantum tensor-engine member / does this change touch it (pull_request) Successful in 6s
wai-quantum CUDA member / member · CUDA (jetson-hub) (pull_request) Successful in 30s
wai-quantum portable tensor program / does this change touch it (pull_request) Successful in 7s
wai-quantum CPU vector units / does this change touch it (pull_request) Successful in 7s
wai-quantum WebGPU member / does this change touch it (pull_request) Successful in 8s
wai-sink-android native sink library / does this change touch it (pull_request) Successful in 6s
wai-sink-swift native sink package / does this change touch it (pull_request) Successful in 6s
WAI mbt2018_mean integer decode (regenerated vectors) / does this change touch it (pull_request) Successful in 6s
wai-web wasm32 / does this change touch it (pull_request) Successful in 6s
wai-quantum OpenCL member / member · OpenCL GPU and CPU (jetson-hub) (pull_request) Successful in 29s
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 27s
wai-quantum portable tensor program / tensor program · GPUs (jetson-hub) (pull_request) Successful in 26s
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (pull_request) Successful in 1m44s
wai-quantum on every processor / emulated · aarch64-unknown-linux-gnu (pull_request) Successful in 2m14s
standards workspaces build + test / macOS energy backends (pull_request) Failing after 2m12s
wai-quantum on every processor / emulated · powerpc64le-unknown-linux-gnu (pull_request) Successful in 3m10s
WAI conformance / fast integer kernels, every x86_64 kernel set (AVX-512 silicon) (pull_request) Successful in 2m57s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 3m26s
wai-quantum HIP member / member · HIP (framework-128gb) (pull_request) Successful in 28s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 1m23s
wai-quantum on every processor / emulated · riscv64gc-unknown-linux-gnu (pull_request) Successful in 4m37s
wai-quantum npu-cores member / member · npu-cores, neural processor (framework-128gb silicon) (pull_request) Successful in 1m17s
wai-quantum OpenCL member / member · OpenCL GPU (framework-128gb) (pull_request) Successful in 23s
wai-quantum portable tensor program / tensor program · integrated GPU (framework-128gb) (pull_request) Successful in 12s
wai-quantum on every processor / emulated · powerpc64-unknown-linux-gnu (pull_request) Successful in 5m41s
wai-web reach builds / wai-web reach · does this change touch it (pull_request) Successful in 6s
wai-quantum CPU vector units / member · vector units, avx2 and avx512 (framework-128gb silicon) (pull_request) Successful in 17s
wai-quantum on every processor / emulated · armv7-unknown-linux-gnueabihf (pull_request) Successful in 6m40s
wai-audit collector and player integration / collector · linux (pull_request) Successful in 1m8s
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Successful in 3m26s
wai-quantum on every processor / emulated · loongarch64-unknown-linux-gnu (pull_request) Successful in 9m5s
wai-quantum on every processor / emulated · s390x-unknown-linux-gnu (pull_request) Successful in 7m28s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 9m35s
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 9m39s
wai-quantum command line / command line · macos (pull_request) Successful in 58s
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Successful in 14s
wai-quantum dataflow member / member · dataflow device absent (macos) (pull_request) Successful in 25s
WAI conformance / faces from keypoints under wasm32-wasip2 (wasmtime) (pull_request) Successful in 2m3s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 52s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 37s
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Successful in 3m15s
wai-quantum editors / editors · macos (pull_request) Successful in 1m6s
wai-quantum WebGPU member / member · DX12 and Vulkan (cbio-windows) (pull_request) Successful in 12m26s
wai-quantum on every processor / emulated · sparc64-unknown-linux-gnu (pull_request) Successful in 9m53s
wai-quantum CUDA member / member · CUDA absent (linux) (pull_request) Successful in 32s
wai-quantum FPGA member / member · FPGA datapath, simulated (macos) (pull_request) Successful in 1m33s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 13m2s
wai-quantum on every processor / emulated · i686-unknown-linux-gnu (pull_request) Successful in 9m39s
wai-quantum command line / command line · linux (pull_request) Successful in 2m3s
wai-quantum WebGPU member / member · integrated GPU, Vulkan (framework-128gb) (pull_request) Successful in 8m45s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 2m51s
wai-quantum Metal member / member · Metal (macos) (pull_request) Successful in 56s
wai-quantum HIP member / member · HIP absent (linux-arm64) (pull_request) Successful in 45s
wai-quantum npu-cores member / member · npu-cores absent (linux-arm64) (pull_request) Successful in 30s
wai-quantum tensor-engine member / member · tensor engine absent (linux-arm64) (pull_request) Successful in 23s
WAI conformance / each feature of the independent verifiers' steps compiles alone (pull_request) Successful in 13m13s
wai-quantum dataflow member / member · dataflow device, simulated (pci 1e52:b140) (pull_request) Successful in 4m10s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 11m26s
wai-quantum FPGA member / member · FPGA simulation absent (linux) (pull_request) Successful in 19s
wai-quantum Metal member / member · Metal absent (linux) (pull_request) Successful in 30s
wai-quantum dataflow member / member · dataflow device, simulated (pci 1e52:401e) (pull_request) Successful in 4m42s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (pull_request) Successful in 2m49s
wai-quantum editors / editors · linux (pull_request) Successful in 1m36s
wai-quantum OpenQASM reader / corpus under wasm32-wasip2 (wasmtime) (pull_request) Successful in 35s
wai-quantum neural-processor member / member · neural processor absent (linux) (pull_request) Successful in 20s
wai-quantum OpenCL member / member · OpenCL absent (linux) (pull_request) Successful in 25s
wai-quantum OpenQASM reader / reader and corpus · linux (pull_request) Successful in 1m13s
WAI examples / WAI examples · android-app · linux-arm64 (pull_request) Successful in 5m50s
wai-quantum matrix-extension member / member · matrix extension, emulated (aarch64 Linux) (pull_request) Successful in 17s
wai-quantum-qpu / clients against their contracts (linux) (pull_request) Successful in 40s
wai-quantum service / service · linux (pull_request) Successful in 56s
wai-quantum for Python / python · linux (pull_request) Successful in 1m52s
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (pull_request) Successful in 14m44s
wai-quantum portable tensor program / tensor program · CPU, mutants, GPU builds (pull_request) Successful in 42s
WAI examples / WAI examples · portable · linux (pull_request) Successful in 10m6s
wai-quantum OpenCL member / member · OpenCL GPU (macos) (pull_request) Successful in 33s
wai-quantum CPU vector units / member · vector unit, rvv 1024-bit (riscv64, emulated) (pull_request) Successful in 22s
wai-quantum CPU vector units / member · vector unit, rvv 128-bit (riscv64, emulated) (pull_request) Successful in 11s
wai-quantum CPU vector units / member · vector unit, sve 128-bit (aarch64, emulated) (pull_request) Successful in 40s
wai-quantum CPU vector units / member · vector unit, sve 2048-bit (aarch64, emulated) (pull_request) Successful in 23s
wai-quantum CPU vector units / member · vector unit, sve 512-bit (aarch64, emulated) (pull_request) Successful in 10s
wai-quantum CPU vector units / member · vector unit, avx2 (x86_64 silicon) (pull_request) Successful in 23s
wai-quantum for Python / python · macos (pull_request) Successful in 1m47s
wai-quantum studio and desktop / studio · browser (pull_request) Successful in 3m40s
wai-quantum-qpu / credentials in the keychain (macos) (pull_request) Successful in 21s
wai-quantum WebGPU member / member · discrete GPU, Vulkan (jetson-hub) (pull_request) Successful in 22m52s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 23m2s
wai-quantum matrix-extension member / member · matrix extension absent (macos) (pull_request) Successful in 15s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 23m58s
wai-quantum neural-processor member / member · neural processor (macos) (pull_request) Successful in 10m31s
wai-quantum portable tensor program / tensor program · Metal and the arm64 CPU (macos) (pull_request) Successful in 18s
wai-quantum service / service · macos (pull_request) Successful in 58s
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Successful in 2m30s
wai-quantum CPU vector units / member · vector unit absent (macos) (pull_request) Successful in 17s
wai-quantum tensor-engine member / member · tensor engine, the kernel toolchain's simulator (linux) (pull_request) Successful in 4m55s
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness · MSRV (pull_request) Successful in 3m29s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 20m35s
wai-quantum WebGPU member / member · browser WebGPU (macos) (pull_request) Successful in 1m55s
wai-quantum signal processor / processor and member · signal processor, emulated (pull_request) Successful in 13m40s
wai-quantum studio and desktop / desktop app · macos (pull_request) Successful in 3m7s
wai-quantum WebGPU member / member · Metal (macos) (pull_request) Successful in 2m56s
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Successful in 2m40s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 6m52s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 5m13s
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Successful in 7m12s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (pull_request) Successful in 8m44s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (pull_request) Successful in 17m32s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 1h0m53s
The editors' CI parses every program in the repository; the OpenQASM 3 corpus's lang/output.qasm declares `output int[32] n = 3;`, which the engine's reader takes and the grammar refused. The generated parser is regenerated; 97 of 97 programs parse, and fmt holds on all of them. Co-Authored-By: Claude Opus 5.5 <[email protected]>
411 lines
13 KiB
JavaScript
411 lines
13 KiB
JavaScript
/**
|
|
* @file OpenQASM 3, and the OpenQASM 2 forms in common use, for tree-sitter.
|
|
* @license Apache-2.0
|
|
*
|
|
* The grammar reads what is written: every statement of OpenQASM 3.1
|
|
* (declarations of every type, gates and subroutines, modifiers, control
|
|
* flow, timing, calibrations, pragmas and annotations) and OpenQASM 2's
|
|
* `qreg`, `creg`, `opaque`, `measure q -> c` and `if(c==1)`. It does not say
|
|
* what a program means; the engine's reader does.
|
|
*/
|
|
|
|
/// <reference types="tree-sitter-cli/dsl" />
|
|
// @ts-check
|
|
|
|
const PREC = {
|
|
logical_or: 1,
|
|
logical_and: 2,
|
|
bit_or: 3,
|
|
bit_xor: 4,
|
|
bit_and: 5,
|
|
equality: 6,
|
|
comparison: 7,
|
|
shift: 8,
|
|
additive: 9,
|
|
multiplicative: 10,
|
|
unary: 11,
|
|
power: 12,
|
|
call: 13,
|
|
index: 14,
|
|
};
|
|
|
|
const DECIMAL = /[0-9](_?[0-9])*/;
|
|
const FLOAT = choice(
|
|
seq(DECIMAL, '.', optional(DECIMAL), optional(/[eE][+-]?[0-9]+/)),
|
|
seq('.', DECIMAL, optional(/[eE][+-]?[0-9]+/)),
|
|
seq(DECIMAL, /[eE][+-]?[0-9]+/),
|
|
);
|
|
|
|
/**
|
|
* One or more of `rule`, separated by commas, with an optional trailing comma.
|
|
* @param {RuleOrLiteral} rule
|
|
*/
|
|
function commaSep1(rule) {
|
|
return seq(rule, repeat(seq(',', rule)), optional(','));
|
|
}
|
|
|
|
module.exports = grammar({
|
|
name: 'openqasm',
|
|
|
|
extras: $ => [/\s/, $.line_comment, $.block_comment],
|
|
|
|
word: $ => $.identifier,
|
|
|
|
conflicts: $ => [
|
|
// After a name and `[`: `g[100ns] q;` calls a gate for a duration,
|
|
// `c[0] = …` assigns, and `c[0];` is an expression.
|
|
[$.gate_call, $.indexed_identifier, $._expression],
|
|
// `rx(θ)[100ns] q;` calls a gate for a duration; `f(x)[0];` indexes a call's value.
|
|
[$.gate_call, $.call_expression],
|
|
],
|
|
|
|
rules: {
|
|
source_file: $ => seq(optional($.version), repeat($._statement_or_scope)),
|
|
|
|
version: $ => seq('OPENQASM', field('number', choice($.integer_literal, $.float_literal)), ';'),
|
|
|
|
_statement_or_scope: $ => choice($._statement, $.scope),
|
|
|
|
scope: $ => seq('{', repeat($._statement_or_scope), '}'),
|
|
|
|
_statement: $ => choice(
|
|
$.pragma,
|
|
$.annotation,
|
|
$.include,
|
|
$.calibration_grammar,
|
|
$.quantum_declaration,
|
|
$.old_style_declaration,
|
|
$.classical_declaration,
|
|
$.const_declaration,
|
|
$.io_declaration,
|
|
$.alias_declaration,
|
|
$.gate_definition,
|
|
$.opaque_declaration,
|
|
$.subroutine_definition,
|
|
$.extern_declaration,
|
|
$.calibration,
|
|
$.calibration_definition,
|
|
$.gate_call,
|
|
$.gphase_call,
|
|
$.measure_statement,
|
|
$.reset_statement,
|
|
$.barrier_statement,
|
|
$.delay_statement,
|
|
$.box_statement,
|
|
$.assignment_statement,
|
|
$.expression_statement,
|
|
$.if_statement,
|
|
$.for_statement,
|
|
$.while_statement,
|
|
$.switch_statement,
|
|
$.return_statement,
|
|
$.break_statement,
|
|
$.continue_statement,
|
|
$.end_statement,
|
|
),
|
|
|
|
pragma: _ => token(seq(choice('#pragma', 'pragma'), /[^\n]*/)),
|
|
|
|
annotation: _ => token(seq('@', /[A-Za-z_][A-Za-z0-9_.]*/, /[^\n]*/)),
|
|
|
|
include: $ => seq('include', field('path', $.string), ';'),
|
|
|
|
calibration_grammar: $ => seq('defcalgrammar', field('name', $.string), ';'),
|
|
|
|
// Declarations.
|
|
|
|
quantum_declaration: $ => seq(field('type', $.qubit_type), field('name', $.identifier), ';'),
|
|
|
|
qubit_type: $ => seq('qubit', optional($.designator)),
|
|
|
|
old_style_declaration: $ => seq(choice('qreg', 'creg'), field('name', $.identifier), optional($.designator), ';'),
|
|
|
|
classical_declaration: $ => seq(
|
|
field('type', choice($.scalar_type, $.array_type)),
|
|
field('name', $.identifier),
|
|
optional(seq('=', field('value', $._declaration_value))),
|
|
';',
|
|
),
|
|
|
|
const_declaration: $ => seq('const', field('type', $.scalar_type), field('name', $.identifier), '=', field('value', $._declaration_value), ';'),
|
|
|
|
// `output` may name its value at once (`output int[32] n = 3;`), as the
|
|
// engine's reader takes it; `input` takes its value when the program is read.
|
|
io_declaration: $ => choice(
|
|
seq('input', field('type', choice($.scalar_type, $.array_type)), field('name', $.identifier), ';'),
|
|
seq('output', field('type', choice($.scalar_type, $.array_type)), field('name', $.identifier), optional(seq('=', field('value', $._expression))), ';'),
|
|
),
|
|
|
|
alias_declaration: $ => seq('let', field('name', $.identifier), '=', field('value', $.alias_expression), ';'),
|
|
|
|
_declaration_value: $ => choice($._expression, $.array_literal, $.measure_expression),
|
|
|
|
designator: $ => seq('[', $._expression, ']'),
|
|
|
|
scalar_type: $ => choice(
|
|
seq(choice('bit', 'int', 'uint', 'float', 'angle'), optional($.designator)),
|
|
'bool',
|
|
'duration',
|
|
'stretch',
|
|
seq('complex', optional(seq('[', $.scalar_type, ']'))),
|
|
),
|
|
|
|
array_type: $ => seq('array', '[', $.scalar_type, ',', commaSep1($._expression), ']'),
|
|
|
|
array_reference_type: $ => seq(
|
|
choice('readonly', 'mutable'),
|
|
'array',
|
|
'[',
|
|
$.scalar_type,
|
|
',',
|
|
choice(commaSep1($._expression), seq('#dim', '=', $._expression)),
|
|
']',
|
|
),
|
|
|
|
// Gates, subroutines and calibrations.
|
|
|
|
gate_definition: $ => seq(
|
|
'gate',
|
|
field('name', $.identifier),
|
|
optional(field('parameters', $.gate_parameters)),
|
|
field('qubits', $.identifier_list),
|
|
field('body', $.scope),
|
|
),
|
|
|
|
opaque_declaration: $ => seq('opaque', field('name', $.identifier), optional(field('parameters', $.gate_parameters)), field('qubits', $.identifier_list), ';'),
|
|
|
|
gate_parameters: $ => seq('(', optional(commaSep1($.identifier)), ')'),
|
|
|
|
identifier_list: $ => commaSep1($.identifier),
|
|
|
|
subroutine_definition: $ => seq(
|
|
'def',
|
|
field('name', $.identifier),
|
|
field('parameters', $.parameter_list),
|
|
optional(field('return_type', $.return_signature)),
|
|
field('body', $.scope),
|
|
),
|
|
|
|
parameter_list: $ => seq('(', optional(commaSep1($.parameter)), ')'),
|
|
|
|
parameter: $ => choice(
|
|
seq(field('type', choice($.scalar_type, $.qubit_type, $.array_reference_type)), field('name', $.identifier)),
|
|
seq(choice('creg', 'qreg'), field('name', $.identifier), optional($.designator)),
|
|
),
|
|
|
|
return_signature: $ => seq('->', $.scalar_type),
|
|
|
|
extern_declaration: $ => seq(
|
|
'extern',
|
|
field('name', $.identifier),
|
|
'(',
|
|
optional(commaSep1(choice($.scalar_type, $.array_reference_type, seq('creg', optional($.designator))))),
|
|
')',
|
|
optional(field('return_type', $.return_signature)),
|
|
';',
|
|
),
|
|
|
|
calibration: $ => seq('cal', field('body', $.calibration_block)),
|
|
|
|
calibration_definition: $ => seq(
|
|
'defcal',
|
|
field('target', choice('measure', 'reset', 'delay', $.identifier)),
|
|
optional(seq('(', optional(commaSep1(choice($.parameter, $._expression))), ')')),
|
|
commaSep1(choice($.hardware_qubit, $.identifier)),
|
|
optional(field('return_type', $.return_signature)),
|
|
field('body', $.calibration_block),
|
|
),
|
|
|
|
// A calibration's body is in its own grammar: kept as text, its braces matched.
|
|
calibration_block: $ => seq('{', repeat(choice($.calibration_text, $.calibration_block)), '}'),
|
|
|
|
calibration_text: _ => token(prec(-1, /[^{}\s][^{}]*/)),
|
|
|
|
// Quantum statements.
|
|
|
|
gate_call: $ => seq(
|
|
repeat($.gate_modifier),
|
|
field('name', $.identifier),
|
|
optional(field('arguments', $.argument_list)),
|
|
optional(field('duration', $.designator)),
|
|
field('operands', $.operand_list),
|
|
';',
|
|
),
|
|
|
|
gphase_call: $ => seq(
|
|
repeat($.gate_modifier),
|
|
'gphase',
|
|
optional(field('arguments', $.argument_list)),
|
|
optional(field('duration', $.designator)),
|
|
optional(field('operands', $.operand_list)),
|
|
';',
|
|
),
|
|
|
|
gate_modifier: $ => seq(
|
|
choice(
|
|
'inv',
|
|
seq('pow', '(', $._expression, ')'),
|
|
seq(choice('ctrl', 'negctrl'), optional(seq('(', $._expression, ')'))),
|
|
),
|
|
'@',
|
|
),
|
|
|
|
operand_list: $ => commaSep1($._operand),
|
|
|
|
_operand: $ => choice($.indexed_identifier, $.hardware_qubit),
|
|
|
|
indexed_identifier: $ => prec.left(seq($.identifier, repeat($.index))),
|
|
|
|
index: $ => seq('[', choice($.set_expression, commaSep1(choice($._expression, $.range_expression))), ']'),
|
|
|
|
measure_statement: $ => seq($.measure_expression, optional(seq('->', field('target', $.indexed_identifier))), ';'),
|
|
|
|
measure_expression: $ => seq('measure', field('operand', $._operand)),
|
|
|
|
reset_statement: $ => seq('reset', field('operand', $._operand), ';'),
|
|
|
|
barrier_statement: $ => seq('barrier', optional($.operand_list), ';'),
|
|
|
|
delay_statement: $ => seq('delay', field('duration', $.designator), optional($.operand_list), ';'),
|
|
|
|
box_statement: $ => seq('box', optional(field('duration', $.designator)), field('body', $.scope)),
|
|
|
|
// Classical statements.
|
|
|
|
assignment_statement: $ => seq(
|
|
field('left', $.indexed_identifier),
|
|
field('operator', choice('=', '+=', '-=', '*=', '/=', '%=', '&=', '|=', '^=', '~=', '<<=', '>>=', '**=')),
|
|
field('right', choice($._expression, $.measure_expression)),
|
|
';',
|
|
),
|
|
|
|
expression_statement: $ => seq($._expression, ';'),
|
|
|
|
if_statement: $ => prec.right(seq(
|
|
'if',
|
|
'(',
|
|
field('condition', $._expression),
|
|
')',
|
|
field('consequence', $._statement_or_scope),
|
|
optional(seq('else', field('alternative', $._statement_or_scope))),
|
|
)),
|
|
|
|
for_statement: $ => seq(
|
|
'for',
|
|
optional(field('type', $.scalar_type)),
|
|
field('variable', $.identifier),
|
|
'in',
|
|
field('iterable', choice($.set_expression, $.range, $.identifier)),
|
|
field('body', $._statement_or_scope),
|
|
),
|
|
|
|
range: $ => seq('[', $.range_expression, ']'),
|
|
|
|
while_statement: $ => seq('while', '(', field('condition', $._expression), ')', field('body', $._statement_or_scope)),
|
|
|
|
switch_statement: $ => seq('switch', '(', field('value', $._expression), ')', '{', repeat(choice($.case_clause, $.default_clause)), '}'),
|
|
|
|
case_clause: $ => seq('case', commaSep1($._expression), field('body', $.scope)),
|
|
|
|
default_clause: $ => seq('default', field('body', $.scope)),
|
|
|
|
return_statement: $ => seq('return', optional(choice($._expression, $.measure_expression)), ';'),
|
|
|
|
break_statement: _ => seq('break', ';'),
|
|
|
|
continue_statement: _ => seq('continue', ';'),
|
|
|
|
end_statement: _ => seq('end', ';'),
|
|
|
|
// Expressions.
|
|
|
|
_expression: $ => choice(
|
|
$.identifier,
|
|
$.hardware_qubit,
|
|
$.integer_literal,
|
|
$.float_literal,
|
|
$.imaginary_literal,
|
|
$.timing_literal,
|
|
$.boolean_literal,
|
|
$.string,
|
|
$.parenthesized_expression,
|
|
$.index_expression,
|
|
$.call_expression,
|
|
$.cast_expression,
|
|
$.durationof_expression,
|
|
$.unary_expression,
|
|
$.binary_expression,
|
|
),
|
|
|
|
parenthesized_expression: $ => seq('(', $._expression, ')'),
|
|
|
|
index_expression: $ => prec(PREC.index, seq(field('value', $._expression), $.index)),
|
|
|
|
call_expression: $ => seq(field('function', $.identifier), field('arguments', $.argument_list)),
|
|
|
|
argument_list: $ => seq('(', optional(commaSep1($._expression)), ')'),
|
|
|
|
cast_expression: $ => prec(PREC.call, seq(field('type', choice($.scalar_type, $.array_type)), '(', $._expression, ')')),
|
|
|
|
durationof_expression: $ => seq('durationof', '(', $.scope, ')'),
|
|
|
|
unary_expression: $ => prec(PREC.unary, seq(field('operator', choice('-', '+', '!', '~')), field('operand', $._expression))),
|
|
|
|
binary_expression: $ => {
|
|
/** @type {[string[], number, 'left' | 'right'][]} */
|
|
const table = [
|
|
[['**'], PREC.power, 'right'],
|
|
[['*', '/', '%'], PREC.multiplicative, 'left'],
|
|
[['+', '-'], PREC.additive, 'left'],
|
|
[['<<', '>>'], PREC.shift, 'left'],
|
|
[['<', '>', '<=', '>='], PREC.comparison, 'left'],
|
|
[['==', '!='], PREC.equality, 'left'],
|
|
[['&'], PREC.bit_and, 'left'],
|
|
[['^'], PREC.bit_xor, 'left'],
|
|
[['|'], PREC.bit_or, 'left'],
|
|
[['&&'], PREC.logical_and, 'left'],
|
|
[['||'], PREC.logical_or, 'left'],
|
|
];
|
|
return choice(...table.map(([ops, p, assoc]) => {
|
|
const op = ops.length === 1 ? ops[0] : choice(...ops);
|
|
const rule = seq(field('left', $._expression), field('operator', op), field('right', $._expression));
|
|
return assoc === 'right' ? prec.right(p, rule) : prec.left(p, rule);
|
|
}));
|
|
},
|
|
|
|
alias_expression: $ => seq($._expression, repeat(seq('++', $._expression))),
|
|
|
|
range_expression: $ => prec.right(seq(
|
|
optional(field('start', $._expression)),
|
|
':',
|
|
optional(field('step_or_end', $._expression)),
|
|
optional(seq(':', optional(field('end', $._expression)))),
|
|
)),
|
|
|
|
set_expression: $ => seq('{', commaSep1($._expression), '}'),
|
|
|
|
array_literal: $ => seq('{', optional(commaSep1(choice($._expression, $.array_literal))), '}'),
|
|
|
|
// Literals and names.
|
|
|
|
integer_literal: _ => token(choice(/0[bB][01](_?[01])*/, /0[oO][0-7](_?[0-7])*/, /0[xX][0-9a-fA-F](_?[0-9a-fA-F])*/, DECIMAL)),
|
|
|
|
float_literal: _ => token(FLOAT),
|
|
|
|
imaginary_literal: _ => token(seq(choice(FLOAT, DECIMAL), /[ \t]*/, 'im')),
|
|
|
|
timing_literal: _ => token(seq(choice(FLOAT, DECIMAL), choice('dt', 'ns', 'us', 'µs', 'ms', 's'))),
|
|
|
|
boolean_literal: _ => choice('true', 'false'),
|
|
|
|
string: _ => token(choice(/"[^"\n]*"/, /'[^'\n]*'/)),
|
|
|
|
hardware_qubit: _ => /\$[0-9]+/,
|
|
|
|
identifier: _ => /[\p{L}_][\p{L}\p{N}_]*/u,
|
|
|
|
line_comment: _ => token(seq('//', /[^\n]*/)),
|
|
|
|
block_comment: _ => token(seq('/*', /[^*]*\*+([^/*][^*]*\*+)*/, '/')),
|
|
},
|
|
});
|