Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
68 kB · 2072 lines
at develop
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- *//* * Main authors: * Guido Tack <tack@gecode.org> * * Copyright: * Guido Tack, 2007 * * This file is part of Gecode, the generic constraint * development environment: * http://www.gecode.org * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */%pure-parser%parse-param {void *parm}%lex-param {void *YYLEX_PARAM}%{#define YYPARSE_PARAM parm#define YYLEX_PARAM static_cast<ParserState*>(parm)->yyscanner#include <gecode/flatzinc.hh>#include <gecode/flatzinc/parser.hh>#include <iostream>#include <fstream>#ifdef HAVE_MMAP#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <unistd.h>#include <sys/types.h>#include <sys/mman.h>#include <sys/stat.h>#endifusing namespace std;int yyparse(void*);int yylex(YYSTYPE*, void* scanner);int yylex_init (void** scanner);int yylex_destroy (void* scanner);int yyget_lineno (void* scanner);void yyset_extra (void* user_defined ,void* yyscanner );extern int yydebug;using namespace Gecode;using namespace Gecode::FlatZinc;void yyerror(void* parm, const char *str) { ParserState* pp = static_cast<ParserState*>(parm); pp->err << "Error: " << str << " in line no. " << yyget_lineno(pp->yyscanner) << std::endl; pp->hadError = true;}void yyassert(ParserState* pp, bool cond, const char* str){ if (!cond) { pp->err << "Error: " << str << " in line no. " << yyget_lineno(pp->yyscanner) << std::endl; pp->hadError = true; }}/* * The symbol tables * */AST::Node* getArrayElement(ParserState* pp, string id, int offset, bool annotation) { if (offset > 0) { SymbolEntry e; if (pp->symbols.get(id,e)) { switch (e.t) { case ST_INTVARARRAY: if (offset > pp->arrays[e.i]) goto error; { std::string n; if (annotation) { std::ostringstream oss; oss << id << "[" << offset << "]"; n = oss.str(); } return new AST::IntVar(pp->arrays[e.i+offset],n); } case ST_BOOLVARARRAY: if (offset > pp->arrays[e.i]) goto error; { std::string n; if (annotation) { std::ostringstream oss; oss << id << "[" << offset << "]"; n = oss.str(); } return new AST::BoolVar(pp->arrays[e.i+offset],n); } case ST_SETVARARRAY: if (offset > pp->arrays[e.i]) goto error; { std::string n; if (annotation) { std::ostringstream oss; oss << id << "[" << offset << "]"; n = oss.str(); } return new AST::SetVar(pp->arrays[e.i+offset],n); } case ST_FLOATVARARRAY: if (offset > pp->arrays[e.i]) goto error; { std::string n; if (annotation) { std::ostringstream oss; oss << id << "[" << offset << "]"; n = oss.str(); } return new AST::FloatVar(pp->arrays[e.i+offset],n); } case ST_INTVALARRAY: if (offset > pp->arrays[e.i]) goto error; return new AST::IntLit(pp->arrays[e.i+offset]); case ST_SETVALARRAY: if (offset > pp->arrays[e.i]) goto error; return new AST::SetLit(pp->setvals[pp->arrays[e.i+1]+offset-1]); case ST_FLOATVALARRAY: if (offset > pp->arrays[e.i]) goto error; return new AST::FloatLit(pp->floatvals[pp->arrays[e.i+1]+offset-1]); default: break; } } }error: pp->err << "Error: array access to " << id << " invalid" << " in line no. " << yyget_lineno(pp->yyscanner) << std::endl; pp->hadError = true; return new AST::IntVar(0); // keep things consistent}AST::Node* getVarRefArg(ParserState* pp, string id, bool annotation = false) { SymbolEntry e; string n; if (annotation) n = id; if (pp->symbols.get(id, e)) { switch (e.t) { case ST_INTVAR: return new AST::IntVar(e.i,n); case ST_BOOLVAR: return new AST::BoolVar(e.i,n); case ST_SETVAR: return new AST::SetVar(e.i,n); case ST_FLOATVAR: return new AST::FloatVar(e.i,n); default: break; } } if (annotation) return new AST::Atom(id); pp->err << "Error: undefined variable " << id << " in line no. " << yyget_lineno(pp->yyscanner) << std::endl; pp->hadError = true; return new AST::IntVar(0); // keep things consistent}void addDomainConstraint(ParserState* pp, std::string id, AST::Node* var, Option<AST::SetLit* >& dom) { if (!dom()) return; AST::Array* args = new AST::Array(2); args->a[0] = var; args->a[1] = dom.some(); pp->domainConstraints.push_back(new ConExpr(id, args, NULL));}void addDomainConstraint(ParserState* pp, AST::Node* var, Option<std::pair<double,double>* > dom) { if (!dom()) return; { AST::Array* args = new AST::Array(2); args->a[0] = new AST::FloatLit(dom.some()->first); args->a[1] = var; pp->domainConstraints.push_back(new ConExpr("float_le", args, NULL)); } { AST::Array* args = new AST::Array(2); AST::FloatVar* fv = static_cast<AST::FloatVar*>(var); args->a[0] = new AST::FloatVar(fv->i,fv->n); args->a[1] = new AST::FloatLit(dom.some()->second); pp->domainConstraints.push_back(new ConExpr("float_le", args, NULL)); } delete dom.some();}int getBaseIntVar(ParserState* pp, int i) { int base = i; IntVarSpec* ivs = static_cast<IntVarSpec*>(pp->intvars[base].second); while (ivs->alias) { base = ivs->i; ivs = static_cast<IntVarSpec*>(pp->intvars[base].second); } return base;}int getBaseBoolVar(ParserState* pp, int i) { int base = i; BoolVarSpec* ivs = static_cast<BoolVarSpec*>(pp->boolvars[base].second); while (ivs->alias) { base = ivs->i; ivs = static_cast<BoolVarSpec*>(pp->boolvars[base].second); } return base;}int getBaseFloatVar(ParserState* pp, int i) { int base = i; FloatVarSpec* ivs = static_cast<FloatVarSpec*>(pp->floatvars[base].second); while (ivs->alias) { base = ivs->i; ivs = static_cast<FloatVarSpec*>(pp->floatvars[base].second); } return base;}int getBaseSetVar(ParserState* pp, int i) { int base = i; SetVarSpec* ivs = static_cast<SetVarSpec*>(pp->setvars[base].second); while (ivs->alias) { base = ivs->i; ivs = static_cast<SetVarSpec*>(pp->setvars[base].second); } return base;}/* * Initialize the root gecode space * */void initfg(ParserState* pp) { if (!pp->hadError) pp->fg->init(pp->intvars.size(), pp->boolvars.size(), pp->setvars.size(), pp->floatvars.size()); for (unsigned int i=0; i<pp->intvars.size(); i++) { if (!pp->hadError) { try { pp->fg->newIntVar(static_cast<IntVarSpec*>(pp->intvars[i].second)); } catch (Gecode::FlatZinc::Error& e) { yyerror(pp, e.toString().c_str()); } } delete pp->intvars[i].second; pp->intvars[i].second = NULL; } for (unsigned int i=0; i<pp->boolvars.size(); i++) { if (!pp->hadError) { try { pp->fg->newBoolVar( static_cast<BoolVarSpec*>(pp->boolvars[i].second)); } catch (Gecode::FlatZinc::Error& e) { yyerror(pp, e.toString().c_str()); } } delete pp->boolvars[i].second; pp->boolvars[i].second = NULL; } for (unsigned int i=0; i<pp->setvars.size(); i++) { if (!pp->hadError) { try { pp->fg->newSetVar(static_cast<SetVarSpec*>(pp->setvars[i].second)); } catch (Gecode::FlatZinc::Error& e) { yyerror(pp, e.toString().c_str()); } } delete pp->setvars[i].second; pp->setvars[i].second = NULL; } for (unsigned int i=0; i<pp->floatvars.size(); i++) { if (!pp->hadError) { try { pp->fg->newFloatVar( static_cast<FloatVarSpec*>(pp->floatvars[i].second)); } catch (Gecode::FlatZinc::Error& e) { yyerror(pp, e.toString().c_str()); } } delete pp->floatvars[i].second; pp->floatvars[i].second = NULL; } if (!pp->hadError) { pp->fg->postConstraints(pp->domainConstraints); pp->fg->postConstraints(pp->constraints); }}void fillPrinter(ParserState& pp, Gecode::FlatZinc::Printer& p) { p.init(pp.getOutput()); for (unsigned int i=0; i<pp.intvars.size(); i++) { if (!pp.hadError) { p.addIntVarName(pp.intvars[i].first); } } for (unsigned int i=0; i<pp.boolvars.size(); i++) { if (!pp.hadError) { p.addBoolVarName(pp.boolvars[i].first); } }#ifdef GECODE_HAS_FLOAT_VARS for (unsigned int i=0; i<pp.floatvars.size(); i++) { if (!pp.hadError) { p.addFloatVarName(pp.floatvars[i].first); } }#endif#ifdef GECODE_HAS_SET_VARS for (unsigned int i=0; i<pp.setvars.size(); i++) { if (!pp.hadError) { p.addSetVarName(pp.setvars[i].first); } }#endif }AST::Node* arrayOutput(AST::Call* ann) { AST::Array* a = NULL; if (ann->args->isArray()) { a = ann->args->getArray(); } else { a = new AST::Array(ann->args); } std::ostringstream oss; oss << "array" << a->a.size() << "d("; for (unsigned int i=0; i<a->a.size(); i++) { AST::SetLit* s = a->a[i]->getSet(); if (s->empty()) oss << "{}, "; else if (s->interval) oss << s->min << ".." << s->max << ", "; else { oss << "{"; for (unsigned int j=0; j<s->s.size(); j++) { oss << s->s[j]; if (j<s->s.size()-1) oss << ","; } oss << "}, "; } } if (!ann->args->isArray()) { a->a[0] = NULL; delete a; } return new AST::String(oss.str());}/* * The main program * */namespace Gecode { namespace FlatZinc { FlatZincSpace* parse(const std::string& filename, Printer& p, std::ostream& err, FlatZincSpace* fzs, Rnd& rnd) {#ifdef HAVE_MMAP int fd; char* data; struct stat sbuf; fd = open(filename.c_str(), O_RDONLY); if (fd == -1) { err << "Cannot open file " << filename << endl; return NULL; } if (stat(filename.c_str(), &sbuf) == -1) { err << "Cannot stat file " << filename << endl; return NULL; } data = (char*)mmap((caddr_t)0, sbuf.st_size, PROT_READ, MAP_SHARED, fd,0); if (data == (caddr_t)(-1)) { err << "Cannot mmap file " << filename << endl; return NULL; } if (fzs == NULL) { fzs = new FlatZincSpace(rnd); } ParserState pp(data, sbuf.st_size, err, fzs);#else std::ifstream file; file.open(filename.c_str()); if (!file.is_open()) { err << "Cannot open file " << filename << endl; return NULL; } std::string s = string(istreambuf_iterator<char>(file), istreambuf_iterator<char>()); if (fzs == NULL) { fzs = new FlatZincSpace(rnd); } ParserState pp(s, err, fzs);#endif yylex_init(&pp.yyscanner); yyset_extra(&pp, pp.yyscanner); // yydebug = 1; yyparse(&pp); fillPrinter(pp, p); if (pp.yyscanner) yylex_destroy(pp.yyscanner); return pp.hadError ? NULL : pp.fg; } FlatZincSpace* parse(std::istream& is, Printer& p, std::ostream& err, FlatZincSpace* fzs, Rnd& rnd) { std::string s = string(istreambuf_iterator<char>(is), istreambuf_iterator<char>()); if (fzs == NULL) { fzs = new FlatZincSpace(rnd); } ParserState pp(s, err, fzs); yylex_init(&pp.yyscanner); yyset_extra(&pp, pp.yyscanner); // yydebug = 1; yyparse(&pp); fillPrinter(pp, p); if (pp.yyscanner) yylex_destroy(pp.yyscanner); return pp.hadError ? NULL : pp.fg; }}}%}%union { int iValue; char* sValue; bool bValue; double dValue; std::vector<int>* setValue; Gecode::FlatZinc::AST::SetLit* setLit; std::vector<double>* floatSetValue; std::vector<Gecode::FlatZinc::AST::SetLit>* setValueList; Gecode::FlatZinc::Option<Gecode::FlatZinc::AST::SetLit* > oSet; Gecode::FlatZinc::Option<std::pair<double,double>* > oPFloat; Gecode::FlatZinc::VarSpec* varSpec; Gecode::FlatZinc::Option<Gecode::FlatZinc::AST::Node*> oArg; std::vector<Gecode::FlatZinc::VarSpec*>* varSpecVec; Gecode::FlatZinc::Option<std::vector<Gecode::FlatZinc::VarSpec*>* > oVarSpecVec; Gecode::FlatZinc::AST::Node* arg; Gecode::FlatZinc::AST::Array* argVec; }%error-verbose%token <iValue> FZ_INT_LIT FZ_BOOL_LIT%token <dValue> FZ_FLOAT_LIT%token <sValue> FZ_ID FZ_U_ID FZ_STRING_LIT%token <bValue> FZ_VAR FZ_PAR%token FZ_ANNOTATION%token FZ_ANY%token FZ_ARRAY%token FZ_BOOL%token FZ_CASE%token FZ_COLONCOLON%token FZ_CONSTRAINT%token FZ_DEFAULT%token FZ_DOTDOT%token FZ_ELSE%token FZ_ELSEIF%token FZ_ENDIF%token FZ_ENUM%token FZ_FLOAT%token FZ_FUNCTION%token FZ_IF%token FZ_INCLUDE%token FZ_INT%token FZ_LET%token <bValue> FZ_MAXIMIZE%token <bValue> FZ_MINIMIZE%token FZ_OF%token FZ_SATISFY%token FZ_OUTPUT%token FZ_PREDICATE%token FZ_RECORD%token FZ_SET%token FZ_SHOW%token FZ_SHOWCOND%token FZ_SOLVE%token FZ_STRING%token FZ_TEST%token FZ_THEN%token FZ_TUPLE%token FZ_TYPE%token FZ_VARIANT_RECORD%token FZ_WHERE%type <sValue> var_par_id%type <setLit> set_literal%type <varSpec> int_init bool_init set_init float_init%type <oSet> int_ti_expr_tail bool_ti_expr_tail%type <oPFloat> float_ti_expr_tail%type <oVarSpecVec> vardecl_int_var_array_init%type <oVarSpecVec> vardecl_bool_var_array_init%type <oVarSpecVec> vardecl_float_var_array_init%type <oVarSpecVec> vardecl_set_var_array_init%type <varSpecVec> int_var_array_literal%type <varSpecVec> bool_var_array_literal%type <varSpecVec> float_var_array_literal%type <varSpecVec> set_var_array_literal%type <varSpecVec> int_init_list int_init_list_head%type <varSpecVec> bool_init_list bool_init_list_head%type <varSpecVec> float_init_list float_init_list_head%type <varSpecVec> set_init_list set_init_list_head%type <setValue> int_list int_list_head%type <setValue> bool_list bool_list_head%type <setValueList> set_literal_list set_literal_list_head%type <floatSetValue> float_list float_list_head%type <arg> flat_expr non_array_expr annotation_expr ann_non_array_expr%type <oArg> non_array_expr_opt%type <argVec> flat_expr_list non_array_expr_list non_array_expr_list_head%type <iValue> solve_expr%type <bValue> minmax%type <argVec> annotations annotations_head%type <arg> annotation annotation_list%%/********************************//* main goal and item lists *//********************************/model : preddecl_items vardecl_items constraint_items solve_item ';'preddecl_items: /* empty */ | preddecl_items_headpreddecl_items_head: preddecl_item ';' | preddecl_items_head preddecl_item ';'vardecl_items: /* emtpy */ | vardecl_items_headvardecl_items_head: vardecl_item ';' | vardecl_items_head vardecl_item ';'constraint_items: /* emtpy */ | constraint_items_headconstraint_items_head: constraint_item ';' | constraint_items_head constraint_item ';'/********************************//* predicate declarations *//********************************/preddecl_item: FZ_PREDICATE FZ_ID '(' pred_arg_list ')' { free($2); }pred_arg_list: /* empty */ | pred_arg_list_head list_tailpred_arg_list_head: pred_arg | pred_arg_list_head ',' pred_argpred_arg: pred_arg_type ':' FZ_ID { free($3); }pred_arg_type: FZ_ARRAY '[' pred_array_init ']' FZ_OF pred_arg_simple_type | FZ_ARRAY '[' pred_array_init ']' FZ_OF FZ_VAR pred_arg_simple_type | FZ_VAR pred_arg_simple_type | pred_arg_simple_typepred_arg_simple_type: int_ti_expr_tail { if ($1()) delete $1.some(); } | FZ_SET FZ_OF int_ti_expr_tail { if ($3()) delete $3.some(); } | FZ_BOOL | FZ_FLOATpred_array_init: pred_array_init_arg | pred_array_init ',' pred_array_init_argpred_array_init_arg: FZ_INT | FZ_INT_LIT FZ_DOTDOT FZ_INT_LIT/********************************//* variable declarations *//********************************/var_par_id : FZ_ID | FZ_U_IDvardecl_item: FZ_VAR int_ti_expr_tail ':' var_par_id annotations non_array_expr_opt { ParserState* pp = static_cast<ParserState*>(parm); bool print = $5 != NULL && $5->hasAtom("output_var"); bool funcDep = $5 != NULL && $5->hasAtom("is_defined_var"); yyassert(pp, pp->symbols.put($4, se_iv(pp->intvars.size())), "Duplicate symbol"); if (print) { pp->output(std::string($4), new AST::IntVar(pp->intvars.size())); } if ($6()) { AST::Node* arg = $6.some(); if (arg->isInt()) { pp->intvars.push_back(varspec($4, new IntVarSpec(arg->getInt(),!print,funcDep))); } else if (arg->isIntVar()) { pp->intvars.push_back(varspec($4, new IntVarSpec(Alias(arg->getIntVar()),!print,funcDep))); } else { yyassert(pp, false, "Invalid var int initializer"); } if (!pp->hadError) addDomainConstraint(pp, "int_in", new AST::IntVar(pp->intvars.size()-1), $2); delete arg; } else { pp->intvars.push_back(varspec($4, new IntVarSpec($2,!print,funcDep))); } delete $5; free($4); } | FZ_VAR bool_ti_expr_tail ':' var_par_id annotations non_array_expr_opt { ParserState* pp = static_cast<ParserState*>(parm); bool print = $5 != NULL && $5->hasAtom("output_var"); bool funcDep = $5 != NULL && $5->hasAtom("is_defined_var"); yyassert(pp, pp->symbols.put($4, se_bv(pp->boolvars.size())), "Duplicate symbol"); if (print) { pp->output(std::string($4), new AST::BoolVar(pp->boolvars.size())); } if ($6()) { AST::Node* arg = $6.some(); if (arg->isBool()) { pp->boolvars.push_back(varspec($4, new BoolVarSpec(arg->getBool(),!print,funcDep))); } else if (arg->isBoolVar()) { pp->boolvars.push_back(varspec($4, new BoolVarSpec(Alias(arg->getBoolVar()),!print,funcDep))); } else { yyassert(pp, false, "Invalid var bool initializer"); } if (!pp->hadError) addDomainConstraint(pp, "int_in", new AST::BoolVar(pp->boolvars.size()-1), $2); delete arg; } else { pp->boolvars.push_back(varspec($4, new BoolVarSpec($2,!print,funcDep))); } delete $5; free($4); } | FZ_VAR float_ti_expr_tail ':' var_par_id annotations non_array_expr_opt { ParserState* pp = static_cast<ParserState*>(parm); bool print = $5 != NULL && $5->hasAtom("output_var"); bool funcDep = $5 != NULL && $5->hasAtom("is_defined_var"); yyassert(pp, pp->symbols.put($4, se_fv(pp->floatvars.size())), "Duplicate symbol"); if (print) { pp->output(std::string($4), new AST::FloatVar(pp->floatvars.size())); } if ($6()) { AST::Node* arg = $6.some(); if (arg->isFloat()) { pp->floatvars.push_back(varspec($4, new FloatVarSpec(arg->getFloat(),!print,funcDep))); } else if (arg->isFloatVar()) { pp->floatvars.push_back(varspec($4, new FloatVarSpec( Alias(arg->getFloatVar()),!print,funcDep))); } else { yyassert(pp, false, "Invalid var float initializer"); } if (!pp->hadError && $2()) { AST::FloatVar* fv = new AST::FloatVar(pp->floatvars.size()-1); addDomainConstraint(pp, fv, $2); } delete arg; } else { Option<std::pair<double,double> > dom = $2() ? Option<std::pair<double,double> >::some(*$2.some()) : Option<std::pair<double,double> >::none(); if ($2()) delete $2.some(); pp->floatvars.push_back(varspec($4, new FloatVarSpec(dom,!print,funcDep))); } delete $5; free($4); } | FZ_VAR FZ_SET FZ_OF int_ti_expr_tail ':' var_par_id annotations non_array_expr_opt { ParserState* pp = static_cast<ParserState*>(parm); bool print = $7 != NULL && $7->hasAtom("output_var"); bool funcDep = $7 != NULL && $7->hasAtom("is_defined_var"); yyassert(pp, pp->symbols.put($6, se_sv(pp->setvars.size())), "Duplicate symbol"); if (print) { pp->output(std::string($6), new AST::SetVar(pp->setvars.size())); } if ($8()) { AST::Node* arg = $8.some(); if (arg->isSet()) { pp->setvars.push_back(varspec($6, new SetVarSpec(arg->getSet(),!print,funcDep))); } else if (arg->isSetVar()) { pp->setvars.push_back(varspec($6, new SetVarSpec(Alias(arg->getSetVar()),!print,funcDep))); delete arg; } else { yyassert(pp, false, "Invalid var set initializer"); delete arg; } if (!pp->hadError) addDomainConstraint(pp, "set_subset", new AST::SetVar(pp->setvars.size()-1), $4); } else { pp->setvars.push_back(varspec($6, new SetVarSpec($4,!print,funcDep))); } delete $7; free($6); } | FZ_INT ':' var_par_id annotations '=' non_array_expr { ParserState* pp = static_cast<ParserState*>(parm); yyassert(pp, $6->isInt(), "Invalid int initializer"); yyassert(pp, pp->symbols.put($3, se_i($6->getInt())), "Duplicate symbol"); delete $4; free($3); } | FZ_FLOAT ':' var_par_id annotations '=' non_array_expr { ParserState* pp = static_cast<ParserState*>(parm); yyassert(pp, $6->isFloat(), "Invalid float initializer"); pp->floatvals.push_back($6->getFloat()); yyassert(pp, pp->symbols.put($3, se_f(pp->floatvals.size()-1)), "Duplicate symbol"); delete $4; free($3); } | FZ_BOOL ':' var_par_id annotations '=' non_array_expr { ParserState* pp = static_cast<ParserState*>(parm); yyassert(pp, $6->isBool(), "Invalid bool initializer"); yyassert(pp, pp->symbols.put($3, se_b($6->getBool())), "Duplicate symbol"); delete $4; free($3); } | FZ_SET FZ_OF FZ_INT ':' var_par_id annotations '=' non_array_expr { ParserState* pp = static_cast<ParserState*>(parm); yyassert(pp, $8->isSet(), "Invalid set initializer"); AST::SetLit* set = $8->getSet(); pp->setvals.push_back(*set); yyassert(pp, pp->symbols.put($5, se_s(pp->setvals.size()-1)), "Duplicate symbol"); delete set; delete $6; free($5); } | FZ_ARRAY '[' FZ_INT_LIT FZ_DOTDOT FZ_INT_LIT ']' FZ_OF FZ_VAR int_ti_expr_tail ':' var_par_id annotations vardecl_int_var_array_init { ParserState* pp = static_cast<ParserState*>(parm); yyassert(pp, $3==1, "Arrays must start at 1"); if (!pp->hadError) { bool print = $12 != NULL && $12->hasCall("output_array"); vector<int> vars($5); if (!pp->hadError) { if ($13()) { vector<VarSpec*>* vsv = $13.some(); yyassert(pp, vsv->size() == static_cast<unsigned int>($5), "Initializer size does not match array dimension"); if (!pp->hadError) { for (int i=0; i<$5; i++) { IntVarSpec* ivsv = static_cast<IntVarSpec*>((*vsv)[i]); if (ivsv->alias) { if (print) static_cast<IntVarSpec*>(pp->intvars[ivsv->i].second)->introduced = false; vars[i] = ivsv->i; } else { if (print) ivsv->introduced = false; vars[i] = pp->intvars.size(); pp->intvars.push_back(varspec($11, ivsv)); } if (!pp->hadError && $9()) { Option<AST::SetLit*> opt = Option<AST::SetLit*>::some(new AST::SetLit(*$9.some())); addDomainConstraint(pp, "int_in", new AST::IntVar(vars[i]), opt); } } } delete vsv; } else { if ($5>0) { for (int i=0; i<$5; i++) { Option<AST::SetLit*> dom = $9() ? Option<AST::SetLit*>::some(new AST::SetLit($9.some())) : Option<AST::SetLit*>::none(); IntVarSpec* ispec = new IntVarSpec(dom,!print,false); vars[i] = pp->intvars.size(); pp->intvars.push_back(varspec($11, ispec)); } } if ($9()) delete $9.some(); } } if (print) { AST::Array* a = new AST::Array(); a->a.push_back(arrayOutput($12->getCall("output_array"))); AST::Array* output = new AST::Array(); for (int i=0; i<$5; i++) output->a.push_back(new AST::IntVar(vars[i])); a->a.push_back(output); a->a.push_back(new AST::String(")")); pp->output(std::string($11), a); } int iva = pp->arrays.size(); pp->arrays.push_back(vars.size()); for (unsigned int i=0; i<vars.size(); i++) pp->arrays.push_back(vars[i]); yyassert(pp, pp->symbols.put($11, se_iva(iva)), "Duplicate symbol"); } delete $12; free($11); } | FZ_ARRAY '[' FZ_INT_LIT FZ_DOTDOT FZ_INT_LIT ']' FZ_OF FZ_VAR bool_ti_expr_tail ':' var_par_id annotations vardecl_bool_var_array_init { ParserState* pp = static_cast<ParserState*>(parm); bool print = $12 != NULL && $12->hasCall("output_array"); yyassert(pp, $3==1, "Arrays must start at 1"); if (!pp->hadError) { vector<int> vars($5); if ($13()) { vector<VarSpec*>* vsv = $13.some(); yyassert(pp, vsv->size() == static_cast<unsigned int>($5), "Initializer size does not match array dimension"); if (!pp->hadError) { for (int i=0; i<$5; i++) { BoolVarSpec* bvsv = static_cast<BoolVarSpec*>((*vsv)[i]); if (bvsv->alias) { if (print) static_cast<BoolVarSpec*>(pp->boolvars[bvsv->i].second)->introduced = false; vars[i] = bvsv->i; } else { if (print) bvsv->introduced = false; vars[i] = pp->boolvars.size(); pp->boolvars.push_back(varspec($11, (*vsv)[i])); } if (!pp->hadError && $9()) { Option<AST::SetLit*> opt = Option<AST::SetLit*>::some(new AST::SetLit(*$9.some())); addDomainConstraint(pp, "int_in", new AST::BoolVar(vars[i]), opt); } } } delete vsv; } else { for (int i=0; i<$5; i++) { Option<AST::SetLit*> dom = $9() ? Option<AST::SetLit*>::some(new AST::SetLit($9.some())) : Option<AST::SetLit*>::none(); vars[i] = pp->boolvars.size(); pp->boolvars.push_back(varspec($11, new BoolVarSpec(dom,!print,false))); } if ($9()) delete $9.some(); } if (print) { AST::Array* a = new AST::Array(); a->a.push_back(arrayOutput($12->getCall("output_array"))); AST::Array* output = new AST::Array(); for (int i=0; i<$5; i++) output->a.push_back(new AST::BoolVar(vars[i])); a->a.push_back(output); a->a.push_back(new AST::String(")")); pp->output(std::string($11), a); } int bva = pp->arrays.size(); pp->arrays.push_back(vars.size()); for (unsigned int i=0; i<vars.size(); i++) pp->arrays.push_back(vars[i]); yyassert(pp, pp->symbols.put($11, se_bva(bva)), "Duplicate symbol"); } delete $12; free($11); } | FZ_ARRAY '[' FZ_INT_LIT FZ_DOTDOT FZ_INT_LIT ']' FZ_OF FZ_VAR float_ti_expr_tail ':' var_par_id annotations vardecl_float_var_array_init { ParserState* pp = static_cast<ParserState*>(parm); yyassert(pp, $3==1, "Arrays must start at 1"); if (!pp->hadError) { bool print = $12 != NULL && $12->hasCall("output_array"); vector<int> vars($5); if (!pp->hadError) { if ($13()) { vector<VarSpec*>* vsv = $13.some(); yyassert(pp, vsv->size() == static_cast<unsigned int>($5), "Initializer size does not match array dimension"); if (!pp->hadError) { for (int i=0; i<$5; i++) { FloatVarSpec* ivsv = static_cast<FloatVarSpec*>((*vsv)[i]); if (ivsv->alias) { if (print) static_cast<FloatVarSpec*>(pp->floatvars[ivsv->i].second)->introduced = false; vars[i] = ivsv->i; } else { if (print) ivsv->introduced = false; vars[i] = pp->floatvars.size(); pp->floatvars.push_back(varspec($11, ivsv)); } if (!pp->hadError && $9()) { Option<std::pair<double,double>*> opt = Option<std::pair<double,double>*>::some( new std::pair<double,double>(*$9.some())); addDomainConstraint(pp, new AST::FloatVar(vars[i]), opt); } } } delete vsv; } else { if ($5>0) { Option<std::pair<double,double> > dom = $9() ? Option<std::pair<double,double> >::some(*$9.some()) : Option<std::pair<double,double> >::none(); for (int i=0; i<$5; i++) { FloatVarSpec* ispec = new FloatVarSpec(dom,!print,false); vars[i] = pp->floatvars.size(); pp->floatvars.push_back(varspec($11, ispec)); } } } } if (print) { AST::Array* a = new AST::Array(); a->a.push_back(arrayOutput($12->getCall("output_array"))); AST::Array* output = new AST::Array(); for (int i=0; i<$5; i++) output->a.push_back(new AST::FloatVar(vars[i])); a->a.push_back(output); a->a.push_back(new AST::String(")")); pp->output(std::string($11), a); } int fva = pp->arrays.size(); pp->arrays.push_back(vars.size()); for (unsigned int i=0; i<vars.size(); i++) pp->arrays.push_back(vars[i]); yyassert(pp, pp->symbols.put($11, se_fva(fva)), "Duplicate symbol"); } if ($9()) delete $9.some(); delete $12; free($11); } | FZ_ARRAY '[' FZ_INT_LIT FZ_DOTDOT FZ_INT_LIT ']' FZ_OF FZ_VAR FZ_SET FZ_OF int_ti_expr_tail ':' var_par_id annotations vardecl_set_var_array_init { ParserState* pp = static_cast<ParserState*>(parm); bool print = $14 != NULL && $14->hasCall("output_array"); yyassert(pp, $3==1, "Arrays must start at 1"); if (!pp->hadError) { vector<int> vars($5); if ($15()) { vector<VarSpec*>* vsv = $15.some(); yyassert(pp, vsv->size() == static_cast<unsigned int>($5), "Initializer size does not match array dimension"); if (!pp->hadError) { for (int i=0; i<$5; i++) { SetVarSpec* svsv = static_cast<SetVarSpec*>((*vsv)[i]); if (svsv->alias) { if (print) static_cast<SetVarSpec*>(pp->setvars[svsv->i].second)->introduced = false; vars[i] = svsv->i; } else { if (print) svsv->introduced = false; vars[i] = pp->setvars.size(); pp->setvars.push_back(varspec($13, (*vsv)[i])); } if (!pp->hadError && $11()) { Option<AST::SetLit*> opt = Option<AST::SetLit*>::some(new AST::SetLit(*$11.some())); addDomainConstraint(pp, "set_subset", new AST::SetVar(vars[i]), opt); } } } delete vsv; } else { if ($5>0) { for (int i=0; i<$5; i++) { Option<AST::SetLit*> dom = $11() ? Option<AST::SetLit*>::some(new AST::SetLit($11.some())) : Option<AST::SetLit*>::none(); SetVarSpec* ispec = new SetVarSpec(dom,!print,false); vars[i] = pp->setvars.size(); pp->setvars.push_back(varspec($13, ispec)); } if ($11()) delete $11.some(); } } if (print) { AST::Array* a = new AST::Array(); a->a.push_back(arrayOutput($14->getCall("output_array"))); AST::Array* output = new AST::Array(); for (int i=0; i<$5; i++) output->a.push_back(new AST::SetVar(vars[i])); a->a.push_back(output); a->a.push_back(new AST::String(")")); pp->output(std::string($13), a); } int sva = pp->arrays.size(); pp->arrays.push_back(vars.size()); for (unsigned int i=0; i<vars.size(); i++) pp->arrays.push_back(vars[i]); yyassert(pp, pp->symbols.put($13, se_sva(sva)), "Duplicate symbol"); } delete $14; free($13); } | FZ_ARRAY '[' FZ_INT_LIT FZ_DOTDOT FZ_INT_LIT ']' FZ_OF FZ_INT ':' var_par_id annotations '=' '[' int_list ']' { ParserState* pp = static_cast<ParserState*>(parm); yyassert(pp, $3==1, "Arrays must start at 1"); yyassert(pp, $14->size() == static_cast<unsigned int>($5), "Initializer size does not match array dimension"); if (!pp->hadError) { int ia = pp->arrays.size(); pp->arrays.push_back($14->size()); for (unsigned int i=0; i<$14->size(); i++) pp->arrays.push_back((*$14)[i]); yyassert(pp, pp->symbols.put($10, se_ia(ia)), "Duplicate symbol"); } delete $14; free($10); delete $11; } | FZ_ARRAY '[' FZ_INT_LIT FZ_DOTDOT FZ_INT_LIT ']' FZ_OF FZ_BOOL ':' var_par_id annotations '=' '[' bool_list ']' { ParserState* pp = static_cast<ParserState*>(parm); yyassert(pp, $3==1, "Arrays must start at 1"); yyassert(pp, $14->size() == static_cast<unsigned int>($5), "Initializer size does not match array dimension"); if (!pp->hadError) { int ia = pp->arrays.size(); pp->arrays.push_back($14->size()); for (unsigned int i=0; i<$14->size(); i++) pp->arrays.push_back((*$14)[i]); yyassert(pp, pp->symbols.put($10, se_ba(ia)), "Duplicate symbol"); } delete $14; free($10); delete $11; } | FZ_ARRAY '[' FZ_INT_LIT FZ_DOTDOT FZ_INT_LIT ']' FZ_OF FZ_FLOAT ':' var_par_id annotations '=' '[' float_list ']' { ParserState* pp = static_cast<ParserState*>(parm); yyassert(pp, $3==1, "Arrays must start at 1"); yyassert(pp, $14->size() == static_cast<unsigned int>($5), "Initializer size does not match array dimension"); if (!pp->hadError) { int fa = pp->arrays.size(); pp->arrays.push_back($14->size()); pp->arrays.push_back(pp->floatvals.size()); for (unsigned int i=0; i<$14->size(); i++) pp->floatvals.push_back((*$14)[i]); yyassert(pp, pp->symbols.put($10, se_fa(fa)), "Duplicate symbol"); } delete $14; delete $11; free($10); } | FZ_ARRAY '[' FZ_INT_LIT FZ_DOTDOT FZ_INT_LIT ']' FZ_OF FZ_SET FZ_OF FZ_INT ':' var_par_id annotations '=' '[' set_literal_list ']' { ParserState* pp = static_cast<ParserState*>(parm); yyassert(pp, $3==1, "Arrays must start at 1"); yyassert(pp, $16->size() == static_cast<unsigned int>($5), "Initializer size does not match array dimension"); if (!pp->hadError) { int sa = pp->arrays.size(); pp->arrays.push_back($16->size()); pp->arrays.push_back(pp->setvals.size()); for (unsigned int i=0; i<$16->size(); i++) pp->setvals.push_back((*$16)[i]); yyassert(pp, pp->symbols.put($12, se_sa(sa)), "Duplicate symbol"); } delete $16; delete $13; free($12); }int_init : FZ_INT_LIT { $$ = new IntVarSpec($1,false,false); } | var_par_id { SymbolEntry e; ParserState* pp = static_cast<ParserState*>(parm); if (pp->symbols.get($1, e) && e.t == ST_INTVAR) $$ = new IntVarSpec(Alias(e.i),false,false); else { pp->err << "Error: undefined identifier for type int " << $1 << " in line no. " << yyget_lineno(pp->yyscanner) << std::endl; pp->hadError = true; $$ = new IntVarSpec(0,false,false); // keep things consistent } free($1); } | var_par_id '[' FZ_INT_LIT ']' { vector<int> v; SymbolEntry e; ParserState* pp = static_cast<ParserState*>(parm); if (pp->symbols.get($1, e) && e.t == ST_INTVARARRAY) { yyassert(pp,$3 > 0 && $3 <= pp->arrays[e.i], "array access out of bounds"); if (!pp->hadError) $$ = new IntVarSpec(Alias(pp->arrays[e.i+$3]),false,false); else $$ = new IntVarSpec(0,false,false); // keep things consistent } else { pp->err << "Error: undefined array identifier for type int " << $1 << " in line no. " << yyget_lineno(pp->yyscanner) << std::endl; pp->hadError = true; $$ = new IntVarSpec(0,false,false); // keep things consistent } free($1); }int_init_list : /* empty */ { $$ = new vector<VarSpec*>(0); } | int_init_list_head list_tail { $$ = $1; }int_init_list_head : int_init { $$ = new vector<VarSpec*>(1); (*$$)[0] = $1; } | int_init_list_head ',' int_init { $$ = $1; $$->push_back($3); }list_tail : | ','int_var_array_literal : '[' int_init_list ']' { $$ = $2; }float_init : FZ_FLOAT_LIT { $$ = new FloatVarSpec($1,false,false); } | var_par_id { SymbolEntry e; ParserState* pp = static_cast<ParserState*>(parm); if (pp->symbols.get($1, e) && e.t == ST_FLOATVAR) $$ = new FloatVarSpec(Alias(e.i),false,false); else { pp->err << "Error: undefined identifier for type float " << $1 << " in line no. " << yyget_lineno(pp->yyscanner) << std::endl; pp->hadError = true; $$ = new FloatVarSpec(0.0,false,false); } free($1); } | var_par_id '[' FZ_INT_LIT ']' { SymbolEntry e; ParserState* pp = static_cast<ParserState*>(parm); if (pp->symbols.get($1, e) && e.t == ST_FLOATVARARRAY) { yyassert(pp,$3 > 0 && $3 <= pp->arrays[e.i], "array access out of bounds"); if (!pp->hadError) $$ = new FloatVarSpec(Alias(pp->arrays[e.i+$3]),false,false); else $$ = new FloatVarSpec(0.0,false,false); } else { pp->err << "Error: undefined array identifier for type float " << $1 << " in line no. " << yyget_lineno(pp->yyscanner) << std::endl; pp->hadError = true; $$ = new FloatVarSpec(0.0,false,false); } free($1); }float_init_list : /* empty */ { $$ = new vector<VarSpec*>(0); } | float_init_list_head list_tail { $$ = $1; }float_init_list_head : float_init { $$ = new vector<VarSpec*>(1); (*$$)[0] = $1; } | float_init_list_head ',' float_init { $$ = $1; $$->push_back($3); }float_var_array_literal : '[' float_init_list ']' { $$ = $2; }bool_init : FZ_BOOL_LIT { $$ = new BoolVarSpec($1,false,false); } | var_par_id { SymbolEntry e; ParserState* pp = static_cast<ParserState*>(parm); if (pp->symbols.get($1, e) && e.t == ST_BOOLVAR) $$ = new BoolVarSpec(Alias(e.i),false,false); else { pp->err << "Error: undefined identifier for type bool " << $1 << " in line no. " << yyget_lineno(pp->yyscanner) << std::endl; pp->hadError = true; $$ = new BoolVarSpec(false,false,false); } free($1); } | var_par_id '[' FZ_INT_LIT ']' { SymbolEntry e; ParserState* pp = static_cast<ParserState*>(parm); if (pp->symbols.get($1, e) && e.t == ST_BOOLVARARRAY) { yyassert(pp,$3 > 0 && $3 <= pp->arrays[e.i], "array access out of bounds"); if (!pp->hadError) $$ = new BoolVarSpec(Alias(pp->arrays[e.i+$3]),false,false); else $$ = new BoolVarSpec(false,false,false); } else { pp->err << "Error: undefined array identifier for type bool " << $1 << " in line no. " << yyget_lineno(pp->yyscanner) << std::endl; pp->hadError = true; $$ = new BoolVarSpec(false,false,false); } free($1); }bool_init_list : /* empty */ { $$ = new vector<VarSpec*>(0); } | bool_init_list_head list_tail { $$ = $1; }bool_init_list_head : bool_init { $$ = new vector<VarSpec*>(1); (*$$)[0] = $1; } | bool_init_list_head ',' bool_init { $$ = $1; $$->push_back($3); }bool_var_array_literal : '[' bool_init_list ']' { $$ = $2; }set_init : set_literal { $$ = new SetVarSpec($1,false,false); } | var_par_id { ParserState* pp = static_cast<ParserState*>(parm); SymbolEntry e; if (pp->symbols.get($1, e) && e.t == ST_SETVAR) $$ = new SetVarSpec(Alias(e.i),false,false); else { pp->err << "Error: undefined identifier for type set " << $1 << " in line no. " << yyget_lineno(pp->yyscanner) << std::endl; pp->hadError = true; $$ = new SetVarSpec(Alias(0),false,false); } free($1); } | var_par_id '[' FZ_INT_LIT ']' { SymbolEntry e; ParserState* pp = static_cast<ParserState*>(parm); if (pp->symbols.get($1, e) && e.t == ST_SETVARARRAY) { yyassert(pp,$3 > 0 && $3 <= pp->arrays[e.i], "array access out of bounds"); if (!pp->hadError) $$ = new SetVarSpec(Alias(pp->arrays[e.i+$3]),false,false); else $$ = new SetVarSpec(Alias(0),false,false); } else { pp->err << "Error: undefined array identifier for type set " << $1 << " in line no. " << yyget_lineno(pp->yyscanner) << std::endl; pp->hadError = true; $$ = new SetVarSpec(Alias(0),false,false); } free($1); }set_init_list : /* empty */ { $$ = new vector<VarSpec*>(0); } | set_init_list_head list_tail { $$ = $1; }set_init_list_head : set_init { $$ = new vector<VarSpec*>(1); (*$$)[0] = $1; } | set_init_list_head ',' set_init { $$ = $1; $$->push_back($3); }set_var_array_literal : '[' set_init_list ']' { $$ = $2; }vardecl_int_var_array_init : /* empty */ { $$ = Option<vector<VarSpec*>* >::none(); } | '=' int_var_array_literal { $$ = Option<vector<VarSpec*>* >::some($2); }vardecl_bool_var_array_init : /* empty */ { $$ = Option<vector<VarSpec*>* >::none(); } | '=' bool_var_array_literal { $$ = Option<vector<VarSpec*>* >::some($2); }vardecl_float_var_array_init : /* empty */ { $$ = Option<vector<VarSpec*>* >::none(); } | '=' float_var_array_literal { $$ = Option<vector<VarSpec*>* >::some($2); }vardecl_set_var_array_init : /* empty */ { $$ = Option<vector<VarSpec*>* >::none(); } | '=' set_var_array_literal { $$ = Option<vector<VarSpec*>* >::some($2); }constraint_item : FZ_CONSTRAINT FZ_ID '(' flat_expr_list ')' annotations { ParserState *pp = static_cast<ParserState*>(parm); if (!pp->hadError) { std::string cid($2); if (cid=="int_eq" && $4->a[0]->isIntVar() && $4->a[1]->isIntVar()) { int base0 = getBaseIntVar(pp,$4->a[0]->getIntVar()); int base1 = getBaseIntVar(pp,$4->a[1]->getIntVar()); if (base0 > base1) { std::swap(base0, base1); } if (base0==base1) { // do nothing, already aliased } else { IntVarSpec* ivs1 = static_cast<IntVarSpec*>(pp->intvars[base1].second); AST::SetLit* sl = NULL; if (ivs1->assigned) { sl = new AST::SetLit(ivs1->i,ivs1->i); } else if (ivs1->domain()) { sl = new AST::SetLit(ivs1->domain.some()->getSet()); } if (sl) { Option<AST::SetLit*> newdom = Option<AST::SetLit*>::some(sl); addDomainConstraint(pp, "int_in", new AST::IntVar(base0), newdom); ivs1->domain = Option<AST::SetLit*>::none(); } ivs1->alias = true; ivs1->i = base0; } } else if (cid=="bool_eq" && $4->a[0]->isBoolVar() && $4->a[1]->isBoolVar()) { int base0 = getBaseBoolVar(pp,$4->a[0]->getBoolVar()); int base1 = getBaseBoolVar(pp,$4->a[1]->getBoolVar()); if (base0 > base1) { std::swap(base0, base1); } if (base0==base1) { // do nothing, already aliased } else { BoolVarSpec* ivs1 = static_cast<BoolVarSpec*>(pp->boolvars[base1].second); AST::SetLit* sl = NULL; if (ivs1->assigned) { sl = new AST::SetLit(ivs1->i,ivs1->i); } else if (ivs1->domain()) { sl = new AST::SetLit(ivs1->domain.some()->getSet()); } if (sl) { Option<AST::SetLit*> newdom = Option<AST::SetLit*>::some(sl); addDomainConstraint(pp, "int_in", new AST::BoolVar(base0), newdom); ivs1->domain = Option<AST::SetLit*>::none(); } ivs1->alias = true; ivs1->i = base0; } } else if (cid=="float_eq" && $4->a[0]->isFloatVar() && $4->a[1]->isFloatVar()) { int base0 = getBaseFloatVar(pp,$4->a[0]->getFloatVar()); int base1 = getBaseFloatVar(pp,$4->a[1]->getFloatVar()); if (base0 > base1) { std::swap(base0, base1); } if (base0==base1) { // do nothing, already aliased } else { FloatVarSpec* ivs1 = static_cast<FloatVarSpec*>(pp->floatvars[base1].second); ivs1->alias = true; ivs1->i = base0; if (ivs1->domain()) { std::pair<double,double>* dom = new std::pair<double,double>(ivs1->domain.some()); addDomainConstraint(pp, new AST::FloatVar(base0), Option<std::pair<double,double>* >::some(dom)); ivs1->domain = Option<std::pair<double,double> >::none(); } } } else if (cid=="set_eq" && $4->a[0]->isSetVar() && $4->a[1]->isSetVar()) { int base0 = getBaseSetVar(pp,$4->a[0]->getSetVar()); int base1 = getBaseSetVar(pp,$4->a[1]->getSetVar()); if (base0 > base1) { std::swap(base0, base1); } if (base0==base1) { // do nothing, already aliased } else { SetVarSpec* ivs1 = static_cast<SetVarSpec*>(pp->setvars[base1].second); ivs1->alias = true; ivs1->i = base0; if (ivs1->upperBound()) { AST::SetLit* sl = new AST::SetLit(ivs1->upperBound.some()->getSet()); Option<AST::SetLit*> newdom = Option<AST::SetLit*>::some(sl); if (ivs1->assigned) { addDomainConstraint(pp, "set_eq", new AST::SetVar(base0), newdom); } else { addDomainConstraint(pp, "set_subset", new AST::SetVar(base0), newdom); } ivs1->upperBound = Option<AST::SetLit*>::none(); } } } else if ( (cid=="int_le" || cid=="int_lt" || cid=="int_ge" || cid=="int_gt" || cid=="int_eq" || cid=="int_ne") && ($4->a[0]->isInt() || $4->a[1]->isInt()) ) { pp->domainConstraints.push_back(new ConExpr($2, $4, $6)); } else if ( cid=="set_in" && ($4->a[0]->isSet() || $4->a[1]->isSet()) ) { pp->domainConstraints.push_back(new ConExpr($2, $4, $6)); } else { pp->constraints.push_back(new ConExpr($2, $4, $6)); } } free($2); }solve_item : FZ_SOLVE annotations FZ_SATISFY { ParserState *pp = static_cast<ParserState*>(parm); initfg(pp); if (!pp->hadError) { try { pp->fg->solve($2); } catch (Gecode::FlatZinc::Error& e) { yyerror(pp, e.toString().c_str()); } } else { delete $2; } } | FZ_SOLVE annotations minmax solve_expr { ParserState *pp = static_cast<ParserState*>(parm); initfg(pp); if (!pp->hadError) { try { int v = $4 < 0 ? (-$4-1) : $4; bool vi = $4 >= 0; if ($3) pp->fg->minimize(v,vi,$2); else pp->fg->maximize(v,vi,$2); } catch (Gecode::FlatZinc::Error& e) { yyerror(pp, e.toString().c_str()); } } else { delete $2; } }/********************************//* type-insts *//********************************/int_ti_expr_tail : FZ_INT { $$ = Option<AST::SetLit* >::none(); } | '{' int_list '}' { $$ = Option<AST::SetLit* >::some(new AST::SetLit(*$2)); } | FZ_INT_LIT FZ_DOTDOT FZ_INT_LIT { $$ = Option<AST::SetLit* >::some(new AST::SetLit($1, $3)); }bool_ti_expr_tail : FZ_BOOL { $$ = Option<AST::SetLit* >::none(); } | '{' bool_list_head list_tail '}' { bool haveTrue = false; bool haveFalse = false; for (int i=$2->size(); i--;) { haveTrue |= ((*$2)[i] == 1); haveFalse |= ((*$2)[i] == 0); } delete $2; $$ = Option<AST::SetLit* >::some( new AST::SetLit(!haveFalse,haveTrue)); }float_ti_expr_tail : FZ_FLOAT { $$ = Option<std::pair<double,double>* >::none(); } | FZ_FLOAT_LIT FZ_DOTDOT FZ_FLOAT_LIT { std::pair<double,double>* dom = new std::pair<double,double>($1,$3); $$ = Option<std::pair<double,double>* >::some(dom); }/********************************//* literals *//********************************/set_literal : '{' int_list '}' { $$ = new AST::SetLit(*$2); } | FZ_INT_LIT FZ_DOTDOT FZ_INT_LIT { $$ = new AST::SetLit($1, $3); }/* list containing only primitive literals */int_list : /* empty */ { $$ = new vector<int>(0); } | int_list_head list_tail { $$ = $1; }int_list_head : FZ_INT_LIT { $$ = new vector<int>(1); (*$$)[0] = $1; } | int_list_head ',' FZ_INT_LIT { $$ = $1; $$->push_back($3); }bool_list : /* empty */ { $$ = new vector<int>(0); } | bool_list_head list_tail { $$ = $1; }bool_list_head : FZ_BOOL_LIT { $$ = new vector<int>(1); (*$$)[0] = $1; } | bool_list_head ',' FZ_BOOL_LIT { $$ = $1; $$->push_back($3); }float_list : /* empty */ { $$ = new vector<double>(0); } | float_list_head list_tail { $$ = $1; }float_list_head: FZ_FLOAT_LIT { $$ = new vector<double>(1); (*$$)[0] = $1; } | float_list_head ',' FZ_FLOAT_LIT { $$ = $1; $$->push_back($3); }set_literal_list : /* empty */ { $$ = new vector<AST::SetLit>(0); } | set_literal_list_head list_tail { $$ = $1; }set_literal_list_head : set_literal { $$ = new vector<AST::SetLit>(1); (*$$)[0] = *$1; delete $1; } | set_literal_list_head ',' set_literal { $$ = $1; $$->push_back(*$3); delete $3; }/********************************//* constraint expressions *//********************************/flat_expr_list : flat_expr { $$ = new AST::Array($1); } | flat_expr_list ',' flat_expr { $$ = $1; $$->append($3); }flat_expr : non_array_expr { $$ = $1; } | '[' non_array_expr_list ']' { $$ = $2; }non_array_expr_opt : /* empty */ { $$ = Option<AST::Node*>::none(); } | '=' non_array_expr { $$ = Option<AST::Node*>::some($2); }non_array_expr : FZ_BOOL_LIT { $$ = new AST::BoolLit($1); } | FZ_INT_LIT { $$ = new AST::IntLit($1); } | FZ_FLOAT_LIT { $$ = new AST::FloatLit($1); } | set_literal { $$ = $1; } | var_par_id /* variable, possibly array */ { ParserState* pp = static_cast<ParserState*>(parm); SymbolEntry e; if (pp->symbols.get($1, e)) { switch (e.t) { case ST_INTVARARRAY: { AST::Array *v = new AST::Array(pp->arrays[e.i]); for (int i=pp->arrays[e.i]; i--;) v->a[i] = new AST::IntVar(pp->arrays[e.i+i+1]); $$ = v; } break; case ST_BOOLVARARRAY: { AST::Array *v = new AST::Array(pp->arrays[e.i]); for (int i=pp->arrays[e.i]; i--;) v->a[i] = new AST::BoolVar(pp->arrays[e.i+i+1]); $$ = v; } break; case ST_FLOATVARARRAY: { AST::Array *v = new AST::Array(pp->arrays[e.i]); for (int i=pp->arrays[e.i]; i--;) v->a[i] = new AST::FloatVar(pp->arrays[e.i+i+1]); $$ = v; } break; case ST_SETVARARRAY: { AST::Array *v = new AST::Array(pp->arrays[e.i]); for (int i=pp->arrays[e.i]; i--;) v->a[i] = new AST::SetVar(pp->arrays[e.i+i+1]); $$ = v; } break; case ST_INTVALARRAY: { AST::Array *v = new AST::Array(pp->arrays[e.i]); for (int i=pp->arrays[e.i]; i--;) v->a[i] = new AST::IntLit(pp->arrays[e.i+i+1]); $$ = v; } break; case ST_BOOLVALARRAY: { AST::Array *v = new AST::Array(pp->arrays[e.i]); for (int i=pp->arrays[e.i]; i--;) v->a[i] = new AST::BoolLit(pp->arrays[e.i+i+1]); $$ = v; } break; case ST_SETVALARRAY: { AST::Array *v = new AST::Array(pp->arrays[e.i]); int idx = pp->arrays[e.i+1]; for (int i=pp->arrays[e.i]; i--;) v->a[i] = new AST::SetLit(pp->setvals[idx+i]); $$ = v; } break; case ST_FLOATVALARRAY: { AST::Array *v = new AST::Array(pp->arrays[e.i]); int idx = pp->arrays[e.i+1]; for (int i=pp->arrays[e.i]; i--;) v->a[i] = new AST::FloatLit(pp->floatvals[idx+i]); $$ = v; } break; case ST_INT: $$ = new AST::IntLit(e.i); break; case ST_BOOL: $$ = new AST::BoolLit(e.i); break; case ST_FLOAT: $$ = new AST::FloatLit(pp->floatvals[e.i]); break; case ST_SET: $$ = new AST::SetLit(pp->setvals[e.i]); break; default: $$ = getVarRefArg(pp,$1); } } else { pp->err << "Error: undefined identifier " << $1 << " in line no. " << yyget_lineno(pp->yyscanner) << std::endl; pp->hadError = true; $$ = NULL; } free($1); } | var_par_id '[' non_array_expr ']' /* array access */ { ParserState* pp = static_cast<ParserState*>(parm); int i = -1; yyassert(pp, $3->isInt(i), "Non-integer array index"); if (!pp->hadError) $$ = getArrayElement(static_cast<ParserState*>(parm),$1,i,false); else $$ = new AST::IntLit(0); // keep things consistent delete $3; free($1); }non_array_expr_list : /* empty */ { $$ = new AST::Array(0); } | non_array_expr_list_head list_tail { $$ = $1; }non_array_expr_list_head : non_array_expr { $$ = new AST::Array($1); } | non_array_expr_list_head ',' non_array_expr { $$ = $1; $$->append($3); }/********************************//* solve expressions *//********************************/solve_expr: var_par_id { ParserState *pp = static_cast<ParserState*>(parm); SymbolEntry e; bool haveSym = pp->symbols.get($1,e); if (haveSym) { switch (e.t) { case ST_INTVAR: $$ = e.i; break; case ST_FLOATVAR: $$ = -e.i-1; break; case ST_INT: case ST_FLOAT: pp->intvars.push_back(varspec("OBJ_CONST_INTRODUCED", new IntVarSpec(0,true,false))); $$ = pp->intvars.size()-1; break; default: pp->err << "Error: unknown int or float variable " << $1 << " in line no. " << yyget_lineno(pp->yyscanner) << std::endl; pp->hadError = true; break; } } else { pp->err << "Error: unknown int or float variable " << $1 << " in line no. " << yyget_lineno(pp->yyscanner) << std::endl; pp->hadError = true; } free($1); } | FZ_INT_LIT { ParserState *pp = static_cast<ParserState*>(parm); pp->intvars.push_back(varspec("OBJ_CONST_INTRODUCED", new IntVarSpec(0,true,false))); $$ = pp->intvars.size()-1; } | FZ_FLOAT_LIT { ParserState *pp = static_cast<ParserState*>(parm); pp->intvars.push_back(varspec("OBJ_CONST_INTRODUCED", new IntVarSpec(0,true,false))); $$ = pp->intvars.size()-1; } | var_par_id '[' FZ_INT_LIT ']' { SymbolEntry e; ParserState *pp = static_cast<ParserState*>(parm); if ( (!pp->symbols.get($1, e)) || (e.t != ST_INTVARARRAY && e.t != ST_FLOATVARARRAY)) { pp->err << "Error: unknown int or float variable array " << $1 << " in line no. " << yyget_lineno(pp->yyscanner) << std::endl; pp->hadError = true; } if ($3 == 0 || $3 > pp->arrays[e.i]) { pp->err << "Error: array index out of bounds for array " << $1 << " in line no. " << yyget_lineno(pp->yyscanner) << std::endl; pp->hadError = true; } else { if (e.t == ST_INTVARARRAY) $$ = pp->arrays[e.i+$3]; else $$ = -pp->arrays[e.i+$3]-1; } free($1); }minmax: FZ_MINIMIZE | FZ_MAXIMIZE/********************************//* annotation expresions *//********************************/annotations : /* empty */ { $$ = NULL; } | annotations_head { $$ = $1; }annotations_head : FZ_COLONCOLON annotation { $$ = new AST::Array($2); } | annotations_head FZ_COLONCOLON annotation { $$ = $1; $$->append($3); }annotation : FZ_ID '(' annotation_list ')' { $$ = new AST::Call($1, AST::extractSingleton($3)); free($1); } | annotation_expr { $$ = $1; }annotation_list: annotation { $$ = new AST::Array($1); } | annotation_list ',' annotation { $$ = $1; $$->append($3); }annotation_expr : ann_non_array_expr { $$ = $1; } | '[' ']' { $$ = new AST::Array(); } | '[' annotation_list annotation_list_tail ']' { $$ = $2; }annotation_list_tail : | ','ann_non_array_expr : FZ_BOOL_LIT { $$ = new AST::BoolLit($1); } | FZ_INT_LIT { $$ = new AST::IntLit($1); } | FZ_FLOAT_LIT { $$ = new AST::FloatLit($1); } | set_literal { $$ = $1; } | var_par_id /* variable, possibly array */ { ParserState* pp = static_cast<ParserState*>(parm); SymbolEntry e; bool gotSymbol = false; if (pp->symbols.get($1, e)) { gotSymbol = true; switch (e.t) { case ST_INTVARARRAY: { AST::Array *v = new AST::Array(pp->arrays[e.i]); for (int i=pp->arrays[e.i]; i--;) { std::ostringstream oss; oss << $1 << "["<<(i+1)<<"]"; v->a[i] = new AST::IntVar(pp->arrays[e.i+i+1], oss.str()); } $$ = v; } break; case ST_BOOLVARARRAY: { AST::Array *v = new AST::Array(pp->arrays[e.i]); for (int i=pp->arrays[e.i]; i--;) { std::ostringstream oss; oss << $1 << "["<<(i+1)<<"]"; v->a[i] = new AST::BoolVar(pp->arrays[e.i+i+1], oss.str()); } $$ = v; } break; case ST_FLOATVARARRAY: { AST::Array *v = new AST::Array(pp->arrays[e.i]); for (int i=pp->arrays[e.i]; i--;) { std::ostringstream oss; oss << $1 << "["<<(i+1)<<"]"; v->a[i] = new AST::FloatVar(pp->arrays[e.i+i+1], oss.str()); } $$ = v; } break; case ST_SETVARARRAY: { AST::Array *v = new AST::Array(pp->arrays[e.i]); for (int i=pp->arrays[e.i]; i--;) { std::ostringstream oss; oss << $1 << "["<<(i+1)<<"]"; v->a[i] = new AST::SetVar(pp->arrays[e.i+i+1], oss.str()); } $$ = v; } break; case ST_INTVALARRAY: { AST::Array *v = new AST::Array(pp->arrays[e.i]); for (int i=pp->arrays[e.i]; i--;) v->a[i] = new AST::IntLit(pp->arrays[e.i+i+1]); $$ = v; } break; case ST_BOOLVALARRAY: { AST::Array *v = new AST::Array(pp->arrays[e.i]); for (int i=pp->arrays[e.i]; i--;) v->a[i] = new AST::BoolLit(pp->arrays[e.i+i+1]); $$ = v; } break; case ST_SETVALARRAY: { AST::Array *v = new AST::Array(pp->arrays[e.i]); int idx = pp->arrays[e.i+1]; for (int i=pp->arrays[e.i]; i--;) v->a[i] = new AST::SetLit(pp->setvals[idx+i]); $$ = v; } break; case ST_FLOATVALARRAY: { AST::Array *v = new AST::Array(pp->arrays[e.i]); int idx = pp->arrays[e.i+1]; for (int i=pp->arrays[e.i]; i--;) v->a[i] = new AST::FloatLit(pp->floatvals[idx+i]); $$ = v; } break; case ST_INT: $$ = new AST::IntLit(e.i); break; case ST_BOOL: $$ = new AST::BoolLit(e.i); break; case ST_FLOAT: $$ = new AST::FloatLit(pp->floatvals[e.i]); break; case ST_SET: $$ = new AST::SetLit(pp->setvals[e.i]); break; default: gotSymbol = false; } } if (!gotSymbol) $$ = getVarRefArg(pp,$1,true); free($1); } | var_par_id '[' ann_non_array_expr ']' /* array access */ { ParserState* pp = static_cast<ParserState*>(parm); int i = -1; yyassert(pp, $3->isInt(i), "Non-integer array index"); if (!pp->hadError) $$ = getArrayElement(static_cast<ParserState*>(parm),$1,i,true); else $$ = new AST::IntLit(0); // keep things consistent free($1); } | FZ_STRING_LIT { $$ = new AST::String($1); free($1); }