1 //----------------------------------------------------------------------------
\r
3 // Compile intermediate codes
\r
4 // $Date: 2003/01/17 19:37:43 $
\r
6 //----------------------------------------------------------------------------
\r
10 #endif //__BORLANDC__
\r
16 #include "QCompiler.h"
\r
17 #include "QParseInfo.h"
\r
19 //----------------------------------------------------------------------------
\r
21 #pragma package(smart_init)
\r
22 #endif //__BORLANDC__
\r
24 using namespace std;
\r
26 //----------------------------------------------------------------------------
\r
27 // Syntax of intermediate code (see also `QCompiler.h')
\r
28 //----------------------------------------------------------------------------
\r
29 const char QCompiler::OP_BRA = '(';
\r
30 const char QCompiler::OP_KET = ')';
\r
31 const char QCompiler::QB_BRA = '[';
\r
32 const char QCompiler::QB_KET = ']';
\r
33 const char QCompiler::DELIM = ',';
\r
35 const QCompiler::QGATES QCompiler::qgates[] = {
\r
36 {"CNOT" ,2,{ at_qbit, at_qbit, at_null}},
\r
37 {"ROT" ,2,{ at_qbit, at_real, at_null}},
\r
38 {"CROT" ,3,{ at_qbit, at_qbit, at_real}},
\r
39 {"H" ,1,{ at_qbit, at_null, at_null}},
\r
40 {"MEASURE" ,1,{ at_qbit, at_null, at_null}},
\r
41 {"SWAP" ,2,{ at_qbit, at_qbit, at_null}},
\r
42 {"PAULIX" ,1,{ at_qbit, at_null, at_null}},
\r
43 {"PAULIY" ,1,{ at_qbit, at_null, at_null}},
\r
44 {"PAULIZ" ,1,{ at_qbit, at_null, at_null}},
\r
45 {"NOT" ,1,{ at_qbit, at_null, at_null}},
\r
46 {"CCNOT",3,{ at_qbit, at_qbit, at_qbit}},
\r
47 {"INIT" ,1,{ at_real, at_null, at_null}}
\r
50 const int QCompiler::opn_max = sizeof(QCompiler::qgates)/sizeof(QCompiler::QGATES);
\r
52 //----------------------------------------------------------------------------
\r
56 QCompiler::QCompiler(void) {
\r
60 //----------------------------------------------------------------------------
\r
62 * Constructor with input stream
\r
64 QCompiler::QCompiler(std::istream &is) {
\r
69 //----------------------------------------------------------------------------
\r
73 QCompiler::~QCompiler() {
\r
75 //----------------------------------------------------------------------------
\r
77 * Read intermediate code from stream
\r
80 QCompiler::ReadFromStream(std::istream &is) {
\r
82 std::string st1 = "";
\r
83 int nlcode = -1; // -1:unknown 0:CR+LF 1:LF+CR 2:CR 3:LF
\r
86 mError = mState = false;
\r
90 if (c1 == 0x0d || c1 == 0x0a) {
\r
94 if (0x0a == is.peek()) {
\r
100 } else {// c1 == 0x0a
\r
101 if (0x0d == is.peek()) {
\r
110 is.read(&c1, 1); // skip one char
\r
114 mLines.push_back(st1);
\r
125 //----------------------------------------------------------------------------
\r
130 QCompiler::Compile(void) {
\r
131 int i, vec_size = mLines.size();
\r
132 for (i = 0; i < vec_size; i++) {
\r
133 if (mLines[i].length() == 0 || mLines[i][0] == '#') {
\r
137 QParseInfo pinfo = ParseOneLine(mLines[i]);
\r
139 if (!CompileOneLine(pinfo)) throw pinfo;
\r
140 } catch (QParseInfo einfo) {
\r
142 CatchError(einfo, i); // is abstract virtual member
\r
149 //----------------------------------------------------------------------------
\r
154 QCompiler::ParseOneLine(const std::string &strline) const {
\r
156 std::string s1, s2; // tmp
\r
157 std::vector<std::string> args;
\r
159 std::vector<int> targets;
\r
160 double rotation = 0;
\r
163 if (!ExtractComArg(strline, OP_BRA, OP_KET, s1, s2)) {
\r
164 return QParseInfo(QParseInfo::er_syntax_error);
\r
167 // Extract aa, bb, and cc from "aa,bb,cc"
\r
168 if (!ExtractField(s2, DELIM, args)) {
\r
170 return QParseInfo(QParseInfo::er_syntax_error);
\r
173 // Get command number from command string
\r
174 if ((comint = GetComint(s1)) == -1) {
\r
176 return QParseInfo(QParseInfo::er_unknown_operation);
\r
180 if (j < qgates[comint].arg_num) {
\r
181 return QParseInfo(QParseInfo::er_lack_of_arguments);
\r
183 if (j > qgates[comint].arg_num) {
\r
184 return QParseInfo(QParseInfo::er_too_many_arguments);
\r
187 for (i = 0; i < j; i++) {
\r
188 switch (qgates[comint].arg_types[i]) {
\r
190 if (ExtractComArg(args[i], QB_BRA, QB_KET, s1, s2) && s1 == "q" && s2 != "") {
\r
191 targets.push_back(std::atoi(s2.c_str()));
\r
193 return QParseInfo(QParseInfo::er_invalid_arguments);
\r
197 rotation = std::atof(args[i].c_str());
\r
198 targets.push_back(std::atof(args[i].c_str()));
\r
205 return QParseInfo(comint, targets, rotation);
\r
207 //----------------------------------------------------------------------------
\r
209 * ex) bra = '[', ket = ']', strline = "q[20]" --> get "q" and "20" as string
\r
210 * bra = '(', ket = ')', strline = CNOT(q[0],q[1])
\r
211 * --> get "CNOT" and "q[0],q[1]" as string
\r
214 QCompiler::ExtractComArg(const std::string &strline, const char bra, const char ket,
\r
216 std::string &Arg) const {
\r
217 int pos_bra = strline.find(bra);
\r
218 int pos_ket = strline.find(ket);
\r
219 int length = strline.length();
\r
222 if (pos_bra < 1 || pos_ket - pos_bra < 1 || pos_ket != length - 1) {
\r
225 Com = strline.substr(0, pos_bra);
\r
226 if (pos_ket - pos_bra >= 2) {
\r
227 Arg = strline.substr(pos_bra + 1, pos_ket - pos_bra - 1);
\r
231 //----------------------------------------------------------------------------
\r
233 * Null field is not allowd, but "" (zero string) is OK.
\r
235 * ex) delim = ',', strline = "q[0],q[4],10"
\r
236 * --> get "q[0]", "q[4]" and "10" as vector<string>, and return true
\r
237 * delim = ',', strline = "aa,,bb" (having null field between aa and bb)
\r
239 * delim = ',', strline = ""
\r
243 QCompiler::ExtractField(const std::string &strline, const char delim,
\r
244 std::vector<std::string> &Args) const {
\r
247 int length = strline.length();
\r
248 std::string s1 = "";
\r
251 for (i = 0; i < length; i++) {
\r
252 if (strline.at(i) == delim) {
\r
254 Args.push_back(s1);
\r
261 s1 += strline.at(i);
\r
264 if (s1.length() > 0) {
\r
265 Args.push_back(s1);
\r
269 //----------------------------------------------------------------------------
\r
271 * Get command number from command string
\r
274 QCompiler::GetComint(const std::string &_str) const {
\r
275 for (int i = 0; i < opn_max; i++)if (_str == qgates[i].opstr) return i;
\r
278 //----------------------------------------------------------------------------
\r