Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 6 additions & 49 deletions include/staq/output/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class JSONOutputter final : public Visitor {
j["cargs"] = {arg1.json_val(), arg2.json_val(), arg3.json_val()};
json_.push_back(j);
}

void visit(CNOTGate& gd) override {
json j;
j["type"] = "Gate";
Expand All @@ -78,7 +79,9 @@ class JSONOutputter final : public Visitor {
gd.tgt().accept(arg1);
j["name"] = "CNOTGate";
j["qargs"] = {arg0.json_val(), arg1.json_val()};
json_.push_back(j);
}

void visit(BarrierGate& gd) override {
using namespace qasmtools::ast;
json j;
Expand All @@ -90,7 +93,9 @@ class JSONOutputter final : public Visitor {
va.accept(jva);
j["qargs"].push_back(jva.json_val());
});
json_.push_back(j);
}

void visit(DeclaredGate& gd) override {
using namespace qasmtools::ast;
json j;
Expand All @@ -108,6 +113,7 @@ class JSONOutputter final : public Visitor {
va.accept(jva);
j["cargs"].push_back(jva.json_val());
});
json_.push_back(j);
}

void visit(AncillaDecl& ad) override {
Expand Down Expand Up @@ -204,55 +210,6 @@ class JSONOutputter final : public Visitor {
json_.push_back(j);
}

// void visit(qasmtools::ast::Gate& g) override {
// using namespace qasmtools::ast;
// json j;
//
// j["type"] = "Gate";
// if (UGate* gd = dynamic_cast<UGate*>(&g)) {
// JSONOutputter arg0, arg1, arg2, arg3;
// gd->arg().accept(arg0);
// gd->arg().accept(arg1);
// gd->arg().accept(arg2);
// gd->arg().accept(arg3);
// j["name"] = "UGate";
// j["qargs"] = {arg0.json_val()};
// j["cargs"] = {arg1.json_val(), arg2.json_val(), arg3.json_val()};
// } else if (CNOTGate* gd = dynamic_cast<CNOTGate*>(&g)) {
// //(typeid(g) == typeid(CNOTGate)) {
// JSONOutputter arg0, arg1;
// gd->ctrl().accept(arg0);
// gd->tgt().accept(arg1);
// j["name"] = "CNOTGate";
// j["qargs"] = {arg0.json_val(), arg1.json_val()};
// } else if (BarrierGate* gd = dynamic_cast<BarrierGate*>(&g)) {
// j["name"] = "BarrierGate";
// j["qargs"] = {};
// gd->foreach_arg([&j](VarAccess& va) {
// JSONOutputter jva;
// va.accept(jva);
// j["qargs"].push_back(jva.json_val());
// });
// } else if (DeclaredGate* gd = dynamic_cast<DeclaredGate*>(&g)) {
// j["name"] = gd->name();
// j["qargs"] = {};
// j["cargs"] = {};
// gd->foreach_qarg([&j](VarAccess& va) {
// JSONOutputter jva;
// va.accept(jva);
// j["qargs"].push_back(jva.json_val());
// });
// gd->foreach_carg([&j](Expr& va) {
// JSONOutputter jva;
// va.accept(jva);
// j["cargs"].push_back(jva.json_val());
// });
// } else {
// throw "";
// }
// json_.push_back(j);
// }

void visit(GateDecl& gd) override {
using namespace qasmtools::ast;
json j;
Expand Down
237 changes: 16 additions & 221 deletions src/tools/json.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "staq/output/json.hpp"
#include <CLI/CLI.hpp>
#include <fstream>
#include <iostream>
#include <nlohmann/json.hpp>
#include <sstream>
Expand All @@ -8,234 +9,28 @@
#include "qasmtools/ast/var.hpp"
#include "qasmtools/parser/parser.hpp"

// using json = nlohmann::json;
//
// /* Forward declarations */
// // [x] class VarAccess;
// // [x] class BExpr,UExpr,PiExpr,IntExpr,RealExpr,VarExpr;
// // [ ] class MeasureStmt,ResetStmt,IfStmt,
// // [x] class UGate,CNOTGate,BarrierGate,DeclaredGate,
// // [ ] class GateDecl,OracleDecl,RegisterDecl,AncillaDecl;
// // [ ] class Program;
//
// json jsonify(qasmtools::ast::VarAccess&);
// json jsonify(qasmtools::ast::Expr&);
// json jsonify(qasmtools::ast::Gate&);
// json jsonify(qasmtools::ast::GateDecl&);
// json jsonify(qasmtools::ast::Stmt&);
// json jsonify(qasmtools::ast::MeasureStmt&);
// json jsonify(qasmtools::ast::ResetStmt&);
// json jsonify(qasmtools::ast::OracleDecl&);
// json jsonify(qasmtools::ast::RegisterDecl&);
// json jsonify(qasmtools::ast::AncillaDecl&);
// json jsonify(qasmtools::ast::IfStmt&);
// json jsonify(qasmtools::ast::Program&);
//
// json jsonify(qasmtools::ast::AncillaDecl& ad) {
// json j;
// j["type"] = "AncillaDecl";
// j["name"] = ad.id();
// j["size"] = ad.size();
// j["is_dirty"] = (ad.is_dirty() ? 1 : 0);
// return j;
// }
//
// json jsonify(qasmtools::ast::RegisterDecl& rd) {
// json j;
// j["type"] = "RegisterDecl";
// j["name"] = rd.id();
// j["is_quantum"] = (rd.is_quantum() ? 1 : 0);
// j["size"] = rd.size();
// return j;
// }
//
// json jsonify(qasmtools::ast::OracleDecl& od) {
// // TODO: verify that this is doing what it needs to do
// json j;
// j["type"] = "OracleDecl";
// j["name"] = od.fname();
// j["params"] = od.params();
// return j;
// }
//
// json jsonify(qasmtools::ast::IfStmt& ist) {
// // TODO: Improve this later.
// json j;
// std::stringstream in;
// ist.pretty_print(in, false);
// j["type"] = "IfStmt";
// j["name"] = "If";
// j["body"] = in.str();
// return j;
// }
//
// json jsonify(qasmtools::ast::ResetStmt& rst) {
// json j;
// j["type"] = "ResetStmt";
// j["name"] = "Reset";
// j["qarg"] = jsonify(rst.arg());
// return j;
// }
//
// json jsonify(qasmtools::ast::MeasureStmt& mst) {
// json j;
// j["type"] = "MeasureStmt";
// j["name"] = "Measurement";
// j["qarg"] = jsonify(mst.q_arg());
// j["carg"] = jsonify(mst.c_arg());
// return j;
// }
//
// json jsonify(qasmtools::ast::VarAccess& va) {
// json j;
// j["type"] = "VarAccess";
// j["name"] = "qubit";
// j["symbol"] = va.var();
// j["offset"] = {};
// if (va.offset().has_value()) {
// j["offset"].push_back(va.offset().value());
// }
// return j;
// }
//
// json jsonify(qasmtools::ast::Expr& expr) {
// json j;
// std::stringstream in;
// expr.pretty_print(in);
// auto ev = expr.constant_eval();
// j["type"] = "Expr";
// j["expr"] = in.str();
// j["val"] = {};
// if (ev.has_value()) {
// j["val"].push_back(ev.value());
// }
// return j;
// }
//
// json jsonify(qasmtools::ast::Gate& g) {
// using namespace qasmtools::ast;
// json j;
// j["type"] = "Gate";
// if (UGate* gd = dynamic_cast<UGate*>(&g)) {
// j["name"] = "UGate";
// j["qargs"] = {jsonify(gd->arg())};
// j["cargs"] = {jsonify(gd->theta()), jsonify(gd->phi()),
// jsonify(gd->lambda())};
// } else if (CNOTGate* gd = dynamic_cast<CNOTGate*>(&g)) {
// j["name"] = "CNOTGate";
// j["qargs"] = {jsonify(gd->ctrl()), jsonify(gd->tgt())};
// } else if (BarrierGate* gd = dynamic_cast<BarrierGate*>(&g)) {
// j["name"] = "BarrierGate";
// j["qargs"] = {};
// gd->foreach_arg(
// [&j](VarAccess& va) { j["qargs"].push_back(jsonify(va)); });
// } else if (DeclaredGate* gd = dynamic_cast<DeclaredGate*>(&g)) {
// j["name"] = gd->name();
// j["qargs"] = {};
// j["cargs"] = {};
// gd->foreach_qarg(
// [&j](VarAccess& va) { j["qargs"].push_back(jsonify(va)); });
// gd->foreach_carg([&j](Expr& va) { j["cargs"].push_back(jsonify(va));
// });
// } else {
// throw "";
// }
// return j;
// }
//
// json jsonify(qasmtools::ast::GateDecl& gd) {
// using namespace qasmtools::ast;
// json j;
// j["type"] = "GateDecl";
// j["name"] = gd.id();
// j["q_params"] = gd.q_params();
// j["c_params"] = gd.c_params();
// j["body"] = {}; // process the body of a GateDecl;
// gd.foreach_stmt([&j](Stmt& st) { j["body"].push_back(jsonify(st)); });
// return j;
// }
//
// json jsonify(qasmtools::ast::Stmt& st) {
// using namespace qasmtools::ast;
// if (GateDecl* gd = dynamic_cast<GateDecl*>(&st)) {
// return jsonify(*gd);
// } else if (Gate* gd = dynamic_cast<Gate*>(&st)) {
// return jsonify(*gd);
// } else if (Gate* gd = dynamic_cast<Gate*>(&st)) {
// return jsonify(*gd);
// } else if (MeasureStmt* gd = dynamic_cast<MeasureStmt*>(&st)) {
// return jsonify(*gd);
// } else if (ResetStmt* gd = dynamic_cast<ResetStmt*>(&st)) {
// return jsonify(*gd);
// } else if (OracleDecl* gd = dynamic_cast<OracleDecl*>(&st)) {
// return jsonify(*gd);
// } else if (RegisterDecl* gd = dynamic_cast<RegisterDecl*>(&st)) {
// return jsonify(*gd);
// } else if (AncillaDecl* gd = dynamic_cast<AncillaDecl*>(&st)) {
// return jsonify(*gd);
// } else if (IfStmt* gd = dynamic_cast<IfStmt*>(&st)) {
// return jsonify(*gd);
// } else {
// throw "";
// }
// }
//
// json jsonify(qasmtools::ast::Program& p) {
// using namespace qasmtools::ast;
// json j;
// p.foreach_stmt([&](Stmt& st) { j.push_back(jsonify(st)); });
// return j;
// }

int main(int argc, char** argv) {
// using namespace staq;
using qasmtools::parser::parse_file;

if (argc == 1) {
std::cout << "Usage: staq [PASSES/OPTIONS] FILE.qasm\n"
<< "Run with --help for more information.\n";
return 0;
}
std::string input_qasm;
using qasmtools::parser::parse_stdin;
std::string filename;

CLI::App app{"staq -- A full-stack quantum processing toolkit"};
app.allow_extras();

app.add_option("FILE.qasm", input_qasm, "OpenQASM circuit")
->required()
->check(CLI::ExistingFile);
CLI::App app{"QASM to JSON converter"};
app.add_option("-o,--output", filename, "Output to a file");

CLI11_PARSE(app, argc, argv);
try {
auto prog = parse_file(input_qasm); // Default std_include=true
if (!prog) {
// This case might not be reached if parse_file throws on error,
// but good to keep for parsers that might return nullptr.
std::cerr << "Error: failed to parse \"" << input_qasm
<< "\" (parser returned null).\n";
return 1;
}

// was working before:
// json jsonified = jsonify(*prog);
// std::cout << jsonified.dump() << std::endl;

auto prog = parse_stdin();
if (prog) {
staq::output::JSONOutputter jo;
prog->accept(jo);
std::cout << jo.json_val().dump() << std::endl;
return 0;
} catch (const qasmtools::parser::ParseError& e) {
std::cerr << "ParseError: " << e.what() << std::endl;
std::cerr
<< "Parsing failed. The error messages above this one (if any) "
"from the parser provide details about the location of the "
"syntax error(s) in the QASM file."
<< std::endl;
return 1;
} catch (const std::exception& e) {
std::cerr << "An unexpected error occurred: " << e.what() << std::endl;
if (filename.empty()) {
std::cout << jo.json_val().dump() << std::endl;
} else {
std::fstream fout(filename);
fout << jo.json_val().dump() << std::endl;
fout.close();
}
} else {
std::cerr << "Error: failed to parse " << std::endl;
return 1;
}

return 0;
}
Loading