qasm-ts 2.1.3 → 2.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,483 @@
1
+ /**
2
+ * OpenQASM 2.0 Lexical Analyzer
3
+ *
4
+ * This module implements the lexer for OpenQASM 2.0, which provides a simpler
5
+ * token set compared to OpenQASM 3.0. The lexer focuses on basic quantum circuit
6
+ * constructs without the advanced classical programming features of version 3.0.
7
+ *
8
+ * Key characteristics of OpenQASM 2.0 lexing:
9
+ * - **Limited token set**: Basic quantum and classical registers only
10
+ * - **Simple operators**: Basic arithmetic and comparison operators
11
+ * - **No control flow**: No tokens for loops, conditionals, or functions
12
+ * - **Gate-focused**: Emphasis on gate definitions and applications
13
+ * - **Mathematical functions**: Built-in math functions (sin, cos, etc.)
14
+ *
15
+ * Supported constructs:
16
+ * - Quantum registers (`qreg`) and classical registers (`creg`)
17
+ * - Gate definitions and applications
18
+ * - Measurements with arrow notation (`->`)
19
+ * - Basic arithmetic expressions for gate parameters
20
+ * - Include statements for library files
21
+ *
22
+ * @module
23
+ *
24
+ * @example OpenQASM 2.0 lexing
25
+ * ```typescript
26
+ * const lexer = new Lexer('qreg q[2]; h q[0]; measure q -> c;');
27
+ * const tokens = lexer.lex();
28
+ * // Produces tokens for register declaration, gate, and measurement
29
+ * ```
30
+ */
31
+ import { Token, lookup } from "./token";
32
+ import { BadEqualsError, MissingSemicolonError, UnsupportedOpenQASMVersionError, } from "../errors";
33
+ /**
34
+ * Handles throwing lexer errors with basic stack trace.
35
+ * @param error - The error to throw.
36
+ * @param number - The line number in the source code.
37
+ * @param code - The source code that the error is about.
38
+ */
39
+ function throwLexerError(error, line, code) {
40
+ throw new error(`Line ${line}: ${code}`);
41
+ }
42
+ /**
43
+ * Returns whether a given character could be an element of a numeric value.
44
+ * @param c - The character.
45
+ * @return Whether the character is numeric.
46
+ */
47
+ function isNumeric(c) {
48
+ return c == "." || !isNaN(parseInt(c));
49
+ }
50
+ /**
51
+ * Returns whether a given character is a letter.
52
+ * @param c - The character.
53
+ * @param matchCase - Whether to check for a letter that is upper case, lower case, or either. (optional)
54
+ * @return Whether the character is a letter.
55
+ */
56
+ function isLetter(c, matchCase) {
57
+ switch (matchCase) {
58
+ case "upper":
59
+ return /^[A-Z]$/.test(c);
60
+ case "lower":
61
+ return /^[a-z]$/.test(c);
62
+ default:
63
+ return /^[A-Za-z]$/.test(c);
64
+ }
65
+ }
66
+ /**
67
+ * Returns whether a given character is unicode.
68
+ * @param c - The character.
69
+ * @param excludePi - Whether to exclude the Pi symbol from consideration.
70
+ * @return - Whether the given character is valid unicode.
71
+ */
72
+ function isUnicode(c, excludePi) {
73
+ const isBasicUnicode = /^\u0000-\u00ff/.test(c);
74
+ switch (excludePi) {
75
+ case true:
76
+ return isBasicUnicode && c !== "\u03C0";
77
+ case false:
78
+ return isBasicUnicode;
79
+ default:
80
+ return isBasicUnicode;
81
+ }
82
+ }
83
+ /**
84
+ * Returns whether a given character is alphanumeric.
85
+ * @param c - The character.
86
+ * @return Whether the character is alphanumeric.
87
+ */
88
+ function isAlpha(c) {
89
+ return /^[0-9a-zA-Z]+$/.test(c);
90
+ }
91
+ /**
92
+ * Returns whether a given character is a newline character.
93
+ * @param c - The character.
94
+ * @return Whether the character is a newline.
95
+ */
96
+ function isNewline(c) {
97
+ return /\n|\r(?!\n)|\u2028|\u2029|\r\n/.test(c);
98
+ }
99
+ /**
100
+ * OpenQASM 2.0 Lexical Analyzer
101
+ *
102
+ * A simpler lexer implementation focused on the core quantum circuit description
103
+ * features of OpenQASM 2.0. This lexer handles the essential constructs needed
104
+ * for basic quantum programming without the complexity of classical programming
105
+ * language features.
106
+ *
107
+ * @example Basic OpenQASM 2.0 tokenization
108
+ * ```typescript
109
+ * const source = `
110
+ * OPENQASM 2.0;
111
+ * include "qelib1.inc";
112
+ * qreg q[2];
113
+ * creg c[2];
114
+ * h q[0];
115
+ * cx q[0],q[1];
116
+ * measure q -> c;
117
+ * `;
118
+ *
119
+ * const lexer = new Lexer(source);
120
+ * const tokens = lexer.lex();
121
+ * ```
122
+ */
123
+ class Lexer {
124
+ /**
125
+ * Creates a lexer.
126
+ * @param input - The string to lex.
127
+ * @param cursor - The starting cursor position.
128
+ */
129
+ constructor(input, cursor = 0) {
130
+ /**
131
+ * Verifies that all appropriate lines end with a semicolon.
132
+ * @return A tuple of the status and if False, returns the problematic line.
133
+ */
134
+ this.verifyInput = () => {
135
+ const lines = this.input.split(/\n|\r(?!\n)|\u2028|\u2029|\r\n/g);
136
+ for (let i = 0; i < lines.length; i++) {
137
+ if (!lines[i].startsWith("//") &&
138
+ !(lines[i].length == 0) &&
139
+ !lines[i].includes("gate") &&
140
+ !(lines[i].trim() == "{" || lines[i].trim() == "}") &&
141
+ !lines[i].includes(";")) {
142
+ return [false, i + 1, lines[i]];
143
+ }
144
+ }
145
+ return [true, null, null];
146
+ };
147
+ /**
148
+ * Calling this method lexes the code represented by the provided string.
149
+ * @return An array of tokens and their corresponding values.
150
+ */
151
+ this.lex = () => {
152
+ const tokens = [];
153
+ let token;
154
+ const verifyInputResult = this.verifyInput();
155
+ if (!verifyInputResult[0]) {
156
+ throwLexerError(MissingSemicolonError, verifyInputResult[1], verifyInputResult[2]);
157
+ }
158
+ while (this.cursor < this.input.length) {
159
+ token = this.nextToken();
160
+ if (token) {
161
+ tokens.push(token);
162
+ }
163
+ }
164
+ return tokens;
165
+ };
166
+ /**
167
+ * Reads a character and advances the cursor.
168
+ * @param num - Optional cursor position modifier.
169
+ */
170
+ this.readChar = (num = 1) => {
171
+ this.cursor += num;
172
+ return this.input[this.cursor - num];
173
+ };
174
+ /**
175
+ * Advances the cusor past the next comment.
176
+ */
177
+ this.skipComment = () => {
178
+ let char = "";
179
+ while (!isNewline(char)) {
180
+ char = this.readChar();
181
+ }
182
+ };
183
+ /**
184
+ * Determines whether the next character to process equals a given character.
185
+ * @param c - The given character.
186
+ * @return Whether the next character equals the given character.
187
+ */
188
+ this.peekEq = (c) => this.peek() == c;
189
+ /**
190
+ * Reads a character without advancing the cursor.
191
+ * @param index - Optional peek position offset.
192
+ */
193
+ this.peek = () => this.input[this.cursor];
194
+ /**
195
+ * Reads a numeric value.
196
+ * @return The numeric value as a string.
197
+ */
198
+ this.readNumeric = () => {
199
+ let num = "";
200
+ while (isNumeric(this.peek())) {
201
+ num += this.readChar();
202
+ }
203
+ return num;
204
+ };
205
+ /**
206
+ * Reads an identifier.
207
+ * @return The identifier as a string.
208
+ */
209
+ this.readIdentifier = () => {
210
+ let id = "";
211
+ let next = this.peek();
212
+ while (isAlpha(next) || next == "_" || isUnicode(next)) {
213
+ id += this.readChar();
214
+ next = this.peek();
215
+ }
216
+ return id;
217
+ };
218
+ /**
219
+ * Reads a string literal.
220
+ * @param terminator - The literal's termination character.
221
+ * @return The literal as a string.
222
+ */
223
+ this.readStringLiteral = (terminator) => {
224
+ let lit = "";
225
+ let char = "";
226
+ while (!(terminator == char)) {
227
+ char = this.readChar();
228
+ lit += char;
229
+ }
230
+ return lit;
231
+ };
232
+ /**
233
+ * Advances the cusor past the next block of whitespace.
234
+ */
235
+ this.skipWhitespace = () => {
236
+ while (" \t\n\r\v".indexOf(this.peek()) > -1) {
237
+ this.cursor += 1;
238
+ }
239
+ return null;
240
+ };
241
+ /**
242
+ * Lexes the next token.
243
+ * @return The next token and its corresponding value.
244
+ */
245
+ this.nextToken = () => {
246
+ this.skipWhitespace();
247
+ if (this.cursor == this.input.length) {
248
+ return [Token.EndOfFile];
249
+ }
250
+ const char = this.peek();
251
+ this.readChar();
252
+ switch (char) {
253
+ case "=":
254
+ if (this.peekEq("=")) {
255
+ this.readChar();
256
+ return [Token.Equals];
257
+ }
258
+ else {
259
+ throwLexerError(BadEqualsError, this.getLineNumber(this.cursor), this.getCurrentLine(this.cursor));
260
+ break;
261
+ }
262
+ case "-":
263
+ if (this.peekEq(">")) {
264
+ this.readChar();
265
+ return [Token.Arrow];
266
+ }
267
+ else {
268
+ return [Token.Minus];
269
+ }
270
+ case "+":
271
+ return [Token.Plus];
272
+ case "*":
273
+ return [Token.Times];
274
+ case "^":
275
+ return [Token.Power];
276
+ case ";":
277
+ return [Token.Semicolon];
278
+ case ",":
279
+ return [Token.Comma];
280
+ case "(":
281
+ return [Token.LParen];
282
+ case "[":
283
+ return [Token.LSParen];
284
+ case "{":
285
+ return [Token.LCParen];
286
+ case ")":
287
+ return [Token.RParen];
288
+ case "]":
289
+ return [Token.RSParen];
290
+ case "}":
291
+ return [Token.RCParen];
292
+ case "/":
293
+ if (this.peekEq("/")) {
294
+ this.skipComment();
295
+ return;
296
+ }
297
+ else {
298
+ return [Token.Divide];
299
+ }
300
+ case "g":
301
+ if (this.input[this.cursor] == "a" &&
302
+ this.input[this.cursor + 1] == "t" &&
303
+ this.input[this.cursor + 2] == "e") {
304
+ this.readChar(3);
305
+ return [Token.Gate];
306
+ }
307
+ {
308
+ const literal = char + this.readIdentifier();
309
+ return [lookup(literal), literal];
310
+ }
311
+ case "q":
312
+ if (this.input[this.cursor] == "r" &&
313
+ this.input[this.cursor + 1] == "e" &&
314
+ this.input[this.cursor + 2] == "g") {
315
+ this.readChar(3);
316
+ return [Token.QReg];
317
+ }
318
+ {
319
+ const qregLit = char + this.readIdentifier();
320
+ return [lookup(qregLit), qregLit];
321
+ }
322
+ case "c":
323
+ if (this.input[this.cursor] == "r" &&
324
+ this.input[this.cursor + 1] == "e" &&
325
+ this.input[this.cursor + 2] == "g") {
326
+ this.readChar(3);
327
+ return [Token.CReg];
328
+ }
329
+ {
330
+ const cregLit = char + this.readIdentifier();
331
+ return [lookup(cregLit), cregLit];
332
+ }
333
+ case "b":
334
+ if (this.input[this.cursor] == "a" &&
335
+ this.input[this.cursor + 1] == "r" &&
336
+ this.input[this.cursor + 2] == "r" &&
337
+ this.input[this.cursor + 3] == "i" &&
338
+ this.input[this.cursor + 4] == "e" &&
339
+ this.input[this.cursor + 5] == "r") {
340
+ this.readChar(6);
341
+ return [Token.Barrier];
342
+ }
343
+ {
344
+ const barLit = char + this.readIdentifier();
345
+ return [lookup(barLit), barLit];
346
+ }
347
+ case "m":
348
+ if (this.input[this.cursor] == "e" &&
349
+ this.input[this.cursor + 1] == "a" &&
350
+ this.input[this.cursor + 2] == "s" &&
351
+ this.input[this.cursor + 3] == "u" &&
352
+ this.input[this.cursor + 4] == "r" &&
353
+ this.input[this.cursor + 5] == "e") {
354
+ this.readChar(6);
355
+ return [Token.Measure];
356
+ }
357
+ {
358
+ const measureLit = char + this.readIdentifier();
359
+ return [lookup(measureLit), measureLit];
360
+ }
361
+ case "O":
362
+ if (this.input[this.cursor].toLowerCase() == "p" &&
363
+ this.input[this.cursor + 1].toLowerCase() == "e" &&
364
+ this.input[this.cursor + 2].toLowerCase() == "n" &&
365
+ this.input[this.cursor + 3] == "Q" &&
366
+ this.input[this.cursor + 4] == "A" &&
367
+ this.input[this.cursor + 5] == "S" &&
368
+ this.input[this.cursor + 6] == "M") {
369
+ this.readChar(7);
370
+ let offset = 0;
371
+ while (this.cursor + offset < this.input.length &&
372
+ " \t".indexOf(this.input[this.cursor + offset]) > -1) {
373
+ offset++;
374
+ }
375
+ // Read the major version
376
+ let majorVersion = "";
377
+ while (this.cursor + offset < this.input.length &&
378
+ !isNaN(parseInt(this.input[this.cursor + offset], 10))) {
379
+ majorVersion += this.input[this.cursor + offset];
380
+ offset++;
381
+ }
382
+ // Attempt to read the minor version
383
+ let minorVersion = undefined;
384
+ if (this.input[this.cursor + offset] == ".") {
385
+ offset++;
386
+ minorVersion = "";
387
+ while (this.cursor + offset < this.input.length &&
388
+ !isNaN(parseInt(this.input[this.cursor + offset], 10))) {
389
+ minorVersion += this.input[this.cursor + offset];
390
+ offset++;
391
+ }
392
+ }
393
+ // Parse major and minor versions
394
+ const major = parseInt(majorVersion, 10);
395
+ const minor = minorVersion ? parseInt(minorVersion, 10) : undefined;
396
+ if (major !== 2) {
397
+ throw new UnsupportedOpenQASMVersionError(`Unsupported OpenQASM version detected: ${majorVersion}.${minor !== null && minor !== void 0 ? minor : 0}`);
398
+ }
399
+ return [Token.OpenQASM];
400
+ }
401
+ {
402
+ const openQasmLit = char + this.readIdentifier();
403
+ return [lookup[openQasmLit], openQasmLit];
404
+ }
405
+ case "i":
406
+ if (this.input[this.cursor] == "n" &&
407
+ this.input[this.cursor + 1] == "c" &&
408
+ this.input[this.cursor + 2] == "l" &&
409
+ this.input[this.cursor + 3] == "u" &&
410
+ this.input[this.cursor + 4] == "d" &&
411
+ this.input[this.cursor + 5] == "e") {
412
+ this.readChar(6);
413
+ return [Token.Include];
414
+ }
415
+ {
416
+ const includeLit = char + this.readIdentifier();
417
+ return [lookup(includeLit), includeLit];
418
+ }
419
+ case "o":
420
+ if (this.input[this.cursor] == "p" &&
421
+ this.input[this.cursor + 1] == "a" &&
422
+ this.input[this.cursor + 2] == "q" &&
423
+ this.input[this.cursor + 3] == "u" &&
424
+ this.input[this.cursor + 4] == "e") {
425
+ this.readChar(5);
426
+ return [Token.Opaque];
427
+ }
428
+ {
429
+ const opaqueLit = char + this.readIdentifier();
430
+ return [lookup(opaqueLit), opaqueLit];
431
+ }
432
+ case '"': {
433
+ const stringLiteral = char + this.readStringLiteral('"');
434
+ return [Token.String, stringLiteral];
435
+ }
436
+ case "’": {
437
+ const singleStringLiteral = char + this.readStringLiteral("’");
438
+ return [Token.String, singleStringLiteral];
439
+ }
440
+ default:
441
+ if (isLetter(char)) {
442
+ const literal = char + this.readIdentifier();
443
+ return [lookup(literal), literal];
444
+ }
445
+ else if (isNumeric(char)) {
446
+ const num = char + this.readNumeric();
447
+ if (num.indexOf(".") != -1) {
448
+ return [Token.Real, parseFloat(num)];
449
+ }
450
+ else {
451
+ return [Token.NNInteger, parseFloat(num)];
452
+ }
453
+ }
454
+ else {
455
+ return [Token.Illegal];
456
+ }
457
+ }
458
+ };
459
+ /**
460
+ * Returns the line number where the current cursor is located.
461
+ * @param cursor - The current cursor position in the input string.
462
+ * @return The line number.
463
+ */
464
+ this.getLineNumber = (cursor) => {
465
+ return this.input
466
+ .substring(0, cursor)
467
+ .split(/\n|\r(?!\n)|\u2028|\u2029|\r\n/).length;
468
+ };
469
+ /**
470
+ * Returns the current line of code where the cursor is located.
471
+ * @param cursor - The current cursor position in the input string.
472
+ * @return The specific line where the cursor is located.
473
+ */
474
+ this.getCurrentLine = (cursor) => {
475
+ const lines = this.input.split(/\n|\r(?!\n)|\u2028|\u2029|\r\n/);
476
+ const lineNumber = this.getLineNumber(cursor);
477
+ return lines[lineNumber - 1];
478
+ };
479
+ this.input = input;
480
+ this.cursor = cursor;
481
+ }
482
+ }
483
+ export default Lexer;
@@ -0,0 +1,187 @@
1
+ /**
2
+ * OpenQASM 2.0 Parser Implementation
3
+ *
4
+ * This module implements a parser for OpenQASM 2.0 that focuses on the core
5
+ * quantum circuit description language without the advanced features of version 3.0.
6
+ * The parser handles quantum and classical register declarations, gate definitions
7
+ * and applications, measurements, and basic control structures.
8
+ *
9
+ * OpenQASM 2.0 parsing capabilities:
10
+ * - **Register declarations**: qreg and creg with size specifications
11
+ * - **Gate definitions**: Custom gate definitions with parameters and bodies
12
+ * - **Gate applications**: Built-in and custom gate applications
13
+ * - **Measurements**: Quantum measurements with classical result storage
14
+ * - **Basic conditionals**: Simple if statements based on classical register values
15
+ * - **Arithmetic expressions**: Parameter expressions for gate operations
16
+ * - **Opaque gates**: External gate declarations
17
+ *
18
+ * The parser maintains a list of known gates and validates gate applications
19
+ * against declared gates and built-in operations.
20
+ *
21
+ * @module
22
+ *
23
+ * @example Parsing OpenQASM 2.0 code
24
+ * ```typescript
25
+ * const tokens = lexer.lex();
26
+ * const parser = new Parser(tokens);
27
+ * const ast = parser.parse();
28
+ *
29
+ * // AST contains simplified node structure for OpenQASM 2.0
30
+ * ```
31
+ */
32
+ import { Token } from "./token";
33
+ import { AstNode, Version, Include } from "./ast";
34
+ /**
35
+ * OpenQASM 2.0 Parser
36
+ *
37
+ * A straightforward recursive descent parser for OpenQASM 2.0 that produces
38
+ * a simplified AST structure appropriate for the more limited feature set
39
+ * of the 2.0 language specification.
40
+ *
41
+ * @example Basic parsing workflow
42
+ * ```typescript
43
+ * const parser = new Parser(tokens);
44
+ * const ast = parser.parse();
45
+ *
46
+ * // Process the resulting AST nodes
47
+ * ast.forEach(node => {
48
+ * if (node instanceof QReg) {
49
+ * console.log(`Quantum register: ${node.id}[${node.size}]`);
50
+ * }
51
+ * });
52
+ * ```
53
+ */
54
+ declare class Parser {
55
+ /** The tokens to parse. */
56
+ tokens: Array<[Token, (number | string)?]>;
57
+ /** The allowed gates. */
58
+ gates: Array<string>;
59
+ /**
60
+ * Creates a parser.
61
+ * @param tokens - Tokens to parse.
62
+ */
63
+ constructor(tokens: Array<[Token, (number | string)?]>);
64
+ /**
65
+ * Calling this method parses the code represented by the provided tokens.
66
+ * @return The abstract syntax tree.
67
+ */
68
+ parse(): Array<AstNode>;
69
+ /**
70
+ * Delegates the parsing of the next set of tokens to the appropriate method.
71
+ * @param tokens - Remaining tokens to parse.
72
+ * @param allowVariables - Whether encountered identifiers should be consider
73
+ variable initializations or references.
74
+ * @return A set of AST nodes.
75
+ */
76
+ parseNode(tokens: Array<[Token, (number | string)?]>, allowVariables?: boolean): Array<AstNode>;
77
+ /**
78
+ * Checks if the next tokens match those expected.
79
+ * @param tokens - Remaining tokens to parse.
80
+ * @param expectedTokens - Expected tokens.
81
+ * @return Whether these is a match.
82
+ */
83
+ matchNext(tokens: Array<[Token, (number | string)?]>, expectedTokens: Array<Token>): boolean;
84
+ /**
85
+ * Parses a quantum register.
86
+ * @param tokens - Remaining tokens to parse.
87
+ * @return An AST node representing the quantum register.
88
+ */
89
+ qreg(tokens: Array<[Token, (number | string)?]>): AstNode;
90
+ /**
91
+ * Parses a classical register.
92
+ * @param tokens - Remaining tokens to parse.
93
+ * @return An AST node representing the classical register.
94
+ */
95
+ creg(tokens: Array<[Token, (number | string)?]>): AstNode;
96
+ /**
97
+ * Parses a conditional.
98
+ * @param tokens - Remaining tokens to parse.
99
+ * @return An AST node representing the conditional.
100
+ */
101
+ conditional(tokens: Array<[Token, (number | string)?]>): AstNode;
102
+ /**
103
+ * Parses a barrier.
104
+ * @param tokens - Remaining tokens to parse.
105
+ * @return An AST node representing the barrier.
106
+ */
107
+ barrier(tokens: Array<[Token, (number | string)?]>): AstNode;
108
+ /**
109
+ * Parses a measurement.
110
+ * @param tokens - Remaining tokens to parse.
111
+ * @return An AST node representing the measurement.
112
+ */
113
+ measure(tokens: Array<[Token, (number | string)?]>): AstNode;
114
+ /**
115
+ * Parses an application of one of the allowed gates.
116
+ * @param tokens - Remaining tokens to parse.
117
+ * @return An AST node representing the gate application.
118
+ */
119
+ application(tokens: Array<[Token, (number | string)?]>, op: string): Array<AstNode>;
120
+ /**
121
+ * Parses a subroutine used in a custom gate definition.
122
+ * @param tokens - Expression tokens to parse.
123
+ * @return A parsed subroutine.
124
+ */
125
+ sub(tokens: Array<[Token, (number | string)?]>): Array<AstNode>;
126
+ /**
127
+ * Parses a parameter value.
128
+ * @param tokens - Tokens to parse.
129
+ * @return An AST node representing the parameter value.
130
+ */
131
+ matchParam(tokens: Array<[Token, (number | string)?]>): AstNode;
132
+ /**
133
+ * Parses a list of parameter values.
134
+ * @param tokens - Tokens to parse.
135
+ * @return An array of AST nodes representing the parameter values.
136
+ */
137
+ matchParamList(tokens: Array<[Token, (number | string)?]>): Array<Array<AstNode>>;
138
+ /**
139
+ * Parses an argument value.
140
+ * @param tokens - Tokens to parse.
141
+ * @return An AST node representing the argument value.
142
+ */
143
+ matchArg(tokens: Array<[Token, (number | string)?]>): number;
144
+ /**
145
+ * Parses a list of argument values.
146
+ * @param tokens - Tokens to parse.
147
+ * @return An array of AST nodes representing the argument values.
148
+ */
149
+ matchArgList(tokens: Array<[Token, (number | string)?]>): Array<[string, number?]>;
150
+ /**
151
+ * Parses an include statement.
152
+ * @param tokens - Tokens to parse.
153
+ * @return An Include node representing the include statement.
154
+ */
155
+ include(tokens: Array<[Token, (number | string)?]>): Include;
156
+ /**
157
+ * Parses the version header and sets the parser version.
158
+ * @param tokens - Tokens to parse.
159
+ * @return A Version node representing the version statement.
160
+ */
161
+ versionHeader(tokens: Array<[Token, (number | string)?]>): Version;
162
+ /**
163
+ * Parses a list of identifiers.
164
+ * @param tokens - Tokens to parse.
165
+ * @return An array of AST nodes representing the identifiers.
166
+ */
167
+ matchIdList(tokens: Array<[Token, (number | string)?]>): Array<string>;
168
+ /**
169
+ * Parses a gate.
170
+ * @param tokens - Remaining tokens to parse.
171
+ * @return An AST node representing the gate.
172
+ */
173
+ gate(tokens: Array<[Token, (number | string)?]>): AstNode;
174
+ /**
175
+ * Parses an opaque declaration if using OpenQASM 2. If using OpenQASM 3 it skips the line.
176
+ * @param tokens - Remaining tokens to parse.
177
+ * @return An AST node representing the opaque declaration.
178
+ */
179
+ opaque(tokens: Array<[Token, (number | string)?]>): AstNode;
180
+ /**
181
+ * Validates whether a register or gate identifier.
182
+ * @param identifier - The identifier to validate.
183
+ * @return Boolean indicating successful validation or not.
184
+ */
185
+ private validateIdentifier;
186
+ }
187
+ export default Parser;