XACC
preprocessor.h
Go to the documentation of this file.
1 /*
2  * This file is part of Quantum++.
3  *
4  * MIT License
5  *
6  * Copyright (c) 2013 - 2020 Vlad Gheorghiu.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  *
26  * Adapted from Bruno Schmitt's Tweedledee library
27  */
28 
34 #ifndef QASM_PREPROCESSOR_H_
35 #define QASM_PREPROCESSOR_H_
36 
37 namespace qpp {
38 namespace qasm {
39 
44 static const std::string std_include_qasm =
45  "gate u3(theta,phi,lambda) q { U(theta,phi,lambda) q; }\n"
46  "gate u2(phi,lambda) q { U(pi/2,phi,lambda) q; }\n"
47  "gate u1(lambda) q { U(0,0,lambda) q; }\n"
48  "gate cx c,t { CX c,t; }\n"
49  "gate id a { U(0,0,0) a; }\n"
50  "gate u0(gamma) q { U(0,0,0) q; }\n"
51  "gate x a { u3(pi,0,pi) a; }\n"
52  "gate y a { u3(pi,pi/2,pi/2) a; }\n"
53  "gate z a { u1(pi) a; }\n"
54  "gate h a { u2(0,pi) a; }\n"
55  "gate s a { u1(pi/2) a; }\n"
56  "gate sdg a { u1(-pi/2) a; }\n"
57  "gate t a { u1(pi/4) a; }\n"
58  "gate tdg a { u1(-pi/4) a; }\n"
59  "gate rx(theta) a { u3(theta, -pi/2,pi/2) a; }\n"
60  "gate ry(theta) a { u3(theta,0,0) a; }\n"
61  "gate rz(phi) a { u1(phi) a; }\n"
62  "gate cz a,b { h b; cx a,b; h b; }\n"
63  "gate cy a,b { sdg b; cx a,b; s b; }\n"
64  "gate swap a,b { cx a,b; cx b,a; cx a,b; }\n"
65  "gate ch a,b { h b; sdg b; cx a,b; h b; t b; cx a,b; t b; h b; s b; x b; s "
66  "a; }\n"
67  "gate ccx a,b,c { h c; cx b,c; tdg c; cx a,c; t c; cx b,c; tdg c; cx a,c; "
68  "t b; t c; h c; cx a,b; t a; tdg b; cx a,b; }\n"
69  "gate crz(lambda) a,b { u1(lambda/2) b; cx a,b; u1(-lambda/2) b; cx a,b; "
70  "}\n"
71  "gate cu1(lambda) a,b { u1(lambda/2) a; cx a,b; u1(-lambda/2) b; cx a,b; "
72  "u1(lambda/2) b; }\n"
73  "gate cu3(theta,phi,lambda) c,t { u1((lambda-phi)/2) t; cx c,t; "
74  "u3(-theta/2,0,-(phi+lambda)/2) t; cx c,t; u3(theta/2,phi,0) t; }\n";
75 
83 static const std::string std_include =
84  "gate u3(theta,phi,lambda) q { U(theta,phi,lambda) q; }\n"
85  "gate u2(phi,lambda) q { U(pi/2,phi,lambda) q; }\n"
86  "gate u1(lambda) q { U(0,0,lambda) q; }\n"
87  "gate cx c,t { CX c,t; }\n"
88  "gate id a { U(0,0,0) a; }\n"
89  "gate u0(gamma) q { U(0,0,0) q; }\n"
90  "gate x a { u3(pi,0,pi) a; }\n"
91  "gate y a { u3(pi,pi/2,pi/2) a; }\n"
92  "gate z a { u1(pi) a; }\n"
93  "gate h a { u2(0,pi) a; }\n"
94  "gate s a { u1(pi/2) a; }\n"
95  "gate sdg a { u1(-pi/2) a; }\n"
96  "gate t a { u1(pi/4) a; }\n"
97  "gate tdg a { u1(-pi/4) a; }\n"
98  "gate r(theta, phi) a { u3(theta,phi-pi/2,-phi+pi/2) a; }\n"
99  "gate rx(theta) a { r(theta,0) a; } \n"
100  "gate ry(theta) a { r(theta,pi/2) a; }\n"
101  "gate rz(phi) a { u1(phi) a; } \n"
102  "gate cz a,b { h b; cx a,b; h b; }\n"
103  "gate cy a,b { sdg b; cx a,b; s b; }\n"
104  "gate swap a,b { cx a,b; cx b,a; cx a,b; }\n"
105  "gate cswap a,b,c { cx c,b; ccx a,b,c; cx c,b; }\n"
106  "gate ch a,b { s b; h b; t b; cx a,b; tdg b; h b; sdg b; }\n"
107  "gate ccx a,b,c { h c; cx b,c; tdg c; cx a,c; t c; cx b,c; tdg c; cx a,c; "
108  "t b; t c; h c; cx a,b; t a; tdg b; cx a,b; }\n"
109  "gate crz(lambda) a,b { u1(lambda/2) b; cx a,b; u1(-lambda/2) b; cx a,b; "
110  "}\n"
111  "gate cu1(lambda) a,b { u1(lambda/2) a; cx a,b; u1(-lambda/2) b; cx a,b; "
112  "u1(lambda/2) b; }\n"
113  "gate cu3(theta,phi,lambda) c,t { u1((lambda+phi)/2) c; "
114  "u1((lambda-phi)/2) t; cx c,t; u3(-theta/2,0,-(phi+lambda)/2) t; cx c,t; "
115  "u3(theta/2,phi,0) t; }\n";
116 
122 class Preprocessor {
123  using LexerPtr = std::unique_ptr<Lexer>;
124 
125  std::vector<LexerPtr> lexer_stack_{};
126  LexerPtr current_lexer_ = nullptr;
127 
128  public:
132  Preprocessor() = default;
133 
143  bool add_target_file(const std::string& file_path) {
144  std::shared_ptr<std::ifstream> ifs(new std::ifstream);
145 
146  ifs->open(file_path, std::ifstream::in);
147 
148  if (!ifs->good()) {
149  return false;
150  }
151 
152  if (current_lexer_ != nullptr) {
153  lexer_stack_.push_back(std::move(current_lexer_));
154  }
155  current_lexer_ = std::unique_ptr<Lexer>(new Lexer(ifs, file_path));
156  return true;
157  }
158 
168  void add_target_stream(std::shared_ptr<std::istream> buffer,
169  const std::string& fname = "") {
170  if (current_lexer_ != nullptr) {
171  lexer_stack_.push_back(std::move(current_lexer_));
172  }
173  current_lexer_ = std::unique_ptr<Lexer>(new Lexer(buffer, fname));
174  }
175 
185  Token next_token() {
186  if (current_lexer_ == nullptr) {
187  return Token(Location(), Token::Kind::eof, "");
188  }
189  auto token = current_lexer_->next_token();
190  if (token.is(Token::Kind::kw_include)) {
191  handle_include();
192  token = current_lexer_->next_token();
193  } else if (token.is(Token::Kind::eof)) {
194  if (!lexer_stack_.empty()) {
195  current_lexer_ = std::move(lexer_stack_.back());
196  lexer_stack_.pop_back();
197  token = current_lexer_->next_token();
198  } else {
199  current_lexer_ = nullptr;
200  }
201  }
202  return token;
203  }
204 
208  void print_all_tokens() {
209  Token current = next_token();
210 
211  while (!current.is(Token::Kind::eof)) {
212  current.location().display(std::cout);
213  std::cout << ": " << current << " " << (std::string) current
214  << "\n";
215 
216  current = next_token();
217  }
218  }
219 
220  private:
228  void handle_include() {
229  auto token = current_lexer_->next_token();
230  if (token.is_not(Token::Kind::string)) {
231  std::cerr << "Error: Include must be followed by a file name\n";
232  return;
233  }
234 
235  std::string target = token;
236  token = current_lexer_->next_token();
237  if (token.is_not(Token::Kind::semicolon)) {
238  std::cerr << "Warning: Missing a ';'\n";
239  }
240  if (add_target_file(target)) {
241  return;
242  } else if (target == "qelib1.inc") {
243  add_target_stream(std::shared_ptr<std::istream>(
244  new std::stringstream(std_include)),
245  "qelib1.inc");
246  return;
247  } else {
248  std::cerr << "Error: Couldn't open file " << target << "\n";
249  }
250  }
251 };
252 
253 } /* namespace qasm */
254 } /* namespace qpp */
255 
256 #endif /* QASM_PREPROCESSOR_H_ */
Quantum++ main namespace.
Definition: circuits.h:35