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.
- package/dist/errors.d.ts +88 -0
- package/dist/errors.js +162 -0
- package/dist/lexer.d.ts +78 -0
- package/dist/lexer.js +116 -0
- package/dist/main.d.ts +87 -0
- package/dist/main.js +122 -0
- package/dist/parser.d.ts +75 -0
- package/dist/parser.js +121 -0
- package/dist/qasm2/ast.d.ts +159 -0
- package/dist/qasm2/ast.js +186 -0
- package/dist/qasm2/lexer.d.ts +135 -0
- package/dist/qasm2/lexer.js +483 -0
- package/dist/qasm2/parser.d.ts +187 -0
- package/dist/qasm2/parser.js +655 -0
- package/dist/qasm2/token.d.ts +89 -0
- package/dist/qasm2/token.js +155 -0
- package/dist/qasm3/ast.d.ts +652 -0
- package/dist/qasm3/ast.js +746 -0
- package/dist/qasm3/lexer.d.ts +156 -0
- package/dist/qasm3/lexer.js +667 -0
- package/dist/qasm3/parser.d.ts +407 -0
- package/dist/qasm3/parser.js +2079 -0
- package/dist/qasm3/token.d.ts +197 -0
- package/dist/qasm3/token.js +420 -0
- package/dist/version.d.ts +41 -0
- package/dist/version.js +53 -0
- package/package.json +1 -1
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error classes for QASM parsing and validation
|
|
3
|
+
*
|
|
4
|
+
* This module provides specific error types for different parsing failures,
|
|
5
|
+
* enabling precise error handling and debugging. Each error includes contextual
|
|
6
|
+
* information about where the error occurred in the source code.
|
|
7
|
+
*
|
|
8
|
+
* @module Error Handling
|
|
9
|
+
*/
|
|
10
|
+
/** Class representing a bad argument exception. */
|
|
11
|
+
declare class BadArgumentError extends Error {
|
|
12
|
+
constructor(message?: string);
|
|
13
|
+
}
|
|
14
|
+
/** Class representing a bad include statement */
|
|
15
|
+
declare class BadIncludeError extends Error {
|
|
16
|
+
constructor(message?: string);
|
|
17
|
+
}
|
|
18
|
+
/** Class representing a bad quantum register exception. */
|
|
19
|
+
declare class BadQregError extends Error {
|
|
20
|
+
constructor(message?: string);
|
|
21
|
+
}
|
|
22
|
+
/** Class representing a bad equality exception. */
|
|
23
|
+
declare class BadEqualsError extends Error {
|
|
24
|
+
constructor(message?: string);
|
|
25
|
+
}
|
|
26
|
+
/** Class representing a bad classical register exception. */
|
|
27
|
+
declare class BadCregError extends Error {
|
|
28
|
+
constructor(message?: string);
|
|
29
|
+
}
|
|
30
|
+
/** Class representing a bad conditional exception. */
|
|
31
|
+
declare class BadConditionalError extends Error {
|
|
32
|
+
constructor(message?: string);
|
|
33
|
+
}
|
|
34
|
+
/** Class representing a bad barrier exception. */
|
|
35
|
+
declare class BadBarrierError extends Error {
|
|
36
|
+
constructor(message?: string);
|
|
37
|
+
}
|
|
38
|
+
/** Class representing a bad measurement exception. */
|
|
39
|
+
declare class BadMeasurementError extends Error {
|
|
40
|
+
constructor(message?: string);
|
|
41
|
+
}
|
|
42
|
+
/** Class representing a bad gate exception. */
|
|
43
|
+
declare class BadGateError extends Error {
|
|
44
|
+
constructor(message?: string);
|
|
45
|
+
}
|
|
46
|
+
/** Class representing a bad parameter exception. */
|
|
47
|
+
declare class BadParameterError extends Error {
|
|
48
|
+
constructor(message?: string);
|
|
49
|
+
}
|
|
50
|
+
/** Class representing a missing semicolon exception. */
|
|
51
|
+
declare class MissingSemicolonError extends Error {
|
|
52
|
+
constructor(message?: string);
|
|
53
|
+
}
|
|
54
|
+
/** Class representing a missing opening or closing parenthesis, bracket, or curly brakcet. */
|
|
55
|
+
declare class MissingBraceError extends Error {
|
|
56
|
+
constructor(message?: string);
|
|
57
|
+
}
|
|
58
|
+
/** Class representing an unsupported OpenQASM version exception. */
|
|
59
|
+
declare class UnsupportedOpenQASMVersionError extends Error {
|
|
60
|
+
constructor(message?: string);
|
|
61
|
+
}
|
|
62
|
+
/** Class representing an error parsing an expected string literal. */
|
|
63
|
+
declare class BadStringLiteralError extends Error {
|
|
64
|
+
constructor(message?: string);
|
|
65
|
+
}
|
|
66
|
+
/** Class representing an error parsing scalar types. */
|
|
67
|
+
declare class BadClassicalTypeError extends Error {
|
|
68
|
+
constructor(message?: string);
|
|
69
|
+
}
|
|
70
|
+
/** Class representing an error parsing an expression. */
|
|
71
|
+
declare class BadExpressionError extends Error {
|
|
72
|
+
constructor(message?: string);
|
|
73
|
+
}
|
|
74
|
+
/** Class representing an error in defining or calling a custom subroutine. */
|
|
75
|
+
declare class BadSubroutineError extends Error {
|
|
76
|
+
constructor(message?: string);
|
|
77
|
+
}
|
|
78
|
+
/** Class representing a bad loop statement declaration. */
|
|
79
|
+
declare class BadLoopError extends Error {
|
|
80
|
+
constructor(message?: string);
|
|
81
|
+
}
|
|
82
|
+
/** Class representing a bad quantum instruction. */
|
|
83
|
+
declare class BadQuantumInstructionError extends Error {
|
|
84
|
+
constructor(message?: string);
|
|
85
|
+
}
|
|
86
|
+
/** Type for returning an error constructor. */
|
|
87
|
+
type ReturnErrorConstructor = new (message?: string) => Error;
|
|
88
|
+
export { BadArgumentError, BadIncludeError, BadCregError, BadQregError, BadConditionalError, BadBarrierError, BadMeasurementError, BadGateError, BadEqualsError, BadParameterError, MissingSemicolonError, MissingBraceError, UnsupportedOpenQASMVersionError, BadStringLiteralError, BadClassicalTypeError, BadExpressionError, BadSubroutineError, BadLoopError, BadQuantumInstructionError, ReturnErrorConstructor, };
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error classes for QASM parsing and validation
|
|
3
|
+
*
|
|
4
|
+
* This module provides specific error types for different parsing failures,
|
|
5
|
+
* enabling precise error handling and debugging. Each error includes contextual
|
|
6
|
+
* information about where the error occurred in the source code.
|
|
7
|
+
*
|
|
8
|
+
* @module Error Handling
|
|
9
|
+
*/
|
|
10
|
+
/** Class representing a bad argument exception. */
|
|
11
|
+
class BadArgumentError extends Error {
|
|
12
|
+
constructor(message) {
|
|
13
|
+
super(message);
|
|
14
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
15
|
+
this.name = BadArgumentError.name;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/** Class representing a bad include statement */
|
|
19
|
+
class BadIncludeError extends Error {
|
|
20
|
+
constructor(message) {
|
|
21
|
+
super(message);
|
|
22
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
23
|
+
this.name = BadIncludeError.name;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** Class representing a bad quantum register exception. */
|
|
27
|
+
class BadQregError extends Error {
|
|
28
|
+
constructor(message) {
|
|
29
|
+
super(message);
|
|
30
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
31
|
+
this.name = BadQregError.name;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** Class representing a bad equality exception. */
|
|
35
|
+
class BadEqualsError extends Error {
|
|
36
|
+
constructor(message) {
|
|
37
|
+
super(message);
|
|
38
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
39
|
+
this.name = BadEqualsError.name;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** Class representing a bad classical register exception. */
|
|
43
|
+
class BadCregError extends Error {
|
|
44
|
+
constructor(message) {
|
|
45
|
+
super(message);
|
|
46
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
47
|
+
this.name = BadCregError.name;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Class representing a bad conditional exception. */
|
|
51
|
+
class BadConditionalError extends Error {
|
|
52
|
+
constructor(message) {
|
|
53
|
+
super(message);
|
|
54
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
55
|
+
this.name = BadConditionalError.name;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** Class representing a bad barrier exception. */
|
|
59
|
+
class BadBarrierError extends Error {
|
|
60
|
+
constructor(message) {
|
|
61
|
+
super(message);
|
|
62
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
63
|
+
this.name = BadBarrierError.name;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** Class representing a bad measurement exception. */
|
|
67
|
+
class BadMeasurementError extends Error {
|
|
68
|
+
constructor(message) {
|
|
69
|
+
super(message);
|
|
70
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
71
|
+
this.name = BadMeasurementError.name;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/** Class representing a bad gate exception. */
|
|
75
|
+
class BadGateError extends Error {
|
|
76
|
+
constructor(message) {
|
|
77
|
+
super(message);
|
|
78
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
79
|
+
this.name = BadGateError.name;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Class representing a bad parameter exception. */
|
|
83
|
+
class BadParameterError extends Error {
|
|
84
|
+
constructor(message) {
|
|
85
|
+
super(message);
|
|
86
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
87
|
+
this.name = BadParameterError.name;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/** Class representing a missing semicolon exception. */
|
|
91
|
+
class MissingSemicolonError extends Error {
|
|
92
|
+
constructor(message) {
|
|
93
|
+
super(message);
|
|
94
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
95
|
+
this.name = MissingSemicolonError.name;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/** Class representing a missing opening or closing parenthesis, bracket, or curly brakcet. */
|
|
99
|
+
class MissingBraceError extends Error {
|
|
100
|
+
constructor(message) {
|
|
101
|
+
super(message);
|
|
102
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
103
|
+
this.name = MissingSemicolonError.name;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/** Class representing an unsupported OpenQASM version exception. */
|
|
107
|
+
class UnsupportedOpenQASMVersionError extends Error {
|
|
108
|
+
constructor(message) {
|
|
109
|
+
super(message);
|
|
110
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
111
|
+
this.name = UnsupportedOpenQASMVersionError.name;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/** Class representing an error parsing an expected string literal. */
|
|
115
|
+
class BadStringLiteralError extends Error {
|
|
116
|
+
constructor(message) {
|
|
117
|
+
super(message);
|
|
118
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
119
|
+
this.name = BadStringLiteralError.name;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/** Class representing an error parsing scalar types. */
|
|
123
|
+
class BadClassicalTypeError extends Error {
|
|
124
|
+
constructor(message) {
|
|
125
|
+
super(message);
|
|
126
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
127
|
+
this.name = BadClassicalTypeError.name;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/** Class representing an error parsing an expression. */
|
|
131
|
+
class BadExpressionError extends Error {
|
|
132
|
+
constructor(message) {
|
|
133
|
+
super(message);
|
|
134
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
135
|
+
this.name = BadExpressionError.name;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/** Class representing an error in defining or calling a custom subroutine. */
|
|
139
|
+
class BadSubroutineError extends Error {
|
|
140
|
+
constructor(message) {
|
|
141
|
+
super(message);
|
|
142
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
143
|
+
this.name = BadSubroutineError.name;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/** Class representing a bad loop statement declaration. */
|
|
147
|
+
class BadLoopError extends Error {
|
|
148
|
+
constructor(message) {
|
|
149
|
+
super(message);
|
|
150
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
151
|
+
this.name = BadLoopError.name;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/** Class representing a bad quantum instruction. */
|
|
155
|
+
class BadQuantumInstructionError extends Error {
|
|
156
|
+
constructor(message) {
|
|
157
|
+
super(message);
|
|
158
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
159
|
+
this.name = BadQuantumInstructionError.name;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
export { BadArgumentError, BadIncludeError, BadCregError, BadQregError, BadConditionalError, BadBarrierError, BadMeasurementError, BadGateError, BadEqualsError, BadParameterError, MissingSemicolonError, MissingBraceError, UnsupportedOpenQASMVersionError, BadStringLiteralError, BadClassicalTypeError, BadExpressionError, BadSubroutineError, BadLoopError, BadQuantumInstructionError, };
|
package/dist/lexer.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main lexer interface for tokenizing QASM code
|
|
3
|
+
*
|
|
4
|
+
* The lexer is responsible for breaking down QASM source code into tokens
|
|
5
|
+
* that can be consumed by the parser. It supports both OpenQASM 2.0 and 3.0
|
|
6
|
+
* syntax, with version-specific lexers handling the differences in token types
|
|
7
|
+
* and syntax rules.
|
|
8
|
+
*
|
|
9
|
+
* The specific Lexer implementations can be found at:
|
|
10
|
+
* - {@link Qasm3Lexer}
|
|
11
|
+
* - {@link Qasm2Lexer}
|
|
12
|
+
*
|
|
13
|
+
* @module Lexing
|
|
14
|
+
*
|
|
15
|
+
* @example Token Flow
|
|
16
|
+
* ```
|
|
17
|
+
* Source Code → Lexer → Tokens → Parser → AST
|
|
18
|
+
* "h q[0];" → [Id, Id, LSParen, NNInteger, RSParen, Semicolon]
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* * @example Basic lexing workflow
|
|
22
|
+
* ```typescript
|
|
23
|
+
* import { lex } from './lexer';
|
|
24
|
+
*
|
|
25
|
+
* const qasmCode = 'OPENQASM 3.0; qubit q; h q;';
|
|
26
|
+
* const tokens = lex(qasmCode);
|
|
27
|
+
* console.log(tokens);
|
|
28
|
+
* // [
|
|
29
|
+
* // [Token.OpenQASM, undefined],
|
|
30
|
+
* // [Token.Id, 'qubit'],
|
|
31
|
+
* // [Token.Id, 'q'],
|
|
32
|
+
* // [Token.Semicolon, undefined],
|
|
33
|
+
* // [Token.Id, 'h'],
|
|
34
|
+
* // [Token.Id, 'q'],
|
|
35
|
+
* // [Token.Semicolon, undefined]
|
|
36
|
+
* // ]
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
import { Token as Qasm2Token } from "./qasm2/token";
|
|
40
|
+
import { Token as Qasm3Token } from "./qasm3/token";
|
|
41
|
+
import { OpenQASMVersion, OpenQASMMajorVersion } from "./version";
|
|
42
|
+
/**
|
|
43
|
+
* Tokenizes OpenQASM source code into an array of tokens.
|
|
44
|
+
*
|
|
45
|
+
* This is the main entry point for lexical analysis. It automatically selects
|
|
46
|
+
* the appropriate lexer implementation based on the OpenQASM version and returns
|
|
47
|
+
* an array of tokens that can be consumed by the parser.
|
|
48
|
+
*
|
|
49
|
+
* Each token is represented as a tuple containing:
|
|
50
|
+
* - **Token type**: An enum value indicating the kind of token
|
|
51
|
+
* - **Token value**: The associated value (for literals, identifiers, operators)
|
|
52
|
+
*
|
|
53
|
+
* @group Lexing
|
|
54
|
+
* @param qasm - The OpenQASM source code to tokenize
|
|
55
|
+
* @param cursor - Starting position in the input string (defaults to 0)
|
|
56
|
+
* @param version - OpenQASM version to use for lexing (defaults to 3.0)
|
|
57
|
+
* @returns Array of token tuples [TokenType, value?]
|
|
58
|
+
* @throws {UnsupportedOpenQASMVersionError} When an unsupported version is specified
|
|
59
|
+
*
|
|
60
|
+
* @example Tokenize OpenQASM 3.0 code
|
|
61
|
+
* ```typescript
|
|
62
|
+
* const tokens = lex('qubit[2] q; h q[0];', 0, 3);
|
|
63
|
+
* // Returns tokens using OpenQASM 3.0 syntax rules
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* @example Tokenize OpenQASM 2.0 code
|
|
67
|
+
* ```typescript
|
|
68
|
+
* const tokens = lex('qreg q[2]; h q[0];', 0, 2);
|
|
69
|
+
* // Returns tokens using OpenQASM 2.0 syntax rules
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* @example Resume lexing from specific position
|
|
73
|
+
* ```typescript
|
|
74
|
+
* const code = 'OPENQASM 3.0; qubit q;';
|
|
75
|
+
* const tokens = lex(code, 12); // Start after "OPENQASM 3.0"
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export declare function lex(qasm: string, cursor?: number, version?: OpenQASMVersion | OpenQASMMajorVersion | number): Array<[Qasm2Token | Qasm3Token, (number | string)?]>;
|
package/dist/lexer.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main lexer interface for tokenizing QASM code
|
|
3
|
+
*
|
|
4
|
+
* The lexer is responsible for breaking down QASM source code into tokens
|
|
5
|
+
* that can be consumed by the parser. It supports both OpenQASM 2.0 and 3.0
|
|
6
|
+
* syntax, with version-specific lexers handling the differences in token types
|
|
7
|
+
* and syntax rules.
|
|
8
|
+
*
|
|
9
|
+
* The specific Lexer implementations can be found at:
|
|
10
|
+
* - {@link Qasm3Lexer}
|
|
11
|
+
* - {@link Qasm2Lexer}
|
|
12
|
+
*
|
|
13
|
+
* @module Lexing
|
|
14
|
+
*
|
|
15
|
+
* @example Token Flow
|
|
16
|
+
* ```
|
|
17
|
+
* Source Code → Lexer → Tokens → Parser → AST
|
|
18
|
+
* "h q[0];" → [Id, Id, LSParen, NNInteger, RSParen, Semicolon]
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* * @example Basic lexing workflow
|
|
22
|
+
* ```typescript
|
|
23
|
+
* import { lex } from './lexer';
|
|
24
|
+
*
|
|
25
|
+
* const qasmCode = 'OPENQASM 3.0; qubit q; h q;';
|
|
26
|
+
* const tokens = lex(qasmCode);
|
|
27
|
+
* console.log(tokens);
|
|
28
|
+
* // [
|
|
29
|
+
* // [Token.OpenQASM, undefined],
|
|
30
|
+
* // [Token.Id, 'qubit'],
|
|
31
|
+
* // [Token.Id, 'q'],
|
|
32
|
+
* // [Token.Semicolon, undefined],
|
|
33
|
+
* // [Token.Id, 'h'],
|
|
34
|
+
* // [Token.Id, 'q'],
|
|
35
|
+
* // [Token.Semicolon, undefined]
|
|
36
|
+
* // ]
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
import { default as Qasm2Lexer } from "./qasm2/lexer";
|
|
40
|
+
import { default as Qasm3Lexer } from "./qasm3/lexer";
|
|
41
|
+
import { OpenQASMVersion, OpenQASMMajorVersion } from "./version";
|
|
42
|
+
import { UnsupportedOpenQASMVersionError } from "./errors";
|
|
43
|
+
/**
|
|
44
|
+
* Tokenizes OpenQASM source code into an array of tokens.
|
|
45
|
+
*
|
|
46
|
+
* This is the main entry point for lexical analysis. It automatically selects
|
|
47
|
+
* the appropriate lexer implementation based on the OpenQASM version and returns
|
|
48
|
+
* an array of tokens that can be consumed by the parser.
|
|
49
|
+
*
|
|
50
|
+
* Each token is represented as a tuple containing:
|
|
51
|
+
* - **Token type**: An enum value indicating the kind of token
|
|
52
|
+
* - **Token value**: The associated value (for literals, identifiers, operators)
|
|
53
|
+
*
|
|
54
|
+
* @group Lexing
|
|
55
|
+
* @param qasm - The OpenQASM source code to tokenize
|
|
56
|
+
* @param cursor - Starting position in the input string (defaults to 0)
|
|
57
|
+
* @param version - OpenQASM version to use for lexing (defaults to 3.0)
|
|
58
|
+
* @returns Array of token tuples [TokenType, value?]
|
|
59
|
+
* @throws {UnsupportedOpenQASMVersionError} When an unsupported version is specified
|
|
60
|
+
*
|
|
61
|
+
* @example Tokenize OpenQASM 3.0 code
|
|
62
|
+
* ```typescript
|
|
63
|
+
* const tokens = lex('qubit[2] q; h q[0];', 0, 3);
|
|
64
|
+
* // Returns tokens using OpenQASM 3.0 syntax rules
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* @example Tokenize OpenQASM 2.0 code
|
|
68
|
+
* ```typescript
|
|
69
|
+
* const tokens = lex('qreg q[2]; h q[0];', 0, 2);
|
|
70
|
+
* // Returns tokens using OpenQASM 2.0 syntax rules
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* @example Resume lexing from specific position
|
|
74
|
+
* ```typescript
|
|
75
|
+
* const code = 'OPENQASM 3.0; qubit q;';
|
|
76
|
+
* const tokens = lex(code, 12); // Start after "OPENQASM 3.0"
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export function lex(qasm, cursor, version) {
|
|
80
|
+
let lexer;
|
|
81
|
+
if (version instanceof OpenQASMVersion) {
|
|
82
|
+
switch (version.major) {
|
|
83
|
+
case OpenQASMMajorVersion.Version2:
|
|
84
|
+
lexer = new Qasm2Lexer(qasm, cursor);
|
|
85
|
+
break;
|
|
86
|
+
case OpenQASMMajorVersion.Version3:
|
|
87
|
+
lexer = new Qasm3Lexer(qasm, cursor);
|
|
88
|
+
break;
|
|
89
|
+
default:
|
|
90
|
+
throw new UnsupportedOpenQASMVersionError(`Unsupported OpenQASM version detected: ${version.major}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else if (typeof version === "number") {
|
|
94
|
+
switch (version) {
|
|
95
|
+
case 2:
|
|
96
|
+
lexer = new Qasm2Lexer(qasm, cursor);
|
|
97
|
+
break;
|
|
98
|
+
case 3:
|
|
99
|
+
lexer = new Qasm3Lexer(qasm, cursor);
|
|
100
|
+
break;
|
|
101
|
+
default:
|
|
102
|
+
throw new UnsupportedOpenQASMVersionError(`Unsupported OpenQASM version detected: ${version}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else if (version === OpenQASMMajorVersion.Version2) {
|
|
106
|
+
lexer = new Qasm2Lexer(qasm, cursor);
|
|
107
|
+
}
|
|
108
|
+
else if (version === OpenQASMMajorVersion.Version3) {
|
|
109
|
+
lexer = new Qasm3Lexer(qasm, cursor);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
lexer = new Qasm3Lexer(qasm, cursor);
|
|
113
|
+
}
|
|
114
|
+
const tokens = lexer.lex();
|
|
115
|
+
return tokens;
|
|
116
|
+
}
|
package/dist/main.d.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main parsing functions for qasm-ts - the primary entry points for parsing OpenQASM code
|
|
3
|
+
* @module Main Functions
|
|
4
|
+
*/
|
|
5
|
+
import type * as qasm2 from "./qasm2/ast";
|
|
6
|
+
import type * as qasm3 from "./qasm3/ast";
|
|
7
|
+
import { OpenQASMVersion, OpenQASMMajorVersion } from "./version";
|
|
8
|
+
/**
|
|
9
|
+
* Parses OpenQASM code from a string and returns the abstract syntax tree.
|
|
10
|
+
*
|
|
11
|
+
* This is the primary entry point for parsing OpenQASM code. It handles both
|
|
12
|
+
* OpenQASM 2.0 and 3.0 syntax, automatically selecting the appropriate lexer
|
|
13
|
+
* and parser based on the version parameter.
|
|
14
|
+
*
|
|
15
|
+
* @group Main Functions
|
|
16
|
+
* @param qasm - The OpenQASM code string to parse
|
|
17
|
+
* @param version - The OpenQASM version to use (defaults to 3.0)
|
|
18
|
+
* @param verbose - Whether to include class names in the output (defaults to false)
|
|
19
|
+
* @param stringify - Whether to return stringified JSON (defaults to false)
|
|
20
|
+
* @returns The corresponding AST as an array of nodes, or stringified JSON if stringify is true
|
|
21
|
+
*
|
|
22
|
+
* @example Basic OpenQASM 3.0 parsing
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { parseString } from 'qasm-ts';
|
|
25
|
+
*
|
|
26
|
+
* const qasmCode = `
|
|
27
|
+
* OPENQASM 3.0;
|
|
28
|
+
* include "stdgates.inc";
|
|
29
|
+
* qubit[2] q;
|
|
30
|
+
* h q[0];
|
|
31
|
+
* cx q[0], q[1];
|
|
32
|
+
* `;
|
|
33
|
+
*
|
|
34
|
+
* const ast = parseString(qasmCode);
|
|
35
|
+
* console.log(ast);
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @example OpenQASM 2.0 parsing
|
|
39
|
+
* ```typescript
|
|
40
|
+
* const qasm2Code = `
|
|
41
|
+
* OPENQASM 2.0;
|
|
42
|
+
* include "qelib1.inc";
|
|
43
|
+
* qreg q[2];
|
|
44
|
+
* creg c[2];
|
|
45
|
+
* h q[0];
|
|
46
|
+
* cx q[0],q[1];
|
|
47
|
+
* measure q -> c;
|
|
48
|
+
* `;
|
|
49
|
+
*
|
|
50
|
+
* const ast = parseString(qasm2Code, 2);
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* @example Verbose output with class names
|
|
54
|
+
* ```typescript
|
|
55
|
+
* const ast = parseString(qasmCode, 3, true);
|
|
56
|
+
* // Output will include __className__ properties for each node
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare function parseString(qasm: string, version?: number | OpenQASMVersion | OpenQASMMajorVersion, verbose?: boolean, stringify?: boolean): string | qasm2.AstNode[] | qasm3.AstNode[];
|
|
60
|
+
/**
|
|
61
|
+
* Parses OpenQASM code from a file and returns the abstract syntax tree.
|
|
62
|
+
*
|
|
63
|
+
* @group Main Functions
|
|
64
|
+
* @param file - The path to the .qasm file to parse
|
|
65
|
+
* @param version - The OpenQASM version to use (defaults to 3.0)
|
|
66
|
+
* @param verbose - Whether to include class names in the output (defaults to false)
|
|
67
|
+
* @param stringify - Whether to return stringified JSON (defaults to false)
|
|
68
|
+
* @returns The corresponding AST as an array of nodes, or stringified JSON if stringify is true
|
|
69
|
+
*
|
|
70
|
+
* @example Parse a QASM file
|
|
71
|
+
* ```typescript
|
|
72
|
+
* import { parseFile } from 'qasm-ts';
|
|
73
|
+
*
|
|
74
|
+
* // Parse OpenQASM 3.0 file
|
|
75
|
+
* const ast = parseFile('./my-circuit.qasm');
|
|
76
|
+
*
|
|
77
|
+
* // Parse OpenQASM 2.0 file
|
|
78
|
+
* const ast2 = parseFile('./legacy-circuit.qasm', 2);
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @example Parse with verbose output
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const ast = parseFile('./circuit.qasm', 3, true);
|
|
84
|
+
* // Includes detailed class information for each AST node
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare function parseFile(file: string, version?: number | OpenQASMVersion | OpenQASMMajorVersion, verbose?: boolean, stringify?: boolean): string | qasm2.AstNode[] | qasm3.AstNode[];
|
package/dist/main.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import { lex } from "./lexer";
|
|
4
|
+
import { parse } from "./parser";
|
|
5
|
+
/**
|
|
6
|
+
* Parses OpenQASM code from a string and returns the abstract syntax tree.
|
|
7
|
+
*
|
|
8
|
+
* This is the primary entry point for parsing OpenQASM code. It handles both
|
|
9
|
+
* OpenQASM 2.0 and 3.0 syntax, automatically selecting the appropriate lexer
|
|
10
|
+
* and parser based on the version parameter.
|
|
11
|
+
*
|
|
12
|
+
* @group Main Functions
|
|
13
|
+
* @param qasm - The OpenQASM code string to parse
|
|
14
|
+
* @param version - The OpenQASM version to use (defaults to 3.0)
|
|
15
|
+
* @param verbose - Whether to include class names in the output (defaults to false)
|
|
16
|
+
* @param stringify - Whether to return stringified JSON (defaults to false)
|
|
17
|
+
* @returns The corresponding AST as an array of nodes, or stringified JSON if stringify is true
|
|
18
|
+
*
|
|
19
|
+
* @example Basic OpenQASM 3.0 parsing
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { parseString } from 'qasm-ts';
|
|
22
|
+
*
|
|
23
|
+
* const qasmCode = `
|
|
24
|
+
* OPENQASM 3.0;
|
|
25
|
+
* include "stdgates.inc";
|
|
26
|
+
* qubit[2] q;
|
|
27
|
+
* h q[0];
|
|
28
|
+
* cx q[0], q[1];
|
|
29
|
+
* `;
|
|
30
|
+
*
|
|
31
|
+
* const ast = parseString(qasmCode);
|
|
32
|
+
* console.log(ast);
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @example OpenQASM 2.0 parsing
|
|
36
|
+
* ```typescript
|
|
37
|
+
* const qasm2Code = `
|
|
38
|
+
* OPENQASM 2.0;
|
|
39
|
+
* include "qelib1.inc";
|
|
40
|
+
* qreg q[2];
|
|
41
|
+
* creg c[2];
|
|
42
|
+
* h q[0];
|
|
43
|
+
* cx q[0],q[1];
|
|
44
|
+
* measure q -> c;
|
|
45
|
+
* `;
|
|
46
|
+
*
|
|
47
|
+
* const ast = parseString(qasm2Code, 2);
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* @example Verbose output with class names
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const ast = parseString(qasmCode, 3, true);
|
|
53
|
+
* // Output will include __className__ properties for each node
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export function parseString(qasm, version, verbose, stringify) {
|
|
57
|
+
let ast;
|
|
58
|
+
const tokens = lex(qasm, undefined, version);
|
|
59
|
+
ast = parse(tokens, version);
|
|
60
|
+
if (verbose === true) {
|
|
61
|
+
if (stringify === true) {
|
|
62
|
+
ast = JSON.stringify(getDetailedOutput(ast), null, 2);
|
|
63
|
+
}
|
|
64
|
+
ast = getDetailedOutput(ast);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
if (stringify === true) {
|
|
68
|
+
ast = JSON.stringify(ast, null, 2);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return ast;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Parses OpenQASM code from a file and returns the abstract syntax tree.
|
|
75
|
+
*
|
|
76
|
+
* @group Main Functions
|
|
77
|
+
* @param file - The path to the .qasm file to parse
|
|
78
|
+
* @param version - The OpenQASM version to use (defaults to 3.0)
|
|
79
|
+
* @param verbose - Whether to include class names in the output (defaults to false)
|
|
80
|
+
* @param stringify - Whether to return stringified JSON (defaults to false)
|
|
81
|
+
* @returns The corresponding AST as an array of nodes, or stringified JSON if stringify is true
|
|
82
|
+
*
|
|
83
|
+
* @example Parse a QASM file
|
|
84
|
+
* ```typescript
|
|
85
|
+
* import { parseFile } from 'qasm-ts';
|
|
86
|
+
*
|
|
87
|
+
* // Parse OpenQASM 3.0 file
|
|
88
|
+
* const ast = parseFile('./my-circuit.qasm');
|
|
89
|
+
*
|
|
90
|
+
* // Parse OpenQASM 2.0 file
|
|
91
|
+
* const ast2 = parseFile('./legacy-circuit.qasm', 2);
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* @example Parse with verbose output
|
|
95
|
+
* ```typescript
|
|
96
|
+
* const ast = parseFile('./circuit.qasm', 3, true);
|
|
97
|
+
* // Includes detailed class information for each AST node
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export function parseFile(file, version, verbose, stringify) {
|
|
101
|
+
return parseString(fs.readFileSync(file, "utf8"), version, verbose, stringify);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Adds class names to AST nodes for detailed inspection.
|
|
105
|
+
* @internal
|
|
106
|
+
*/
|
|
107
|
+
function getDetailedOutput(object) {
|
|
108
|
+
if (Array.isArray(object)) {
|
|
109
|
+
return object.map(getDetailedOutput);
|
|
110
|
+
}
|
|
111
|
+
else if (object !== null && typeof object === "object") {
|
|
112
|
+
const result = {};
|
|
113
|
+
result["__className__"] = object.constructor.name;
|
|
114
|
+
for (const [key, value] of Object.entries(object)) {
|
|
115
|
+
result[key] = getDetailedOutput(value);
|
|
116
|
+
}
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
return object;
|
|
121
|
+
}
|
|
122
|
+
}
|