Maestro 0.1.0
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
qasm.h
Go to the documentation of this file.
1
11
12#pragma once
13
14#ifndef _QASM_H_
15#define _QASM_H_
16
17#include "SyntaxTree.h"
18
19namespace qasm {
20
22 template <typename, typename, typename> struct result {
23 typedef void type;
24 };
25
26 template <typename Iterator>
27 void operator()(qi::info const &what, Iterator err_pos, Iterator last) const {
28 std::cout << "Error! Expecting " << what << " here: \""
29 << std::string(err_pos, last) << "\"\n";
30 }
31};
32
33phx::function<error_handler_> const error_handler = error_handler_();
34} // namespace qasm
35
37 (std::vector<std::string>, comments)(double, version)(
38 std::vector<std::string>,
39 includes)(std::vector<qasm::StatementType>,
40 statements))
41
42namespace qasm {
43
44void printd(const double &v) { std::cout << "version: " << v << "\n"; }
45
46void prints(const std::string &s) { std::cout << "statement: " << s << "\n"; }
47
48// TODO:
49// 1. 'opaque' will be parsed but ignored in the first phase.
50// 2. 'barrier' will be parsed, but ignored in the first phase. In this case we
51// might want to add a 'barrier' operation in our circuit. For now it's not
52// existent. Adding it would have implications in circuit execution with the
53// discrete event simulator and also in the transpiler functionality.
54
55template <typename Iterator = std::string::iterator,
56 typename Skipper = ascii::space_type>
57struct QasmGrammar : qi::grammar<Iterator, Program(), Skipper> {
58 QasmGrammar() : QasmGrammar::base_type{program} {
59 version = (qi::omit[qi::lexeme[qi::lit("OPENQASM") >> qi::space]] >>
60 qi::double_ >> ';')[qi::_val = qi::_1];
61
62 comments %= *comment;
63 includes %= *include;
64
65 program = comments >> (-version) >> includes >> statements;
66
67 statements %= *statement;
68
69 statement =
70 comment[qi::_val = AddComment(qi::_1)] |
71 decl[qi::_val = AddDeclaration(qi::_1)] |
72 opaque[qi::_val = AddOpaqueDecl(qi::_1, std::ref(opaqueGates),
73 std::ref(qreg_map))] |
74 condOp[qi::_val =
75 AddCondQop(qi::_1, std::ref(qreg_map), std::ref(creg_map),
76 std::ref(opaqueGates), std::ref(definedGates))] |
77 gatedeclfull[qi::_val = AddGateDecl(qi::_1, std::ref(definedGates))] |
78 qop[qi::_val = qi::_1];
79
80 // this is the opaque gate declaration, it will be simply ignored (in 3.0 is
81 // supposed to be ignored)
82
83 opaque %= qi::omit[qi::lexeme[qi::lit("opaque") >> qi::space]] >>
84 identifier >>
85 (('(' >> idList >> ')') | ('(' >> qi::eps >> ')') | qi::eps) >>
86 idList >> ';';
87
88 // **************************************************************************************************************************************************************
89
90 // some of the more complex things
91
92 gatedecl %= qi::omit[qi::lexeme[qi::lit("gate") >> qi::space]] >>
93 identifier >>
94 (('(' >> idList >> ')') | ('(' >> qi::eps >> ')') | qi::eps) >>
95 idList >> '{';
96
97 simplebarrier %=
98 qi::omit[qi::lexeme[qi::lit("barrier") >> qi::space]] >> idList >> ';';
99 gatedeclop %= simplebarrier | (uop >> ';');
100
101 gatedeclfull %= gatedecl >> *gatedeclop >> '}';
102
103 // **************************************************************************************************************************************************************
104
105 condOp %= qi::lit("if") >> '(' >> identifier >> qi::lit("==") >> qi::int_ >>
106 ')' >> qop;
107
108 simpleGatecall %=
109 (identifier >> mixedList) | (identifier >> '(' >> ')' >> mixedList);
110 expGatecall %= identifier >> '(' >> expList >> ')' >> mixedList;
111
112 gatecall %= simpleGatecall | expGatecall;
113
114 ugateCall %=
115 (qi::lit("U") | qi::lit("u")) >> '(' >> expList >> ')' >> argument;
116 cxgateCall %=
117 qi::omit[qi::lexeme[(qi::lit("CX") | qi::lit("cx")) >> qi::space]] >>
118 argument >> ',' >> argument;
119
120 uop %= cxgateCall | ugateCall | gatecall;
121
122 qop = (measureOp[qi::_val = AddMeasure(qi::_1, std::ref(creg_map),
123 std::ref(qreg_map))] |
124 resetOp[qi::_val = AddReset(qi::_1, std::ref(qreg_map))] |
125 barrierOp[qi::_val = AddBarrier(qi::_1, std::ref(qreg_map))] |
126 uop[qi::_val =
127 AddGate(qi::_1, std::ref(qreg_map), std::ref(opaqueGates),
128 std::ref(definedGates))]) >>
129 ';';
130
131 // **************************************************************************************************************************************************************
132
133 qregdecl %= (qi::omit[qi::lexeme[qi::lit("qreg") >> qi::space]] >>
134 indexedId)[qi::_val = AddQreg(std::ref(qreg_counter),
135 std::ref(qreg_map), qi::_1)];
136 cregdecl %= (qi::omit[qi::lexeme[qi::lit("creg") >> qi::space]] >>
137 indexedId)[qi::_val = AddCreg(std::ref(creg_counter),
138 std::ref(creg_map), qi::_1)];
139
140 decl %= (qregdecl | cregdecl) >> ';';
141
142 measureOp %= qi::omit[qi::lexeme[qi::lit("measure") >> qi::space]] >>
143 argument >> qi::lit("->") >> argument;
144 resetOp %= qi::omit[qi::lexeme[qi::lit("reset") >> qi::space]] >> argument;
145 barrierOp %=
146 qi::omit[qi::lexeme[qi::lit("barrier") >> qi::space]] >> mixedList;
147
148 // **************************************************************************************************************************************************************
149
150 idList %= identifier % ',';
151
152 indexedId = (identifier >> '[' >> qi::int_ >>
153 ']')[qi::_val = MakeIndexedId(qi::_1, qi::_2)];
154
155 argument %= indexedId | identifier;
156 mixedList %= argument % ',';
157
158 // **************************************************************************************************************************************************************
159 // expressions
160
161 expList %= expression % ',';
162
163 expression = (product >> qi::char_("+-") >>
164 expression)[qi::_val = MakeBinary(qi::_2, qi::_1, qi::_3)] |
165 product[qi::_val = qi::_1];
166 product = (factor2 >> qi::char_("*/") >>
167 product)[qi::_val = MakeBinary(qi::_2, qi::_1, qi::_3)] |
168 factor2[qi::_val = qi::_1];
169
170 factor2 =
171 (factor >> '^' >> factor2)[qi::_val = MakeBinary('^', qi::_1, qi::_2)] |
172 factor[qi::_val = qi::_1];
173 unary = (qi::char_("+-") >> factor)[qi::_val = MakeUnary(qi::_1, qi::_2)];
174 factor = group[qi::_val = qi::_1] | constant[qi::_val = qi::_1] |
175 unary[qi::_val = qi::_1] |
176 (funcName >> group)[qi::_val = MakeFunction(qi::_1, qi::_2)] |
177 identifier[qi::_val = MakeVariable(qi::_1)];
178 constant = qi::double_[qi::_val = MakeConstant(qi::_1)] |
179 qi::int_[qi::_val = MakeConstant(qi::_1)] |
180 pi[qi::_val = MakeConstant(qi::_1)];
181 group %= '(' >> expression >> ')';
182
183 funcName %= qi::string("sin") | qi::string("cos") | qi::string("tan") |
184 qi::string("exp") | qi::string("ln") | qi::string("sqrt");
185 pi %= qi::lit("pi")[qi::_val = M_PI];
186
187 // **************************************************************************************************************************************************************
188
189 // very basic stuff
190 comment %= qi::lexeme[qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol];
191 quoted_string %= qi::lexeme['"' >> +(qi::char_ - '"') >> '"'];
192 include %= qi::omit[qi::lexeme[qi::lit("include") >> qi::space]] >>
193 quoted_string >> ';';
194 identifier %= (qi::lexeme[qi::char_("a-z") >> *qi::char_("a-zA-Z0-9_")]);
195
196 // Debugging and error handling and reporting support.
197 BOOST_SPIRIT_DEBUG_NODE(version);
198 BOOST_SPIRIT_DEBUG_NODE(program);
199 BOOST_SPIRIT_DEBUG_NODE(statement);
200 BOOST_SPIRIT_DEBUG_NODE(statements);
201
202 BOOST_SPIRIT_DEBUG_NODE(opaque);
203
204 BOOST_SPIRIT_DEBUG_NODE(gatedecl);
205 BOOST_SPIRIT_DEBUG_NODE(simplebarrier);
206 BOOST_SPIRIT_DEBUG_NODE(gatedeclop);
207 BOOST_SPIRIT_DEBUG_NODE(gatedeclfull);
208
209 BOOST_SPIRIT_DEBUG_NODE(condOp);
210 BOOST_SPIRIT_DEBUG_NODE(simpleGatecall);
211 BOOST_SPIRIT_DEBUG_NODE(expGatecall);
212 BOOST_SPIRIT_DEBUG_NODE(gatecall);
213 BOOST_SPIRIT_DEBUG_NODE(ugateCall);
214 BOOST_SPIRIT_DEBUG_NODE(cxgateCall);
215 BOOST_SPIRIT_DEBUG_NODE(uop);
216 BOOST_SPIRIT_DEBUG_NODE(qop);
217
218 BOOST_SPIRIT_DEBUG_NODE(qregdecl);
219 BOOST_SPIRIT_DEBUG_NODE(cregdecl);
220 BOOST_SPIRIT_DEBUG_NODE(decl);
221 BOOST_SPIRIT_DEBUG_NODE(resetOp);
222 BOOST_SPIRIT_DEBUG_NODE(measureOp);
223 BOOST_SPIRIT_DEBUG_NODE(barrierOp);
224
225 BOOST_SPIRIT_DEBUG_NODE(idList);
226 BOOST_SPIRIT_DEBUG_NODE(indexedId);
227 BOOST_SPIRIT_DEBUG_NODE(argument);
228 BOOST_SPIRIT_DEBUG_NODE(mixedList);
229
230 BOOST_SPIRIT_DEBUG_NODE(expList);
231
232 BOOST_SPIRIT_DEBUG_NODE(expression);
233 BOOST_SPIRIT_DEBUG_NODE(product);
234 BOOST_SPIRIT_DEBUG_NODE(factor2);
235 BOOST_SPIRIT_DEBUG_NODE(unary);
236 BOOST_SPIRIT_DEBUG_NODE(factor);
237 BOOST_SPIRIT_DEBUG_NODE(constant);
238 BOOST_SPIRIT_DEBUG_NODE(group);
239 BOOST_SPIRIT_DEBUG_NODE(funcName);
240 BOOST_SPIRIT_DEBUG_NODE(pi);
241
242 BOOST_SPIRIT_DEBUG_NODE(comment);
243 BOOST_SPIRIT_DEBUG_NODE(quoted_string);
244 BOOST_SPIRIT_DEBUG_NODE(include);
245 BOOST_SPIRIT_DEBUG_NODE(identifier);
246
247 // Error handling
248 qi::on_error<qi::fail>(expression, error_handler(qi::_4, qi::_3, qi::_2));
249 // TODO: add more error handlers if needed
250 qi::on_error<qi::fail>(program, error_handler(qi::_4, qi::_3, qi::_2));
251 }
252
253 void clear() {
254 creg_counter = 0;
255 qreg_counter = 0;
256 creg_map.clear();
257 qreg_map.clear();
258 opaqueGates.clear();
259 definedGates.clear();
260 }
261
262 qi::rule<Iterator, Program(), Skipper> program;
263
264 qi::rule<Iterator, double(), Skipper> version;
265
266 qi::rule<Iterator, StatementType, Skipper> statement;
267 qi::rule<Iterator, std::vector<StatementType>(), Skipper> statements;
268
269 qi::rule<Iterator, OpaqueDeclType(), Skipper> opaque;
270
271 qi::rule<Iterator, GateDeclType(), Skipper> gatedecl;
272 qi::rule<Iterator, SimpleBarrierType(), Skipper> simplebarrier;
273 qi::rule<Iterator, GateDeclOpType(), Skipper> gatedeclop;
274 qi::rule<Iterator,
275 boost::fusion::vector<GateDeclType, std::vector<GateDeclOpType>>(),
276 Skipper>
277 gatedeclfull;
278
279 qi::rule<Iterator, CondOpType(), Skipper> condOp;
280
281 qi::rule<Iterator, UGateCallType, Skipper> ugateCall;
282 qi::rule<Iterator, CXGateCallType, Skipper> cxgateCall;
283
284 qi::rule<Iterator, SimpleGatecallType(), Skipper> simpleGatecall;
285 qi::rule<Iterator, ExpGatecallType(), Skipper> expGatecall;
286 qi::rule<Iterator, GatecallType(), Skipper> gatecall;
287 qi::rule<Iterator, UopType(), Skipper> uop;
288 qi::rule<Iterator, QopType(), Skipper> qop;
289
290 qi::rule<Iterator, IndexedId(), Skipper> qregdecl;
291 qi::rule<Iterator, IndexedId(), Skipper> cregdecl;
292 qi::rule<Iterator, IndexedId(), Skipper> decl;
293
294 qi::rule<Iterator, ResetType(), Skipper> resetOp;
295 qi::rule<Iterator, MeasureType(), Skipper> measureOp;
296 qi::rule<Iterator, BarrierType(), Skipper> barrierOp;
297
298 qi::rule<Iterator, std::vector<std::string>(), Skipper> idList;
299
300 qi::rule<Iterator, IndexedId(), Skipper> indexedId;
301
302 qi::rule<Iterator, ArgumentType(), Skipper> argument;
303 qi::rule<Iterator, MixedListType(), Skipper> mixedList;
304
305 qi::rule<Iterator, std::vector<Expression>(), Skipper> expList;
306
307 qi::rule<Iterator, Expression(), Skipper> expression, group, product, factor,
308 factor2;
309 qi::rule<Iterator, UnaryOperator(), Skipper> unary;
310 qi::rule<Iterator, Constant(), Skipper> constant;
311
312 qi::rule<Iterator, std::string(), Skipper> funcName;
313 qi::rule<Iterator, std::string(), Skipper> comment;
314 qi::rule<Iterator, std::vector<std::string>(), Skipper> comments;
315 qi::rule<Iterator, std::string(), Skipper> include;
316 qi::rule<Iterator, std::vector<std::string>(), Skipper> includes;
317 qi::rule<Iterator, std::string(), Skipper> quoted_string;
318 qi::rule<Iterator, std::string(), Skipper> identifier;
319 qi::rule<Iterator, double(), Skipper> pi;
320
321 int creg_counter = 0;
322 int qreg_counter = 0;
323
324 std::unordered_map<std::string, IndexedId> creg_map;
325 std::unordered_map<std::string, IndexedId> qreg_map;
326
327 std::unordered_map<std::string, StatementType> opaqueGates;
328 std::unordered_map<std::string, StatementType> definedGates;
329};
330
331} // namespace qasm
332
333#endif // !_QASM_H_
phx::function< error_handler_ > const error_handler
Definition qasm.h:33
BOOST_FUSION_ADAPT_STRUCT(qasm::Program,(std::vector< std::string >, comments)(double, version)(std::vector< std::string >, includes)(std::vector< qasm::StatementType >, statements)) namespace qasm
Definition qasm.h:36
void operator()(qi::info const &what, Iterator err_pos, Iterator last) const
Definition qasm.h:27