qasm-ts 1.1.3 → 2.1.0

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.
Files changed (203) hide show
  1. package/.eslintrc.json +13 -0
  2. package/.github/workflows/draft-pdf.yml +24 -0
  3. package/CONTRIBUTING.md +3 -0
  4. package/LICENSE +201 -0
  5. package/dist/errors.js +128 -2
  6. package/dist/lexer.js +110 -291
  7. package/dist/main.js +123 -18
  8. package/dist/parser.js +117 -482
  9. package/dist/{ast.js → qasm2/ast.js} +71 -2
  10. package/dist/qasm2/lexer.js +489 -0
  11. package/dist/qasm2/parser.js +659 -0
  12. package/dist/qasm2/token.js +160 -0
  13. package/dist/qasm3/ast.js +1081 -0
  14. package/dist/qasm3/lexer.js +673 -0
  15. package/dist/qasm3/parser.js +2083 -0
  16. package/dist/qasm3/token.js +425 -0
  17. package/dist/version.js +57 -0
  18. package/docs/assets/hierarchy.js +1 -0
  19. package/docs/custom.css +3 -0
  20. package/docs/docs-readme.md +208 -0
  21. package/docs/index.html +17 -0
  22. package/docs/typedoc/.nojekyll +1 -0
  23. package/docs/typedoc/assets/custom.css +3 -0
  24. package/docs/typedoc/assets/hierarchy.js +1 -0
  25. package/docs/typedoc/assets/highlight.css +99 -0
  26. package/docs/typedoc/assets/icons.js +18 -0
  27. package/docs/typedoc/assets/icons.svg +1 -0
  28. package/docs/typedoc/assets/main.js +60 -0
  29. package/docs/typedoc/assets/navigation.js +1 -0
  30. package/docs/typedoc/assets/search.js +1 -0
  31. package/docs/typedoc/assets/style.css +1633 -0
  32. package/docs/typedoc/classes/Error_Handling.BadArgumentError.html +12 -0
  33. package/docs/typedoc/classes/Error_Handling.BadBarrierError.html +12 -0
  34. package/docs/typedoc/classes/Error_Handling.BadClassicalTypeError.html +12 -0
  35. package/docs/typedoc/classes/Error_Handling.BadConditionalError.html +12 -0
  36. package/docs/typedoc/classes/Error_Handling.BadCregError.html +12 -0
  37. package/docs/typedoc/classes/Error_Handling.BadEqualsError.html +12 -0
  38. package/docs/typedoc/classes/Error_Handling.BadExpressionError.html +12 -0
  39. package/docs/typedoc/classes/Error_Handling.BadGateError.html +12 -0
  40. package/docs/typedoc/classes/Error_Handling.BadIncludeError.html +12 -0
  41. package/docs/typedoc/classes/Error_Handling.BadLoopError.html +12 -0
  42. package/docs/typedoc/classes/Error_Handling.BadMeasurementError.html +12 -0
  43. package/docs/typedoc/classes/Error_Handling.BadParameterError.html +12 -0
  44. package/docs/typedoc/classes/Error_Handling.BadQregError.html +12 -0
  45. package/docs/typedoc/classes/Error_Handling.BadQuantumInstructionError.html +12 -0
  46. package/docs/typedoc/classes/Error_Handling.BadStringLiteralError.html +12 -0
  47. package/docs/typedoc/classes/Error_Handling.BadSubroutineError.html +12 -0
  48. package/docs/typedoc/classes/Error_Handling.MissingBraceError.html +12 -0
  49. package/docs/typedoc/classes/Error_Handling.MissingSemicolonError.html +12 -0
  50. package/docs/typedoc/classes/Error_Handling.UnsupportedOpenQASMVersionError.html +12 -0
  51. package/docs/typedoc/classes/Version_Management.OpenQASMVersion.html +16 -0
  52. package/docs/typedoc/classes/qasm2_ast.ApplyGate.html +6 -0
  53. package/docs/typedoc/classes/qasm2_ast.AstNode.html +3 -0
  54. package/docs/typedoc/classes/qasm2_ast.Barrier.html +5 -0
  55. package/docs/typedoc/classes/qasm2_ast.CReg.html +5 -0
  56. package/docs/typedoc/classes/qasm2_ast.Cos.html +3 -0
  57. package/docs/typedoc/classes/qasm2_ast.Divide.html +3 -0
  58. package/docs/typedoc/classes/qasm2_ast.Exp.html +3 -0
  59. package/docs/typedoc/classes/qasm2_ast.Gate.html +7 -0
  60. package/docs/typedoc/classes/qasm2_ast.Id.html +4 -0
  61. package/docs/typedoc/classes/qasm2_ast.If.html +6 -0
  62. package/docs/typedoc/classes/qasm2_ast.Include.html +4 -0
  63. package/docs/typedoc/classes/qasm2_ast.Ln.html +3 -0
  64. package/docs/typedoc/classes/qasm2_ast.Measure.html +7 -0
  65. package/docs/typedoc/classes/qasm2_ast.Minus.html +3 -0
  66. package/docs/typedoc/classes/qasm2_ast.NNInteger.html +4 -0
  67. package/docs/typedoc/classes/qasm2_ast.Opaque.html +6 -0
  68. package/docs/typedoc/classes/qasm2_ast.Pi.html +3 -0
  69. package/docs/typedoc/classes/qasm2_ast.Plus.html +3 -0
  70. package/docs/typedoc/classes/qasm2_ast.Power.html +3 -0
  71. package/docs/typedoc/classes/qasm2_ast.QReg.html +5 -0
  72. package/docs/typedoc/classes/qasm2_ast.Real.html +4 -0
  73. package/docs/typedoc/classes/qasm2_ast.Sin.html +3 -0
  74. package/docs/typedoc/classes/qasm2_ast.Sqrt.html +3 -0
  75. package/docs/typedoc/classes/qasm2_ast.Tan.html +3 -0
  76. package/docs/typedoc/classes/qasm2_ast.Times.html +3 -0
  77. package/docs/typedoc/classes/qasm2_ast.Variable.html +4 -0
  78. package/docs/typedoc/classes/qasm2_ast.Version.html +4 -0
  79. package/docs/typedoc/classes/qasm2_lexer.default.html +57 -0
  80. package/docs/typedoc/classes/qasm2_parser.default.html +93 -0
  81. package/docs/typedoc/classes/qasm3_ast.AliasStatement.html +5 -0
  82. package/docs/typedoc/classes/qasm3_ast.AngleType.html +4 -0
  83. package/docs/typedoc/classes/qasm3_ast.Arithmetic.html +6 -0
  84. package/docs/typedoc/classes/qasm3_ast.ArrayAccess.html +5 -0
  85. package/docs/typedoc/classes/qasm3_ast.ArrayDeclaration.html +7 -0
  86. package/docs/typedoc/classes/qasm3_ast.ArrayInitializer.html +4 -0
  87. package/docs/typedoc/classes/qasm3_ast.ArrayReference.html +5 -0
  88. package/docs/typedoc/classes/qasm3_ast.AssignmentStatement.html +5 -0
  89. package/docs/typedoc/classes/qasm3_ast.AstNode.html +3 -0
  90. package/docs/typedoc/classes/qasm3_ast.Binary.html +6 -0
  91. package/docs/typedoc/classes/qasm3_ast.BitType.html +4 -0
  92. package/docs/typedoc/classes/qasm3_ast.BitstringLiteral.html +4 -0
  93. package/docs/typedoc/classes/qasm3_ast.BoolType.html +3 -0
  94. package/docs/typedoc/classes/qasm3_ast.BooleanLiteral.html +4 -0
  95. package/docs/typedoc/classes/qasm3_ast.BoxDefinition.html +7 -0
  96. package/docs/typedoc/classes/qasm3_ast.BranchingStatement.html +8 -0
  97. package/docs/typedoc/classes/qasm3_ast.BreakStatement.html +3 -0
  98. package/docs/typedoc/classes/qasm3_ast.CalibrationGrammarDeclaration.html +6 -0
  99. package/docs/typedoc/classes/qasm3_ast.CaseStatement.html +5 -0
  100. package/docs/typedoc/classes/qasm3_ast.Cast.html +5 -0
  101. package/docs/typedoc/classes/qasm3_ast.ClassicalDeclaration.html +7 -0
  102. package/docs/typedoc/classes/qasm3_ast.ClassicalType.html +3 -0
  103. package/docs/typedoc/classes/qasm3_ast.ComplexType.html +6 -0
  104. package/docs/typedoc/classes/qasm3_ast.ContinueStatement.html +3 -0
  105. package/docs/typedoc/classes/qasm3_ast.DefaultStatement.html +4 -0
  106. package/docs/typedoc/classes/qasm3_ast.DurationLiteral.html +5 -0
  107. package/docs/typedoc/classes/qasm3_ast.DurationOf.html +4 -0
  108. package/docs/typedoc/classes/qasm3_ast.DurationType.html +3 -0
  109. package/docs/typedoc/classes/qasm3_ast.Euler.html +3 -0
  110. package/docs/typedoc/classes/qasm3_ast.Expression.html +3 -0
  111. package/docs/typedoc/classes/qasm3_ast.ExternSignature.html +8 -0
  112. package/docs/typedoc/classes/qasm3_ast.FloatLiteral.html +4 -0
  113. package/docs/typedoc/classes/qasm3_ast.FloatType.html +6 -0
  114. package/docs/typedoc/classes/qasm3_ast.ForLoopStatement.html +12 -0
  115. package/docs/typedoc/classes/qasm3_ast.HardwareQubit.html +5 -0
  116. package/docs/typedoc/classes/qasm3_ast.IODeclaration.html +5 -0
  117. package/docs/typedoc/classes/qasm3_ast.Identifier.html +4 -0
  118. package/docs/typedoc/classes/qasm3_ast.ImaginaryLiteral.html +4 -0
  119. package/docs/typedoc/classes/qasm3_ast.Include.html +6 -0
  120. package/docs/typedoc/classes/qasm3_ast.IndexSet.html +5 -0
  121. package/docs/typedoc/classes/qasm3_ast.IntType.html +4 -0
  122. package/docs/typedoc/classes/qasm3_ast.IntegerLiteral.html +4 -0
  123. package/docs/typedoc/classes/qasm3_ast.MathFunction.html +5 -0
  124. package/docs/typedoc/classes/qasm3_ast.NumericLiteral.html +4 -0
  125. package/docs/typedoc/classes/qasm3_ast.Parameters.html +4 -0
  126. package/docs/typedoc/classes/qasm3_ast.Pi.html +3 -0
  127. package/docs/typedoc/classes/qasm3_ast.ProgramBlock.html +7 -0
  128. package/docs/typedoc/classes/qasm3_ast.QuantumBarrier.html +6 -0
  129. package/docs/typedoc/classes/qasm3_ast.QuantumBlock.html +6 -0
  130. package/docs/typedoc/classes/qasm3_ast.QuantumDeclaration.html +8 -0
  131. package/docs/typedoc/classes/qasm3_ast.QuantumDelay.html +5 -0
  132. package/docs/typedoc/classes/qasm3_ast.QuantumGateCall.html +9 -0
  133. package/docs/typedoc/classes/qasm3_ast.QuantumGateDefinition.html +9 -0
  134. package/docs/typedoc/classes/qasm3_ast.QuantumGateModifier.html +5 -0
  135. package/docs/typedoc/classes/qasm3_ast.QuantumMeasurement.html +6 -0
  136. package/docs/typedoc/classes/qasm3_ast.QuantumMeasurementAssignment.html +8 -0
  137. package/docs/typedoc/classes/qasm3_ast.QuantumReset.html +4 -0
  138. package/docs/typedoc/classes/qasm3_ast.Range.html +6 -0
  139. package/docs/typedoc/classes/qasm3_ast.ReturnStatement.html +4 -0
  140. package/docs/typedoc/classes/qasm3_ast.SizeOf.html +5 -0
  141. package/docs/typedoc/classes/qasm3_ast.Statement.html +12 -0
  142. package/docs/typedoc/classes/qasm3_ast.StretchType.html +3 -0
  143. package/docs/typedoc/classes/qasm3_ast.SubroutineBlock.html +6 -0
  144. package/docs/typedoc/classes/qasm3_ast.SubroutineCall.html +5 -0
  145. package/docs/typedoc/classes/qasm3_ast.SubroutineDefinition.html +10 -0
  146. package/docs/typedoc/classes/qasm3_ast.SubscriptedIdentifier.html +5 -0
  147. package/docs/typedoc/classes/qasm3_ast.SwitchStatement.html +6 -0
  148. package/docs/typedoc/classes/qasm3_ast.Tau.html +3 -0
  149. package/docs/typedoc/classes/qasm3_ast.TrigFunction.html +5 -0
  150. package/docs/typedoc/classes/qasm3_ast.UIntType.html +4 -0
  151. package/docs/typedoc/classes/qasm3_ast.Unary.html +5 -0
  152. package/docs/typedoc/classes/qasm3_ast.Version.html +6 -0
  153. package/docs/typedoc/classes/qasm3_ast.WhileLoopStatement.html +6 -0
  154. package/docs/typedoc/classes/qasm3_lexer.default.html +71 -0
  155. package/docs/typedoc/classes/qasm3_parser.default.html +237 -0
  156. package/docs/typedoc/enums/Version_Management.OpenQASMMajorVersion.html +4 -0
  157. package/docs/typedoc/enums/qasm2_token.Token.html +42 -0
  158. package/docs/typedoc/enums/qasm3_ast.ArithmeticOp.html +9 -0
  159. package/docs/typedoc/enums/qasm3_ast.ArrayReferenceModifier.html +4 -0
  160. package/docs/typedoc/enums/qasm3_ast.BinaryOp.html +15 -0
  161. package/docs/typedoc/enums/qasm3_ast.DurationUnit.html +7 -0
  162. package/docs/typedoc/enums/qasm3_ast.IOModifier.html +4 -0
  163. package/docs/typedoc/enums/qasm3_ast.MathFunctionTypes.html +12 -0
  164. package/docs/typedoc/enums/qasm3_ast.QuantumGateModifierName.html +6 -0
  165. package/docs/typedoc/enums/qasm3_ast.TrigFunctionTypes.html +8 -0
  166. package/docs/typedoc/enums/qasm3_ast.UnaryOp.html +5 -0
  167. package/docs/typedoc/enums/qasm3_token.Token.html +113 -0
  168. package/docs/typedoc/functions/Lexing.lex.html +24 -0
  169. package/docs/typedoc/functions/Main_Functions.parseFile.html +13 -0
  170. package/docs/typedoc/functions/Main_Functions.parseString.html +19 -0
  171. package/docs/typedoc/functions/Parsing.parse.html +15 -0
  172. package/docs/typedoc/functions/qasm2_token.inverseLookup.html +3 -0
  173. package/docs/typedoc/functions/qasm2_token.lookup.html +4 -0
  174. package/docs/typedoc/functions/qasm2_token.notParam.html +3 -0
  175. package/docs/typedoc/functions/qasm3_token.inverseLookup.html +9 -0
  176. package/docs/typedoc/functions/qasm3_token.lookup.html +10 -0
  177. package/docs/typedoc/functions/qasm3_token.notParam.html +11 -0
  178. package/docs/typedoc/hierarchy.html +1 -0
  179. package/docs/typedoc/index.html +76 -0
  180. package/docs/typedoc/modules/Error_Handling.html +5 -0
  181. package/docs/typedoc/modules/Lexing.html +20 -0
  182. package/docs/typedoc/modules/Main_Functions.html +2 -0
  183. package/docs/typedoc/modules/Parsing.html +24 -0
  184. package/docs/typedoc/modules/Version_Management.html +8 -0
  185. package/docs/typedoc/modules/qasm2_ast.html +22 -0
  186. package/docs/typedoc/modules/qasm2_lexer.html +24 -0
  187. package/docs/typedoc/modules/qasm2_parser.html +21 -0
  188. package/docs/typedoc/modules/qasm2_token.html +15 -0
  189. package/docs/typedoc/modules/qasm3_ast.html +26 -0
  190. package/docs/typedoc/modules/qasm3_lexer.html +25 -0
  191. package/docs/typedoc/modules/qasm3_parser.html +25 -0
  192. package/docs/typedoc/modules/qasm3_token.html +15 -0
  193. package/docs/typedoc/modules.html +1 -0
  194. package/docs/typedoc/types/Error_Handling.ReturnErrorConstructor.html +2 -0
  195. package/docs/typedoc.json +47 -0
  196. package/package.json +10 -5
  197. package/paper/jats/paper.jats +464 -0
  198. package/paper/main.bib +191 -0
  199. package/paper/paper.md +166 -0
  200. package/paper/paper.pdf +0 -0
  201. package/readme.md +117 -47
  202. package/dist/example.js +0 -22
  203. package/dist/token.js +0 -89
package/dist/parser.js CHANGED
@@ -1,489 +1,124 @@
1
1
  "use strict";
2
- exports.__esModule = true;
3
- var token_1 = require("./token");
2
+ /**
3
+ * Main parser interface for generating AST from tokens
4
+ *
5
+ * The parser is responsible for transforming a stream of tokens into an Abstract
6
+ * Syntax Tree (AST) that represents the structure of the OpenQASM program. It acts
7
+ * as a dispatcher, selecting the appropriate version-specific parser based on the
8
+ * OpenQASM version being used.
9
+ *
10
+ * The parsing process follows these steps:
11
+ * 1. Receive tokenized input from the lexer
12
+ * 2. Determine OpenQASM version (2.0 or 3.0)
13
+ * 3. Select appropriate parser implementation
14
+ * 4. Generate version-specific AST nodes
15
+ *
16
+ * The specific Parser implementations can be found at:
17
+ * - {@link Qasm3Parser}
18
+ * - {@link Qasm2Parser}
19
+ *
20
+ * @module Parsing
21
+ *
22
+ * @example Basic parsing workflow
23
+ * ```typescript
24
+ * import { lex } from './lexer';
25
+ * import { parse } from './parser';
26
+ *
27
+ * const qasmCode = 'OPENQASM 3.0; h q[0];';
28
+ * const tokens = lex(qasmCode, undefined, 3);
29
+ * const ast = parse(tokens, 3);
30
+ * console.log(ast); // Array of AST nodes
31
+ * ```
32
+ *
33
+ * @example Version-specific parsing
34
+ * ```typescript
35
+ * // Parse as OpenQASM 2.0
36
+ * const ast2 = parse(tokens, 2);
37
+ *
38
+ * // Parse as OpenQASM 3.0
39
+ * const ast3 = parse(tokens, 3);
40
+ *
41
+ * // Use OpenQASMVersion object
42
+ * const version = new OpenQASMVersion(3, 0);
43
+ * const ast = parse(tokens, version);
44
+ * ```
45
+ */
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ exports.parse = parse;
48
+ var parser_1 = require("./qasm2/parser");
49
+ var parser_2 = require("./qasm3/parser");
50
+ var version_1 = require("./version");
4
51
  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;
52
+ /**
53
+ * Parses an array of tokens into an Abstract Syntax Tree (AST).
54
+ *
55
+ * This is the main entry point for parsing tokenized OpenQASM code. It automatically
56
+ * selects the appropriate parser implementation based on the specified version and
57
+ * returns an AST that can be used for further analysis, compilation, or execution.
58
+ *
59
+ * @group Parsing
60
+ * @param tokens - Array of tokens generated by the lexer
61
+ * @param version - OpenQASM version to use for parsing (defaults to 3.0)
62
+ * @returns Abstract Syntax Tree representing the parsed program
63
+ * @throws {UnsupportedOpenQASMVersionError} When an unsupported version is specified
64
+ *
65
+ * @example Parse OpenQASM 3.0 tokens
66
+ * ```typescript
67
+ * const tokens = lex('OPENQASM 3.0; qubit q; h q;');
68
+ * const ast = parse(tokens, 3);
69
+ * // Returns array of OpenQASM 3.0 AST nodes
70
+ * ```
71
+ *
72
+ * @example Parse OpenQASM 2.0 tokens
73
+ * ```typescript
74
+ * const tokens = lex('OPENQASM 2.0; qreg q[1]; h q[0];');
75
+ * const ast = parse(tokens, 2);
76
+ * // Returns array of OpenQASM 2.0 AST nodes
77
+ * ```
78
+ */
79
+ function parse(tokens, version) {
80
+ var parser;
81
+ var castTokens;
82
+ if (version instanceof version_1.OpenQASMVersion) {
83
+ switch (version.major) {
84
+ case version_1.OpenQASMMajorVersion.Version2:
85
+ castTokens = tokens;
86
+ parser = new parser_1.default(castTokens);
143
87
  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])) {
88
+ case version_1.OpenQASMMajorVersion.Version3:
89
+ castTokens = tokens;
90
+ parser = new parser_1.default(castTokens);
319
91
  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);
92
+ default:
93
+ throw new errors_1.UnsupportedOpenQASMVersionError("Unsupported OpenQASM version detected: ".concat(version.major));
334
94
  }
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])) {
95
+ }
96
+ else if (typeof version === "number") {
97
+ switch (version) {
98
+ case 2:
99
+ castTokens = tokens;
100
+ parser = new parser_1.default(castTokens);
361
101
  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++;
102
+ case 3:
103
+ castTokens = tokens;
104
+ parser = new parser_2.default(castTokens);
105
+ break;
106
+ default:
107
+ throw new errors_1.UnsupportedOpenQASMVersionError("Unsupported OpenQASM version detected: ".concat(version));
481
108
  }
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;
109
+ }
110
+ else if (version === version_1.OpenQASMMajorVersion.Version2) {
111
+ castTokens = tokens;
112
+ parser = new parser_1.default(castTokens);
113
+ }
114
+ else if (version === version_1.OpenQASMMajorVersion.Version3) {
115
+ castTokens = tokens;
116
+ parser = new parser_2.default(castTokens);
117
+ }
118
+ else {
119
+ castTokens = tokens;
120
+ parser = new parser_2.default(castTokens);
121
+ }
122
+ var ast = parser.parse();
123
+ return ast;
124
+ }