qasm-ts 1.1.1
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/ast.js +267 -0
- package/dist/errors.js +148 -0
- package/dist/example.js +22 -0
- package/dist/lexer.js +300 -0
- package/dist/main.js +26 -0
- package/dist/parser.js +489 -0
- package/dist/token.js +89 -0
- package/package.json +36 -0
- package/readme.md +122 -0
- package/src/ast.ts +192 -0
- package/src/errors.ts +102 -0
- package/src/lexer.ts +319 -0
- package/src/main.ts +27 -0
- package/src/parser.ts +531 -0
- package/src/token.ts +92 -0
- package/tsconfig.json +14 -0
package/readme.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# QASM TypeScript
|
|
2
|
+
|
|
3
|
+
OpenQASM, the low-level programming language for quantum circuit specification, implemented in TypeScript.
|
|
4
|
+
|
|
5
|
+
Language documentation is provided by IBM [here](https://github.com/Qiskit/openqasm/blob/master/spec/qasm2.rst).
|
|
6
|
+
|
|
7
|
+
## New in Version 1.1.0
|
|
8
|
+
|
|
9
|
+
- Checking for invalid code structure
|
|
10
|
+
- Supporting custom gates
|
|
11
|
+
- Rejecting unsupported gates
|
|
12
|
+
- Better parameter parsing
|
|
13
|
+
- Added conformance tests
|
|
14
|
+
- Found and fixed bugs related to conformity
|
|
15
|
+
- Jasmine unit tests
|
|
16
|
+
- Lexing string literals
|
|
17
|
+
|
|
18
|
+
## New in Latest Subversion
|
|
19
|
+
|
|
20
|
+
- Updated readme.
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
Import the parse function or parseString function from the package.
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
import { parse, parseString } from 'qasm-ts';
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`parse` can be called with a file path to a `.qasm` file. It will parse the file and return the abstract syntax tree representation.
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
let ast = parse(<file-path>);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`parseString` should be called with a string of QASM code. It will parse the code and return the abstract syntax tree representation.
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
let ast = parseString(<qasm-string>);
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Example I/O
|
|
43
|
+
|
|
44
|
+
### Input: Deutsch_Algorithm.qasm
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
// Implementation of Deutsch algorithm with two qubits for f(x)=x
|
|
48
|
+
OPENQASM 2.0;
|
|
49
|
+
include "qelib1.inc";
|
|
50
|
+
|
|
51
|
+
qreg q[5];
|
|
52
|
+
creg c[5];
|
|
53
|
+
|
|
54
|
+
x q[4];
|
|
55
|
+
h q[3];
|
|
56
|
+
h q[4];
|
|
57
|
+
cx q[3],q[4];
|
|
58
|
+
h q[3];
|
|
59
|
+
measure q[3] -> c[3];
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Output: Abstract Syntax Tree
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
[ QReg { id: 'q', size: 5 },
|
|
66
|
+
QReg { id: 'c', size: 5 },
|
|
67
|
+
[ ApplyGate { name: 'x', qubits: [['q',4]], params: [] } ],
|
|
68
|
+
[ ApplyGate { name: 'h', qubits: [['q',3]], params: [] } ],
|
|
69
|
+
[ ApplyGate { name: 'h', qubits: [['q',4]], params: [] } ],
|
|
70
|
+
[ ApplyGate { name: 'cx', qubits: [['q',3],['q',4]], params: [] } ],
|
|
71
|
+
[ ApplyGate { name: 'h', qubits: [['q',3]], params: [] } ],
|
|
72
|
+
Measure {
|
|
73
|
+
src_index: 3,
|
|
74
|
+
src_register: 'q',
|
|
75
|
+
dest_index: 3,
|
|
76
|
+
dest_register: 'c'
|
|
77
|
+
} ]
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Source code
|
|
81
|
+
|
|
82
|
+
Feel free to clone, fork, comment or contribute on [GitHub](https://github.com/comp-phys-marc/qasm-ts)!
|
|
83
|
+
|
|
84
|
+
## Transpiling
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
tsc src/*.ts --outDir dist
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Installing dependencies
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
npm install
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Run Unit Tests, Conformance Tests
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
npm test
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## References
|
|
103
|
+
|
|
104
|
+
The original OpenQASM authors:
|
|
105
|
+
|
|
106
|
+
- Andrew W. Cross, Lev S. Bishop, John A. Smolin, Jay M. Gambetta "Open Quantum Assembly Language" [arXiv:1707.03429](http://web.archive.org/web/20210121114036/https://arxiv.org/abs/1707.03429).
|
|
107
|
+
|
|
108
|
+
Another strongly typed implementation from which this project took some inspiration:
|
|
109
|
+
|
|
110
|
+
- [Adam Kelly's Rust QASM Parser](https://github.com/libtangle/qasm-rust)
|
|
111
|
+
|
|
112
|
+
## License
|
|
113
|
+
|
|
114
|
+
Copyright 2019 Marcus Edwards
|
|
115
|
+
|
|
116
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
package/src/ast.ts
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
|
|
2
|
+
/** Base class representing a basic AST node. */
|
|
3
|
+
class AstNode {}
|
|
4
|
+
|
|
5
|
+
/** Class representing a qubit register. */
|
|
6
|
+
class QReg extends AstNode {
|
|
7
|
+
size:number;
|
|
8
|
+
id:string;
|
|
9
|
+
constructor(id:string, size:number) {
|
|
10
|
+
super();
|
|
11
|
+
this.id = id;
|
|
12
|
+
this.size = size;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Class representing a classical register. */
|
|
17
|
+
class CReg extends AstNode {
|
|
18
|
+
size:number;
|
|
19
|
+
id:string;
|
|
20
|
+
constructor(id:string, size:number) {
|
|
21
|
+
super();
|
|
22
|
+
this.id = id;
|
|
23
|
+
this.size = size;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Class representing an identifier. */
|
|
28
|
+
class Id extends AstNode {
|
|
29
|
+
id:string;
|
|
30
|
+
constructor(id:string) {
|
|
31
|
+
super();
|
|
32
|
+
this.id = id;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Class representing a barrier. */
|
|
37
|
+
class Barrier extends AstNode {
|
|
38
|
+
index:number;
|
|
39
|
+
register:string;
|
|
40
|
+
constructor(register:string, index?:number) {
|
|
41
|
+
super();
|
|
42
|
+
this.index = index || null;
|
|
43
|
+
this.register = register;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Class representing a variable. */
|
|
48
|
+
class Variable extends AstNode {
|
|
49
|
+
value:string;
|
|
50
|
+
constructor(value:string) {
|
|
51
|
+
super();
|
|
52
|
+
this.value= value|| null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Class representing a measurement. */
|
|
57
|
+
class Measure extends AstNode {
|
|
58
|
+
src_index:number;
|
|
59
|
+
src_register:string;
|
|
60
|
+
dest_index:number;
|
|
61
|
+
dest_register:string;
|
|
62
|
+
constructor(src_register:string, dest_register:string, src_index?:number,
|
|
63
|
+
dest_index?:number) {
|
|
64
|
+
super();
|
|
65
|
+
this.src_index = src_index != undefined ? src_index : null;
|
|
66
|
+
this.src_register = src_register;
|
|
67
|
+
this.dest_index = dest_index != undefined ? dest_index : null;
|
|
68
|
+
this.dest_register = dest_register;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Class representing a gate application. */
|
|
73
|
+
class ApplyGate extends AstNode {
|
|
74
|
+
name:string;
|
|
75
|
+
qubits:Array<[string, number?]>;
|
|
76
|
+
params:Array<AstNode>;
|
|
77
|
+
constructor(name:string, qubits:Array<[string, number?]>,
|
|
78
|
+
params:Array<AstNode>) {
|
|
79
|
+
super();
|
|
80
|
+
this.name = name;
|
|
81
|
+
this.qubits = qubits;
|
|
82
|
+
this.params = params;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Class representing a gate. */
|
|
87
|
+
class Gate extends AstNode {
|
|
88
|
+
name:string;
|
|
89
|
+
registers:Array<string>;
|
|
90
|
+
params:Array<string>;
|
|
91
|
+
nodes:Array<AstNode>;
|
|
92
|
+
constructor(name:string, registers:Array<string>, params:Array<string>, nodes:Array<AstNode>) {
|
|
93
|
+
super();
|
|
94
|
+
this.name = name;
|
|
95
|
+
this.registers = registers;
|
|
96
|
+
this.params = params;
|
|
97
|
+
this.nodes = nodes;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/** Class representing conditional. */
|
|
101
|
+
class If extends AstNode {
|
|
102
|
+
register:string;
|
|
103
|
+
param:number;
|
|
104
|
+
gate:AstNode;
|
|
105
|
+
constructor(register:string, param:number, gate:AstNode) {
|
|
106
|
+
super();
|
|
107
|
+
this.register = register;
|
|
108
|
+
this.param = param;
|
|
109
|
+
this.gate = gate;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Class representing minus. */
|
|
114
|
+
class Minus extends AstNode {}
|
|
115
|
+
|
|
116
|
+
/** Class representing plus. */
|
|
117
|
+
class Plus extends AstNode {}
|
|
118
|
+
|
|
119
|
+
/** Class representing times. */
|
|
120
|
+
class Times extends AstNode {}
|
|
121
|
+
|
|
122
|
+
/** Class representing power. */
|
|
123
|
+
class Power extends AstNode {}
|
|
124
|
+
|
|
125
|
+
/** Class representing division. */
|
|
126
|
+
class Divide extends AstNode {}
|
|
127
|
+
|
|
128
|
+
/** Class representing pi. */
|
|
129
|
+
class Pi extends AstNode {}
|
|
130
|
+
|
|
131
|
+
/** Class representing the square root. */
|
|
132
|
+
class Sqrt extends AstNode {}
|
|
133
|
+
|
|
134
|
+
/** Class representing natural logarithm. */
|
|
135
|
+
class Ln extends AstNode {}
|
|
136
|
+
|
|
137
|
+
/** Class representing exponentiation. */
|
|
138
|
+
class Exp extends AstNode {}
|
|
139
|
+
|
|
140
|
+
/** Class representing tagnent. */
|
|
141
|
+
class Tan extends AstNode {}
|
|
142
|
+
|
|
143
|
+
/** Class representing cosine. */
|
|
144
|
+
class Cos extends AstNode {}
|
|
145
|
+
|
|
146
|
+
/** Class representing sine. */
|
|
147
|
+
class Sin extends AstNode {}
|
|
148
|
+
|
|
149
|
+
/** Class representing an integer. */
|
|
150
|
+
class NNInteger extends AstNode {
|
|
151
|
+
value:number;
|
|
152
|
+
constructor(value:number) {
|
|
153
|
+
super();
|
|
154
|
+
this.value = value;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** Class representing a real. */
|
|
159
|
+
class Real extends AstNode {
|
|
160
|
+
value:number;
|
|
161
|
+
constructor(value:number) {
|
|
162
|
+
super();
|
|
163
|
+
this.value = value;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export {
|
|
168
|
+
AstNode,
|
|
169
|
+
QReg,
|
|
170
|
+
CReg,
|
|
171
|
+
Barrier,
|
|
172
|
+
Measure,
|
|
173
|
+
ApplyGate,
|
|
174
|
+
Gate,
|
|
175
|
+
If,
|
|
176
|
+
Id,
|
|
177
|
+
Divide,
|
|
178
|
+
Plus,
|
|
179
|
+
Minus,
|
|
180
|
+
Times,
|
|
181
|
+
Power,
|
|
182
|
+
Sin,
|
|
183
|
+
Cos,
|
|
184
|
+
Tan,
|
|
185
|
+
Exp,
|
|
186
|
+
Ln,
|
|
187
|
+
Sqrt,
|
|
188
|
+
Pi,
|
|
189
|
+
NNInteger,
|
|
190
|
+
Real,
|
|
191
|
+
Variable
|
|
192
|
+
};
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/** Class representing a bad argument exception. */
|
|
2
|
+
class BadArgumentError extends Error {
|
|
3
|
+
constructor(message?: string) {
|
|
4
|
+
super(message);
|
|
5
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
6
|
+
this.name = BadArgumentError.name;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** Class representing a bad quantum register exception. */
|
|
11
|
+
class BadQregError extends Error {
|
|
12
|
+
constructor(message?: string) {
|
|
13
|
+
super(message);
|
|
14
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
15
|
+
this.name = BadQregError.name;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Class representing a bad equality exception. */
|
|
20
|
+
class BadEqualsError extends Error {
|
|
21
|
+
constructor(message?: string) {
|
|
22
|
+
super(message);
|
|
23
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
24
|
+
this.name = BadEqualsError.name;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Class representing a bad classical register exception. */
|
|
29
|
+
class BadCregError extends Error {
|
|
30
|
+
constructor(message?: string) {
|
|
31
|
+
super(message);
|
|
32
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
33
|
+
this.name = BadCregError.name;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Class representing a bad conditional exception. */
|
|
38
|
+
class BadConditionalError extends Error {
|
|
39
|
+
constructor(message?: string) {
|
|
40
|
+
super(message);
|
|
41
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
42
|
+
this.name = BadConditionalError.name;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Class representing a bad barrier exception. */
|
|
47
|
+
class BadBarrierError extends Error {
|
|
48
|
+
constructor(message?: string) {
|
|
49
|
+
super(message);
|
|
50
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
51
|
+
this.name = BadBarrierError.name;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Class representing a bad measurement exception. */
|
|
56
|
+
class BadMeasurementError extends Error {
|
|
57
|
+
constructor(message?: string) {
|
|
58
|
+
super(message);
|
|
59
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
60
|
+
this.name = BadMeasurementError.name;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Class representing a bad gate exception. */
|
|
65
|
+
class BadGateError extends Error {
|
|
66
|
+
constructor(message?: string) {
|
|
67
|
+
super(message);
|
|
68
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
69
|
+
this.name = BadGateError.name;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Class representing a bad parameter exception. */
|
|
74
|
+
class BadParameterError extends Error {
|
|
75
|
+
constructor(message?: string) {
|
|
76
|
+
super(message);
|
|
77
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
78
|
+
this.name = BadParameterError.name;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Class representing a missing semicolon exception. */
|
|
83
|
+
class MissingSemicolonError extends Error {
|
|
84
|
+
constructor(message?: string) {
|
|
85
|
+
super(message);
|
|
86
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
87
|
+
this.name = MissingSemicolonError.name;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export {
|
|
92
|
+
BadArgumentError,
|
|
93
|
+
BadCregError,
|
|
94
|
+
BadQregError,
|
|
95
|
+
BadConditionalError,
|
|
96
|
+
BadBarrierError,
|
|
97
|
+
BadMeasurementError,
|
|
98
|
+
BadGateError,
|
|
99
|
+
BadEqualsError,
|
|
100
|
+
BadParameterError,
|
|
101
|
+
MissingSemicolonError
|
|
102
|
+
};
|