39 (std::vector<std::string>, comments)(
double, version)(
40 std::vector<std::string>,
41 includes)(std::vector<qasm::StatementType>,
46void printd(
const double &v) { std::cout <<
"version: " << v <<
"\n"; }
48void prints(
const std::string &s) { std::cout <<
"statement: " << s <<
"\n"; }
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];
67 program = comments >> (-version) >> includes >> statements;
69 statements %= *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))] |
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];
85 opaque %= qi::omit[qi::lexeme[qi::lit(
"opaque") >> qi::space]] >>
87 ((
'(' >> idList >>
')') | (
'(' >> qi::eps >>
')') | qi::eps) >>
94 gatedecl %= qi::omit[qi::lexeme[qi::lit(
"gate") >> qi::space]] >>
96 ((
'(' >> idList >>
')') | (
'(' >> qi::eps >>
')') | qi::eps) >>
100 qi::omit[qi::lexeme[qi::lit(
"barrier") >> qi::space]] >> idList >>
';';
101 gatedeclop %= simplebarrier | (uop >>
';');
103 gatedeclfull %= gatedecl >> *gatedeclop >>
'}';
107 condOp %= qi::lit(
"if") >>
'(' >> identifier >> qi::lit(
"==") >> qi::int_ >>
111 (identifier >> mixedList) | (identifier >>
'(' >>
')' >> mixedList);
112 expGatecall %= identifier >>
'(' >> expList >>
')' >> mixedList;
114 gatecall %= simpleGatecall | expGatecall;
117 (qi::lit(
"U") | qi::lit(
"u")) >>
'(' >> expList >>
')' >> argument;
119 qi::omit[qi::lexeme[(qi::lit(
"CX") | qi::lit(
"cx")) >> qi::space]] >>
120 argument >>
',' >> argument;
122 uop %= cxgateCall | ugateCall | gatecall;
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))] |
129 AddGate(qi::_1, std::ref(qreg_map), std::ref(opaqueGates),
130 std::ref(definedGates))]) >>
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)];
142 decl %= (qregdecl | cregdecl) >>
';';
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;
148 qi::omit[qi::lexeme[qi::lit(
"barrier") >> qi::space]] >> mixedList;
152 idList %= identifier %
',';
154 indexedId = (identifier >>
'[' >> qi::int_ >>
155 ']')[qi::_val = MakeIndexedId(qi::_1, qi::_2)];
157 argument %= indexedId | identifier;
158 mixedList %= argument %
',';
163 expList %= expression %
',';
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];
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 >>
')';
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];
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_")]);
199 BOOST_SPIRIT_DEBUG_NODE(version);
200 BOOST_SPIRIT_DEBUG_NODE(program);
201 BOOST_SPIRIT_DEBUG_NODE(statement);
202 BOOST_SPIRIT_DEBUG_NODE(statements);
204 BOOST_SPIRIT_DEBUG_NODE(opaque);
206 BOOST_SPIRIT_DEBUG_NODE(gatedecl);
207 BOOST_SPIRIT_DEBUG_NODE(simplebarrier);
208 BOOST_SPIRIT_DEBUG_NODE(gatedeclop);
209 BOOST_SPIRIT_DEBUG_NODE(gatedeclfull);
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);
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);
227 BOOST_SPIRIT_DEBUG_NODE(idList);
228 BOOST_SPIRIT_DEBUG_NODE(indexedId);
229 BOOST_SPIRIT_DEBUG_NODE(argument);
230 BOOST_SPIRIT_DEBUG_NODE(mixedList);
232 BOOST_SPIRIT_DEBUG_NODE(expList);
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);
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);
250 qi::on_error<qi::fail>(expression, error_handler(qi::_4, qi::_3, qi::_2));
252 qi::on_error<qi::fail>(program, error_handler(qi::_4, qi::_3, qi::_2));
261 definedGates.clear();
264 qi::rule<Iterator, Program(), Skipper> program;
266 qi::rule<Iterator, double(), Skipper> version;
268 qi::rule<Iterator, StatementType, Skipper> statement;
269 qi::rule<Iterator, std::vector<StatementType>(), Skipper> statements;
271 qi::rule<Iterator, OpaqueDeclType(), Skipper> opaque;
273 qi::rule<Iterator, GateDeclType(), Skipper> gatedecl;
274 qi::rule<Iterator, SimpleBarrierType(), Skipper> simplebarrier;
275 qi::rule<Iterator, GateDeclOpType(), Skipper> gatedeclop;
277 boost::fusion::vector<GateDeclType, std::vector<GateDeclOpType>>(),
281 qi::rule<Iterator, CondOpType(), Skipper> condOp;
283 qi::rule<Iterator, UGateCallType, Skipper> ugateCall;
284 qi::rule<Iterator, CXGateCallType, Skipper> cxgateCall;
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;
292 qi::rule<Iterator, IndexedId(), Skipper> qregdecl;
293 qi::rule<Iterator, IndexedId(), Skipper> cregdecl;
294 qi::rule<Iterator, IndexedId(), Skipper> decl;
296 qi::rule<Iterator, ResetType(), Skipper> resetOp;
297 qi::rule<Iterator, MeasureType(), Skipper> measureOp;
298 qi::rule<Iterator, BarrierType(), Skipper> barrierOp;
300 qi::rule<Iterator, std::vector<std::string>(), Skipper> idList;
302 qi::rule<Iterator, IndexedId(), Skipper> indexedId;
304 qi::rule<Iterator, ArgumentType(), Skipper> argument;
305 qi::rule<Iterator, MixedListType(), Skipper> mixedList;
307 qi::rule<Iterator, std::vector<Expression>(), Skipper> expList;
309 qi::rule<Iterator, Expression(), Skipper> expression, group, product, factor,
311 qi::rule<Iterator, UnaryOperator(), Skipper> unary;
312 qi::rule<Iterator, Constant(), Skipper> constant;
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;
323 int creg_counter = 0;
324 int qreg_counter = 0;
326 std::unordered_map<std::string, IndexedId> creg_map;
327 std::unordered_map<std::string, IndexedId> qreg_map;
329 std::unordered_map<std::string, StatementType> opaqueGates;
330 std::unordered_map<std::string, StatementType> definedGates;