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
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 GECODE_VTABLE_EXPORT 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 GECODE_VTABLE_EXPORT 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 isFloat(double& i);
00086 bool isCall(const std::string& id);
00088 Call* getCall(void);
00090 bool hasCall(const std::string& id);
00092 Call* getCall(const std::string& id);
00094 Array* getArray(void);
00096 Atom* getAtom(void);
00098 int getIntVar(void);
00100 int getBoolVar(void);
00102 int getFloatVar(void);
00104 int getSetVar(void);
00105
00107 int getInt(void);
00109 bool getBool(void);
00111 double getFloat(void);
00113 SetLit *getSet(void);
00114
00116 std::string getString(void);
00117
00119 bool isIntVar(void);
00121 bool isBoolVar(void);
00123 bool isSetVar(void);
00125 bool isFloatVar(void);
00127 bool isInt(void);
00129 bool isFloat(void);
00131 bool isBool(void);
00133 bool isString(void);
00135 bool isArray(void);
00137 bool isSet(void);
00139 bool isAtom(void);
00140
00142 virtual void print(std::ostream&) = 0;
00143 };
00144
00146 class GECODE_VTABLE_EXPORT BoolLit : public Node {
00147 public:
00148 bool b;
00149 BoolLit(bool b0) : b(b0) {}
00150 virtual void print(std::ostream& os) {
00151 os << "b(" << (b ? "true" : "false") << ")";
00152 }
00153 };
00155 class GECODE_VTABLE_EXPORT IntLit : public Node {
00156 public:
00157 int i;
00158 IntLit(int i0) : i(i0) {}
00159 virtual void print(std::ostream& os) {
00160 os << "i("<<i<<")";
00161 }
00162 };
00164 class GECODE_VTABLE_EXPORT FloatLit : public Node {
00165 public:
00166 double d;
00167 FloatLit(double d0) : d(d0) {}
00168 virtual void print(std::ostream& os) {
00169 os << "f("<<d<<")";
00170 }
00171 };
00173 class GECODE_VTABLE_EXPORT SetLit : public Node {
00174 public:
00175 bool interval;
00176 int min; int max;
00177 std::vector<int> s;
00178 SetLit(void) {}
00179 SetLit(int min0, int max0) : interval(true), min(min0), max(max0) {}
00180 SetLit(const std::vector<int>& s0) : interval(false), s(s0) {}
00181 bool empty(void) const {
00182 return ( (interval && min>max) || (!interval && s.size() == 0));
00183 }
00184 virtual void print(std::ostream& os) {
00185 os << "s()";
00186 }
00187 };
00188
00190 class GECODE_VTABLE_EXPORT Var : public Node {
00191 public:
00192 int i;
00193 Var(int i0) : i(i0) {}
00194 };
00196 class GECODE_VTABLE_EXPORT BoolVar : public Var {
00197 public:
00198 BoolVar(int i0) : Var(i0) {}
00199 virtual void print(std::ostream& os) {
00200 os << "xb("<<i<<")";
00201 }
00202 };
00204 class GECODE_VTABLE_EXPORT IntVar : public Var {
00205 public:
00206 IntVar(int i0) : Var(i0) {}
00207 virtual void print(std::ostream& os) {
00208 os << "xi("<<i<<")";
00209 }
00210 };
00212 class GECODE_VTABLE_EXPORT FloatVar : public Var {
00213 public:
00214 FloatVar(int i0) : Var(i0) {}
00215 virtual void print(std::ostream& os) {
00216 os << "xf("<<i<<")";
00217 }
00218 };
00220 class GECODE_VTABLE_EXPORT SetVar : public Var {
00221 public:
00222 SetVar(int i0) : Var(i0) {}
00223 virtual void print(std::ostream& os) {
00224 os << "xs("<<i<<")";
00225 }
00226 };
00227
00229 class GECODE_VTABLE_EXPORT Array : public Node {
00230 public:
00231 std::vector<Node*> a;
00232 Array(const std::vector<Node*>& a0)
00233 : a(a0) {}
00234 Array(Node* n)
00235 : a(1) { a[0] = n; }
00236 Array(int n=0) : a(n) {}
00237 virtual void print(std::ostream& os) {
00238 os << "[";
00239 for (unsigned int i=0; i<a.size(); i++) {
00240 a[i]->print(os);
00241 if (i<a.size()-1)
00242 os << ", ";
00243 }
00244 os << "]";
00245 }
00246 ~Array(void) {
00247 for (int i=a.size(); i--;)
00248 delete a[i];
00249 }
00250 };
00251
00253 class GECODE_VTABLE_EXPORT Call : public Node {
00254 public:
00255 std::string id;
00256 Node* args;
00257 Call(const std::string& id0, Node* args0)
00258 : id(id0), args(args0) {}
00259 ~Call(void) { delete args; }
00260 virtual void print(std::ostream& os) {
00261 os << id << "("; args->print(os); os << ")";
00262 }
00263 Array* getArgs(unsigned int n) {
00264 Array *a = args->getArray();
00265 if (a->a.size() != n)
00266 throw TypeError("arity mismatch");
00267 return a;
00268 }
00269 };
00270
00272 class GECODE_VTABLE_EXPORT ArrayAccess : public Node {
00273 public:
00274 Node* a;
00275 Node* idx;
00276 ArrayAccess(Node* a0, Node* idx0)
00277 : a(a0), idx(idx0) {}
00278 ~ArrayAccess(void) { delete a; delete idx; }
00279 virtual void print(std::ostream& os) {
00280 a->print(os);
00281 os << "[";
00282 idx->print(os);
00283 os << "]";
00284 }
00285 };
00286
00288 class GECODE_VTABLE_EXPORT Atom : public Node {
00289 public:
00290 std::string id;
00291 Atom(const std::string& id0) : id(id0) {}
00292 virtual void print(std::ostream& os) {
00293 os << id;
00294 }
00295 };
00296
00298 class GECODE_VTABLE_EXPORT String : public Node {
00299 public:
00300 std::string s;
00301 String(const std::string& s0) : s(s0) {}
00302 virtual void print(std::ostream& os) {
00303 os << "s(\"" << s << "\")";
00304 }
00305 };
00306
00307 inline
00308 Node::~Node(void) {}
00309
00310 inline void
00311 Node::append(Node* newNode) {
00312 Array* a = dynamic_cast<Array*>(this);
00313 if (!a)
00314 throw TypeError("array expected");
00315 a->a.push_back(newNode);
00316 }
00317
00318 inline bool
00319 Node::hasAtom(const std::string& id) {
00320 if (Array* a = dynamic_cast<Array*>(this)) {
00321 for (int i=a->a.size(); i--;)
00322 if (Atom* at = dynamic_cast<Atom*>(a->a[i]))
00323 if (at->id == id)
00324 return true;
00325 } else if (Atom* a = dynamic_cast<Atom*>(this)) {
00326 return a->id == id;
00327 }
00328 return false;
00329 }
00330
00331 inline bool
00332 Node::isCall(const std::string& id) {
00333 if (Call* a = dynamic_cast<Call*>(this)) {
00334 if (a->id == id)
00335 return true;
00336 }
00337 return false;
00338 }
00339
00340 inline Call*
00341 Node::getCall(void) {
00342 if (Call* a = dynamic_cast<Call*>(this))
00343 return a;
00344 throw TypeError("call expected");
00345 }
00346
00347 inline bool
00348 Node::hasCall(const std::string& id) {
00349 if (Array* a = dynamic_cast<Array*>(this)) {
00350 for (int i=a->a.size(); i--;)
00351 if (Call* at = dynamic_cast<Call*>(a->a[i]))
00352 if (at->id == id) {
00353 return true;
00354 }
00355 } else if (Call* a = dynamic_cast<Call*>(this)) {
00356 return a->id == id;
00357 }
00358 return false;
00359 }
00360
00361 inline bool
00362 Node::isInt(int& i) {
00363 if (IntLit* il = dynamic_cast<IntLit*>(this)) {
00364 i = il->i;
00365 return true;
00366 }
00367 return false;
00368 }
00369
00370 inline bool
00371 Node::isFloat(double& d) {
00372 if (FloatLit* fl = dynamic_cast<FloatLit*>(this)) {
00373 d = fl->d;
00374 return true;
00375 }
00376 return false;
00377 }
00378
00379 inline Call*
00380 Node::getCall(const std::string& id) {
00381 if (Array* a = dynamic_cast<Array*>(this)) {
00382 for (int i=a->a.size(); i--;)
00383 if (Call* at = dynamic_cast<Call*>(a->a[i]))
00384 if (at->id == id)
00385 return at;
00386 } else if (Call* a = dynamic_cast<Call*>(this)) {
00387 if (a->id == id)
00388 return a;
00389 }
00390 throw TypeError("call expected");
00391 }
00392
00393 inline Array*
00394 Node::getArray(void) {
00395 if (Array* a = dynamic_cast<Array*>(this))
00396 return a;
00397 throw TypeError("array expected");
00398 }
00399
00400 inline Atom*
00401 Node::getAtom(void) {
00402 if (Atom* a = dynamic_cast<Atom*>(this))
00403 return a;
00404 throw TypeError("atom expected");
00405 }
00406
00407 inline int
00408 Node::getIntVar(void) {
00409 if (IntVar* a = dynamic_cast<IntVar*>(this))
00410 return a->i;
00411 throw TypeError("integer variable expected");
00412 }
00413 inline int
00414 Node::getBoolVar(void) {
00415 if (BoolVar* a = dynamic_cast<BoolVar*>(this))
00416 return a->i;
00417 throw TypeError("bool variable expected");
00418 }
00419 inline int
00420 Node::getFloatVar(void) {
00421 if (FloatVar* a = dynamic_cast<FloatVar*>(this))
00422 return a->i;
00423 throw TypeError("integer variable expected");
00424 }
00425 inline int
00426 Node::getSetVar(void) {
00427 if (SetVar* a = dynamic_cast<SetVar*>(this))
00428 return a->i;
00429 throw TypeError("set variable expected");
00430 }
00431 inline int
00432 Node::getInt(void) {
00433 if (IntLit* a = dynamic_cast<IntLit*>(this))
00434 return a->i;
00435 throw TypeError("integer literal expected");
00436 }
00437 inline bool
00438 Node::getBool(void) {
00439 if (BoolLit* a = dynamic_cast<BoolLit*>(this))
00440 return a->b;
00441 throw TypeError("bool literal expected");
00442 }
00443 inline double
00444 Node::getFloat(void) {
00445 if (FloatLit* a = dynamic_cast<FloatLit*>(this))
00446 return a->d;
00447 throw TypeError("float literal expected");
00448 }
00449 inline SetLit*
00450 Node::getSet(void) {
00451 if (SetLit* a = dynamic_cast<SetLit*>(this))
00452 return a;
00453 throw TypeError("set literal expected");
00454 }
00455 inline std::string
00456 Node::getString(void) {
00457 if (String* a = dynamic_cast<String*>(this))
00458 return a->s;
00459 throw TypeError("string literal expected");
00460 }
00461 inline bool
00462 Node::isIntVar(void) {
00463 return (dynamic_cast<IntVar*>(this) != NULL);
00464 }
00465 inline bool
00466 Node::isBoolVar(void) {
00467 return (dynamic_cast<BoolVar*>(this) != NULL);
00468 }
00469 inline bool
00470 Node::isSetVar(void) {
00471 return (dynamic_cast<SetVar*>(this) != NULL);
00472 }
00473 inline bool
00474 Node::isFloatVar(void) {
00475 return (dynamic_cast<FloatVar*>(this) != NULL);
00476 }
00477 inline bool
00478 Node::isInt(void) {
00479 return (dynamic_cast<IntLit*>(this) != NULL);
00480 }
00481 inline bool
00482 Node::isBool(void) {
00483 return (dynamic_cast<BoolLit*>(this) != NULL);
00484 }
00485 inline bool
00486 Node::isFloat(void) {
00487 return (dynamic_cast<FloatLit*>(this) != NULL);
00488 }
00489 inline bool
00490 Node::isSet(void) {
00491 return (dynamic_cast<SetLit*>(this) != NULL);
00492 }
00493 inline bool
00494 Node::isString(void) {
00495 return (dynamic_cast<String*>(this) != NULL);
00496 }
00497 inline bool
00498 Node::isArray(void) {
00499 return (dynamic_cast<Array*>(this) != NULL);
00500 }
00501 inline bool
00502 Node::isAtom(void) {
00503 return (dynamic_cast<Atom*>(this) != NULL);
00504 }
00505
00506 inline Node*
00507 extractSingleton(Node* n) {
00508 if (Array* a = dynamic_cast<Array*>(n)) {
00509 if (a->a.size() == 1) {
00510 Node *ret = a->a[0];
00511 a->a[0] = NULL;
00512 delete a;
00513 return ret;
00514 }
00515 }
00516 return n;
00517 }
00518
00519 }}}
00520
00521 #endif
00522
00523