ast.hh
Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 00002 /* 00003 * Main authors: 00004 * Guido Tack <tack@gecode.org> 00005 * 00006 * Copyright: 00007 * Guido Tack, 2007 00008 * 00009 * Last modified: 00010 * $Date: 2010-05-08 16:41:44 +0200 (Sat, 08 May 2010) $ by $Author: tack $ 00011 * $Revision: 10909 $ 00012 * 00013 * This file is part of Gecode, the generic constraint 00014 * development environment: 00015 * http://www.gecode.org 00016 * 00017 * Permission is hereby granted, free of charge, to any person obtaining 00018 * a copy of this software and associated documentation files (the 00019 * "Software"), to deal in the Software without restriction, including 00020 * without limitation the rights to use, copy, modify, merge, publish, 00021 * distribute, sublicense, and/or sell copies of the Software, and to 00022 * permit persons to whom the Software is furnished to do so, subject to 00023 * the following conditions: 00024 * 00025 * The above copyright notice and this permission notice shall be 00026 * included in all copies or substantial portions of the Software. 00027 * 00028 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00029 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00030 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00031 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 00032 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 00033 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 00034 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00035 * 00036 */ 00037 00038 #ifndef __GECODE_FLATZINC_AST_HH__ 00039 #define __GECODE_FLATZINC_AST_HH__ 00040 00041 #include <vector> 00042 #include <string> 00043 #include <iostream> 00044 #include <cstdlib> 00045 00051 namespace Gecode { namespace FlatZinc { namespace AST { 00052 00053 class Call; 00054 class Array; 00055 class Atom; 00056 class SetLit; 00057 00059 class TypeError { 00060 private: 00061 std::string _what; 00062 public: 00063 TypeError() : _what("") {} 00064 TypeError(std::string what) : _what(what) {} 00065 std::string what(void) const { return _what; } 00066 }; 00067 00071 class Node { 00072 public: 00074 virtual ~Node(void); 00075 00077 void append(Node* n); 00078 00080 bool hasAtom(const std::string& id); 00082 bool isInt(int& i); 00084 bool isCall(const std::string& id); 00086 Call* getCall(void); 00088 bool hasCall(const std::string& id); 00090 Call* getCall(const std::string& id); 00092 Array* getArray(void); 00094 Atom* getAtom(void); 00096 int getIntVar(void); 00098 int getBoolVar(void); 00100 int getSetVar(void); 00101 00103 int getInt(void); 00105 bool getBool(void); 00107 double getFloat(void); 00109 SetLit *getSet(void); 00110 00112 std::string getString(void); 00113 00115 bool isIntVar(void); 00117 bool isBoolVar(void); 00119 bool isSetVar(void); 00121 bool isInt(void); 00123 bool isBool(void); 00125 bool isString(void); 00127 bool isArray(void); 00129 bool isSet(void); 00131 bool isAtom(void); 00132 00134 virtual void print(std::ostream&) = 0; 00135 }; 00136 00138 class BoolLit : public Node { 00139 public: 00140 bool b; 00141 BoolLit(bool b0) : b(b0) {} 00142 virtual void print(std::ostream& os) { 00143 os << "b(" << (b ? "true" : "false") << ")"; 00144 } 00145 }; 00147 class IntLit : public Node { 00148 public: 00149 int i; 00150 IntLit(int i0) : i(i0) {} 00151 virtual void print(std::ostream& os) { 00152 os << "i("<<i<<")"; 00153 } 00154 }; 00156 class FloatLit : public Node { 00157 public: 00158 double d; 00159 FloatLit(double d0) : d(d0) {} 00160 virtual void print(std::ostream& os) { 00161 os << "f("<<d<<")"; 00162 } 00163 }; 00165 class SetLit : public Node { 00166 public: 00167 bool interval; 00168 int min; int max; 00169 std::vector<int> s; 00170 SetLit(void) {} 00171 SetLit(int min0, int max0) : interval(true), min(min0), max(max0) {} 00172 SetLit(const std::vector<int>& s0) : interval(false), s(s0) {} 00173 bool empty(void) const { 00174 return ( (interval && min>max) || (!interval && s.size() == 0)); 00175 } 00176 virtual void print(std::ostream& os) { 00177 os << "s()"; 00178 } 00179 }; 00180 00182 class Var : public Node { 00183 public: 00184 int i; 00185 Var(int i0) : i(i0) {} 00186 }; 00188 class BoolVar : public Var { 00189 public: 00190 BoolVar(int i0) : Var(i0) {} 00191 virtual void print(std::ostream& os) { 00192 os << "xb("<<i<<")"; 00193 } 00194 }; 00196 class IntVar : public Var { 00197 public: 00198 IntVar(int i0) : Var(i0) {} 00199 virtual void print(std::ostream& os) { 00200 os << "xi("<<i<<")"; 00201 } 00202 }; 00204 class FloatVar : public Var { 00205 public: 00206 FloatVar(int i0) : Var(i0) {} 00207 virtual void print(std::ostream& os) { 00208 os << "xf("<<i<<")"; 00209 } 00210 }; 00212 class SetVar : public Var { 00213 public: 00214 SetVar(int i0) : Var(i0) {} 00215 virtual void print(std::ostream& os) { 00216 os << "xs("<<i<<")"; 00217 } 00218 }; 00219 00221 class Array : public Node { 00222 public: 00223 std::vector<Node*> a; 00224 Array(const std::vector<Node*>& a0) 00225 : a(a0) {} 00226 Array(Node* n) 00227 : a(1) { a[0] = n; } 00228 Array(int n=0) : a(n) {} 00229 virtual void print(std::ostream& os) { 00230 os << "["; 00231 for (unsigned int i=0; i<a.size(); i++) { 00232 a[i]->print(os); 00233 if (i<a.size()-1) 00234 os << ", "; 00235 } 00236 os << "]"; 00237 } 00238 ~Array(void) { 00239 for (int i=a.size(); i--;) 00240 delete a[i]; 00241 } 00242 }; 00243 00245 class Call : public Node { 00246 public: 00247 std::string id; 00248 Node* args; 00249 Call(const std::string& id0, Node* args0) 00250 : id(id0), args(args0) {} 00251 ~Call(void) { delete args; } 00252 virtual void print(std::ostream& os) { 00253 os << id << "("; args->print(os); os << ")"; 00254 } 00255 Array* getArgs(unsigned int n) { 00256 Array *a = args->getArray(); 00257 if (a->a.size() != n) 00258 throw TypeError("arity mismatch"); 00259 return a; 00260 } 00261 }; 00262 00264 class ArrayAccess : public Node { 00265 public: 00266 Node* a; 00267 Node* idx; 00268 ArrayAccess(Node* a0, Node* idx0) 00269 : a(a0), idx(idx0) {} 00270 ~ArrayAccess(void) { delete a; delete idx; } 00271 virtual void print(std::ostream& os) { 00272 a->print(os); 00273 os << "["; 00274 idx->print(os); 00275 os << "]"; 00276 } 00277 }; 00278 00280 class Atom : public Node { 00281 public: 00282 std::string id; 00283 Atom(const std::string& id0) : id(id0) {} 00284 virtual void print(std::ostream& os) { 00285 os << id; 00286 } 00287 }; 00288 00290 class String : public Node { 00291 public: 00292 std::string s; 00293 String(const std::string& s0) : s(s0) {} 00294 virtual void print(std::ostream& os) { 00295 os << "s(\"" << s << "\")"; 00296 } 00297 }; 00298 00299 inline 00300 Node::~Node(void) {} 00301 00302 inline void 00303 Node::append(Node* newNode) { 00304 Array* a = dynamic_cast<Array*>(this); 00305 if (!a) 00306 throw TypeError("array expected"); 00307 a->a.push_back(newNode); 00308 } 00309 00310 inline bool 00311 Node::hasAtom(const std::string& id) { 00312 if (Array* a = dynamic_cast<Array*>(this)) { 00313 for (int i=a->a.size(); i--;) 00314 if (Atom* at = dynamic_cast<Atom*>(a->a[i])) 00315 if (at->id == id) 00316 return true; 00317 } else if (Atom* a = dynamic_cast<Atom*>(this)) { 00318 return a->id == id; 00319 } 00320 return false; 00321 } 00322 00323 inline bool 00324 Node::isCall(const std::string& id) { 00325 if (Call* a = dynamic_cast<Call*>(this)) { 00326 if (a->id == id) 00327 return true; 00328 } 00329 return false; 00330 } 00331 00332 inline Call* 00333 Node::getCall(void) { 00334 if (Call* a = dynamic_cast<Call*>(this)) 00335 return a; 00336 throw TypeError("call expected"); 00337 } 00338 00339 inline bool 00340 Node::hasCall(const std::string& id) { 00341 if (Array* a = dynamic_cast<Array*>(this)) { 00342 for (int i=a->a.size(); i--;) 00343 if (Call* at = dynamic_cast<Call*>(a->a[i])) 00344 if (at->id == id) { 00345 return true; 00346 } 00347 } else if (Call* a = dynamic_cast<Call*>(this)) { 00348 return a->id == id; 00349 } 00350 return false; 00351 } 00352 00353 inline bool 00354 Node::isInt(int& i) { 00355 if (IntLit* il = dynamic_cast<IntLit*>(this)) { 00356 i = il->i; 00357 return true; 00358 } 00359 return false; 00360 } 00361 00362 inline Call* 00363 Node::getCall(const std::string& id) { 00364 if (Array* a = dynamic_cast<Array*>(this)) { 00365 for (int i=a->a.size(); i--;) 00366 if (Call* at = dynamic_cast<Call*>(a->a[i])) 00367 if (at->id == id) 00368 return at; 00369 } else if (Call* a = dynamic_cast<Call*>(this)) { 00370 if (a->id == id) 00371 return a; 00372 } 00373 throw TypeError("call expected"); 00374 } 00375 00376 inline Array* 00377 Node::getArray(void) { 00378 if (Array* a = dynamic_cast<Array*>(this)) 00379 return a; 00380 throw TypeError("array expected"); 00381 } 00382 00383 inline Atom* 00384 Node::getAtom(void) { 00385 if (Atom* a = dynamic_cast<Atom*>(this)) 00386 return a; 00387 throw TypeError("atom expected"); 00388 } 00389 00390 inline int 00391 Node::getIntVar(void) { 00392 if (IntVar* a = dynamic_cast<IntVar*>(this)) 00393 return a->i; 00394 throw TypeError("integer variable expected"); 00395 } 00396 inline int 00397 Node::getBoolVar(void) { 00398 if (BoolVar* a = dynamic_cast<BoolVar*>(this)) 00399 return a->i; 00400 throw TypeError("bool variable expected"); 00401 } 00402 inline int 00403 Node::getSetVar(void) { 00404 if (SetVar* a = dynamic_cast<SetVar*>(this)) 00405 return a->i; 00406 throw TypeError("set variable expected"); 00407 } 00408 inline int 00409 Node::getInt(void) { 00410 if (IntLit* a = dynamic_cast<IntLit*>(this)) 00411 return a->i; 00412 throw TypeError("integer literal expected"); 00413 } 00414 inline bool 00415 Node::getBool(void) { 00416 if (BoolLit* a = dynamic_cast<BoolLit*>(this)) 00417 return a->b; 00418 throw TypeError("bool literal expected"); 00419 } 00420 inline double 00421 Node::getFloat(void) { 00422 if (FloatLit* a = dynamic_cast<FloatLit*>(this)) 00423 return a->d; 00424 throw TypeError("float literal expected"); 00425 } 00426 inline SetLit* 00427 Node::getSet(void) { 00428 if (SetLit* a = dynamic_cast<SetLit*>(this)) 00429 return a; 00430 throw TypeError("set literal expected"); 00431 } 00432 inline std::string 00433 Node::getString(void) { 00434 if (String* a = dynamic_cast<String*>(this)) 00435 return a->s; 00436 throw TypeError("string literal expected"); 00437 } 00438 inline bool 00439 Node::isIntVar(void) { 00440 return (dynamic_cast<IntVar*>(this) != NULL); 00441 } 00442 inline bool 00443 Node::isBoolVar(void) { 00444 return (dynamic_cast<BoolVar*>(this) != NULL); 00445 } 00446 inline bool 00447 Node::isSetVar(void) { 00448 return (dynamic_cast<SetVar*>(this) != NULL); 00449 } 00450 inline bool 00451 Node::isInt(void) { 00452 return (dynamic_cast<IntLit*>(this) != NULL); 00453 } 00454 inline bool 00455 Node::isBool(void) { 00456 return (dynamic_cast<BoolLit*>(this) != NULL); 00457 } 00458 inline bool 00459 Node::isSet(void) { 00460 return (dynamic_cast<SetLit*>(this) != NULL); 00461 } 00462 inline bool 00463 Node::isString(void) { 00464 return (dynamic_cast<String*>(this) != NULL); 00465 } 00466 inline bool 00467 Node::isArray(void) { 00468 return (dynamic_cast<Array*>(this) != NULL); 00469 } 00470 inline bool 00471 Node::isAtom(void) { 00472 return (dynamic_cast<Atom*>(this) != NULL); 00473 } 00474 00475 inline Node* 00476 extractSingleton(Node* n) { 00477 if (Array* a = dynamic_cast<Array*>(n)) { 00478 if (a->a.size() == 1) { 00479 Node *ret = a->a[0]; 00480 a->a[0] = NULL; 00481 delete a; 00482 return ret; 00483 } 00484 } 00485 return n; 00486 } 00487 00488 }}} 00489 00490 #endif 00491 00492 // STATISTICS: flatzinc-any