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/dist/parser.js
ADDED
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
exports.__esModule = true;
|
|
3
|
+
var token_1 = require("./token");
|
|
4
|
+
var errors_1 = require("./errors");
|
|
5
|
+
var ast_1 = require("./ast");
|
|
6
|
+
/** Class representing a token parser. */
|
|
7
|
+
var Parser = /** @class */ (function () {
|
|
8
|
+
/**
|
|
9
|
+
* Creates a parser.
|
|
10
|
+
* @param tokens - Tokens to parse.
|
|
11
|
+
*/
|
|
12
|
+
function Parser(tokens) {
|
|
13
|
+
this.tokens = tokens;
|
|
14
|
+
this.gates = [
|
|
15
|
+
'x',
|
|
16
|
+
'y',
|
|
17
|
+
'z',
|
|
18
|
+
'u1',
|
|
19
|
+
'u2',
|
|
20
|
+
'u3',
|
|
21
|
+
's',
|
|
22
|
+
'sdg',
|
|
23
|
+
'h',
|
|
24
|
+
'tdg',
|
|
25
|
+
'cx',
|
|
26
|
+
'cy',
|
|
27
|
+
'cz',
|
|
28
|
+
't',
|
|
29
|
+
'ccx',
|
|
30
|
+
'reset',
|
|
31
|
+
'cu1',
|
|
32
|
+
'ccy',
|
|
33
|
+
'ccz'
|
|
34
|
+
];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Calling this method parses the code represented by the provided tokens.
|
|
38
|
+
* @return The abstract syntax tree.
|
|
39
|
+
*/
|
|
40
|
+
Parser.prototype.parse = function () {
|
|
41
|
+
var ast = [];
|
|
42
|
+
var i = 0;
|
|
43
|
+
while (i < (this.tokens.length - 1)) {
|
|
44
|
+
var nodes = this.parseNode(this.tokens.slice(i));
|
|
45
|
+
ast = ast.concat(nodes ? nodes : []);
|
|
46
|
+
while (!(this.matchNext(this.tokens.slice(i), [token_1.Token.Semicolon]))) {
|
|
47
|
+
if (this.matchNext(this.tokens.slice(i), [token_1.Token.LCParen])) {
|
|
48
|
+
while (!(this.matchNext(this.tokens.slice(i), [token_1.Token.RCParen]))) {
|
|
49
|
+
i++;
|
|
50
|
+
}
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
i++;
|
|
54
|
+
}
|
|
55
|
+
i++;
|
|
56
|
+
}
|
|
57
|
+
return ast;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Delegates the parsing of the next set of tokens to the appropriate method.
|
|
61
|
+
* @param tokens - Remaining tokens to parse.
|
|
62
|
+
* @param allowVariables - Whether encountered identifiers should be consider
|
|
63
|
+
variable initializations or references.
|
|
64
|
+
* @return A set of AST nodes.
|
|
65
|
+
*/
|
|
66
|
+
Parser.prototype.parseNode = function (tokens, allowVariables) {
|
|
67
|
+
if (allowVariables === void 0) { allowVariables = false; }
|
|
68
|
+
var token = tokens[0];
|
|
69
|
+
switch (token[0]) {
|
|
70
|
+
case token_1.Token.QReg:
|
|
71
|
+
return [this.qreg(tokens.slice(1))];
|
|
72
|
+
case token_1.Token.CReg:
|
|
73
|
+
return [this.creg(tokens.slice(1))];
|
|
74
|
+
case token_1.Token.Barrier:
|
|
75
|
+
return [this.barrier(tokens.slice(1))];
|
|
76
|
+
case token_1.Token.Measure:
|
|
77
|
+
return [this.measure(tokens.slice(1))];
|
|
78
|
+
case token_1.Token.Id:
|
|
79
|
+
if (!(token[1].toString().indexOf('QASM') != -1) &&
|
|
80
|
+
!(token[1].toString().indexOf('include') != -1)) {
|
|
81
|
+
if (this.gates.includes(token[1].toString())) {
|
|
82
|
+
return [this.application(tokens, token[1].toString())];
|
|
83
|
+
}
|
|
84
|
+
else if (allowVariables) {
|
|
85
|
+
return [new ast_1.Variable(token[1].toString())];
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
throw errors_1.BadGateError;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
return [];
|
|
93
|
+
}
|
|
94
|
+
case token_1.Token.Gate:
|
|
95
|
+
return [this.gate(tokens.slice(1))];
|
|
96
|
+
case token_1.Token.If:
|
|
97
|
+
return [this.conditional(tokens.slice(1))];
|
|
98
|
+
case token_1.Token.Power:
|
|
99
|
+
return [new ast_1.Power()];
|
|
100
|
+
case token_1.Token.Divide:
|
|
101
|
+
return [new ast_1.Divide()];
|
|
102
|
+
case token_1.Token.Times:
|
|
103
|
+
return [new ast_1.Times()];
|
|
104
|
+
case token_1.Token.Plus:
|
|
105
|
+
return [new ast_1.Plus()];
|
|
106
|
+
case token_1.Token.Minus:
|
|
107
|
+
return [new ast_1.Minus()];
|
|
108
|
+
case token_1.Token.Pi:
|
|
109
|
+
return [new ast_1.Pi()];
|
|
110
|
+
case token_1.Token.Sin:
|
|
111
|
+
return [new ast_1.Sin()];
|
|
112
|
+
case token_1.Token.Cos:
|
|
113
|
+
return [new ast_1.Cos()];
|
|
114
|
+
case token_1.Token.Exp:
|
|
115
|
+
return [new ast_1.Exp()];
|
|
116
|
+
case token_1.Token.Ln:
|
|
117
|
+
return [new ast_1.Ln()];
|
|
118
|
+
case token_1.Token.Sqrt:
|
|
119
|
+
return [new ast_1.Sqrt()];
|
|
120
|
+
case token_1.Token.Tan:
|
|
121
|
+
return [new ast_1.Tan()];
|
|
122
|
+
case token_1.Token.NNInteger:
|
|
123
|
+
return [new ast_1.NNInteger(Number(token[1]))];
|
|
124
|
+
case token_1.Token.Real:
|
|
125
|
+
return [new ast_1.Real(Number(token[1]))];
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* Checks if the next tokens match those expected.
|
|
130
|
+
* @param tokens - Remaining tokens to parse.
|
|
131
|
+
* @param expectedTokens - Expected tokens.
|
|
132
|
+
* @return Whether these is a match.
|
|
133
|
+
*/
|
|
134
|
+
Parser.prototype.matchNext = function (tokens, expectedTokens) {
|
|
135
|
+
var matches = true;
|
|
136
|
+
var i = 0;
|
|
137
|
+
if (tokens.length == 0) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
while (i < expectedTokens.length) {
|
|
141
|
+
if (tokens[i][0] != expectedTokens[i]) {
|
|
142
|
+
matches = false;
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
i++;
|
|
146
|
+
}
|
|
147
|
+
return matches;
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* Parses a quantum register.
|
|
151
|
+
* @param tokens - Remaining tokens to parse.
|
|
152
|
+
* @return An AST node representing the quantum register.
|
|
153
|
+
*/
|
|
154
|
+
Parser.prototype.qreg = function (tokens) {
|
|
155
|
+
if (this.matchNext(tokens, [token_1.Token.Id, token_1.Token.LSParen, token_1.Token.NNInteger, token_1.Token.RSParen, token_1.Token.Semicolon])) {
|
|
156
|
+
var id = tokens[0][1];
|
|
157
|
+
var size = tokens[2][1];
|
|
158
|
+
return new ast_1.QReg(id.toString(), Number(size));
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
throw errors_1.BadQregError;
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* Parses a classical register.
|
|
166
|
+
* @param tokens - Remaining tokens to parse.
|
|
167
|
+
* @return An AST node representing the classical register.
|
|
168
|
+
*/
|
|
169
|
+
Parser.prototype.creg = function (tokens) {
|
|
170
|
+
if (this.matchNext(tokens, [token_1.Token.Id, token_1.Token.LSParen, token_1.Token.NNInteger,
|
|
171
|
+
token_1.Token.RSParen, token_1.Token.Semicolon])) {
|
|
172
|
+
var id = tokens[0][1];
|
|
173
|
+
var size = tokens[2][1];
|
|
174
|
+
return new ast_1.CReg(id.toString(), Number(size));
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
throw errors_1.BadCregError;
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
/**
|
|
181
|
+
* Parses a conditional.
|
|
182
|
+
* @param tokens - Remaining tokens to parse.
|
|
183
|
+
* @return An AST node representing the conditional.
|
|
184
|
+
*/
|
|
185
|
+
Parser.prototype.conditional = function (tokens) {
|
|
186
|
+
if (this.matchNext(tokens, [token_1.Token.LParen, token_1.Token.Id, token_1.Token.Equals, token_1.Token.NNInteger, token_1.Token.RParen])) {
|
|
187
|
+
var id = tokens[1][1];
|
|
188
|
+
var val = tokens[3][1];
|
|
189
|
+
var node = this.parseNode(tokens.slice(5));
|
|
190
|
+
return new ast_1.If(id.toString(), Number(val), node);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
throw errors_1.BadConditionalError;
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
/**
|
|
197
|
+
* Parses a barrier.
|
|
198
|
+
* @param tokens - Remaining tokens to parse.
|
|
199
|
+
* @return An AST node representing the barrier.
|
|
200
|
+
*/
|
|
201
|
+
Parser.prototype.barrier = function (tokens) {
|
|
202
|
+
if (this.matchNext(tokens, [token_1.Token.Id, token_1.Token.Semicolon])) {
|
|
203
|
+
var id = tokens[0][1];
|
|
204
|
+
return new ast_1.Barrier(id.toString());
|
|
205
|
+
}
|
|
206
|
+
else if (this.matchNext(tokens, [token_1.Token.Id, token_1.Token.LParen,
|
|
207
|
+
token_1.Token.NNInteger, token_1.Token.RParen, token_1.Token.Semicolon])) {
|
|
208
|
+
var id = tokens[0][1];
|
|
209
|
+
var index = tokens[2][1];
|
|
210
|
+
return new ast_1.Barrier(id.toString(), Number(index));
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
throw errors_1.BadBarrierError;
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
/**
|
|
217
|
+
* Parses a measurement.
|
|
218
|
+
* @param tokens - Remaining tokens to parse.
|
|
219
|
+
* @return An AST node representing the measurement.
|
|
220
|
+
*/
|
|
221
|
+
Parser.prototype.measure = function (tokens) {
|
|
222
|
+
var first_id;
|
|
223
|
+
var second_id;
|
|
224
|
+
var first_index;
|
|
225
|
+
var second_index;
|
|
226
|
+
if (this.matchNext(tokens, [token_1.Token.Id, token_1.Token.Arrow])) {
|
|
227
|
+
first_id = tokens[0][1].toString();
|
|
228
|
+
tokens = tokens.slice(2);
|
|
229
|
+
}
|
|
230
|
+
else if (this.matchNext(tokens, [token_1.Token.Id, token_1.Token.LSParen, token_1.Token.NNInteger, token_1.Token.RSParen, token_1.Token.Arrow])) {
|
|
231
|
+
first_id = tokens[0][1].toString();
|
|
232
|
+
first_index = Number(tokens[2][1]);
|
|
233
|
+
tokens = tokens.slice(5);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
throw errors_1.BadMeasurementError;
|
|
237
|
+
}
|
|
238
|
+
if (this.matchNext(tokens, [token_1.Token.Id, token_1.Token.Semicolon])) {
|
|
239
|
+
second_id = tokens[0][1].toString();
|
|
240
|
+
tokens = tokens.slice(2);
|
|
241
|
+
}
|
|
242
|
+
else if (this.matchNext(tokens, [token_1.Token.Id, token_1.Token.LSParen, token_1.Token.NNInteger, token_1.Token.RSParen, token_1.Token.Semicolon])) {
|
|
243
|
+
second_id = tokens[0][1].toString();
|
|
244
|
+
second_index = Number(tokens[2][1]);
|
|
245
|
+
tokens = tokens.slice(5);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
throw errors_1.BadMeasurementError;
|
|
249
|
+
}
|
|
250
|
+
if (first_index != undefined && second_index != undefined) {
|
|
251
|
+
return new ast_1.Measure(first_id, second_id, first_index, second_index);
|
|
252
|
+
}
|
|
253
|
+
else if (first_index != undefined) {
|
|
254
|
+
return new ast_1.Measure(first_id, second_id, first_index = first_index);
|
|
255
|
+
}
|
|
256
|
+
else if (second_index != undefined) {
|
|
257
|
+
return new ast_1.Measure(first_id, second_id, second_index = second_index);
|
|
258
|
+
}
|
|
259
|
+
return new ast_1.Measure(first_id, second_id);
|
|
260
|
+
};
|
|
261
|
+
/**
|
|
262
|
+
* Parses an application of one of the allowed gates.
|
|
263
|
+
* @param tokens - Remaining tokens to parse.
|
|
264
|
+
* @return An AST node representing the gate application.
|
|
265
|
+
*/
|
|
266
|
+
Parser.prototype.application = function (tokens, op) {
|
|
267
|
+
var params = [];
|
|
268
|
+
var list = [];
|
|
269
|
+
var applications = [];
|
|
270
|
+
var id;
|
|
271
|
+
if (tokens[0][1] == op) {
|
|
272
|
+
tokens = tokens.slice(1);
|
|
273
|
+
}
|
|
274
|
+
if (this.matchNext(tokens, [token_1.Token.LParen])) {
|
|
275
|
+
if (this.matchNext(tokens.slice(1), [token_1.Token.RParen])) {
|
|
276
|
+
params = [];
|
|
277
|
+
tokens = tokens.slice(2);
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
params = this.matchParamList(tokens.slice(1));
|
|
281
|
+
var count = 0;
|
|
282
|
+
var commas = 0;
|
|
283
|
+
for (var i in params) {
|
|
284
|
+
commas += 1;
|
|
285
|
+
for (var j in params[i]) {
|
|
286
|
+
count++;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
tokens = tokens.slice(count + (commas - 1) + 2);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
var args = this.matchArgList(tokens);
|
|
293
|
+
for (var arg in args) {
|
|
294
|
+
id = args[arg][0];
|
|
295
|
+
list.push(args[arg]);
|
|
296
|
+
}
|
|
297
|
+
applications.push(new ast_1.ApplyGate(op, list, params));
|
|
298
|
+
return applications;
|
|
299
|
+
};
|
|
300
|
+
/**
|
|
301
|
+
* Parses a subroutine used in a custom gate definition.
|
|
302
|
+
* @param tokens - Expression tokens to parse.
|
|
303
|
+
* @return A parsed subroutine.
|
|
304
|
+
*/
|
|
305
|
+
Parser.prototype.sub = function (tokens) {
|
|
306
|
+
var ast = [];
|
|
307
|
+
var i = 0;
|
|
308
|
+
if (this.matchNext(tokens.slice(i), [token_1.Token.LCParen])) {
|
|
309
|
+
tokens = tokens.slice(1);
|
|
310
|
+
}
|
|
311
|
+
while ((i < (tokens.length - 1)) && (tokens[i][0] != token_1.Token.RCParen)) {
|
|
312
|
+
var nodes = this.parseNode(tokens.slice(i));
|
|
313
|
+
ast = ast.concat(nodes ? nodes : []);
|
|
314
|
+
while ((!this.matchNext(tokens.slice(i), [token_1.Token.Semicolon])) &&
|
|
315
|
+
(!this.matchNext(tokens.slice(i), [token_1.Token.RCParen]))) {
|
|
316
|
+
i++;
|
|
317
|
+
}
|
|
318
|
+
if (this.matchNext(tokens.slice(i), [token_1.Token.RCParen])) {
|
|
319
|
+
break;
|
|
320
|
+
}
|
|
321
|
+
i++;
|
|
322
|
+
}
|
|
323
|
+
return ast;
|
|
324
|
+
};
|
|
325
|
+
/**
|
|
326
|
+
* Parses a parameter value.
|
|
327
|
+
* @param tokens - Tokens to parse.
|
|
328
|
+
* @return An AST node representing the parameter value.
|
|
329
|
+
*/
|
|
330
|
+
Parser.prototype.matchParam = function (tokens) {
|
|
331
|
+
var param;
|
|
332
|
+
if (!(token_1.notParam(tokens[0][0]))) {
|
|
333
|
+
param = this.parseNode([tokens[0]], true);
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
throw errors_1.BadParameterError;
|
|
337
|
+
}
|
|
338
|
+
return param;
|
|
339
|
+
};
|
|
340
|
+
/**
|
|
341
|
+
* Parses a list of parameter values.
|
|
342
|
+
* @param tokens - Tokens to parse.
|
|
343
|
+
* @return An array of AST nodes representing the parameter values.
|
|
344
|
+
*/
|
|
345
|
+
Parser.prototype.matchParamList = function (tokens) {
|
|
346
|
+
var args = [];
|
|
347
|
+
var i = 0;
|
|
348
|
+
var j = 0;
|
|
349
|
+
args[0] = [];
|
|
350
|
+
while (!this.matchNext(tokens.slice(j), [token_1.Token.RParen])) {
|
|
351
|
+
while (!this.matchNext(tokens.slice(j), [token_1.Token.Comma]) &&
|
|
352
|
+
!this.matchNext(tokens.slice(j), [token_1.Token.RParen])) {
|
|
353
|
+
if (token_1.notParam(tokens[j][0])) {
|
|
354
|
+
throw errors_1.BadParameterError;
|
|
355
|
+
}
|
|
356
|
+
var next = this.matchParam(tokens.slice(j));
|
|
357
|
+
args[i].push(next);
|
|
358
|
+
j++;
|
|
359
|
+
}
|
|
360
|
+
if (this.matchNext(tokens.slice(j), [token_1.Token.RParen])) {
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
i++;
|
|
364
|
+
j++;
|
|
365
|
+
args[i] = [];
|
|
366
|
+
}
|
|
367
|
+
return args;
|
|
368
|
+
};
|
|
369
|
+
/**
|
|
370
|
+
* Parses an argument value.
|
|
371
|
+
* @param tokens - Tokens to parse.
|
|
372
|
+
* @return An AST node representing the argument value.
|
|
373
|
+
*/
|
|
374
|
+
Parser.prototype.matchArg = function (tokens) {
|
|
375
|
+
var index;
|
|
376
|
+
if (this.matchNext(tokens, [token_1.Token.LSParen])) {
|
|
377
|
+
tokens = tokens.slice(1);
|
|
378
|
+
if (this.matchNext(tokens, [token_1.Token.NNInteger])) {
|
|
379
|
+
index = Number(tokens[0][1]);
|
|
380
|
+
tokens = tokens.slice(1);
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
throw errors_1.BadArgumentError;
|
|
384
|
+
}
|
|
385
|
+
if (this.matchNext(tokens, [token_1.Token.RSParen])) {
|
|
386
|
+
return index;
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
throw errors_1.BadArgumentError;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
/**
|
|
394
|
+
* Parses a list of argument values.
|
|
395
|
+
* @param tokens - Tokens to parse.
|
|
396
|
+
* @return An array of AST nodes representing the argument values.
|
|
397
|
+
*/
|
|
398
|
+
Parser.prototype.matchArgList = function (tokens) {
|
|
399
|
+
var args = [];
|
|
400
|
+
var next;
|
|
401
|
+
var id;
|
|
402
|
+
var j = 0;
|
|
403
|
+
while (j < tokens.length && !this.matchNext(tokens.slice(j), [token_1.Token.Semicolon])) {
|
|
404
|
+
if (this.matchNext(tokens.slice(j), [token_1.Token.Id])) {
|
|
405
|
+
id = tokens[j][1].toString();
|
|
406
|
+
var index = this.matchArg(tokens.slice(j + 1));
|
|
407
|
+
next = [id, index];
|
|
408
|
+
args.push(next);
|
|
409
|
+
if (index != undefined) {
|
|
410
|
+
j += 4;
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
j++;
|
|
414
|
+
}
|
|
415
|
+
if (this.matchNext(tokens.slice(j), [token_1.Token.Comma])) {
|
|
416
|
+
j++;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
else {
|
|
420
|
+
throw errors_1.BadArgumentError;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return args;
|
|
424
|
+
};
|
|
425
|
+
/**
|
|
426
|
+
* Parses a list of identifiers.
|
|
427
|
+
* @param tokens - Tokens to parse.
|
|
428
|
+
* @return An array of AST nodes representing the identifiers.
|
|
429
|
+
*/
|
|
430
|
+
Parser.prototype.matchIdList = function (tokens) {
|
|
431
|
+
var args = [];
|
|
432
|
+
var head;
|
|
433
|
+
if (this.matchNext(tokens, [token_1.Token.Id])) {
|
|
434
|
+
head = tokens[0][1].toString();
|
|
435
|
+
}
|
|
436
|
+
tokens = tokens.slice(1);
|
|
437
|
+
args.push(head);
|
|
438
|
+
if (this.matchNext(tokens, [token_1.Token.Comma])) {
|
|
439
|
+
tokens = tokens.slice(1);
|
|
440
|
+
var sub = this.matchIdList(tokens);
|
|
441
|
+
args = args.concat(sub);
|
|
442
|
+
}
|
|
443
|
+
return args;
|
|
444
|
+
};
|
|
445
|
+
/**
|
|
446
|
+
* Parses a gate.
|
|
447
|
+
* @param tokens - Remaining tokens to parse.
|
|
448
|
+
* @return An AST node representing the gate.
|
|
449
|
+
*/
|
|
450
|
+
Parser.prototype.gate = function (tokens) {
|
|
451
|
+
var name;
|
|
452
|
+
var params;
|
|
453
|
+
var registers;
|
|
454
|
+
var applications;
|
|
455
|
+
if (this.matchNext(tokens, [token_1.Token.Id])) {
|
|
456
|
+
name = tokens[0][1].toString();
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
throw errors_1.BadGateError;
|
|
460
|
+
}
|
|
461
|
+
tokens = tokens.slice(1);
|
|
462
|
+
if (this.matchNext(tokens, [token_1.Token.LParen])) {
|
|
463
|
+
tokens = tokens.slice(1);
|
|
464
|
+
if (this.matchNext(tokens, [token_1.Token.RParen])) {
|
|
465
|
+
params = [];
|
|
466
|
+
tokens = tokens.slice(1);
|
|
467
|
+
}
|
|
468
|
+
else {
|
|
469
|
+
params = this.matchIdList(tokens);
|
|
470
|
+
var count_1 = 0;
|
|
471
|
+
for (var i in params) {
|
|
472
|
+
count_1++;
|
|
473
|
+
}
|
|
474
|
+
tokens = tokens.slice(count_1 + 1);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
registers = this.matchIdList(tokens);
|
|
478
|
+
var count = 0;
|
|
479
|
+
for (var i in registers) {
|
|
480
|
+
count++;
|
|
481
|
+
}
|
|
482
|
+
tokens = tokens.slice(count + (count - 1));
|
|
483
|
+
applications = this.sub(tokens);
|
|
484
|
+
this.gates.push(name);
|
|
485
|
+
return new ast_1.Gate(name, registers, params, applications);
|
|
486
|
+
};
|
|
487
|
+
return Parser;
|
|
488
|
+
}());
|
|
489
|
+
exports["default"] = Parser;
|
package/dist/token.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
exports.__esModule = true;
|
|
3
|
+
exports.inverseLookup = exports.lookup = exports.notParam = exports.Token = void 0;
|
|
4
|
+
var Token;
|
|
5
|
+
(function (Token) {
|
|
6
|
+
Token[Token["Illegal"] = 0] = "Illegal";
|
|
7
|
+
Token[Token["EndOfFile"] = 1] = "EndOfFile";
|
|
8
|
+
Token[Token["Real"] = 2] = "Real";
|
|
9
|
+
Token[Token["NNInteger"] = 3] = "NNInteger";
|
|
10
|
+
Token[Token["Id"] = 4] = "Id";
|
|
11
|
+
Token[Token["OpenQASM"] = 5] = "OpenQASM";
|
|
12
|
+
Token[Token["Semicolon"] = 6] = "Semicolon";
|
|
13
|
+
Token[Token["Comma"] = 7] = "Comma";
|
|
14
|
+
Token[Token["LParen"] = 8] = "LParen";
|
|
15
|
+
Token[Token["LSParen"] = 9] = "LSParen";
|
|
16
|
+
Token[Token["LCParen"] = 10] = "LCParen";
|
|
17
|
+
Token[Token["RParen"] = 11] = "RParen";
|
|
18
|
+
Token[Token["RSParen"] = 12] = "RSParen";
|
|
19
|
+
Token[Token["RCParen"] = 13] = "RCParen";
|
|
20
|
+
Token[Token["Arrow"] = 14] = "Arrow";
|
|
21
|
+
Token[Token["Equals"] = 15] = "Equals";
|
|
22
|
+
Token[Token["Plus"] = 16] = "Plus";
|
|
23
|
+
Token[Token["Minus"] = 17] = "Minus";
|
|
24
|
+
Token[Token["Times"] = 18] = "Times";
|
|
25
|
+
Token[Token["Divide"] = 19] = "Divide";
|
|
26
|
+
Token[Token["Power"] = 20] = "Power";
|
|
27
|
+
Token[Token["Sin"] = 21] = "Sin";
|
|
28
|
+
Token[Token["Cos"] = 22] = "Cos";
|
|
29
|
+
Token[Token["Tan"] = 23] = "Tan";
|
|
30
|
+
Token[Token["Exp"] = 24] = "Exp";
|
|
31
|
+
Token[Token["Ln"] = 25] = "Ln";
|
|
32
|
+
Token[Token["Sqrt"] = 26] = "Sqrt";
|
|
33
|
+
Token[Token["Pi"] = 27] = "Pi";
|
|
34
|
+
Token[Token["QReg"] = 28] = "QReg";
|
|
35
|
+
Token[Token["CReg"] = 29] = "CReg";
|
|
36
|
+
Token[Token["Barrier"] = 30] = "Barrier";
|
|
37
|
+
Token[Token["Gate"] = 31] = "Gate";
|
|
38
|
+
Token[Token["Measure"] = 32] = "Measure";
|
|
39
|
+
Token[Token["Reset"] = 33] = "Reset";
|
|
40
|
+
Token[Token["Include"] = 34] = "Include";
|
|
41
|
+
Token[Token["If"] = 35] = "If";
|
|
42
|
+
Token[Token["String"] = 36] = "String";
|
|
43
|
+
})(Token || (Token = {}));
|
|
44
|
+
exports.Token = Token;
|
|
45
|
+
var lookupMap = {
|
|
46
|
+
'if': Token.If,
|
|
47
|
+
'sin': Token.Sin,
|
|
48
|
+
'cos': Token.Cos,
|
|
49
|
+
'tan': Token.Tan,
|
|
50
|
+
'exp': Token.Exp,
|
|
51
|
+
'ln': Token.Ln,
|
|
52
|
+
'sqrt': Token.Sqrt,
|
|
53
|
+
'pi': Token.Pi,
|
|
54
|
+
'+': Token.Plus,
|
|
55
|
+
'-': Token.Minus,
|
|
56
|
+
'/': Token.Divide,
|
|
57
|
+
'*': Token.Times,
|
|
58
|
+
'^': Token.Power
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Returns the token that represents a given string.
|
|
62
|
+
* @param ident - The string.
|
|
63
|
+
* @return The corresponding token.
|
|
64
|
+
*/
|
|
65
|
+
function lookup(ident) {
|
|
66
|
+
return ident in lookupMap ? lookupMap[ident] : Token.Id;
|
|
67
|
+
}
|
|
68
|
+
exports.lookup = lookup;
|
|
69
|
+
/**
|
|
70
|
+
* Returns the string representation of a token.
|
|
71
|
+
* @param tokens - The token.
|
|
72
|
+
* @return The string representation of the token.
|
|
73
|
+
*/
|
|
74
|
+
function inverseLookup(token) {
|
|
75
|
+
return Object.keys(lookupMap).find(function (ident) { return lookupMap[ident] == token; });
|
|
76
|
+
}
|
|
77
|
+
exports.inverseLookup = inverseLookup;
|
|
78
|
+
/**
|
|
79
|
+
* Determines whether a token denotes a parameter.
|
|
80
|
+
* @param tokens - The token.
|
|
81
|
+
* @return Whether the token does NOT denote a parameter.
|
|
82
|
+
*/
|
|
83
|
+
function notParam(token) {
|
|
84
|
+
if (token == Token.NNInteger || token == Token.Real || token == Token.Id || this.inverseLookup(token)) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
exports.notParam = notParam;
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "qasm-ts",
|
|
3
|
+
"version": "1.1.1",
|
|
4
|
+
"description": "QASM, the low-level programming language for quantum circuit specification, implemented in TypeScript.",
|
|
5
|
+
"main": "dist/main.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "ts-node node_modules/jasmine/bin/jasmine"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/comp-phys-marc/qasm-ts.git"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"Quantum",
|
|
15
|
+
"Programming",
|
|
16
|
+
"QASM",
|
|
17
|
+
"OpenQASM",
|
|
18
|
+
"Language"
|
|
19
|
+
],
|
|
20
|
+
"author": "Marcus Edwards",
|
|
21
|
+
"license": "Apache-2.0",
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/comp-phys-marc/qasm-ts/issues"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://github.com/comp-phys-marc/qasm-ts#readme",
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"path": "^0.12.7",
|
|
28
|
+
"ts-node": "^8.3.0",
|
|
29
|
+
"typescript": "^3.5.3"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/jasmine": "^3.4.0",
|
|
33
|
+
"@types/node": "^12.7.2",
|
|
34
|
+
"jasmine": "^3.4.0"
|
|
35
|
+
}
|
|
36
|
+
}
|