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 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 std::cerr << "type error" << std::endl;
00307 std::exit(-1);
00308 }
00309 a->a.push_back(newNode);
00310 }
00311
00312 inline bool
00313 Node::hasAtom(const std::string& id) {
00314 if (Array* a = dynamic_cast<Array*>(this)) {
00315 for (int i=a->a.size(); i--;)
00316 if (Atom* at = dynamic_cast<Atom*>(a->a[i]))
00317 if (at->id == id)
00318 return true;
00319 } else if (Atom* a = dynamic_cast<Atom*>(this)) {
00320 return a->id == id;
00321 }
00322 return false;
00323 }
00324
00325 inline bool
00326 Node::isCall(const std::string& id) {
00327 if (Call* a = dynamic_cast<Call*>(this)) {
00328 if (a->id == id)
00329 return true;
00330 }
00331 return false;
00332 }
00333
00334 inline Call*
00335 Node::getCall(void) {
00336 if (Call* a = dynamic_cast<Call*>(this))
00337 return a;
00338 throw TypeError("call expected");
00339 }
00340
00341 inline bool
00342 Node::hasCall(const std::string& id) {
00343 if (Array* a = dynamic_cast<Array*>(this)) {
00344 for (int i=a->a.size(); i--;)
00345 if (Call* at = dynamic_cast<Call*>(a->a[i]))
00346 if (at->id == id) {
00347 return true;
00348 }
00349 } else if (Call* a = dynamic_cast<Call*>(this)) {
00350 return a->id == id;
00351 }
00352 return false;
00353 }
00354
00355 inline bool
00356 Node::isInt(int& i) {
00357 if (IntLit* il = dynamic_cast<IntLit*>(this)) {
00358 i = il->i;
00359 return true;
00360 }
00361 return false;
00362 }
00363
00364 inline Call*
00365 Node::getCall(const std::string& id) {
00366 if (Array* a = dynamic_cast<Array*>(this)) {
00367 for (int i=a->a.size(); i--;)
00368 if (Call* at = dynamic_cast<Call*>(a->a[i]))
00369 if (at->id == id)
00370 return at;
00371 } else if (Call* a = dynamic_cast<Call*>(this)) {
00372 if (a->id == id)
00373 return a;
00374 }
00375 throw TypeError("call expected");
00376 }
00377
00378 inline Array*
00379 Node::getArray(void) {
00380 if (Array* a = dynamic_cast<Array*>(this))
00381 return a;
00382 throw TypeError("array expected");
00383 }
00384
00385 inline Atom*
00386 Node::getAtom(void) {
00387 if (Atom* a = dynamic_cast<Atom*>(this))
00388 return a;
00389 throw TypeError("atom expected");
00390 }
00391
00392 inline int
00393 Node::getIntVar(void) {
00394 if (IntVar* a = dynamic_cast<IntVar*>(this))
00395 return a->i;
00396 throw TypeError("integer variable expected");
00397 }
00398 inline int
00399 Node::getBoolVar(void) {
00400 if (BoolVar* a = dynamic_cast<BoolVar*>(this))
00401 return a->i;
00402 throw TypeError("bool variable expected");
00403 }
00404 inline int
00405 Node::getSetVar(void) {
00406 if (SetVar* a = dynamic_cast<SetVar*>(this))
00407 return a->i;
00408 throw TypeError("set variable expected");
00409 }
00410 inline int
00411 Node::getInt(void) {
00412 if (IntLit* a = dynamic_cast<IntLit*>(this))
00413 return a->i;
00414 throw TypeError("integer literal expected");
00415 }
00416 inline bool
00417 Node::getBool(void) {
00418 if (BoolLit* a = dynamic_cast<BoolLit*>(this))
00419 return a->b;
00420 throw TypeError("bool literal expected");
00421 }
00422 inline double
00423 Node::getFloat(void) {
00424 if (FloatLit* a = dynamic_cast<FloatLit*>(this))
00425 return a->d;
00426 throw TypeError("float literal expected");
00427 }
00428 inline SetLit*
00429 Node::getSet(void) {
00430 if (SetLit* a = dynamic_cast<SetLit*>(this))
00431 return a;
00432 throw TypeError("set literal expected");
00433 }
00434 inline std::string
00435 Node::getString(void) {
00436 if (String* a = dynamic_cast<String*>(this))
00437 return a->s;
00438 throw TypeError("string literal expected");
00439 }
00440 inline bool
00441 Node::isIntVar(void) {
00442 return (dynamic_cast<IntVar*>(this) != NULL);
00443 }
00444 inline bool
00445 Node::isBoolVar(void) {
00446 return (dynamic_cast<BoolVar*>(this) != NULL);
00447 }
00448 inline bool
00449 Node::isSetVar(void) {
00450 return (dynamic_cast<SetVar*>(this) != NULL);
00451 }
00452 inline bool
00453 Node::isInt(void) {
00454 return (dynamic_cast<IntLit*>(this) != NULL);
00455 }
00456 inline bool
00457 Node::isBool(void) {
00458 return (dynamic_cast<BoolLit*>(this) != NULL);
00459 }
00460 inline bool
00461 Node::isSet(void) {
00462 return (dynamic_cast<SetLit*>(this) != NULL);
00463 }
00464 inline bool
00465 Node::isString(void) {
00466 return (dynamic_cast<String*>(this) != NULL);
00467 }
00468 inline bool
00469 Node::isArray(void) {
00470 return (dynamic_cast<Array*>(this) != NULL);
00471 }
00472 inline bool
00473 Node::isAtom(void) {
00474 return (dynamic_cast<Atom*>(this) != NULL);
00475 }
00476
00477 inline Node*
00478 extractSingleton(Node* n) {
00479 if (Array* a = dynamic_cast<Array*>(n)) {
00480 if (a->a.size() == 1) {
00481 Node *ret = a->a[0];
00482 a->a[0] = NULL;
00483 delete a;
00484 return ret;
00485 }
00486 }
00487 return n;
00488 }
00489
00490 }}}
00491
00492 #endif
00493
00494