ast.hh
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef __GECODE_FLATZINC_AST_HH__
00035 #define __GECODE_FLATZINC_AST_HH__
00036
00037 #include <vector>
00038 #include <string>
00039 #include <iostream>
00040 #include <cstdlib>
00041
00047 namespace Gecode { namespace FlatZinc { namespace AST {
00048
00049 class Call;
00050 class Array;
00051 class Atom;
00052 class SetLit;
00053
00055 class GECODE_VTABLE_EXPORT TypeError {
00056 private:
00057 std::string _what;
00058 public:
00059 TypeError() : _what("") {}
00060 TypeError(std::string what) : _what(what) {}
00061 std::string what(void) const { return _what; }
00062 };
00063
00067 class GECODE_VTABLE_EXPORT Node {
00068 public:
00070 virtual ~Node(void);
00071
00073 void append(Node* n);
00074
00076 bool hasAtom(const std::string& id);
00078 bool isInt(int& i);
00080 bool isFloat(double& i);
00082 bool isCall(const std::string& id);
00084 Call* getCall(void);
00086 bool hasCall(const std::string& id);
00088 Call* getCall(const std::string& id);
00090 Array* getArray(void);
00092 Atom* getAtom(void);
00094 std::string getVarName(void);
00096 int getIntVar(void);
00098 int getBoolVar(void);
00100 int getFloatVar(void);
00102 int getSetVar(void);
00103
00105 int getInt(void);
00107 bool getBool(void);
00109 double getFloat(void);
00111 SetLit *getSet(void);
00112
00114 std::string getString(void);
00115
00117 bool isIntVar(void);
00119 bool isBoolVar(void);
00121 bool isSetVar(void);
00123 bool isFloatVar(void);
00125 bool isInt(void);
00127 bool isFloat(void);
00129 bool isBool(void);
00131 bool isString(void);
00133 bool isArray(void);
00135 bool isSet(void);
00137 bool isAtom(void);
00138
00140 virtual void print(std::ostream&) = 0;
00141 };
00142
00144 class GECODE_VTABLE_EXPORT BoolLit : public Node {
00145 public:
00146 bool b;
00147 BoolLit(bool b0) : b(b0) {}
00148 virtual void print(std::ostream& os) {
00149 os << "b(" << (b ? "true" : "false") << ")";
00150 }
00151 };
00153 class GECODE_VTABLE_EXPORT IntLit : public Node {
00154 public:
00155 int i;
00156 IntLit(int i0) : i(i0) {}
00157 virtual void print(std::ostream& os) {
00158 os << "i("<<i<<")";
00159 }
00160 };
00162 class GECODE_VTABLE_EXPORT FloatLit : public Node {
00163 public:
00164 double d;
00165 FloatLit(double d0) : d(d0) {}
00166 virtual void print(std::ostream& os) {
00167 os << "f("<<d<<")";
00168 }
00169 };
00171 class GECODE_VTABLE_EXPORT SetLit : public Node {
00172 public:
00173 bool interval;
00174 int min; int max;
00175 std::vector<int> s;
00176 SetLit(void) {}
00177 SetLit(int min0, int max0) : interval(true), min(min0), max(max0) {}
00178 SetLit(const std::vector<int>& s0) : interval(false), s(s0) {}
00179 explicit SetLit(SetLit* s0) : interval(s0->interval), min(s0->min), max(s0->max), s(s0->s) {}
00180 bool empty(void) const {
00181 return ( (interval && min>max) || (!interval && s.size() == 0));
00182 }
00183 virtual void print(std::ostream& os) {
00184 os << "s()";
00185 }
00186 };
00187
00189 class GECODE_VTABLE_EXPORT Var : public Node {
00190 public:
00191 int i;
00192 std::string n;
00194 Var(int i0, const std::string& n0) : i(i0), n(n0) {}
00195 };
00197 class GECODE_VTABLE_EXPORT BoolVar : public Var {
00198 public:
00200 BoolVar(int i0, const std::string& n0="") : Var(i0,n0) {}
00201 virtual void print(std::ostream& os) {
00202 os << "xb("<<i<<")";
00203 }
00204 };
00206 class GECODE_VTABLE_EXPORT IntVar : public Var {
00207 public:
00208 IntVar(int i0, const std::string& n0="") : Var(i0,n0) {}
00209 virtual void print(std::ostream& os) {
00210 os << "xi("<<i<<")";
00211 }
00212 };
00214 class GECODE_VTABLE_EXPORT FloatVar : public Var {
00215 public:
00216 FloatVar(int i0, const std::string& n0="") : Var(i0,n0) {}
00217 virtual void print(std::ostream& os) {
00218 os << "xf("<<i<<")";
00219 }
00220 };
00222 class GECODE_VTABLE_EXPORT SetVar : public Var {
00223 public:
00224 SetVar(int i0, const std::string& n0="") : Var(i0,n0) {}
00225 virtual void print(std::ostream& os) {
00226 os << "xs("<<i<<")";
00227 }
00228 };
00229
00231 class GECODE_VTABLE_EXPORT Array : public Node {
00232 public:
00233 std::vector<Node*> a;
00234 Array(const std::vector<Node*>& a0)
00235 : a(a0) {}
00236 Array(Node* n)
00237 : a(1) { a[0] = n; }
00238 Array(int n=0) : a(n) {}
00239 virtual void print(std::ostream& os) {
00240 os << "[";
00241 for (unsigned int i=0; i<a.size(); i++) {
00242 a[i]->print(os);
00243 if (i<a.size()-1)
00244 os << ", ";
00245 }
00246 os << "]";
00247 }
00248 ~Array(void) {
00249 for (int i=a.size(); i--;)
00250 delete a[i];
00251 }
00252 };
00253
00255 class GECODE_VTABLE_EXPORT Call : public Node {
00256 public:
00257 std::string id;
00258 Node* args;
00259 Call(const std::string& id0, Node* args0)
00260 : id(id0), args(args0) {}
00261 ~Call(void) { delete args; }
00262 virtual void print(std::ostream& os) {
00263 os << id << "("; args->print(os); os << ")";
00264 }
00265 Array* getArgs(unsigned int n) {
00266 Array *a = args->getArray();
00267 if (a->a.size() != n)
00268 throw TypeError("arity mismatch");
00269 return a;
00270 }
00271 };
00272
00274 class GECODE_VTABLE_EXPORT ArrayAccess : public Node {
00275 public:
00276 Node* a;
00277 Node* idx;
00278 ArrayAccess(Node* a0, Node* idx0)
00279 : a(a0), idx(idx0) {}
00280 ~ArrayAccess(void) { delete a; delete idx; }
00281 virtual void print(std::ostream& os) {
00282 a->print(os);
00283 os << "[";
00284 idx->print(os);
00285 os << "]";
00286 }
00287 };
00288
00290 class GECODE_VTABLE_EXPORT Atom : public Node {
00291 public:
00292 std::string id;
00293 Atom(const std::string& id0) : id(id0) {}
00294 virtual void print(std::ostream& os) {
00295 os << id;
00296 }
00297 };
00298
00300 class GECODE_VTABLE_EXPORT String : public Node {
00301 public:
00302 std::string s;
00303 String(const std::string& s0) : s(s0) {}
00304 virtual void print(std::ostream& os) {
00305 os << "s(\"" << s << "\")";
00306 }
00307 };
00308
00309 inline
00310 Node::~Node(void) {}
00311
00312 inline void
00313 Node::append(Node* newNode) {
00314 Array* a = dynamic_cast<Array*>(this);
00315 if (!a)
00316 throw TypeError("array expected");
00317 a->a.push_back(newNode);
00318 }
00319
00320 inline bool
00321 Node::hasAtom(const std::string& id) {
00322 if (Array* a = dynamic_cast<Array*>(this)) {
00323 for (int i=a->a.size(); i--;)
00324 if (Atom* at = dynamic_cast<Atom*>(a->a[i]))
00325 if (at->id == id)
00326 return true;
00327 } else if (Atom* a = dynamic_cast<Atom*>(this)) {
00328 return a->id == id;
00329 }
00330 return false;
00331 }
00332
00333 inline bool
00334 Node::isCall(const std::string& id) {
00335 if (Call* a = dynamic_cast<Call*>(this)) {
00336 if (a->id == id)
00337 return true;
00338 }
00339 return false;
00340 }
00341
00342 inline Call*
00343 Node::getCall(void) {
00344 if (Call* a = dynamic_cast<Call*>(this))
00345 return a;
00346 throw TypeError("call expected");
00347 }
00348
00349 inline bool
00350 Node::hasCall(const std::string& id) {
00351 if (Array* a = dynamic_cast<Array*>(this)) {
00352 for (int i=a->a.size(); i--;)
00353 if (Call* at = dynamic_cast<Call*>(a->a[i]))
00354 if (at->id == id) {
00355 return true;
00356 }
00357 } else if (Call* a = dynamic_cast<Call*>(this)) {
00358 return a->id == id;
00359 }
00360 return false;
00361 }
00362
00363 inline bool
00364 Node::isInt(int& i) {
00365 if (IntLit* il = dynamic_cast<IntLit*>(this)) {
00366 i = il->i;
00367 return true;
00368 }
00369 return false;
00370 }
00371
00372 inline bool
00373 Node::isFloat(double& d) {
00374 if (FloatLit* fl = dynamic_cast<FloatLit*>(this)) {
00375 d = fl->d;
00376 return true;
00377 }
00378 return false;
00379 }
00380
00381 inline Call*
00382 Node::getCall(const std::string& id) {
00383 if (Array* a = dynamic_cast<Array*>(this)) {
00384 for (int i=a->a.size(); i--;)
00385 if (Call* at = dynamic_cast<Call*>(a->a[i]))
00386 if (at->id == id)
00387 return at;
00388 } else if (Call* a = dynamic_cast<Call*>(this)) {
00389 if (a->id == id)
00390 return a;
00391 }
00392 throw TypeError("call expected");
00393 }
00394
00395 inline Array*
00396 Node::getArray(void) {
00397 if (Array* a = dynamic_cast<Array*>(this))
00398 return a;
00399 throw TypeError("array expected");
00400 }
00401
00402 inline Atom*
00403 Node::getAtom(void) {
00404 if (Atom* a = dynamic_cast<Atom*>(this))
00405 return a;
00406 throw TypeError("atom expected");
00407 }
00408
00409 inline std::string
00410 Node::getVarName(void) {
00411 if (Var* a = dynamic_cast<Var*>(this))
00412 return a->n;
00413 throw TypeError("variable expected");
00414 }
00415 inline int
00416 Node::getIntVar(void) {
00417 if (IntVar* a = dynamic_cast<IntVar*>(this))
00418 return a->i;
00419 throw TypeError("integer variable expected");
00420 }
00421 inline int
00422 Node::getBoolVar(void) {
00423 if (BoolVar* a = dynamic_cast<BoolVar*>(this))
00424 return a->i;
00425 throw TypeError("bool variable expected");
00426 }
00427 inline int
00428 Node::getFloatVar(void) {
00429 if (FloatVar* a = dynamic_cast<FloatVar*>(this))
00430 return a->i;
00431 throw TypeError("integer variable expected");
00432 }
00433 inline int
00434 Node::getSetVar(void) {
00435 if (SetVar* a = dynamic_cast<SetVar*>(this))
00436 return a->i;
00437 throw TypeError("set variable expected");
00438 }
00439 inline int
00440 Node::getInt(void) {
00441 if (IntLit* a = dynamic_cast<IntLit*>(this))
00442 return a->i;
00443 throw TypeError("integer literal expected");
00444 }
00445 inline bool
00446 Node::getBool(void) {
00447 if (BoolLit* a = dynamic_cast<BoolLit*>(this))
00448 return a->b;
00449 throw TypeError("bool literal expected");
00450 }
00451 inline double
00452 Node::getFloat(void) {
00453 if (FloatLit* a = dynamic_cast<FloatLit*>(this))
00454 return a->d;
00455 throw TypeError("float literal expected");
00456 }
00457 inline SetLit*
00458 Node::getSet(void) {
00459 if (SetLit* a = dynamic_cast<SetLit*>(this))
00460 return a;
00461 throw TypeError("set literal expected");
00462 }
00463 inline std::string
00464 Node::getString(void) {
00465 if (String* a = dynamic_cast<String*>(this))
00466 return a->s;
00467 throw TypeError("string literal expected");
00468 }
00469 inline bool
00470 Node::isIntVar(void) {
00471 return (dynamic_cast<IntVar*>(this) != NULL);
00472 }
00473 inline bool
00474 Node::isBoolVar(void) {
00475 return (dynamic_cast<BoolVar*>(this) != NULL);
00476 }
00477 inline bool
00478 Node::isSetVar(void) {
00479 return (dynamic_cast<SetVar*>(this) != NULL);
00480 }
00481 inline bool
00482 Node::isFloatVar(void) {
00483 return (dynamic_cast<FloatVar*>(this) != NULL);
00484 }
00485 inline bool
00486 Node::isInt(void) {
00487 return (dynamic_cast<IntLit*>(this) != NULL);
00488 }
00489 inline bool
00490 Node::isBool(void) {
00491 return (dynamic_cast<BoolLit*>(this) != NULL);
00492 }
00493 inline bool
00494 Node::isFloat(void) {
00495 return (dynamic_cast<FloatLit*>(this) != NULL);
00496 }
00497 inline bool
00498 Node::isSet(void) {
00499 return (dynamic_cast<SetLit*>(this) != NULL);
00500 }
00501 inline bool
00502 Node::isString(void) {
00503 return (dynamic_cast<String*>(this) != NULL);
00504 }
00505 inline bool
00506 Node::isArray(void) {
00507 return (dynamic_cast<Array*>(this) != NULL);
00508 }
00509 inline bool
00510 Node::isAtom(void) {
00511 return (dynamic_cast<Atom*>(this) != NULL);
00512 }
00513
00514 inline Node*
00515 extractSingleton(Node* n) {
00516 if (Array* a = dynamic_cast<Array*>(n)) {
00517 if (a->a.size() == 1) {
00518 Node *ret = a->a[0];
00519 a->a[0] = NULL;
00520 delete a;
00521 return ret;
00522 }
00523 }
00524 return n;
00525 }
00526
00527 }}}
00528
00529 #endif
00530
00531