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 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 GECODE_VTABLE_EXPORT 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 GECODE_VTABLE_EXPORT 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 GECODE_VTABLE_EXPORT 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 GECODE_VTABLE_EXPORT 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 GECODE_VTABLE_EXPORT Var : public Node {
00183 public:
00184 int i;
00185 Var(int i0) : i(i0) {}
00186 };
00188 class GECODE_VTABLE_EXPORT 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 GECODE_VTABLE_EXPORT 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 GECODE_VTABLE_EXPORT 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 GECODE_VTABLE_EXPORT 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 GECODE_VTABLE_EXPORT 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 GECODE_VTABLE_EXPORT 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 GECODE_VTABLE_EXPORT 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 GECODE_VTABLE_EXPORT 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 GECODE_VTABLE_EXPORT 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