40 includes)(std::vector<qasm::StatementType>, statements))
45inline void printd(
const double &v)
47 std::cout <<
"version: " << v <<
"\n";
50inline void prints(
const std::string &s)
52 std::cout <<
"statement: " << s <<
"\n";
62template <
typename Iterator>
struct QasmSkipper : qi::grammar<Iterator>
64 QasmSkipper() : QasmSkipper::base_type(skip)
68 blockComment = qi::lexeme[qi::lit(
"/*") >> *(qi::char_ - qi::lit(
"*/")) >> qi::lit(
"*/")];
69 skip = ascii::space | blockComment;
72 qi::rule<Iterator> skip;
73 qi::rule<Iterator> blockComment;
76struct MakeSupportedVersionExpr
78 template <
typename,
typename,
typename>
struct result
85 double operator()(
unsigned int major,
const boost::optional<unsigned int> &minor,
bool &isQasm3)
const
87 if (major != 2U && major != 3U)
88 throw std::invalid_argument(
"Unsupported OpenQASM major version " + std::to_string(major) +
". Only versions 2.x and 3.x are supported.");
90 if (major == 2U && !minor)
91 throw std::invalid_argument(
"OpenQASM 2 requires an explicit minor version, as in "
94 isQasm3 = major == 3U;
96 return static_cast<double>(major);
98 return std::stod(std::to_string(major) +
"." + std::to_string(*minor));
102inline phx::function<MakeSupportedVersionExpr> MakeSupportedVersion;
104struct ValidateIncludeExpr
106 template <
typename>
struct result
108 typedef std::string type;
111 std::string operator()(
const std::string &includeName)
const
113 if (includeName !=
"qelib1.inc" && includeName !=
"stdgates.inc")
114 throw std::invalid_argument(
"Unsupported OpenQASM include '" + includeName +
115 "'. Only qelib1.inc and "
116 "stdgates.inc are recognized prelude markers.");
121inline phx::function<ValidateIncludeExpr> ValidateInclude;
123template <
typename Iterator = std::
string::iterator,
typename Skipper = QasmSkipper<Iterator>>
struct QasmGrammar : qi::grammar<Iterator, Program(), Skipper>
125 QasmGrammar() : QasmGrammar::base_type{program}
127 version = (qi::omit[qi::lexeme[qi::lit(
"OPENQASM") >> qi::space]] >> qi::lexeme[qi::uint_ >> -(
'.' >> qi::uint_)] >>
128 ';')[qi::_val = MakeSupportedVersion(qi::_1, qi::_2, phx::ref(isQasm3))];
134 unsupportedKeywords.add(
"for",
"OpenQASM 3 'for' loops are not supported.")(
"while",
"OpenQASM 3 'while' loops are not supported.")(
135 "def",
"OpenQASM 3 subroutine definitions ('def') are not supported.")(
"let",
"OpenQASM 3 register aliases ('let') are not supported.")(
136 "duration",
"OpenQASM 3 duration declarations ('duration') are not supported.")(
"box",
"OpenQASM 3 box blocks ('box') are not supported.")(
137 "array",
"OpenQASM 3 array declarations ('array') are not supported.")(
"output",
"OpenQASM 3 output declarations ('output') are not supported.")(
138 "const",
"OpenQASM 3 constant declarations ('const') are not supported.")(
"extern",
139 "OpenQASM 3 external subroutines ('extern') are not supported.")(
140 "stretch",
"OpenQASM 3 stretch declarations ('stretch') are not supported.")(
"pragma",
"OpenQASM 3 pragma statements are not supported.")(
141 "defcal",
"OpenQASM 3 calibration definitions ('defcal') are not supported.");
147 qasm3OnlyGates.add(
"phase",
"phase")(
"cphase",
"cphase")(
"gphase",
"gphase");
149 durationUnit.add(
"ns", 1e-9)(
"us", 1e-6)(
"ms", 1e-3)(
"s", 1.0)(
"dt", -1.0);
151 comments %= *comment;
152 includes %= *include;
156 program = comments >> (-version) >> includes >> statements;
166 *(condOpBraced[phx::insert(qi::_val, phx::end(qi::_val), phx::begin(qi::_1), phx::end(qi::_1))] | statement[phx::push_back(qi::_val, qi::_1)]);
168 statement = comment[qi::_val = AddComment(qi::_1)] | decl[qi::_val = AddDeclaration(qi::_1)] |
169 opaque[qi::_val = AddOpaqueDecl(qi::_1, std::ref(opaqueGates), std::ref(qreg_map), std::ref(declarations))] |
170 condOp[qi::_val = AddCondQop(qi::_1, std::ref(qreg_map), std::ref(creg_map), std::ref(opaqueGates), std::ref(definedGates))] |
171 gatedeclfull[qi::_val = AddGateDecl(qi::_1, std::ref(definedGates), std::ref(declarations))] |
172 inputdecl[qi::_val = AddInputDecl(qi::_1, std::ref(inputNames), std::ref(declarations), std::ref(inputBindings), std::ref(inputValues))] |
173 unsupportedConstruct[qi::_val = qi::_1] | qop[qi::_val = qi::_1];
179 qi::omit[qi::lexeme[qi::lit(
"opaque") >> qi::space]] >> identifier >> ((
'(' >> idList >>
')') | (
'(' >> qi::eps >>
')') | qi::eps) >> idList >>
';';
186 qi::omit[qi::lexeme[qi::lit(
"gate") >> qi::space]] >> identifier >> ((
'(' >> idList >>
')') | (
'(' >> qi::eps >>
')') | qi::eps) >> idList >>
'{';
188 simplebarrier %= qi::omit[qi::lexeme[qi::lit(
"barrier") >> qi::space]] >> idList >>
';';
189 gateBodyModifier = (+modifier)[qi::_val = RejectGateBodyModifier(qi::_1)];
190 gatedeclop %= simplebarrier | (uop >>
';') | gateBodyModifier;
192 gatedeclfull %= gatedecl >> *gatedeclop >>
'}';
198 condOp %= qi::lit(
"if") >>
'(' >> identifier >> qi::lit(
"==") >> qi::int_ >>
')' >> qop;
212 condBitTest = (qi::lit(
'!') >> indexedId)[qi::_val = MakeCondBitTest(qi::_1,
false)] | indexedId[qi::_val = MakeCondBitTest(qi::_1,
true)];
217 condHead = (identifier >> qi::lit(
"==") >> qi::int_)[qi::_val = MakeRegCondHead(qi::_1, qi::_2)] |
218 (condBitTest % qi::lit(
"&&"))[qi::_val = MakeBitCondHead(qi::_1)];
236 condOpBraced = qi::eps(phx::ref(isQasm3)) >>
237 (qi::lit(
"if") >>
'(' >> condHead >>
')' >>
'{' >> *qop >>
'}' >>
238 -(qi::lit(
"else") >>
'{' >> *qop >>
'}'))[qi::_val = AddCondQopBraced(qi::_1, qi::_2, qi::_3, std::ref(qreg_map), std::ref(creg_map),
239 std::ref(opaqueGates), std::ref(definedGates))];
250 simpleGatecall %= identifier >> qi::omit[-(qi::lit(
'(') >> qi::lit(
')'))] >> mixedList;
253 expGatecall %= identifier >>
'(' >> expList >>
')' >> (mixedList | qi::attr(MixedListType()));
255 gatecall %= simpleGatecall | expGatecall;
266 ugateCall %= (qi::lit(
"U") | qi::lit(
"u")) >>
'(' >> expList >>
')' >> argument >> !qi::lit(
',');
267 cxgateCall %= qi::omit[qi::lexeme[(qi::lit(
"CX") | qi::lit(
"cx")) >> qi::space]] >> argument >>
',' >> argument >> !qi::lit(
',');
281 qasm2RejectedGate = qi::eps(!phx::ref(isQasm3)) >>
282 qi::lexeme[qasm3OnlyGates >> !qi::char_(
"a-zA-Z0-9_")][qi::_pass = RejectQasm3OnlyGate(qi::_1, std::ref(definedGates))];
284 uop %= qasm2RejectedGate | cxgateCall | ugateCall | gatecall;
298 ctrlMod = (qi::lit(
"ctrl") >> -(
'(' >> expression >>
')') >>
'@')[qi::_val = MakeCtrlModifier(ModifierKind::Ctrl, qi::_1, std::ref(inputValues))];
300 (qi::lit(
"negctrl") >> -(
'(' >> expression >>
')') >>
'@')[qi::_val = MakeCtrlModifier(ModifierKind::NegCtrl, qi::_1, std::ref(inputValues))];
301 invMod %= qi::lit(
"inv") >>
'@' >> qi::attr(ModifierType(ModifierKind::Inv));
302 powMod = (qi::lit(
"pow") >>
'(' >> expression >>
')' >>
'@')[qi::_val = MakePowModifier(qi::_1, std::ref(inputValues))];
304 modifier %= qi::eps(phx::ref(isQasm3)) >> (ctrlMod | negctrlMod | invMod | powMod);
305 modifiers %= *modifier;
306 modifiedUop %= modifiers >> uop;
308 qop = (measureOp[qi::_val = AddMeasure(qi::_1, std::ref(creg_map), std::ref(qreg_map))] |
309 measureAssignOp[qi::_val = AddMeasure(qi::_1, std::ref(creg_map), std::ref(qreg_map))] | measureNoTarget[qi::_val = qi::_1] |
310 resetOp[qi::_val = AddReset(qi::_1, std::ref(qreg_map))] | barrierOp[qi::_val = AddBarrier(qi::_1, std::ref(qreg_map))] |
311 delayOp[qi::_val = AddDelay(qi::_1, std::ref(qreg_map))] |
312 modifiedUop[qi::_val = AddModifiedGate(qi::_1, std::ref(qreg_map), std::ref(opaqueGates), std::ref(definedGates), std::ref(inputValues))]) >>
317 qregdecl %= (qi::omit[qi::lexeme[qi::lit(
"qreg") >> qi::space]] >>
318 indexedId)[qi::_val = AddQreg(std::ref(qreg_counter), std::ref(qreg_map), std::ref(declarations), qi::_1)];
319 cregdecl %= (qi::omit[qi::lexeme[qi::lit(
"creg") >> qi::space]] >>
320 indexedId)[qi::_val = AddCreg(std::ref(creg_counter), std::ref(creg_map), std::ref(declarations), qi::_1)];
330 qubitdecl = qi::eps(phx::ref(isQasm3)) >>
331 ((qi::lit(
"qubit") >>
'[' >> qi::int_ >>
']' >>
332 identifier)[qi::_val = AddQreg(std::ref(qreg_counter), std::ref(qreg_map), std::ref(declarations), MakeIndexedId(qi::_2, qi::_1))] |
333 (qi::omit[qi::lexeme[qi::lit(
"qubit") >> qi::space]] >> qi::attr(1) >>
334 identifier)[qi::_val = AddQreg(std::ref(qreg_counter), std::ref(qreg_map), std::ref(declarations), MakeIndexedId(qi::_2, qi::_1))]);
335 bitdecl = qi::eps(phx::ref(isQasm3)) >>
336 ((qi::lit(
"bit") >>
'[' >> qi::int_ >>
']' >>
337 identifier)[qi::_val = AddCreg(std::ref(creg_counter), std::ref(creg_map), std::ref(declarations), MakeIndexedId(qi::_2, qi::_1))] |
338 (qi::omit[qi::lexeme[qi::lit(
"bit") >> qi::space]] >> qi::attr(1) >>
339 identifier)[qi::_val = AddCreg(std::ref(creg_counter), std::ref(creg_map), std::ref(declarations), MakeIndexedId(qi::_2, qi::_1))]);
341 decl %= (qregdecl | cregdecl | qubitdecl | bitdecl) >>
';';
355 qi::lexeme[(qi::string(
"float") | qi::string(
"int") | qi::string(
"uint") | qi::string(
"bool") | qi::string(
"angle")) >> !qi::char_(
"a-zA-Z0-9_")];
357 qi::eps(phx::ref(isQasm3)) >> qi::omit[qi::lexeme[qi::lit(
"input") >> qi::space]] >> inputType >> -(
'[' >> qi::int_ >>
']') >> identifier >>
';';
370 unsupportedConstruct =
371 qi::eps(phx::ref(isQasm3)) >> qi::lexeme[unsupportedKeywords >> !qi::char_(
"a-zA-Z0-9_")][qi::_val = RejectUnsupportedConstruct(qi::_1)];
373 measureOp %= qi::omit[qi::lexeme[qi::lit(
"measure") >> qi::space]] >> argument >> qi::lit(
"->") >> argument;
379 measureAssignOp = qi::eps(phx::ref(isQasm3)) >> (argument >>
'=' >> qi::omit[qi::lexeme[qi::lit(
"measure") >> qi::space]] >>
380 argument)[qi::_val = phx::construct<MeasureType>(qi::_2, qi::_1)];
393 measureNoTarget = (qi::omit[qi::lexeme[qi::lit(
"measure") >> qi::space]] >> argument)[qi::_val = RejectMeasureWithoutTarget(qi::_1)];
394 resetOp %= qi::omit[qi::lexeme[qi::lit(
"reset") >> qi::space]] >> argument;
407 barrierOp %= (qi::omit[qi::lexeme[qi::lit(
"barrier") >> qi::space]] >> mixedList) |
408 (qi::eps(phx::ref(isQasm3)) >> qi::omit[qi::lexeme[qi::lit(
"barrier") >> !qi::char_(
"a-zA-Z0-9_")]] >> qi::attr(MixedListType()));
410 delayOp = (qi::omit[qi::lexeme[qi::lit(
"delay") >> (qi::space | &qi::char_(
"[("))]] >>
411 ((
'[' >> expression >> -durationUnit >>
']') | (
'(' >> expression >> -durationUnit >>
')')) >>
412 mixedList)[qi::_val = MakeDelay(qi::_1, qi::_2, std::ref(inputValues))];
416 idList %= identifier %
',';
418 indexedId = (identifier >>
'[' >> qi::int_ >>
']')[qi::_val = MakeIndexedId(qi::_1, qi::_2)];
420 argument %= indexedId | identifier;
421 mixedList %= argument %
',';
426 expList %= expression %
',';
444 (qi::eps(phx::ref(isQasm3)) >> additive >> qi::lit(
'^') >> expression)[qi::_val = MakeBinary(
'X', qi::_1, qi::_2)] | additive[qi::_val = qi::_1];
457 additive = product[qi::_val = qi::_1] >> *(qi::char_(
"+-") >> product)[qi::_val = MakeBinary(qi::_1, qi::_val, qi::_2)];
458 product = unary[qi::_val = qi::_1] >> *(qi::char_(
"*/") >> unary)[qi::_val = MakeBinary(qi::_1, qi::_val, qi::_2)];
467 unary = (qi::char_(
"+-") >> unary)[qi::_val = MakeUnary(qi::_1, qi::_2)] | factor2[qi::_val = qi::_1];
479 factor2 = (qi::eps(phx::ref(isQasm3)) >> factor >> qi::lit(
"**") >> unary)[qi::_val = MakeBinary(
'^', qi::_1, qi::_2)] |
480 (qi::eps(!phx::ref(isQasm3)) >> factor >> qi::lit(
'^') >> unary)[qi::_val = MakeBinary(
'^', qi::_1, qi::_2)] | factor[qi::_val = qi::_1];
481 factor = group[qi::_val = qi::_1] | constant[qi::_val = qi::_1] | (funcName >> group)[qi::_val = MakeFunction(qi::_1, qi::_2)] |
482 identifier[qi::_val = MakeVariable(qi::_1)];
491 constant = qi::real_parser<double, qi::ureal_policies<double>>()[qi::_val = MakeConstant(qi::_1)] | pi[qi::_val = MakeConstant(qi::_1)];
492 group %=
'(' >> expression >>
')';
494 funcName %= qi::string(
"sin") | qi::string(
"cos") | qi::string(
"tan") | qi::string(
"exp") | qi::string(
"ln") | qi::string(
"sqrt");
495 pi %= qi::lit(
"pi")[qi::_val = M_PI];
500 comment %= qi::lexeme[qi::lit(
"//") >> *(qi::char_ - qi::eol) >> -qi::eol];
501 quoted_string %= qi::lexeme[
'"' >> +(qi::char_ -
'"') >>
'"'];
504 include = (qi::omit[qi::lexeme[qi::lit(
"include") >> qi::space]] >> quoted_string >>
';')[qi::_val = ValidateInclude(qi::_1)];
519 identifier %= qi::lexeme[((qi::eps(phx::ref(isQasm3)) >> qi::char_(
"a-zA-Z_")) | qi::char_(
"a-z")) >> *qi::char_(
"a-zA-Z0-9_")];
522 BOOST_SPIRIT_DEBUG_NODE(version);
523 BOOST_SPIRIT_DEBUG_NODE(program);
524 BOOST_SPIRIT_DEBUG_NODE(statement);
525 BOOST_SPIRIT_DEBUG_NODE(statements);
527 BOOST_SPIRIT_DEBUG_NODE(opaque);
529 BOOST_SPIRIT_DEBUG_NODE(gatedecl);
530 BOOST_SPIRIT_DEBUG_NODE(simplebarrier);
531 BOOST_SPIRIT_DEBUG_NODE(gateBodyModifier);
532 BOOST_SPIRIT_DEBUG_NODE(gatedeclop);
533 BOOST_SPIRIT_DEBUG_NODE(gatedeclfull);
535 BOOST_SPIRIT_DEBUG_NODE(condOp);
536 BOOST_SPIRIT_DEBUG_NODE(condBitTest);
537 BOOST_SPIRIT_DEBUG_NODE(condHead);
538 BOOST_SPIRIT_DEBUG_NODE(condOpBraced);
539 BOOST_SPIRIT_DEBUG_NODE(simpleGatecall);
540 BOOST_SPIRIT_DEBUG_NODE(expGatecall);
541 BOOST_SPIRIT_DEBUG_NODE(gatecall);
542 BOOST_SPIRIT_DEBUG_NODE(qasm2RejectedGate);
543 BOOST_SPIRIT_DEBUG_NODE(ugateCall);
544 BOOST_SPIRIT_DEBUG_NODE(cxgateCall);
545 BOOST_SPIRIT_DEBUG_NODE(uop);
546 BOOST_SPIRIT_DEBUG_NODE(ctrlMod);
547 BOOST_SPIRIT_DEBUG_NODE(negctrlMod);
548 BOOST_SPIRIT_DEBUG_NODE(invMod);
549 BOOST_SPIRIT_DEBUG_NODE(powMod);
550 BOOST_SPIRIT_DEBUG_NODE(modifier);
551 BOOST_SPIRIT_DEBUG_NODE(modifiers);
552 BOOST_SPIRIT_DEBUG_NODE(modifiedUop);
553 BOOST_SPIRIT_DEBUG_NODE(qop);
555 BOOST_SPIRIT_DEBUG_NODE(qregdecl);
556 BOOST_SPIRIT_DEBUG_NODE(cregdecl);
557 BOOST_SPIRIT_DEBUG_NODE(qubitdecl);
558 BOOST_SPIRIT_DEBUG_NODE(bitdecl);
559 BOOST_SPIRIT_DEBUG_NODE(decl);
560 BOOST_SPIRIT_DEBUG_NODE(inputdecl);
561 BOOST_SPIRIT_DEBUG_NODE(unsupportedConstruct);
562 BOOST_SPIRIT_DEBUG_NODE(resetOp);
563 BOOST_SPIRIT_DEBUG_NODE(measureOp);
564 BOOST_SPIRIT_DEBUG_NODE(measureAssignOp);
565 BOOST_SPIRIT_DEBUG_NODE(measureNoTarget);
566 BOOST_SPIRIT_DEBUG_NODE(barrierOp);
568 BOOST_SPIRIT_DEBUG_NODE(idList);
569 BOOST_SPIRIT_DEBUG_NODE(indexedId);
570 BOOST_SPIRIT_DEBUG_NODE(argument);
571 BOOST_SPIRIT_DEBUG_NODE(mixedList);
573 BOOST_SPIRIT_DEBUG_NODE(expList);
575 BOOST_SPIRIT_DEBUG_NODE(expression);
576 BOOST_SPIRIT_DEBUG_NODE(additive);
577 BOOST_SPIRIT_DEBUG_NODE(product);
578 BOOST_SPIRIT_DEBUG_NODE(factor2);
579 BOOST_SPIRIT_DEBUG_NODE(unary);
580 BOOST_SPIRIT_DEBUG_NODE(factor);
581 BOOST_SPIRIT_DEBUG_NODE(constant);
582 BOOST_SPIRIT_DEBUG_NODE(group);
583 BOOST_SPIRIT_DEBUG_NODE(funcName);
584 BOOST_SPIRIT_DEBUG_NODE(pi);
586 BOOST_SPIRIT_DEBUG_NODE(comment);
587 BOOST_SPIRIT_DEBUG_NODE(quoted_string);
588 BOOST_SPIRIT_DEBUG_NODE(include);
589 BOOST_SPIRIT_DEBUG_NODE(identifier);
592 qi::on_error<qi::fail>(expression, error_handler(qi::_4, qi::_3, qi::_2));
594 qi::on_error<qi::fail>(program, error_handler(qi::_4, qi::_3, qi::_2));
603 declarations.clear();
605 definedGates.clear();
607 inputBindings.clear();
612 qi::rule<Iterator, Program(), Skipper> program;
614 qi::rule<Iterator, double(), Skipper> version;
616 qi::rule<Iterator, StatementType, Skipper> statement;
617 qi::rule<Iterator, std::vector<StatementType>(), Skipper> statements;
619 qi::rule<Iterator, OpaqueDeclType(), Skipper> opaque;
621 qi::rule<Iterator, GateDeclType(), Skipper> gatedecl;
622 qi::rule<Iterator, SimpleBarrierType(), Skipper> simplebarrier;
623 qi::rule<Iterator, UopType(), Skipper> gateBodyModifier;
624 qi::rule<Iterator, GateDeclOpType(), Skipper> gatedeclop;
625 qi::rule<Iterator, boost::fusion::vector<GateDeclType, std::vector<GateDeclOpType>>(), Skipper> gatedeclfull;
627 qi::rule<Iterator, CondOpType(), Skipper> condOp;
628 qi::rule<Iterator, CondBitTest(), Skipper> condBitTest;
629 qi::rule<Iterator, CondHeadType(), Skipper> condHead;
630 qi::rule<Iterator, std::vector<StatementType>(), Skipper> condOpBraced;
632 qi::rule<Iterator, UGateCallType, Skipper> ugateCall;
633 qi::rule<Iterator, CXGateCallType, Skipper> cxgateCall;
635 qi::rule<Iterator, SimpleGatecallType(), Skipper> simpleGatecall;
636 qi::rule<Iterator, ExpGatecallType(), Skipper> expGatecall;
637 qi::rule<Iterator, GatecallType(), Skipper> gatecall;
638 qi::rule<Iterator, UopType(), Skipper> qasm2RejectedGate;
639 qi::rule<Iterator, UopType(), Skipper> uop;
641 qi::rule<Iterator, ModifierType(), Skipper> ctrlMod;
642 qi::rule<Iterator, ModifierType(), Skipper> negctrlMod;
643 qi::rule<Iterator, ModifierType(), Skipper> invMod;
644 qi::rule<Iterator, ModifierType(), Skipper> powMod;
645 qi::rule<Iterator, ModifierType(), Skipper> modifier;
646 qi::rule<Iterator, ModifierListType(), Skipper> modifiers;
647 qi::rule<Iterator, ModifiedUopType(), Skipper> modifiedUop;
649 qi::rule<Iterator, QopType(), Skipper> qop;
651 qi::rule<Iterator, IndexedId(), Skipper> qregdecl;
652 qi::rule<Iterator, IndexedId(), Skipper> cregdecl;
653 qi::rule<Iterator, IndexedId(), Skipper> qubitdecl;
654 qi::rule<Iterator, IndexedId(), Skipper> bitdecl;
655 qi::rule<Iterator, IndexedId(), Skipper> decl;
657 qi::rule<Iterator, std::string(), Skipper> inputType;
658 qi::rule<Iterator, InputDeclType(), Skipper> inputdecl;
660 qi::rule<Iterator, StatementType, Skipper> unsupportedConstruct;
662 qi::rule<Iterator, ResetType(), Skipper> resetOp;
663 qi::rule<Iterator, MeasureType(), Skipper> measureOp;
664 qi::rule<Iterator, MeasureType(), Skipper> measureAssignOp;
665 qi::rule<Iterator, QopType(), Skipper> measureNoTarget;
666 qi::rule<Iterator, BarrierType(), Skipper> barrierOp;
667 qi::rule<Iterator, DelayType(), Skipper> delayOp;
669 qi::rule<Iterator, std::vector<std::string>(), Skipper> idList;
671 qi::rule<Iterator, IndexedId(), Skipper> indexedId;
673 qi::rule<Iterator, ArgumentType(), Skipper> argument;
674 qi::rule<Iterator, MixedListType(), Skipper> mixedList;
676 qi::rule<Iterator, std::vector<Expression>(), Skipper> expList;
681 qi::rule<Iterator, Expression(), Skipper> expression, additive, group, product, factor, factor2, unary;
682 qi::rule<Iterator, Constant(), Skipper> constant;
684 qi::rule<Iterator, std::string(), Skipper> funcName;
685 qi::rule<Iterator, std::string(), Skipper> comment;
686 qi::rule<Iterator, std::vector<std::string>(), Skipper> comments;
687 qi::rule<Iterator, std::string(), Skipper> include;
688 qi::rule<Iterator, std::vector<std::string>(), Skipper> includes;
689 qi::rule<Iterator, std::string(), Skipper> quoted_string;
690 qi::rule<Iterator, std::string(), Skipper> identifier;
691 qi::rule<Iterator, double(), Skipper> pi;
694 qi::symbols<char, std::string> unsupportedKeywords;
698 qi::symbols<char, std::string> qasm3OnlyGates;
699 qi::symbols<char, double> durationUnit;
701 int creg_counter = 0;
702 int qreg_counter = 0;
704 bool isQasm3 =
false;
706 std::unordered_map<std::string, IndexedId> creg_map;
707 std::unordered_map<std::string, IndexedId> qreg_map;
708 DeclarationRegistry declarations;
710 std::unordered_map<std::string, StatementType> opaqueGates;
711 std::unordered_map<std::string, StatementType> definedGates;
715 std::vector<std::string> inputNames;
716 std::unordered_map<std::string, double> inputBindings;
717 std::unordered_map<std::string, double> inputValues;
719 void ValidateInputBindings()
const
721 for (
const auto &[name, value] : inputBindings)
724 if (std::find(inputNames.begin(), inputNames.end(), name) == inputNames.end())
725 throw std::invalid_argument(
"No input declaration for binding '" + name +
"'.");