37 (std::vector<std::string>, comments)(
double, version)(
38 std::vector<std::string>,
39 includes)(std::vector<qasm::StatementType>,
44void printd(
const double &v) { std::cout <<
"version: " << v <<
"\n"; }
46void prints(
const std::string &s) { std::cout <<
"statement: " << s <<
"\n"; }
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];
65 program = comments >> (-version) >> includes >> statements;
67 statements %= *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))] |
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];
83 opaque %= qi::omit[qi::lexeme[qi::lit(
"opaque") >> qi::space]] >>
85 ((
'(' >> idList >>
')') | (
'(' >> qi::eps >>
')') | qi::eps) >>
92 gatedecl %= qi::omit[qi::lexeme[qi::lit(
"gate") >> qi::space]] >>
94 ((
'(' >> idList >>
')') | (
'(' >> qi::eps >>
')') | qi::eps) >>
98 qi::omit[qi::lexeme[qi::lit(
"barrier") >> qi::space]] >> idList >>
';';
99 gatedeclop %= simplebarrier | (uop >>
';');
101 gatedeclfull %= gatedecl >> *gatedeclop >>
'}';
105 condOp %= qi::lit(
"if") >>
'(' >> identifier >> qi::lit(
"==") >> qi::int_ >>
109 (identifier >> mixedList) | (identifier >>
'(' >>
')' >> mixedList);
110 expGatecall %= identifier >>
'(' >> expList >>
')' >> mixedList;
112 gatecall %= simpleGatecall | expGatecall;
115 (qi::lit(
"U") | qi::lit(
"u")) >>
'(' >> expList >>
')' >> argument;
117 qi::omit[qi::lexeme[(qi::lit(
"CX") | qi::lit(
"cx")) >> qi::space]] >>
118 argument >>
',' >> argument;
120 uop %= cxgateCall | ugateCall | gatecall;
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))] |
127 AddGate(qi::_1, std::ref(qreg_map), std::ref(opaqueGates),
128 std::ref(definedGates))]) >>
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)];
140 decl %= (qregdecl | cregdecl) >>
';';
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;
146 qi::omit[qi::lexeme[qi::lit(
"barrier") >> qi::space]] >> mixedList;
150 idList %= identifier %
',';
152 indexedId = (identifier >>
'[' >> qi::int_ >>
153 ']')[qi::_val = MakeIndexedId(qi::_1, qi::_2)];
155 argument %= indexedId | identifier;
156 mixedList %= argument %
',';
161 expList %= expression %
',';
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];
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 >>
')';
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];
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_")]);
197 BOOST_SPIRIT_DEBUG_NODE(version);
198 BOOST_SPIRIT_DEBUG_NODE(program);
199 BOOST_SPIRIT_DEBUG_NODE(statement);
200 BOOST_SPIRIT_DEBUG_NODE(statements);
202 BOOST_SPIRIT_DEBUG_NODE(opaque);
204 BOOST_SPIRIT_DEBUG_NODE(gatedecl);
205 BOOST_SPIRIT_DEBUG_NODE(simplebarrier);
206 BOOST_SPIRIT_DEBUG_NODE(gatedeclop);
207 BOOST_SPIRIT_DEBUG_NODE(gatedeclfull);
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);
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);
225 BOOST_SPIRIT_DEBUG_NODE(idList);
226 BOOST_SPIRIT_DEBUG_NODE(indexedId);
227 BOOST_SPIRIT_DEBUG_NODE(argument);
228 BOOST_SPIRIT_DEBUG_NODE(mixedList);
230 BOOST_SPIRIT_DEBUG_NODE(expList);
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);
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);
248 qi::on_error<qi::fail>(expression, error_handler(qi::_4, qi::_3, qi::_2));
250 qi::on_error<qi::fail>(program, error_handler(qi::_4, qi::_3, qi::_2));
259 definedGates.clear();
262 qi::rule<Iterator, Program(), Skipper> program;
264 qi::rule<Iterator, double(), Skipper> version;
266 qi::rule<Iterator, StatementType, Skipper> statement;
267 qi::rule<Iterator, std::vector<StatementType>(), Skipper> statements;
269 qi::rule<Iterator, OpaqueDeclType(), Skipper> opaque;
271 qi::rule<Iterator, GateDeclType(), Skipper> gatedecl;
272 qi::rule<Iterator, SimpleBarrierType(), Skipper> simplebarrier;
273 qi::rule<Iterator, GateDeclOpType(), Skipper> gatedeclop;
275 boost::fusion::vector<GateDeclType, std::vector<GateDeclOpType>>(),
279 qi::rule<Iterator, CondOpType(), Skipper> condOp;
281 qi::rule<Iterator, UGateCallType, Skipper> ugateCall;
282 qi::rule<Iterator, CXGateCallType, Skipper> cxgateCall;
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;
290 qi::rule<Iterator, IndexedId(), Skipper> qregdecl;
291 qi::rule<Iterator, IndexedId(), Skipper> cregdecl;
292 qi::rule<Iterator, IndexedId(), Skipper> decl;
294 qi::rule<Iterator, ResetType(), Skipper> resetOp;
295 qi::rule<Iterator, MeasureType(), Skipper> measureOp;
296 qi::rule<Iterator, BarrierType(), Skipper> barrierOp;
298 qi::rule<Iterator, std::vector<std::string>(), Skipper> idList;
300 qi::rule<Iterator, IndexedId(), Skipper> indexedId;
302 qi::rule<Iterator, ArgumentType(), Skipper> argument;
303 qi::rule<Iterator, MixedListType(), Skipper> mixedList;
305 qi::rule<Iterator, std::vector<Expression>(), Skipper> expList;
307 qi::rule<Iterator, Expression(), Skipper> expression, group, product, factor,
309 qi::rule<Iterator, UnaryOperator(), Skipper> unary;
310 qi::rule<Iterator, Constant(), Skipper> constant;
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;
321 int creg_counter = 0;
322 int qreg_counter = 0;
324 std::unordered_map<std::string, IndexedId> creg_map;
325 std::unordered_map<std::string, IndexedId> qreg_map;
327 std::unordered_map<std::string, StatementType> opaqueGates;
328 std::unordered_map<std::string, StatementType> definedGates;