this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Guido Tack <tack@gecode.org> 5 * 6 * Copyright: 7 * Guido Tack, 2007 8 * 9 * This file is part of Gecode, the generic constraint 10 * development environment: 11 * http://www.gecode.org 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining 14 * a copy of this software and associated documentation files (the 15 * "Software"), to deal in the Software without restriction, including 16 * without limitation the rights to use, copy, modify, merge, publish, 17 * distribute, sublicense, and/or sell copies of the Software, and to 18 * permit persons to whom the Software is furnished to do so, subject to 19 * the following conditions: 20 * 21 * The above copyright notice and this permission notice shall be 22 * included in all copies or substantial portions of the Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 28 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 29 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31 * 32 */ 33 34#ifndef GECODE_FLATZINC_AST_HH 35#define GECODE_FLATZINC_AST_HH 36 37#include <vector> 38#include <string> 39#include <iostream> 40#include <cstdlib> 41 42/** 43 * \namespace Gecode::FlatZinc::AST 44 * \brief Abstract syntax trees for the %FlatZinc interpreter 45 */ 46 47namespace Gecode { namespace FlatZinc { namespace AST { 48 49 class Call; 50 class Array; 51 class Atom; 52 class SetLit; 53 54 /// %Exception signaling type error 55 class GECODE_VTABLE_EXPORT TypeError { 56 private: 57 std::string _what; 58 public: 59 TypeError() : _what("") {} 60 TypeError(std::string what) : _what(what) {} 61 std::string what(void) const { return _what; } 62 }; 63 64 /** 65 * \brief A node in a %FlatZinc abstract syntax tree 66 */ 67 class GECODE_VTABLE_EXPORT Node { 68 public: 69 /// Destructor 70 virtual ~Node(void); 71 72 /// Append \a n to an array node 73 void append(Node* n); 74 75 /// Test if node has atom with \a id 76 bool hasAtom(const std::string& id); 77 /// Test if node is int, if yes set \a i to the value 78 bool isInt(int& i); 79 /// Test if node is float, if yes set \a d to the value 80 bool isFloat(double& i); 81 /// Test if node is function call with \a id 82 bool isCall(const std::string& id); 83 /// Return function call 84 Call* getCall(void); 85 /// Test if node is function call or array containing function call \a id 86 bool hasCall(const std::string& id); 87 /// Return function call \a id 88 Call* getCall(const std::string& id); 89 /// Cast this node to an array node 90 Array* getArray(void); 91 /// Cast this node to an Atom node 92 Atom* getAtom(void); 93 /// Return name of variable represented by this node 94 std::string getVarName(void); 95 /// Cast this node to an integer variable node 96 int getIntVar(void); 97 /// Cast this node to a Boolean variable node 98 int getBoolVar(void); 99 /// Cast this node to a Float variable node 100 int getFloatVar(void); 101 /// Cast this node to a set variable node 102 int getSetVar(void); 103 104 /// Cast this node to an integer node 105 int getInt(void); 106 /// Cast this node to a Boolean node 107 bool getBool(void); 108 /// Cast this node to a Float node 109 double getFloat(void); 110 /// Cast this node to a set literal node 111 SetLit *getSet(void); 112 113 /// Cast this node to a string node 114 std::string getString(void); 115 116 /// Test if node is an integer variable node 117 bool isIntVar(void); 118 /// Test if node is a Boolean variable node 119 bool isBoolVar(void); 120 /// Test if node is a set variable node 121 bool isSetVar(void); 122 /// Test if node is a float variable node 123 bool isFloatVar(void); 124 /// Test if node is an integer node 125 bool isInt(void); 126 /// Test if node is a float node 127 bool isFloat(void); 128 /// Test if node is a Boolean node 129 bool isBool(void); 130 /// Test if node is a string node 131 bool isString(void); 132 /// Test if node is an array node 133 bool isArray(void); 134 /// Test if node is a set literal node 135 bool isSet(void); 136 /// Test if node is an atom node 137 bool isAtom(void); 138 139 /// Output string representation 140 virtual void print(std::ostream&) = 0; 141 }; 142 143 /// Boolean literal node 144 class GECODE_VTABLE_EXPORT BoolLit : public Node { 145 public: 146 bool b; 147 BoolLit(bool b0) : b(b0) {} 148 virtual void print(std::ostream& os) { 149 os << "b(" << (b ? "true" : "false") << ")"; 150 } 151 }; 152 /// Integer literal node 153 class GECODE_VTABLE_EXPORT IntLit : public Node { 154 public: 155 int i; 156 IntLit(int i0) : i(i0) {} 157 virtual void print(std::ostream& os) { 158 os << "i("<<i<<")"; 159 } 160 }; 161 /// Float literal node 162 class GECODE_VTABLE_EXPORT FloatLit : public Node { 163 public: 164 double d; 165 FloatLit(double d0) : d(d0) {} 166 virtual void print(std::ostream& os) { 167 os << "f("<<d<<")"; 168 } 169 }; 170 /// %Set literal node 171 class GECODE_VTABLE_EXPORT SetLit : public Node { 172 public: 173 bool interval; 174 int min; int max; 175 std::vector<int> s; 176 SetLit(void) {} 177 SetLit(int min0, int max0) : interval(true), min(min0), max(max0) {} 178 SetLit(const std::vector<int>& s0) : interval(false), s(s0) {} 179 explicit SetLit(SetLit* s0) : interval(s0->interval), min(s0->min), max(s0->max), s(s0->s) {} 180 bool empty(void) const { 181 return ( (interval && min>max) || (!interval && s.size() == 0)); 182 } 183 virtual void print(std::ostream& os) { 184 os << "s()"; 185 } 186 }; 187 188 /// Variable node base class 189 class GECODE_VTABLE_EXPORT Var : public Node { 190 public: 191 int i; //< Index 192 std::string n; //< Name 193 /// Constructor 194 Var(int i0, const std::string& n0) : i(i0), n(n0) {} 195 }; 196 /// Boolean variable node 197 class GECODE_VTABLE_EXPORT BoolVar : public Var { 198 public: 199 /// Constructor 200 BoolVar(int i0, const std::string& n0="") : Var(i0,n0) {} 201 virtual void print(std::ostream& os) { 202 os << "xb("<<i<<")"; 203 } 204 }; 205 /// Integer variable node 206 class GECODE_VTABLE_EXPORT IntVar : public Var { 207 public: 208 IntVar(int i0, const std::string& n0="") : Var(i0,n0) {} 209 virtual void print(std::ostream& os) { 210 os << "xi("<<i<<")"; 211 } 212 }; 213 /// Float variable node 214 class GECODE_VTABLE_EXPORT FloatVar : public Var { 215 public: 216 FloatVar(int i0, const std::string& n0="") : Var(i0,n0) {} 217 virtual void print(std::ostream& os) { 218 os << "xf("<<i<<")"; 219 } 220 }; 221 /// %Set variable node 222 class GECODE_VTABLE_EXPORT SetVar : public Var { 223 public: 224 SetVar(int i0, const std::string& n0="") : Var(i0,n0) {} 225 virtual void print(std::ostream& os) { 226 os << "xs("<<i<<")"; 227 } 228 }; 229 230 /// %Array node 231 class GECODE_VTABLE_EXPORT Array : public Node { 232 public: 233 std::vector<Node*> a; 234 Array(const std::vector<Node*>& a0) 235 : a(a0) {} 236 Array(Node* n) 237 : a(1) { a[0] = n; } 238 Array(int n=0) : a(n) {} 239 virtual void print(std::ostream& os) { 240 os << "["; 241 for (unsigned int i=0; i<a.size(); i++) { 242 a[i]->print(os); 243 if (i<a.size()-1) 244 os << ", "; 245 } 246 os << "]"; 247 } 248 ~Array(void) { 249 for (int i=a.size(); i--;) 250 delete a[i]; 251 } 252 }; 253 254 /// %Node representing a function call 255 class GECODE_VTABLE_EXPORT Call : public Node { 256 public: 257 std::string id; 258 Node* args; 259 Call(const std::string& id0, Node* args0) 260 : id(id0), args(args0) {} 261 ~Call(void) { delete args; } 262 virtual void print(std::ostream& os) { 263 os << id << "("; args->print(os); os << ")"; 264 } 265 Array* getArgs(unsigned int n) { 266 Array *a = args->getArray(); 267 if (a->a.size() != n) 268 throw TypeError("arity mismatch"); 269 return a; 270 } 271 }; 272 273 /// %Node representing an array access 274 class GECODE_VTABLE_EXPORT ArrayAccess : public Node { 275 public: 276 Node* a; 277 Node* idx; 278 ArrayAccess(Node* a0, Node* idx0) 279 : a(a0), idx(idx0) {} 280 ~ArrayAccess(void) { delete a; delete idx; } 281 virtual void print(std::ostream& os) { 282 a->print(os); 283 os << "["; 284 idx->print(os); 285 os << "]"; 286 } 287 }; 288 289 /// %Node representing an atom 290 class GECODE_VTABLE_EXPORT Atom : public Node { 291 public: 292 std::string id; 293 Atom(const std::string& id0) : id(id0) {} 294 virtual void print(std::ostream& os) { 295 os << id; 296 } 297 }; 298 299 /// %String node 300 class GECODE_VTABLE_EXPORT String : public Node { 301 public: 302 std::string s; 303 String(const std::string& s0) : s(s0) {} 304 virtual void print(std::ostream& os) { 305 os << "s(\"" << s << "\")"; 306 } 307 }; 308 309 inline 310 Node::~Node(void) {} 311 312 inline void 313 Node::append(Node* newNode) { 314 Array* a = dynamic_cast<Array*>(this); 315 if (!a) 316 throw TypeError("array expected"); 317 a->a.push_back(newNode); 318 } 319 320 inline bool 321 Node::hasAtom(const std::string& id) { 322 if (Array* a = dynamic_cast<Array*>(this)) { 323 for (int i=a->a.size(); i--;) 324 if (Atom* at = dynamic_cast<Atom*>(a->a[i])) 325 if (at->id == id) 326 return true; 327 } else if (Atom* a = dynamic_cast<Atom*>(this)) { 328 return a->id == id; 329 } 330 return false; 331 } 332 333 inline bool 334 Node::isCall(const std::string& id) { 335 if (Call* a = dynamic_cast<Call*>(this)) { 336 if (a->id == id) 337 return true; 338 } 339 return false; 340 } 341 342 inline Call* 343 Node::getCall(void) { 344 if (Call* a = dynamic_cast<Call*>(this)) 345 return a; 346 throw TypeError("call expected"); 347 } 348 349 inline bool 350 Node::hasCall(const std::string& id) { 351 if (Array* a = dynamic_cast<Array*>(this)) { 352 for (int i=a->a.size(); i--;) 353 if (Call* at = dynamic_cast<Call*>(a->a[i])) 354 if (at->id == id) { 355 return true; 356 } 357 } else if (Call* a = dynamic_cast<Call*>(this)) { 358 return a->id == id; 359 } 360 return false; 361 } 362 363 inline bool 364 Node::isInt(int& i) { 365 if (IntLit* il = dynamic_cast<IntLit*>(this)) { 366 i = il->i; 367 return true; 368 } 369 return false; 370 } 371 372 inline bool 373 Node::isFloat(double& d) { 374 if (FloatLit* fl = dynamic_cast<FloatLit*>(this)) { 375 d = fl->d; 376 return true; 377 } 378 return false; 379 } 380 381 inline Call* 382 Node::getCall(const std::string& id) { 383 if (Array* a = dynamic_cast<Array*>(this)) { 384 for (int i=a->a.size(); i--;) 385 if (Call* at = dynamic_cast<Call*>(a->a[i])) 386 if (at->id == id) 387 return at; 388 } else if (Call* a = dynamic_cast<Call*>(this)) { 389 if (a->id == id) 390 return a; 391 } 392 throw TypeError("call expected"); 393 } 394 395 inline Array* 396 Node::getArray(void) { 397 if (Array* a = dynamic_cast<Array*>(this)) 398 return a; 399 throw TypeError("array expected"); 400 } 401 402 inline Atom* 403 Node::getAtom(void) { 404 if (Atom* a = dynamic_cast<Atom*>(this)) 405 return a; 406 throw TypeError("atom expected"); 407 } 408 409 inline std::string 410 Node::getVarName(void) { 411 if (Var* a = dynamic_cast<Var*>(this)) 412 return a->n; 413 throw TypeError("variable expected"); 414 } 415 inline int 416 Node::getIntVar(void) { 417 if (IntVar* a = dynamic_cast<IntVar*>(this)) 418 return a->i; 419 throw TypeError("integer variable expected"); 420 } 421 inline int 422 Node::getBoolVar(void) { 423 if (BoolVar* a = dynamic_cast<BoolVar*>(this)) 424 return a->i; 425 throw TypeError("bool variable expected"); 426 } 427 inline int 428 Node::getFloatVar(void) { 429 if (FloatVar* a = dynamic_cast<FloatVar*>(this)) 430 return a->i; 431 throw TypeError("integer variable expected"); 432 } 433 inline int 434 Node::getSetVar(void) { 435 if (SetVar* a = dynamic_cast<SetVar*>(this)) 436 return a->i; 437 throw TypeError("set variable expected"); 438 } 439 inline int 440 Node::getInt(void) { 441 if (IntLit* a = dynamic_cast<IntLit*>(this)) 442 return a->i; 443 throw TypeError("integer literal expected"); 444 } 445 inline bool 446 Node::getBool(void) { 447 if (BoolLit* a = dynamic_cast<BoolLit*>(this)) 448 return a->b; 449 throw TypeError("bool literal expected"); 450 } 451 inline double 452 Node::getFloat(void) { 453 if (FloatLit* a = dynamic_cast<FloatLit*>(this)) 454 return a->d; 455 throw TypeError("float literal expected"); 456 } 457 inline SetLit* 458 Node::getSet(void) { 459 if (SetLit* a = dynamic_cast<SetLit*>(this)) 460 return a; 461 throw TypeError("set literal expected"); 462 } 463 inline std::string 464 Node::getString(void) { 465 if (String* a = dynamic_cast<String*>(this)) 466 return a->s; 467 throw TypeError("string literal expected"); 468 } 469 inline bool 470 Node::isIntVar(void) { 471 return (dynamic_cast<IntVar*>(this) != nullptr); 472 } 473 inline bool 474 Node::isBoolVar(void) { 475 return (dynamic_cast<BoolVar*>(this) != nullptr); 476 } 477 inline bool 478 Node::isSetVar(void) { 479 return (dynamic_cast<SetVar*>(this) != nullptr); 480 } 481 inline bool 482 Node::isFloatVar(void) { 483 return (dynamic_cast<FloatVar*>(this) != nullptr); 484 } 485 inline bool 486 Node::isInt(void) { 487 return (dynamic_cast<IntLit*>(this) != nullptr); 488 } 489 inline bool 490 Node::isBool(void) { 491 return (dynamic_cast<BoolLit*>(this) != nullptr); 492 } 493 inline bool 494 Node::isFloat(void) { 495 return (dynamic_cast<FloatLit*>(this) != nullptr); 496 } 497 inline bool 498 Node::isSet(void) { 499 return (dynamic_cast<SetLit*>(this) != nullptr); 500 } 501 inline bool 502 Node::isString(void) { 503 return (dynamic_cast<String*>(this) != nullptr); 504 } 505 inline bool 506 Node::isArray(void) { 507 return (dynamic_cast<Array*>(this) != nullptr); 508 } 509 inline bool 510 Node::isAtom(void) { 511 return (dynamic_cast<Atom*>(this) != nullptr); 512 } 513 514 inline Node* 515 extractSingleton(Node* n) { 516 if (Array* a = dynamic_cast<Array*>(n)) { 517 if (a->a.size() == 1) { 518 Node *ret = a->a[0]; 519 a->a[0] = nullptr; 520 delete a; 521 return ret; 522 } 523 } 524 return n; 525 } 526 527}}} 528 529#endif 530 531// STATISTICS: flatzinc-any