39 (std::vector<std::string>, comments)(
double, version)(
40 std::vector<std::string>,
41 includes)(std::vector<qasm::StatementType>,
46inline void printd(
const double &v) { std::cout <<
"version: " << v <<
"\n"; }
48inline void prints(
const std::string &s) {
49 std::cout <<
"statement: " << s <<
"\n";
59template <
typename Iterator>
60struct QasmSkipper : qi::grammar<Iterator> {
61 QasmSkipper() : QasmSkipper::base_type(skip) {
64 blockComment = qi::lexeme[qi::lit(
"/*") >> *(qi::char_ - qi::lit(
"*/")) >>
66 skip = ascii::space | blockComment;
69 qi::rule<Iterator> skip;
70 qi::rule<Iterator> blockComment;
73struct MakeSupportedVersionExpr {
74 template <
typename,
typename,
typename>
81 double operator()(
unsigned int major,
82 const boost::optional<unsigned int> &minor,
83 bool &isQasm3)
const {
84 if (major != 2U && major != 3U)
85 throw std::invalid_argument(
"Unsupported OpenQASM major version " +
86 std::to_string(major) +
87 ". Only versions 2.x and 3.x are supported.");
89 if (major == 2U && !minor)
90 throw std::invalid_argument(
91 "OpenQASM 2 requires an explicit minor version, as in "
94 isQasm3 = major == 3U;
95 if (!minor)
return static_cast<double>(major);
97 return std::stod(std::to_string(major) +
"." + std::to_string(*minor));
101inline phx::function<MakeSupportedVersionExpr> MakeSupportedVersion;
103struct ValidateIncludeExpr {
106 typedef std::string type;
109 std::string operator()(
const std::string &includeName)
const {
110 if (includeName !=
"qelib1.inc" && includeName !=
"stdgates.inc")
111 throw std::invalid_argument(
112 "Unsupported OpenQASM include '" + includeName +
113 "'. Only qelib1.inc and "
114 "stdgates.inc are recognized prelude markers.");
119inline phx::function<ValidateIncludeExpr> ValidateInclude;
121template <
typename Iterator = std::string::iterator,
122 typename Skipper = QasmSkipper<Iterator>>
123struct QasmGrammar : qi::grammar<Iterator, Program(), Skipper> {
124 QasmGrammar() : QasmGrammar::base_type{program} {
125 version = (qi::omit[qi::lexeme[qi::lit(
"OPENQASM") >> qi::space]] >>
126 qi::lexeme[qi::uint_ >> -(
'.' >> qi::uint_)] >>
127 ';')[qi::_val = MakeSupportedVersion(qi::_1, qi::_2,
134 unsupportedKeywords.add(
"for",
"OpenQASM 3 'for' loops are not supported.")(
135 "while",
"OpenQASM 3 'while' loops are not supported.")(
136 "def",
"OpenQASM 3 subroutine definitions ('def') are not supported.")(
137 "let",
"OpenQASM 3 register aliases ('let') are not supported.")(
139 "OpenQASM 3 duration declarations ('duration') are not supported.")(
140 "box",
"OpenQASM 3 box blocks ('box') are not supported.")(
141 "array",
"OpenQASM 3 array declarations ('array') are not supported.")(
143 "OpenQASM 3 output declarations ('output') are not supported.")(
145 "OpenQASM 3 constant declarations ('const') are not supported.")(
147 "OpenQASM 3 external subroutines ('extern') are not supported.")(
149 "OpenQASM 3 stretch declarations ('stretch') are not supported.")(
150 "pragma",
"OpenQASM 3 pragma statements are not supported.")(
152 "OpenQASM 3 calibration definitions ('defcal') are not supported.");
158 qasm3OnlyGates.add(
"phase",
"phase")(
"cphase",
"cphase")(
"gphase",
161 durationUnit.add(
"ns", 1e-9)(
"us", 1e-6)(
"ms", 1e-3)(
"s", 1.0)(
"dt", -1.0);
163 comments %= *comment;
164 includes %= *include;
168 program = comments >> (-version) >> includes >> statements;
178 *(condOpBraced[phx::insert(qi::_val, phx::end(qi::_val),
179 phx::begin(qi::_1), phx::end(qi::_1))] |
180 statement[phx::push_back(qi::_val, qi::_1)]);
183 comment[qi::_val = AddComment(qi::_1)] |
184 decl[qi::_val = AddDeclaration(qi::_1)] |
186 AddOpaqueDecl(qi::_1, std::ref(opaqueGates),
187 std::ref(qreg_map), std::ref(declarations))] |
189 AddCondQop(qi::_1, std::ref(qreg_map), std::ref(creg_map),
190 std::ref(opaqueGates), std::ref(definedGates))] |
191 gatedeclfull[qi::_val = AddGateDecl(qi::_1, std::ref(definedGates),
192 std::ref(declarations))] |
193 inputdecl[qi::_val = AddInputDecl(
194 qi::_1, std::ref(inputNames), std::ref(declarations),
195 std::ref(inputBindings), std::ref(inputValues))] |
196 unsupportedConstruct[qi::_val = qi::_1] | qop[qi::_val = qi::_1];
201 opaque %= qi::omit[qi::lexeme[qi::lit(
"opaque") >> qi::space]] >>
203 ((
'(' >> idList >>
')') | (
'(' >> qi::eps >>
')') | qi::eps) >>
210 gatedecl %= qi::omit[qi::lexeme[qi::lit(
"gate") >> qi::space]] >>
212 ((
'(' >> idList >>
')') | (
'(' >> qi::eps >>
')') | qi::eps) >>
216 qi::omit[qi::lexeme[qi::lit(
"barrier") >> qi::space]] >> idList >>
';';
217 gateBodyModifier = (+modifier)[qi::_val = RejectGateBodyModifier(qi::_1)];
218 gatedeclop %= simplebarrier | (uop >>
';') | gateBodyModifier;
220 gatedeclfull %= gatedecl >> *gatedeclop >>
'}';
226 condOp %= qi::lit(
"if") >>
'(' >> identifier >> qi::lit(
"==") >> qi::int_ >>
242 (qi::lit(
'!') >> indexedId)[qi::_val = MakeCondBitTest(qi::_1,
false)] |
243 indexedId[qi::_val = MakeCondBitTest(qi::_1,
true)];
249 (identifier >> qi::lit(
"==") >>
250 qi::int_)[qi::_val = MakeRegCondHead(qi::_1, qi::_2)] |
251 (condBitTest % qi::lit(
"&&"))[qi::_val = MakeBitCondHead(qi::_1)];
270 qi::eps(phx::ref(isQasm3)) >>
271 (qi::lit(
"if") >>
'(' >> condHead >>
')' >>
'{' >> *qop >>
'}' >>
272 -(qi::lit(
"else") >>
'{' >> *qop >>
'}'))
273 [qi::_val = AddCondQopBraced(
274 qi::_1, qi::_2, qi::_3, std::ref(qreg_map), std::ref(creg_map),
275 std::ref(opaqueGates), std::ref(definedGates))];
287 identifier >> qi::omit[-(qi::lit(
'(') >> qi::lit(
')'))] >> mixedList;
290 expGatecall %= identifier >>
'(' >> expList >>
')' >>
291 (mixedList | qi::attr(MixedListType()));
293 gatecall %= simpleGatecall | expGatecall;
304 ugateCall %= (qi::lit(
"U") | qi::lit(
"u")) >>
'(' >> expList >>
')' >>
305 argument >> !qi::lit(
',');
307 qi::omit[qi::lexeme[(qi::lit(
"CX") | qi::lit(
"cx")) >> qi::space]] >>
308 argument >>
',' >> argument >> !qi::lit(
',');
322 qasm2RejectedGate = qi::eps(!phx::ref(isQasm3)) >>
323 qi::lexeme[qasm3OnlyGates >> !qi::char_(
"a-zA-Z0-9_")]
324 [qi::_pass = RejectQasm3OnlyGate(
325 qi::_1, std::ref(definedGates))];
327 uop %= qasm2RejectedGate | cxgateCall | ugateCall | gatecall;
341 ctrlMod = (qi::lit(
"ctrl") >> -(
'(' >> expression >>
')') >>
342 '@')[qi::_val = MakeCtrlModifier(ModifierKind::Ctrl, qi::_1,
343 std::ref(inputValues))];
345 (qi::lit(
"negctrl") >> -(
'(' >> expression >>
')') >>
346 '@')[qi::_val = MakeCtrlModifier(ModifierKind::NegCtrl, qi::_1,
347 std::ref(inputValues))];
349 qi::lit(
"inv") >>
'@' >> qi::attr(ModifierType(ModifierKind::Inv));
350 powMod = (qi::lit(
"pow") >>
'(' >> expression >>
')' >>
351 '@')[qi::_val = MakePowModifier(qi::_1, std::ref(inputValues))];
354 qi::eps(phx::ref(isQasm3)) >> (ctrlMod | negctrlMod | invMod | powMod);
355 modifiers %= *modifier;
356 modifiedUop %= modifiers >> uop;
358 qop = (measureOp[qi::_val = AddMeasure(qi::_1, std::ref(creg_map),
359 std::ref(qreg_map))] |
360 measureAssignOp[qi::_val = AddMeasure(qi::_1, std::ref(creg_map),
361 std::ref(qreg_map))] |
362 measureNoTarget[qi::_val = qi::_1] |
363 resetOp[qi::_val = AddReset(qi::_1, std::ref(qreg_map))] |
364 barrierOp[qi::_val = AddBarrier(qi::_1, std::ref(qreg_map))] |
365 delayOp[qi::_val = AddDelay(qi::_1, std::ref(qreg_map))] |
366 modifiedUop[qi::_val = AddModifiedGate(
367 qi::_1, std::ref(qreg_map), std::ref(opaqueGates),
368 std::ref(definedGates), std::ref(inputValues))]) >>
373 qregdecl %= (qi::omit[qi::lexeme[qi::lit(
"qreg") >> qi::space]] >>
374 indexedId)[qi::_val = AddQreg(std::ref(qreg_counter),
376 std::ref(declarations), qi::_1)];
377 cregdecl %= (qi::omit[qi::lexeme[qi::lit(
"creg") >> qi::space]] >>
378 indexedId)[qi::_val = AddCreg(std::ref(creg_counter),
380 std::ref(declarations), qi::_1)];
391 qi::eps(phx::ref(isQasm3)) >>
392 ((qi::lit(
"qubit") >>
'[' >> qi::int_ >>
']' >>
393 identifier)[qi::_val =
394 AddQreg(std::ref(qreg_counter), std::ref(qreg_map),
395 std::ref(declarations),
396 MakeIndexedId(qi::_2, qi::_1))] |
397 (qi::omit[qi::lexeme[qi::lit(
"qubit") >> qi::space]] >> qi::attr(1) >>
398 identifier)[qi::_val =
399 AddQreg(std::ref(qreg_counter), std::ref(qreg_map),
400 std::ref(declarations),
401 MakeIndexedId(qi::_2, qi::_1))]);
403 qi::eps(phx::ref(isQasm3)) >>
404 ((qi::lit(
"bit") >>
'[' >> qi::int_ >>
']' >>
405 identifier)[qi::_val =
406 AddCreg(std::ref(creg_counter), std::ref(creg_map),
407 std::ref(declarations),
408 MakeIndexedId(qi::_2, qi::_1))] |
409 (qi::omit[qi::lexeme[qi::lit(
"bit") >> qi::space]] >> qi::attr(1) >>
410 identifier)[qi::_val =
411 AddCreg(std::ref(creg_counter), std::ref(creg_map),
412 std::ref(declarations),
413 MakeIndexedId(qi::_2, qi::_1))]);
415 decl %= (qregdecl | cregdecl | qubitdecl | bitdecl) >>
';';
428 inputType %= qi::lexeme[(qi::string(
"float") | qi::string(
"int") |
429 qi::string(
"uint") | qi::string(
"bool") |
430 qi::string(
"angle")) >>
431 !qi::char_(
"a-zA-Z0-9_")];
432 inputdecl %= qi::eps(phx::ref(isQasm3)) >>
433 qi::omit[qi::lexeme[qi::lit(
"input") >> qi::space]] >>
434 inputType >> -(
'[' >> qi::int_ >>
']') >> identifier >>
';';
447 unsupportedConstruct =
448 qi::eps(phx::ref(isQasm3)) >>
449 qi::lexeme[unsupportedKeywords >> !qi::char_(
"a-zA-Z0-9_")]
450 [qi::_val = RejectUnsupportedConstruct(qi::_1)];
452 measureOp %= qi::omit[qi::lexeme[qi::lit(
"measure") >> qi::space]] >>
453 argument >> qi::lit(
"->") >> argument;
460 qi::eps(phx::ref(isQasm3)) >>
462 qi::omit[qi::lexeme[qi::lit(
"measure") >> qi::space]] >>
463 argument)[qi::_val = phx::construct<MeasureType>(qi::_2, qi::_1)];
476 measureNoTarget = (qi::omit[qi::lexeme[qi::lit(
"measure") >> qi::space]] >>
477 argument)[qi::_val = RejectMeasureWithoutTarget(qi::_1)];
478 resetOp %= qi::omit[qi::lexeme[qi::lit(
"reset") >> qi::space]] >> argument;
492 (qi::omit[qi::lexeme[qi::lit(
"barrier") >> qi::space]] >> mixedList) |
493 (qi::eps(phx::ref(isQasm3)) >>
494 qi::omit[qi::lexeme[qi::lit(
"barrier") >> !qi::char_(
"a-zA-Z0-9_")]] >>
495 qi::attr(MixedListType()));
498 (qi::omit[qi::lexeme[qi::lit(
"delay") >> (qi::space | &qi::char_(
"[("))]] >>
499 ((
'[' >> expression >> -durationUnit >>
']') |
500 (
'(' >> expression >> -durationUnit >>
')')) >>
501 mixedList)[qi::_val = MakeDelay(qi::_1, qi::_2,
502 std::ref(inputValues))];
506 idList %= identifier %
',';
508 indexedId = (identifier >>
'[' >> qi::int_ >>
509 ']')[qi::_val = MakeIndexedId(qi::_1, qi::_2)];
511 argument %= indexedId | identifier;
512 mixedList %= argument %
',';
517 expList %= expression %
',';
534 expression = (qi::eps(phx::ref(isQasm3)) >> additive >> qi::lit(
'^') >>
535 expression)[qi::_val = MakeBinary(
'X', qi::_1, qi::_2)] |
536 additive[qi::_val = qi::_1];
549 additive = product[qi::_val = qi::_1] >>
551 product)[qi::_val = MakeBinary(qi::_1, qi::_val, qi::_2)];
552 product = unary[qi::_val = qi::_1] >>
554 unary)[qi::_val = MakeBinary(qi::_1, qi::_val, qi::_2)];
563 unary = (qi::char_(
"+-") >> unary)[qi::_val = MakeUnary(qi::_1, qi::_2)] |
564 factor2[qi::_val = qi::_1];
576 factor2 = (qi::eps(phx::ref(isQasm3)) >> factor >> qi::lit(
"**") >>
577 unary)[qi::_val = MakeBinary(
'^', qi::_1, qi::_2)] |
578 (qi::eps(!phx::ref(isQasm3)) >> factor >> qi::lit(
'^') >>
579 unary)[qi::_val = MakeBinary(
'^', qi::_1, qi::_2)] |
580 factor[qi::_val = qi::_1];
581 factor = group[qi::_val = qi::_1] | constant[qi::_val = qi::_1] |
582 (funcName >> group)[qi::_val = MakeFunction(qi::_1, qi::_2)] |
583 identifier[qi::_val = MakeVariable(qi::_1)];
592 constant = qi::real_parser<double, qi::ureal_policies<double>>()
593 [qi::_val = MakeConstant(qi::_1)] |
594 pi[qi::_val = MakeConstant(qi::_1)];
595 group %=
'(' >> expression >>
')';
597 funcName %= qi::string(
"sin") | qi::string(
"cos") | qi::string(
"tan") |
598 qi::string(
"exp") | qi::string(
"ln") | qi::string(
"sqrt");
599 pi %= qi::lit(
"pi")[qi::_val = M_PI];
604 comment %= qi::lexeme[qi::lit(
"//") >> *(qi::char_ - qi::eol) >> -qi::eol];
605 quoted_string %= qi::lexeme[
'"' >> +(qi::char_ -
'"') >>
'"'];
608 include = (qi::omit[qi::lexeme[qi::lit(
"include") >> qi::space]] >>
609 quoted_string >>
';')[qi::_val = ValidateInclude(qi::_1)];
625 qi::lexeme[((qi::eps(phx::ref(isQasm3)) >> qi::char_(
"a-zA-Z_")) |
627 *qi::char_(
"a-zA-Z0-9_")];
630 BOOST_SPIRIT_DEBUG_NODE(version);
631 BOOST_SPIRIT_DEBUG_NODE(program);
632 BOOST_SPIRIT_DEBUG_NODE(statement);
633 BOOST_SPIRIT_DEBUG_NODE(statements);
635 BOOST_SPIRIT_DEBUG_NODE(opaque);
637 BOOST_SPIRIT_DEBUG_NODE(gatedecl);
638 BOOST_SPIRIT_DEBUG_NODE(simplebarrier);
639 BOOST_SPIRIT_DEBUG_NODE(gateBodyModifier);
640 BOOST_SPIRIT_DEBUG_NODE(gatedeclop);
641 BOOST_SPIRIT_DEBUG_NODE(gatedeclfull);
643 BOOST_SPIRIT_DEBUG_NODE(condOp);
644 BOOST_SPIRIT_DEBUG_NODE(condBitTest);
645 BOOST_SPIRIT_DEBUG_NODE(condHead);
646 BOOST_SPIRIT_DEBUG_NODE(condOpBraced);
647 BOOST_SPIRIT_DEBUG_NODE(simpleGatecall);
648 BOOST_SPIRIT_DEBUG_NODE(expGatecall);
649 BOOST_SPIRIT_DEBUG_NODE(gatecall);
650 BOOST_SPIRIT_DEBUG_NODE(qasm2RejectedGate);
651 BOOST_SPIRIT_DEBUG_NODE(ugateCall);
652 BOOST_SPIRIT_DEBUG_NODE(cxgateCall);
653 BOOST_SPIRIT_DEBUG_NODE(uop);
654 BOOST_SPIRIT_DEBUG_NODE(ctrlMod);
655 BOOST_SPIRIT_DEBUG_NODE(negctrlMod);
656 BOOST_SPIRIT_DEBUG_NODE(invMod);
657 BOOST_SPIRIT_DEBUG_NODE(powMod);
658 BOOST_SPIRIT_DEBUG_NODE(modifier);
659 BOOST_SPIRIT_DEBUG_NODE(modifiers);
660 BOOST_SPIRIT_DEBUG_NODE(modifiedUop);
661 BOOST_SPIRIT_DEBUG_NODE(qop);
663 BOOST_SPIRIT_DEBUG_NODE(qregdecl);
664 BOOST_SPIRIT_DEBUG_NODE(cregdecl);
665 BOOST_SPIRIT_DEBUG_NODE(qubitdecl);
666 BOOST_SPIRIT_DEBUG_NODE(bitdecl);
667 BOOST_SPIRIT_DEBUG_NODE(decl);
668 BOOST_SPIRIT_DEBUG_NODE(inputdecl);
669 BOOST_SPIRIT_DEBUG_NODE(unsupportedConstruct);
670 BOOST_SPIRIT_DEBUG_NODE(resetOp);
671 BOOST_SPIRIT_DEBUG_NODE(measureOp);
672 BOOST_SPIRIT_DEBUG_NODE(measureAssignOp);
673 BOOST_SPIRIT_DEBUG_NODE(measureNoTarget);
674 BOOST_SPIRIT_DEBUG_NODE(barrierOp);
676 BOOST_SPIRIT_DEBUG_NODE(idList);
677 BOOST_SPIRIT_DEBUG_NODE(indexedId);
678 BOOST_SPIRIT_DEBUG_NODE(argument);
679 BOOST_SPIRIT_DEBUG_NODE(mixedList);
681 BOOST_SPIRIT_DEBUG_NODE(expList);
683 BOOST_SPIRIT_DEBUG_NODE(expression);
684 BOOST_SPIRIT_DEBUG_NODE(additive);
685 BOOST_SPIRIT_DEBUG_NODE(product);
686 BOOST_SPIRIT_DEBUG_NODE(factor2);
687 BOOST_SPIRIT_DEBUG_NODE(unary);
688 BOOST_SPIRIT_DEBUG_NODE(factor);
689 BOOST_SPIRIT_DEBUG_NODE(constant);
690 BOOST_SPIRIT_DEBUG_NODE(group);
691 BOOST_SPIRIT_DEBUG_NODE(funcName);
692 BOOST_SPIRIT_DEBUG_NODE(pi);
694 BOOST_SPIRIT_DEBUG_NODE(comment);
695 BOOST_SPIRIT_DEBUG_NODE(quoted_string);
696 BOOST_SPIRIT_DEBUG_NODE(include);
697 BOOST_SPIRIT_DEBUG_NODE(identifier);
700 qi::on_error<qi::fail>(expression, error_handler(qi::_4, qi::_3, qi::_2));
702 qi::on_error<qi::fail>(program, error_handler(qi::_4, qi::_3, qi::_2));
710 declarations.clear();
712 definedGates.clear();
714 inputBindings.clear();
719 qi::rule<Iterator, Program(), Skipper> program;
721 qi::rule<Iterator, double(), Skipper> version;
723 qi::rule<Iterator, StatementType, Skipper> statement;
724 qi::rule<Iterator, std::vector<StatementType>(), Skipper> statements;
726 qi::rule<Iterator, OpaqueDeclType(), Skipper> opaque;
728 qi::rule<Iterator, GateDeclType(), Skipper> gatedecl;
729 qi::rule<Iterator, SimpleBarrierType(), Skipper> simplebarrier;
730 qi::rule<Iterator, UopType(), Skipper> gateBodyModifier;
731 qi::rule<Iterator, GateDeclOpType(), Skipper> gatedeclop;
733 boost::fusion::vector<GateDeclType, std::vector<GateDeclOpType>>(),
737 qi::rule<Iterator, CondOpType(), Skipper> condOp;
738 qi::rule<Iterator, CondBitTest(), Skipper> condBitTest;
739 qi::rule<Iterator, CondHeadType(), Skipper> condHead;
740 qi::rule<Iterator, std::vector<StatementType>(), Skipper> condOpBraced;
742 qi::rule<Iterator, UGateCallType, Skipper> ugateCall;
743 qi::rule<Iterator, CXGateCallType, Skipper> cxgateCall;
745 qi::rule<Iterator, SimpleGatecallType(), Skipper> simpleGatecall;
746 qi::rule<Iterator, ExpGatecallType(), Skipper> expGatecall;
747 qi::rule<Iterator, GatecallType(), Skipper> gatecall;
748 qi::rule<Iterator, UopType(), Skipper> qasm2RejectedGate;
749 qi::rule<Iterator, UopType(), Skipper> uop;
751 qi::rule<Iterator, ModifierType(), Skipper> ctrlMod;
752 qi::rule<Iterator, ModifierType(), Skipper> negctrlMod;
753 qi::rule<Iterator, ModifierType(), Skipper> invMod;
754 qi::rule<Iterator, ModifierType(), Skipper> powMod;
755 qi::rule<Iterator, ModifierType(), Skipper> modifier;
756 qi::rule<Iterator, ModifierListType(), Skipper> modifiers;
757 qi::rule<Iterator, ModifiedUopType(), Skipper> modifiedUop;
759 qi::rule<Iterator, QopType(), Skipper> qop;
761 qi::rule<Iterator, IndexedId(), Skipper> qregdecl;
762 qi::rule<Iterator, IndexedId(), Skipper> cregdecl;
763 qi::rule<Iterator, IndexedId(), Skipper> qubitdecl;
764 qi::rule<Iterator, IndexedId(), Skipper> bitdecl;
765 qi::rule<Iterator, IndexedId(), Skipper> decl;
767 qi::rule<Iterator, std::string(), Skipper> inputType;
768 qi::rule<Iterator, InputDeclType(), Skipper> inputdecl;
770 qi::rule<Iterator, StatementType, Skipper> unsupportedConstruct;
772 qi::rule<Iterator, ResetType(), Skipper> resetOp;
773 qi::rule<Iterator, MeasureType(), Skipper> measureOp;
774 qi::rule<Iterator, MeasureType(), Skipper> measureAssignOp;
775 qi::rule<Iterator, QopType(), Skipper> measureNoTarget;
776 qi::rule<Iterator, BarrierType(), Skipper> barrierOp;
777 qi::rule<Iterator, DelayType(), Skipper> delayOp;
779 qi::rule<Iterator, std::vector<std::string>(), Skipper> idList;
781 qi::rule<Iterator, IndexedId(), Skipper> indexedId;
783 qi::rule<Iterator, ArgumentType(), Skipper> argument;
784 qi::rule<Iterator, MixedListType(), Skipper> mixedList;
786 qi::rule<Iterator, std::vector<Expression>(), Skipper> expList;
791 qi::rule<Iterator, Expression(), Skipper> expression, additive, group,
792 product, factor, factor2, unary;
793 qi::rule<Iterator, Constant(), Skipper> constant;
795 qi::rule<Iterator, std::string(), Skipper> funcName;
796 qi::rule<Iterator, std::string(), Skipper> comment;
797 qi::rule<Iterator, std::vector<std::string>(), Skipper> comments;
798 qi::rule<Iterator, std::string(), Skipper> include;
799 qi::rule<Iterator, std::vector<std::string>(), Skipper> includes;
800 qi::rule<Iterator, std::string(), Skipper> quoted_string;
801 qi::rule<Iterator, std::string(), Skipper> identifier;
802 qi::rule<Iterator, double(), Skipper> pi;
805 qi::symbols<char, std::string> unsupportedKeywords;
809 qi::symbols<char, std::string> qasm3OnlyGates;
810 qi::symbols<char, double> durationUnit;
812 int creg_counter = 0;
813 int qreg_counter = 0;
815 bool isQasm3 =
false;
817 std::unordered_map<std::string, IndexedId> creg_map;
818 std::unordered_map<std::string, IndexedId> qreg_map;
819 DeclarationRegistry declarations;
821 std::unordered_map<std::string, StatementType> opaqueGates;
822 std::unordered_map<std::string, StatementType> definedGates;
826 std::vector<std::string> inputNames;
827 std::unordered_map<std::string, double> inputBindings;
828 std::unordered_map<std::string, double> inputValues;
830 void ValidateInputBindings()
const {
831 for (
const auto &[name, value] : inputBindings) {
833 if (std::find(inputNames.begin(), inputNames.end(), name) ==
835 throw std::invalid_argument(
"No input declaration for binding '" +