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