Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
50 kB · 1599 lines
at develop
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- *//* * Main authors: * Guido Tack <guido.tack@monash.edu> *//* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */%define api.pure%parse-param {void *parm}%define api.header.include {<minizinc/parser.tab.hh>}%lex-param {void* SCANNER}%{#define SCANNER static_cast<ParserState*>(parm)->yyscanner#include <iostream>#include <fstream>#include <map>#include <cerrno>namespace MiniZinc{ class ParserLocation; }#define YYLTYPE MiniZinc::ParserLocation#define YYLTYPE_IS_DECLARED 1#define YYLTYPE_IS_TRIVIAL 0#define YYMAXDEPTH 10000#define YYINITDEPTH 10000#include <minizinc/parser.hh>#include <minizinc/file_utils.hh>using namespace std;using namespace MiniZinc;#define YYLLOC_DEFAULT(Current, Rhs, N) \ (Current).filename(Rhs[1].filename()); \ (Current).first_line(Rhs[1].first_line()); \ (Current).first_column(Rhs[1].first_column()); \ (Current).last_line(Rhs[N].last_line()); \ (Current).last_column(Rhs[N].last_column());int mzn_yyparse(void*);int mzn_yylex(YYSTYPE*, YYLTYPE*, void* scanner);int mzn_yylex_init (void** scanner);int mzn_yylex_destroy (void* scanner);int mzn_yyget_lineno (void* scanner);void mzn_yyset_extra (void* user_defined ,void* yyscanner );extern int yydebug;void yyerror(YYLTYPE* location, void* parm, const string& str) { ParserState* pp = static_cast<ParserState*>(parm); Model* m = pp->model; while (m->parent() != NULL) { m = m->parent(); pp->err << "(included from file '" << m->filename() << "')" << endl; } pp->err << location->toString() << ":" << endl; pp->printCurrentLine(location->first_column(),location->last_column()); pp->err << "Error: " << str << std::endl; pp->hadError = true; pp->syntaxErrors.push_back(SyntaxError(Location(*location), str));}bool notInDatafile(YYLTYPE* location, void* parm, const string& item) { ParserState* pp = static_cast<ParserState*>(parm); if (pp->isDatafile) { yyerror(location,parm,item+" item not allowed in data file"); return false; } return true;}Expression* createDocComment(const ParserLocation& loc, const std::string& s) { std::vector<Expression*> args(1); args[0] = new StringLit(loc, s); Call* c = new Call(Location(loc), constants().ann.doc_comment, args); c->type(Type::ann()); return c;}Expression* createArrayAccess(const ParserLocation& loc, Expression* e, std::vector<std::vector<Expression*> >& idx) { Expression* ret = e; for (unsigned int i=0; i<idx.size(); i++) { ret = new ArrayAccess(Location(loc), ret, idx[i]); } return ret;}%}%union { long long int iValue; char* sValue; bool bValue; double dValue; MiniZinc::Item* item; MiniZinc::VarDecl* vardeclexpr; std::vector<MiniZinc::VarDecl*>* vardeclexpr_v; MiniZinc::TypeInst* tiexpr; std::vector<MiniZinc::TypeInst*>* tiexpr_v; MiniZinc::Expression* expression; std::vector<MiniZinc::Expression*>* expression_v; std::vector<std::vector<MiniZinc::Expression*> >* expression_vv; std::vector<std::vector<std::vector<MiniZinc::Expression*> > >* expression_vvv; MiniZinc::Generator* generator; std::vector<MiniZinc::Generator>* generator_v; std::vector<std::string>* string_v; std::vector<std::pair<MiniZinc::Expression*,MiniZinc::Expression*> >* expression_p; MiniZinc::Generators* generators; }%locations%define parse.error verbose%initial-action{ GCLock lock; @$.filename(ASTString(static_cast<ParserState*>(parm)->filename));}%token <iValue> MZN_INTEGER_LITERAL "integer literal" MZN_BOOL_LITERAL "bool literal"%token <dValue> MZN_FLOAT_LITERAL "float literal"%token <sValue> MZN_IDENTIFIER "identifier" MZN_QUOTED_IDENTIFIER "quoted identifier" MZN_STRING_LITERAL "string literal"%token <sValue> MZN_STRING_QUOTE_START "interpolated string start" MZN_STRING_QUOTE_MID "interpolated string middle" MZN_STRING_QUOTE_END "interpolated string end"%token <sValue> MZN_TI_IDENTIFIER "type-inst identifier" MZN_TI_ENUM_IDENTIFIER "type-inst enum identifier" MZN_DOC_COMMENT "documentation comment" MZN_DOC_FILE_COMMENT "file-level documentation comment"%token MZN_VAR "var" MZN_PAR "par"%token MZN_ABSENT "<>"%token MZN_ANN "ann"%token MZN_ANNOTATION "annotation"%token MZN_ANY "any"%token MZN_ARRAY "array"%token MZN_BOOL "bool"%token MZN_CASE "case"%token MZN_CONSTRAINT "constraint"%token MZN_DEFAULT "default"%token MZN_ELSE "else"%token MZN_ELSEIF "elseif"%token MZN_ENDIF "endif"%token MZN_ENUM "enum"%token MZN_FLOAT "float"%token MZN_FUNCTION "function"%token MZN_IF "if"%token MZN_INCLUDE "include"%token MZN_INFINITY "infinity"%token MZN_INT "int"%token MZN_LET "let"%token MZN_LIST "list"%token <bValue> MZN_MAXIMIZE "maximize"%token <bValue> MZN_MINIMIZE "minimize"%token MZN_OF "of"%token MZN_OPT "opt"%token MZN_SATISFY "satisfy"%token MZN_OUTPUT "output"%token MZN_PREDICATE "predicate"%token MZN_RECORD "record"%token MZN_SET "set"%token MZN_SOLVE "solve"%token MZN_STRING "string"%token MZN_TEST "test"%token MZN_THEN "then"%token MZN_TUPLE "tuple"%token MZN_TYPE "type"%token MZN_UNDERSCORE "_"%token MZN_VARIANT_RECORD "variant_record"%token MZN_WHERE "where"%token MZN_LEFT_BRACKET "["%token MZN_LEFT_2D_BRACKET "[|"%token MZN_RIGHT_BRACKET "]"%token MZN_RIGHT_2D_BRACKET "|]"// Used to signal an error when parsing a MiniZinc file// that contains identifiers starting with _%token FLATZINC_IDENTIFIER%token MZN_INVALID_INTEGER_LITERAL "invalid integer literal"%token MZN_INVALID_FLOAT_LITERAL "invalid float literal"%token MZN_UNTERMINATED_STRING "unterminated string"%token MZN_END_OF_LINE_IN_STRING "end of line inside string literal"%token MZN_INVALID_NULL "null character"%token END 0 "end of file"%token MZN_EQUIV "<->"%token MZN_IMPL "->" MZN_RIMPL "<-"%token MZN_OR "\\/" MZN_XOR "xor"%token MZN_AND "/\\"%token MZN_LE "<" MZN_GR ">" MZN_LQ "<=" MZN_GQ ">=" MZN_EQ "=" MZN_NQ "!=" MZN_WEAK_EQ "~="%token MZN_IN "in" MZN_SUBSET "subset" MZN_SUPERSET "superset"%token MZN_UNION "union" MZN_DIFF "diff" MZN_SYMDIFF "symdiff"%token MZN_DOTDOT ".."%token MZN_PLUS "+" MZN_MINUS "-" MZN_WEAK_PLUS "~+" MZN_WEAK_MINUS "~-"%token MZN_MULT "*" MZN_DIV "/" MZN_IDIV "div" MZN_MOD "mod" MZN_INTERSECT "intersect" MZN_WEAK_MULT "~*"%token MZN_POW "^"%token MZN_NOT "not"%token MZN_PLUSPLUS "++"%token MZN_COLONCOLON "::"%right PREC_ANNO%left MZN_EQUIV%left MZN_IMPL MZN_RIMPL%left MZN_OR MZN_XOR%left MZN_AND%nonassoc MZN_LE MZN_GR MZN_LQ MZN_GQ MZN_EQ MZN_NQ MZN_WEAK_EQ%nonassoc MZN_IN MZN_SUBSET MZN_SUPERSET%left MZN_UNION MZN_DIFF MZN_SYMDIFF MZN_INTERSECT %nonassoc MZN_DOTDOT%left MZN_PLUS MZN_MINUS MZN_WEAK_PLUS MZN_WEAK_MINUS%left MZN_MULT MZN_DIV MZN_IDIV MZN_MOD MZN_WEAK_MULT%left MZN_POW%nonassoc MZN_NOT%left MZN_PLUSPLUS%left MZN_QUOTED_IDENTIFIER%left MZN_COLONCOLON%token MZN_EQUIV_QUOTED "'<->'"%token MZN_IMPL_QUOTED "'->'" MZN_RIMPL_QUOTED "'<-'"%token MZN_OR_QUOTED "'\\/'" MZN_XOR_QUOTED "'xor'"%token MZN_AND_QUOTED "'/\\'"%token MZN_LE_QUOTED "'<'" MZN_GR_QUOTED "'>'" MZN_LQ_QUOTED "'<='" MZN_GQ_QUOTED "'>='" MZN_EQ_QUOTED "'='" MZN_NQ_QUOTED "'!='"%token MZN_IN_QUOTED "'in'" MZN_SUBSET_QUOTED "'subset'" MZN_SUPERSET_QUOTED "'superset'"%token MZN_UNION_QUOTED "'union'" MZN_DIFF_QUOTED "'diff'" MZN_SYMDIFF_QUOTED "'symdiff'"%token MZN_DOTDOT_QUOTED "'..'"%token MZN_PLUS_QUOTED "'+'" MZN_MINUS_QUOTED "'-'"%token MZN_MULT_QUOTED "'*'" MZN_DIV_QUOTED "'/'" MZN_IDIV_QUOTED "'div'" MZN_MOD_QUOTED "'mod'" MZN_INTERSECT_QUOTED "'intersect'"%token MZN_POW_QUOTED "'^'"%token MZN_NOT_QUOTED "'not'"%token MZN_COLONCOLON_QUOTED "'::'"%token MZN_PLUSPLUS_QUOTED "'++'"%type <item> item item_tail include_item vardecl_item assign_item constraint_item solve_item output_item predicate_item annotation_item function_item%type <vardeclexpr> ti_expr_and_id ti_expr_and_id_or_anon let_vardecl_item%type <vardeclexpr_v> params params_list params_list_head%type <tiexpr> ti_expr base_ti_expr base_ti_expr_tail%type <tiexpr_v> ti_expr_list ti_expr_list_head%type <expression> expr expr_atom_head expr_atom_head_nonstring array_access_expr%type <expression> set_expr string_expr string_quote_rest annotation_expr%type <expression> simple_array_literal simple_array_literal_2d simple_array_comp if_then_else_expr call_expr quoted_op_call let_expr operation_item_tail set_literal set_comp%type <expression_v> expr_list expr_list_head array_access_expr_list array_access_expr_list_head elseif_list let_vardecl_item_list enum_id_list string_lit_list%type <expression_vv> simple_array_literal_2d_list array_access_tail%type <expression_vvv> simple_array_literal_3d_list%type <generators> comp_tail%type <generator> generator generator_eq%type <generator_v> generator_list generator_list_head%type <string_v> id_list id_list_head%type <expression_p> comp_or_expr comp_or_expr_head%type <expression_v> annotations ne_annotations%type <iValue> quoted_op%type <sValue> id_or_quoted_op%type <bValue> opt_opt%%/********************************//* main goal and item lists *//********************************/model : item_listitem_list : /* empty */ | item_list_head semi_or_noneitem_list_head: item { ParserState* pp = static_cast<ParserState*>(parm); if ($1) { pp->model->addItem($1); GC::unlock(); GC::lock(); } } | doc_file_comments item { ParserState* pp = static_cast<ParserState*>(parm); if ($2) { pp->model->addItem($2); GC::unlock(); GC::lock(); } } | item_list_head ';' item { ParserState* pp = static_cast<ParserState*>(parm); if ($3) { pp->model->addItem($3); GC::unlock(); GC::lock(); } } | item_list_head ';' doc_file_comments item { ParserState* pp = static_cast<ParserState*>(parm); if ($4) { pp->model->addItem($4); GC::unlock(); GC::lock(); } } | item error_item_start{ yyerror(&@2, parm, "unexpected item, expecting ';' or end of file"); YYERROR; } | error ';' itemdoc_file_comments: MZN_DOC_FILE_COMMENT { ParserState* pp = static_cast<ParserState*>(parm); if (pp->parseDocComments && $1) { pp->model->addDocComment($1); } free($1); } | doc_file_comments MZN_DOC_FILE_COMMENT { ParserState* pp = static_cast<ParserState*>(parm); if (pp->parseDocComments && $2) { pp->model->addDocComment($2); } free($2); }semi_or_none : | ';'item : MZN_DOC_COMMENT item_tail { $$ = $2; ParserState* pp = static_cast<ParserState*>(parm); if (FunctionI* fi = Item::dyn_cast<FunctionI>($$)) { if (pp->parseDocComments) { fi->ann().add(createDocComment(@1,$1)); } } else if (VarDeclI* vdi = Item::dyn_cast<VarDeclI>($$)) { if (pp->parseDocComments) { vdi->e()->addAnnotation(createDocComment(@1,$1)); } } else { yyerror(&@2, parm, "documentation comments are only supported for function, predicate and variable declarations"); } free($1); } | item_tail { $$ = $1; }item_tail : include_item { $$=notInDatafile(&@$,parm,"include") ? $1 : NULL; } | vardecl_item { $$=notInDatafile(&@$,parm,"variable declaration") ? $1 : NULL; } | assign_item | constraint_item { $$=notInDatafile(&@$,parm,"constraint") ? $1 : NULL; } | solve_item { $$=notInDatafile(&@$,parm,"solve") ? $1 : NULL; } | output_item { $$=notInDatafile(&@$,parm,"output") ? $1 : NULL; } | predicate_item { $$=notInDatafile(&@$,parm,"predicate") ? $1 : NULL; } | function_item { $$=notInDatafile(&@$,parm,"predicate") ? $1 : NULL; } | annotation_item { $$=notInDatafile(&@$,parm,"annotation") ? $1 : NULL; }error_item_start : MZN_INCLUDE | MZN_ENUM | MZN_OUTPUT | MZN_CONSTRAINT | MZN_SOLVE | MZN_PREDICATE | MZN_FUNCTION | MZN_TEST | MZN_ANNOTATIONinclude_item : MZN_INCLUDE MZN_STRING_LITERAL { ParserState* pp = static_cast<ParserState*>(parm); map<string,Model*>::iterator ret = pp->seenModels.find($2); IncludeI* ii = new IncludeI(@$,ASTString($2)); $$ = ii; if (ret == pp->seenModels.end()) { Model* im = new Model; im->setParent(pp->model); im->setFilename($2); string fpath = FileUtils::dir_name(pp->filename); string fbase = FileUtils::base_name(pp->filename); if (fpath=="") fpath="./"; ParseWorkItem pm(im, ii, fpath, $2); pp->files.push_back(pm); ii->m(im); pp->seenModels.insert(pair<string,Model*>($2,im)); } else { ii->m(ret->second, false); } free($2); }vardecl_item : ti_expr_and_id annotations { if ($1 && $2) $1->addAnnotations(*$2); if ($1) $$ = new VarDeclI(@$,$1); delete $2; } | ti_expr_and_id annotations MZN_EQ expr { if ($1) $1->e($4); if ($1 && $2) $1->addAnnotations(*$2); if ($1) $$ = new VarDeclI(@$,$1); delete $2; } | MZN_ENUM MZN_IDENTIFIER { TypeInst* ti = new TypeInst(@$,Type::parsetint()); ti->setIsEnum(true); VarDecl* vd = new VarDecl(@$,ti,$2); free($2); $$ = new VarDeclI(@$,vd); } | MZN_ENUM MZN_IDENTIFIER MZN_EQ '{' enum_id_list '}' { TypeInst* ti = new TypeInst(@$,Type::parsetint()); ti->setIsEnum(true); SetLit* sl = new SetLit(@$, *$5); VarDecl* vd = new VarDecl(@$,ti,$2,sl); free($2); delete $5; $$ = new VarDeclI(@$,vd); } | MZN_ENUM MZN_IDENTIFIER MZN_EQ MZN_LEFT_BRACKET string_lit_list MZN_RIGHT_BRACKET { TypeInst* ti = new TypeInst(@$,Type::parsetint()); ti->setIsEnum(true); vector<Expression*> args; args.push_back(new ArrayLit(@$,*$5)); Call* sl = new Call(@$, constants().ids.anonEnumFromStrings, args); VarDecl* vd = new VarDecl(@$,ti,$2,sl); free($2); delete $5; $$ = new VarDeclI(@$,vd); } | MZN_ENUM MZN_IDENTIFIER MZN_EQ MZN_IDENTIFIER '(' expr ')' { TypeInst* ti = new TypeInst(@$,Type::parsetint()); ti->setIsEnum(true); vector<Expression*> args; args.push_back($6); Call* sl = new Call(@$, ASTString($4), args); VarDecl* vd = new VarDecl(@$,ti,$2,sl); free($2); free($4); $$ = new VarDeclI(@$,vd); }string_lit_list : // empty { $$ = new std::vector<Expression*>(); } | MZN_STRING_LITERAL { $$ = new std::vector<Expression*>(); $$->push_back(new StringLit(@$, $1)); free($1); } | string_lit_list ',' MZN_STRING_LITERAL { $$ = $1; if ($$) $$->push_back(new StringLit(@$, $3)); free($3); }enum_id_list : // empty { $$ = new std::vector<Expression*>(); } | MZN_IDENTIFIER { $$ = new std::vector<Expression*>(); $$->push_back(new Id(@$,$1,NULL)); free($1); } | enum_id_list ',' MZN_IDENTIFIER { $$ = $1; if ($$) $$->push_back(new Id(@$,$3,NULL)); free($3); }assign_item : MZN_IDENTIFIER MZN_EQ expr { $$ = new AssignI(@$,$1,$3); free($1); }constraint_item : MZN_CONSTRAINT expr { $$ = new ConstraintI(@$,$2);} | MZN_CONSTRAINT MZN_COLONCOLON string_expr expr { $$ = new ConstraintI(@$,$4); if ($4 && $3) $$->cast<ConstraintI>()->e()->ann().add(new Call(@2, ASTString("mzn_constraint_name"), {$3})); }solve_item : MZN_SOLVE annotations MZN_SATISFY { $$ = SolveI::sat(@$); if ($$ && $2) $$->cast<SolveI>()->ann().add(*$2); delete $2; } | MZN_SOLVE annotations MZN_MINIMIZE expr { $$ = SolveI::min(@$,$4); if ($$ && $2) $$->cast<SolveI>()->ann().add(*$2); delete $2; } | MZN_SOLVE annotations MZN_MAXIMIZE expr { $$ = SolveI::max(@$,$4); if ($$ && $2) $$->cast<SolveI>()->ann().add(*$2); delete $2; }output_item : MZN_OUTPUT expr { $$ = new OutputI(@$,$2);}predicate_item : MZN_PREDICATE MZN_IDENTIFIER params annotations operation_item_tail { if ($3) $$ = new FunctionI(@$,$2,new TypeInst(@$, Type::varbool()),*$3,$5); if ($$ && $4) $$->cast<FunctionI>()->ann().add(*$4); free($2); delete $3; delete $4; } | MZN_TEST MZN_IDENTIFIER params annotations operation_item_tail { if ($3) $$ = new FunctionI(@$,$2,new TypeInst(@$, Type::parbool()),*$3,$5); if ($$ && $4) $$->cast<FunctionI>()->ann().add(*$4); free($2); delete $3; delete $4; }function_item : MZN_FUNCTION ti_expr ':' id_or_quoted_op params annotations operation_item_tail { if ($5) $$ = new FunctionI(@$,$4,$2,*$5,$7); if ($$ && $6) $$->cast<FunctionI>()->ann().add(*$6); free($4); delete $5; delete $6; } | ti_expr ':' MZN_IDENTIFIER '(' params_list ')' annotations operation_item_tail { if ($5) $$ = new FunctionI(@$,$3,$1,*$5,$8); if ($$ && $7) $$->cast<FunctionI>()->ann().add(*$7); free($3); delete $5; delete $7; }annotation_item : MZN_ANNOTATION MZN_IDENTIFIER params { TypeInst* ti=new TypeInst(@1,Type::ann()); if ($3==NULL || $3->empty()) { VarDecl* vd = new VarDecl(@$,ti,$2); $$ = new VarDeclI(@$,vd); } else { $$ = new FunctionI(@$,$2,ti,*$3,NULL); } free($2); delete $3; } | MZN_ANNOTATION MZN_IDENTIFIER params MZN_EQ expr { TypeInst* ti=new TypeInst(@1,Type::ann()); if ($3) $$ = new FunctionI(@$,$2,ti,*$3,$5); delete $3; }operation_item_tail : /*empty*/ { $$=NULL; } | MZN_EQ expr { $$=$2; }params : /* empty */ { $$=new vector<VarDecl*>(); } | '(' params_list ')' { $$=$2; } | '(' error ')' { $$=new vector<VarDecl*>(); }params_list : /* empty */ { $$=new vector<VarDecl*>(); } | params_list_head comma_or_none { $$=$1; }params_list_head : ti_expr_and_id_or_anon { $$=new vector<VarDecl*>(); if ($1) $1->toplevel(false); if ($1) $$->push_back($1); } | params_list_head ',' ti_expr_and_id_or_anon { $$=$1; if ($3) $3->toplevel(false); if ($1 && $3) $1->push_back($3); }comma_or_none : | ','ti_expr_and_id_or_anon : ti_expr_and_id { $$=$1; } | ti_expr { if ($1) $$=new VarDecl(@$, $1, ""); } ti_expr_and_id : ti_expr ':' MZN_IDENTIFIER { if ($1 && $3) $$ = new VarDecl(@$, $1, $3); free($3); }ti_expr_list : ti_expr_list_head comma_or_none { $$=$1; }ti_expr_list_head : ti_expr { $$=new vector<TypeInst*>(); $$->push_back($1); } | ti_expr_list_head ',' ti_expr { $$=$1; if ($1 && $3) $1->push_back($3); }ti_expr : base_ti_expr | MZN_ARRAY MZN_LEFT_BRACKET ti_expr_list MZN_RIGHT_BRACKET MZN_OF base_ti_expr { $$ = $6; if ($$ && $3) $$->setRanges(*$3); delete $3; } | MZN_LIST MZN_OF base_ti_expr { $$ = $3; std::vector<TypeInst*> ti(1); ti[0] = new TypeInst(@$,Type::parint()); if ($$) $$->setRanges(ti); }base_ti_expr : base_ti_expr_tail { $$ = $1; } | MZN_OPT base_ti_expr_tail { $$ = $2; if ($$) { Type tt = $$->type(); tt.ot(Type::OT_OPTIONAL); $$->type(tt); } } | MZN_PAR opt_opt base_ti_expr_tail { $$ = $3; if ($$ && $2) { Type tt = $$->type(); tt.ot(Type::OT_OPTIONAL); $$->type(tt); } } | MZN_VAR opt_opt base_ti_expr_tail { $$ = $3; if ($$) { Type tt = $$->type(); tt.ti(Type::TI_VAR); if ($2) tt.ot(Type::OT_OPTIONAL); $$->type(tt); } } | opt_opt MZN_SET MZN_OF base_ti_expr_tail { $$ = $4; if ($$) { Type tt = $$->type(); tt.st(Type::ST_SET); if ($1) tt.ot(Type::OT_OPTIONAL); $$->type(tt); } } | MZN_PAR opt_opt MZN_SET MZN_OF base_ti_expr_tail { $$ = $5; if ($$) { Type tt = $$->type(); tt.st(Type::ST_SET); if ($2) tt.ot(Type::OT_OPTIONAL); $$->type(tt); } } | MZN_VAR opt_opt MZN_SET MZN_OF base_ti_expr_tail { $$ = $5; if ($$) { Type tt = $$->type(); tt.ti(Type::TI_VAR); tt.st(Type::ST_SET); if ($2) tt.ot(Type::OT_OPTIONAL); $$->type(tt); } }opt_opt: /* nothing */ { $$ = false; } | MZN_OPT { $$ = true; }base_ti_expr_tail : MZN_INT { $$ = new TypeInst(@$,Type::parint()); } | MZN_BOOL { $$ = new TypeInst(@$,Type::parbool()); } | MZN_FLOAT { $$ = new TypeInst(@$,Type::parfloat()); } | MZN_STRING { $$ = new TypeInst(@$,Type::parstring()); } | MZN_ANN { $$ = new TypeInst(@$,Type::ann()); } | set_expr { if ($1) $$ = new TypeInst(@$,Type(),$1); } | MZN_TI_IDENTIFIER { $$ = new TypeInst(@$,Type::top(), new TIId(@$, $1)); free($1); } | MZN_TI_ENUM_IDENTIFIER { $$ = new TypeInst(@$,Type::parint(), new TIId(@$, $1)); free($1); }array_access_expr_list : array_access_expr_list_head comma_or_nonearray_access_expr_list_head : array_access_expr { $$=new std::vector<MiniZinc::Expression*>; $$->push_back($1); } | array_access_expr_list_head ',' array_access_expr { $$=$1; if ($$ && $3) $$->push_back($3); }array_access_expr : expr { $$ = $1; } | MZN_DOTDOT { $$=new SetLit(@$, IntSetVal::a(-IntVal::infinity(),IntVal::infinity())); } | MZN_DOTDOT expr { if ($2==NULL) { $$ = NULL; } else if ($2->isa<IntLit>()) { $$=new SetLit(@$, IntSetVal::a(-IntVal::infinity(),$2->cast<IntLit>()->v())); } else { $$=new BinOp(@$, IntLit::a(-IntVal::infinity()), BOT_DOTDOT, $2); } } | expr MZN_DOTDOT { if ($1==NULL) { $$ = NULL; } else if ($1->isa<IntLit>()) { $$=new SetLit(@$, IntSetVal::a($1->cast<IntLit>()->v(),IntVal::infinity())); } else { $$=new BinOp(@$, $1, BOT_DOTDOT, IntLit::a(IntVal::infinity())); } }expr_list : expr_list_head comma_or_noneexpr_list_head : expr { $$=new std::vector<MiniZinc::Expression*>; $$->push_back($1); } | expr_list_head ',' expr { $$=$1; if ($$ && $3) $$->push_back($3); }///set_expr : expr_atom_head | set_expr MZN_COLONCOLON annotation_expr { if ($1 && $3) $1->addAnnotation($3); $$=$1; } | set_expr MZN_UNION set_expr { $$=new BinOp(@$, $1, BOT_UNION, $3); } | set_expr MZN_DIFF set_expr { $$=new BinOp(@$, $1, BOT_DIFF, $3); } | set_expr MZN_SYMDIFF set_expr { $$=new BinOp(@$, $1, BOT_SYMDIFF, $3); } | set_expr MZN_DOTDOT set_expr { if ($1==NULL || $3==NULL) { $$ = NULL; } else if ($1->isa<IntLit>() && $3->isa<IntLit>()) { $$=new SetLit(@$, IntSetVal::a($1->cast<IntLit>()->v(),$3->cast<IntLit>()->v())); } else { $$=new BinOp(@$, $1, BOT_DOTDOT, $3); } } | MZN_DOTDOT_QUOTED '(' expr ',' expr ')' { if ($3==NULL || $5==NULL) { $$ = NULL; } else if ($3->isa<IntLit>() && $5->isa<IntLit>()) { $$=new SetLit(@$, IntSetVal::a($3->cast<IntLit>()->v(),$5->cast<IntLit>()->v())); } else { $$=new BinOp(@$, $3, BOT_DOTDOT, $5); } } | set_expr MZN_INTERSECT set_expr { $$=new BinOp(@$, $1, BOT_INTERSECT, $3); } | set_expr MZN_PLUSPLUS set_expr { $$=new BinOp(@$, $1, BOT_PLUSPLUS, $3); } | set_expr MZN_PLUS set_expr { $$=new BinOp(@$, $1, BOT_PLUS, $3); } | set_expr MZN_MINUS set_expr { $$=new BinOp(@$, $1, BOT_MINUS, $3); } | set_expr MZN_MULT set_expr { $$=new BinOp(@$, $1, BOT_MULT, $3); } | set_expr MZN_DIV set_expr { $$=new BinOp(@$, $1, BOT_DIV, $3); } | set_expr MZN_IDIV set_expr { $$=new BinOp(@$, $1, BOT_IDIV, $3); } | set_expr MZN_MOD set_expr { $$=new BinOp(@$, $1, BOT_MOD, $3); } | set_expr MZN_POW set_expr { $$=new BinOp(@$, $1, BOT_POW, $3); } | set_expr MZN_WEAK_PLUS set_expr { vector<Expression*> args; args.push_back($1); args.push_back($3); $$=new Call(@$, ASTString("~+"), args); } | set_expr MZN_WEAK_MINUS set_expr { vector<Expression*> args; args.push_back($1); args.push_back($3); $$=new Call(@$, ASTString("~-"), args); } | set_expr MZN_WEAK_MULT set_expr { vector<Expression*> args; args.push_back($1); args.push_back($3); $$=new Call(@$, ASTString("~*"), args); } | set_expr MZN_WEAK_EQ set_expr { vector<Expression*> args; args.push_back($1); args.push_back($3); $$=new Call(@$, ASTString("~="), args); } | set_expr MZN_QUOTED_IDENTIFIER set_expr { vector<Expression*> args; args.push_back($1); args.push_back($3); $$=new Call(@$, $2, args); free($2); } | MZN_PLUS set_expr %prec MZN_NOT { $$=new UnOp(@$, UOT_PLUS, $2); } | MZN_MINUS set_expr %prec MZN_NOT { if ($2 && $2->isa<IntLit>()) { $$ = IntLit::a(-$2->cast<IntLit>()->v()); } else if ($2 && $2->isa<FloatLit>()) { $$ = FloatLit::a(-$2->cast<FloatLit>()->v()); } else { $$=new UnOp(@$, UOT_MINUS, $2); } }///expr : expr_atom_head | expr MZN_COLONCOLON annotation_expr { if ($1 && $3) $1->addAnnotation($3); $$=$1; } | expr MZN_EQUIV expr { $$=new BinOp(@$, $1, BOT_EQUIV, $3); } | expr MZN_IMPL expr { $$=new BinOp(@$, $1, BOT_IMPL, $3); } | expr MZN_RIMPL expr { $$=new BinOp(@$, $1, BOT_RIMPL, $3); } | expr MZN_OR expr { $$=new BinOp(@$, $1, BOT_OR, $3); } | expr MZN_XOR expr { $$=new BinOp(@$, $1, BOT_XOR, $3); } | expr MZN_AND expr { $$=new BinOp(@$, $1, BOT_AND, $3); } | expr MZN_LE expr { $$=new BinOp(@$, $1, BOT_LE, $3); } | expr MZN_GR expr { $$=new BinOp(@$, $1, BOT_GR, $3); } | expr MZN_LQ expr { $$=new BinOp(@$, $1, BOT_LQ, $3); } | expr MZN_GQ expr { $$=new BinOp(@$, $1, BOT_GQ, $3); } | expr MZN_EQ expr { $$=new BinOp(@$, $1, BOT_EQ, $3); } | expr MZN_NQ expr { $$=new BinOp(@$, $1, BOT_NQ, $3); } | expr MZN_IN expr { $$=new BinOp(@$, $1, BOT_IN, $3); } | expr MZN_SUBSET expr { $$=new BinOp(@$, $1, BOT_SUBSET, $3); } | expr MZN_SUPERSET expr { $$=new BinOp(@$, $1, BOT_SUPERSET, $3); } | expr MZN_UNION expr { $$=new BinOp(@$, $1, BOT_UNION, $3); } | expr MZN_DIFF expr { $$=new BinOp(@$, $1, BOT_DIFF, $3); } | expr MZN_SYMDIFF expr { $$=new BinOp(@$, $1, BOT_SYMDIFF, $3); } | expr MZN_DOTDOT expr { if ($1==NULL || $3==NULL) { $$ = NULL; } else if ($1->isa<IntLit>() && $3->isa<IntLit>()) { $$=new SetLit(@$, IntSetVal::a($1->cast<IntLit>()->v(),$3->cast<IntLit>()->v())); } else { $$=new BinOp(@$, $1, BOT_DOTDOT, $3); } } | MZN_DOTDOT_QUOTED '(' expr ',' expr ')' { if ($3==NULL || $5==NULL) { $$ = NULL; } else if ($3->isa<IntLit>() && $5->isa<IntLit>()) { $$=new SetLit(@$, IntSetVal::a($3->cast<IntLit>()->v(),$5->cast<IntLit>()->v())); } else { $$=new BinOp(@$, $3, BOT_DOTDOT, $5); } } | expr MZN_INTERSECT expr { $$=new BinOp(@$, $1, BOT_INTERSECT, $3); } | expr MZN_PLUSPLUS expr { $$=new BinOp(@$, $1, BOT_PLUSPLUS, $3); } | expr MZN_PLUS expr { $$=new BinOp(@$, $1, BOT_PLUS, $3); } | expr MZN_MINUS expr { $$=new BinOp(@$, $1, BOT_MINUS, $3); } | expr MZN_MULT expr { $$=new BinOp(@$, $1, BOT_MULT, $3); } | expr MZN_DIV expr { $$=new BinOp(@$, $1, BOT_DIV, $3); } | expr MZN_IDIV expr { $$=new BinOp(@$, $1, BOT_IDIV, $3); } | expr MZN_MOD expr { $$=new BinOp(@$, $1, BOT_MOD, $3); } | expr MZN_POW expr { $$=new BinOp(@$, $1, BOT_POW, $3); } | expr MZN_WEAK_PLUS expr { vector<Expression*> args; args.push_back($1); args.push_back($3); $$=new Call(@$, ASTString("~+"), args); } | expr MZN_WEAK_MINUS expr { vector<Expression*> args; args.push_back($1); args.push_back($3); $$=new Call(@$, ASTString("~-"), args); } | expr MZN_WEAK_MULT expr { vector<Expression*> args; args.push_back($1); args.push_back($3); $$=new Call(@$, ASTString("~*"), args); } | expr MZN_WEAK_EQ expr { vector<Expression*> args; args.push_back($1); args.push_back($3); $$=new Call(@$, ASTString("~="), args); } | expr MZN_QUOTED_IDENTIFIER expr { vector<Expression*> args; args.push_back($1); args.push_back($3); $$=new Call(@$, $2, args); free($2); } | MZN_NOT expr %prec MZN_NOT { $$=new UnOp(@$, UOT_NOT, $2); } | MZN_PLUS expr %prec MZN_NOT { if (($2 && $2->isa<IntLit>()) || ($2 && $2->isa<FloatLit>())) { $$ = $2; } else { $$=new UnOp(@$, UOT_PLUS, $2); } } | MZN_MINUS expr %prec MZN_NOT { if ($2 && $2->isa<IntLit>()) { $$ = IntLit::a(-$2->cast<IntLit>()->v()); } else if ($2 && $2->isa<FloatLit>()) { $$ = FloatLit::a(-$2->cast<FloatLit>()->v()); } else { $$=new UnOp(@$, UOT_MINUS, $2); } }expr_atom_head : expr_atom_head_nonstring { $$=$1; } | string_expr { $$=$1; }expr_atom_head_nonstring : '(' expr ')' { $$=$2; } | '(' expr ')' array_access_tail { if ($4) $$=createArrayAccess(@$, $2, *$4); delete $4; } | MZN_IDENTIFIER { $$=new Id(@$, $1, NULL); free($1); } | MZN_IDENTIFIER array_access_tail { if ($2) $$=createArrayAccess(@$, new Id(@1,$1,NULL), *$2); free($1); delete $2; } | MZN_UNDERSCORE { $$=new AnonVar(@$); } | MZN_UNDERSCORE array_access_tail { if ($2) $$=createArrayAccess(@$, new AnonVar(@$), *$2); delete $2; } | MZN_BOOL_LITERAL { $$=constants().boollit(($1!=0)); } | MZN_INTEGER_LITERAL { $$=IntLit::a($1); } | MZN_INFINITY { $$=IntLit::a(IntVal::infinity()); } | MZN_FLOAT_LITERAL { $$=FloatLit::a($1); } | MZN_ABSENT { $$=constants().absent; } | set_literal | set_literal array_access_tail { if ($2) $$=createArrayAccess(@$, $1, *$2); delete $2; } | set_comp | set_comp array_access_tail { if ($2) $$=createArrayAccess(@$, $1, *$2); delete $2; } | simple_array_literal | simple_array_literal array_access_tail { if ($2) $$=createArrayAccess(@$, $1, *$2); delete $2; } | simple_array_literal_2d | simple_array_literal_2d array_access_tail { if ($2) $$=createArrayAccess(@$, $1, *$2); delete $2; } | simple_array_comp | simple_array_comp array_access_tail { if ($2) $$=createArrayAccess(@$, $1, *$2); delete $2; } | if_then_else_expr | if_then_else_expr array_access_tail { if ($2) $$=createArrayAccess(@$, $1, *$2); delete $2; } | let_expr | call_expr | call_expr array_access_tail { if ($2) $$=createArrayAccess(@$, $1, *$2); delete $2; }string_expr: MZN_STRING_LITERAL { $$=new StringLit(@$, $1); free($1); } | MZN_STRING_QUOTE_START string_quote_rest { $$=new BinOp(@$, new StringLit(@$, $1), BOT_PLUSPLUS, $2); free($1); }string_quote_rest: expr_list_head MZN_STRING_QUOTE_END { if ($1) $$=new BinOp(@$, new Call(@$, ASTString("format"), *$1), BOT_PLUSPLUS, new StringLit(@$,$2)); free($2); delete $1; } | expr_list_head MZN_STRING_QUOTE_MID string_quote_rest { if ($1) $$=new BinOp(@$, new Call(@$, ASTString("format"), *$1), BOT_PLUSPLUS, new BinOp(@$, new StringLit(@$,$2), BOT_PLUSPLUS, $3)); free($2); delete $1; }array_access_tail : MZN_LEFT_BRACKET array_access_expr_list MZN_RIGHT_BRACKET { $$=new std::vector<std::vector<Expression*> >(); if ($2) { $$->push_back(*$2); delete $2; } } | array_access_tail MZN_LEFT_BRACKET array_access_expr_list MZN_RIGHT_BRACKET { $$=$1; if ($$ && $3) { $$->push_back(*$3); delete $3; } }set_literal : '{' '}' { $$ = new SetLit(@$, std::vector<Expression*>()); } | '{' expr_list '}' { if ($2) $$ = new SetLit(@$, *$2); delete $2; }set_comp : '{' expr '|' comp_tail '}' { if ($4) $$ = new Comprehension(@$, $2, *$4, true); delete $4; }comp_tail : generator_list { if ($1) $$=new Generators; $$->_g = *$1; delete $1; }generator_list : generator_list_head comma_or_nonegenerator_list_head : generator { $$=new std::vector<Generator>; if ($1) $$->push_back(*$1); delete $1; } | generator_eq { $$=new std::vector<Generator>; if ($1) $$->push_back(*$1); delete $1; } | generator_eq MZN_WHERE expr { $$=new std::vector<Generator>; if ($1) $$->push_back(*$1); if ($1 && $3) $$->push_back(Generator($$->size(),$3)); delete $1; } | generator_list_head ',' generator { $$=$1; if ($$ && $3) $$->push_back(*$3); delete $3; } | generator_list_head ',' generator_eq { $$=$1; if ($$ && $3) $$->push_back(*$3); delete $3; } | generator_list_head ',' generator_eq MZN_WHERE expr { $$=$1; if ($$ && $3) $$->push_back(*$3); if ($$ && $3 && $5) $$->push_back(Generator($$->size(),$5)); delete $3; }generator : id_list MZN_IN expr { if ($1 && $3) $$=new Generator(*$1,$3,NULL); else $$=NULL; delete $1; } | id_list MZN_IN expr MZN_WHERE expr { if ($1 && $3) $$=new Generator(*$1,$3,$5); else $$=NULL; delete $1; }generator_eq : MZN_IDENTIFIER MZN_EQ expr { if ($3) $$=new Generator({$1},NULL,$3); else $$=NULL; free($1); }id_list : id_list_head comma_or_noneid_list_head : MZN_IDENTIFIER { $$=new std::vector<std::string>; $$->push_back($1); free($1); } | id_list_head ',' MZN_IDENTIFIER { $$=$1; if ($$ && $3) $$->push_back($3); free($3); }simple_array_literal : MZN_LEFT_BRACKET MZN_RIGHT_BRACKET { $$=new ArrayLit(@$, std::vector<MiniZinc::Expression*>()); } | MZN_LEFT_BRACKET expr_list MZN_RIGHT_BRACKET { if ($2) $$=new ArrayLit(@$, *$2); delete $2; }simple_array_literal_2d : MZN_LEFT_2D_BRACKET MZN_RIGHT_2D_BRACKET { $$=new ArrayLit(@$, std::vector<std::vector<Expression*> >()); } | MZN_LEFT_2D_BRACKET simple_array_literal_2d_list MZN_RIGHT_2D_BRACKET { if ($2) { $$=new ArrayLit(@$, *$2); for (unsigned int i=1; i<$2->size(); i++) if ((*$2)[i].size() != (*$2)[i-1].size()) yyerror(&@2, parm, "syntax error, all sub-arrays of 2d array literal must have the same length"); delete $2; } else { $$ = NULL; } } | MZN_LEFT_2D_BRACKET simple_array_literal_2d_list '|' MZN_RIGHT_2D_BRACKET { if ($2) { $$=new ArrayLit(@$, *$2); for (unsigned int i=1; i<$2->size(); i++) if ((*$2)[i].size() != (*$2)[i-1].size()) yyerror(&@2, parm, "syntax error, all sub-arrays of 2d array literal must have the same length"); delete $2; } else { $$ = NULL; } } | MZN_LEFT_2D_BRACKET simple_array_literal_3d_list MZN_RIGHT_2D_BRACKET { if ($2) { std::vector<std::pair<int,int> > dims(3); dims[0] = std::pair<int,int>(1,static_cast<int>($2->size())); if ($2->size()==0) { dims[1] = std::pair<int,int>(1,0); dims[2] = std::pair<int,int>(1,0); } else { dims[1] = std::pair<int,int>(1,static_cast<int>((*$2)[0].size())); if ((*$2)[0].size()==0) { dims[2] = std::pair<int,int>(1,0); } else { dims[2] = std::pair<int,int>(1,static_cast<int>((*$2)[0][0].size())); } } std::vector<Expression*> a; for (int i=0; i<dims[0].second; i++) { if ((*$2)[i].size() != dims[1].second) { yyerror(&@2, parm, "syntax error, all sub-arrays of 3d array literal must have the same length"); } else { for (int j=0; j<dims[1].second; j++) { if ((*$2)[i][j].size() != dims[2].second) { yyerror(&@2, parm, "syntax error, all sub-arrays of 3d array literal must have the same length"); } else { for (int k=0; k<dims[2].second; k++) { a.push_back((*$2)[i][j][k]); } } } } } $$ = new ArrayLit(@$,a,dims); delete $2; } else { $$ = NULL; } }simple_array_literal_3d_list : '|' '|' { $$=new std::vector<std::vector<std::vector<MiniZinc::Expression*> > >; } | '|' simple_array_literal_2d_list '|' { $$=new std::vector<std::vector<std::vector<MiniZinc::Expression*> > >; if ($2) $$->push_back(*$2); delete $2; } | simple_array_literal_3d_list ',' '|' simple_array_literal_2d_list '|' { $$=$1; if ($$ && $4) $$->push_back(*$4); delete $4; }simple_array_literal_2d_list : expr_list { $$=new std::vector<std::vector<MiniZinc::Expression*> >; if ($1) $$->push_back(*$1); delete $1; } | simple_array_literal_2d_list '|' expr_list { $$=$1; if ($$ && $3) $$->push_back(*$3); delete $3; }simple_array_comp : MZN_LEFT_BRACKET expr '|' comp_tail MZN_RIGHT_BRACKET { if ($4) $$=new Comprehension(@$, $2, *$4, false); delete $4; }if_then_else_expr : MZN_IF expr MZN_THEN expr MZN_ENDIF { std::vector<Expression*> iexps; iexps.push_back($2); iexps.push_back($4); $$=new ITE(@$, iexps, NULL); } | MZN_IF expr MZN_THEN expr elseif_list MZN_ELSE expr MZN_ENDIF { std::vector<Expression*> iexps; iexps.push_back($2); iexps.push_back($4); if ($5) { for (unsigned int i=0; i<$5->size(); i+=2) { iexps.push_back((*$5)[i]); iexps.push_back((*$5)[i+1]); } } $$=new ITE(@$, iexps,$7); delete $5; }elseif_list : { $$=new std::vector<MiniZinc::Expression*>; } | elseif_list MZN_ELSEIF expr MZN_THEN expr { $$=$1; if ($$ && $3 && $5) { $$->push_back($3); $$->push_back($5); } }quoted_op : MZN_EQUIV_QUOTED { $$=BOT_EQUIV; } | MZN_IMPL_QUOTED { $$=BOT_IMPL; } | MZN_RIMPL_QUOTED { $$=BOT_RIMPL; } | MZN_OR_QUOTED { $$=BOT_OR; } | MZN_XOR_QUOTED { $$=BOT_XOR; } | MZN_AND_QUOTED { $$=BOT_AND; } | MZN_LE_QUOTED { $$=BOT_LE; } | MZN_GR_QUOTED { $$=BOT_GR; } | MZN_LQ_QUOTED { $$=BOT_LQ; } | MZN_GQ_QUOTED { $$=BOT_GQ; } | MZN_EQ_QUOTED { $$=BOT_EQ; } | MZN_NQ_QUOTED { $$=BOT_NQ; } | MZN_IN_QUOTED { $$=BOT_IN; } | MZN_SUBSET_QUOTED { $$=BOT_SUBSET; } | MZN_SUPERSET_QUOTED { $$=BOT_SUPERSET; } | MZN_UNION_QUOTED { $$=BOT_UNION; } | MZN_DIFF_QUOTED { $$=BOT_DIFF; } | MZN_SYMDIFF_QUOTED { $$=BOT_SYMDIFF; } | MZN_PLUS_QUOTED { $$=BOT_PLUS; } | MZN_MINUS_QUOTED { $$=BOT_MINUS; } | MZN_MULT_QUOTED { $$=BOT_MULT; } | MZN_POW_QUOTED { $$=BOT_POW; } | MZN_DIV_QUOTED { $$=BOT_DIV; } | MZN_IDIV_QUOTED { $$=BOT_IDIV; } | MZN_MOD_QUOTED { $$=BOT_MOD; } | MZN_INTERSECT_QUOTED { $$=BOT_INTERSECT; } | MZN_PLUSPLUS_QUOTED { $$=BOT_PLUSPLUS; } | MZN_NOT_QUOTED { $$=-1; }quoted_op_call : quoted_op '(' expr ',' expr ')' { if ($1==-1) { $$=NULL; yyerror(&@3, parm, "syntax error, unary operator with two arguments"); } else { $$=new BinOp(@$, $3,static_cast<BinOpType>($1),$5); } } | quoted_op '(' expr ')' { int uot=-1; switch ($1) { case -1: uot = UOT_NOT; break; case BOT_MINUS: uot = UOT_MINUS; break; case BOT_PLUS: uot = UOT_PLUS; break; default: yyerror(&@3, parm, "syntax error, binary operator with unary argument list"); break; } if (uot==-1) $$=NULL; else { if (uot==UOT_PLUS && $3 && ($3->isa<IntLit>() || $3->isa<FloatLit>())) { $$ = $3; } else if (uot==UOT_MINUS && $3 && $3->isa<IntLit>()) { $$ = IntLit::a(-$3->cast<IntLit>()->v()); } else if (uot==UOT_MINUS && $3 && $3->isa<FloatLit>()) { $$ = FloatLit::a(-$3->cast<FloatLit>()->v()); } else { $$=new UnOp(@$, static_cast<UnOpType>(uot),$3); } } }call_expr : MZN_IDENTIFIER '(' ')' { $$=new Call(@$, $1, std::vector<Expression*>()); free($1); } | quoted_op_call | MZN_IDENTIFIER '(' comp_or_expr ')' { if ($3!=NULL) { bool hadWhere = false; std::vector<Expression*> args; for (unsigned int i=0; i<$3->size(); i++) { if ((*$3)[i].second) { yyerror(&@3, parm, "syntax error, 'where' expression outside generator call"); hadWhere = true; $$=NULL; } args.push_back((*$3)[i].first); } if (!hadWhere) { $$=new Call(@$, $1, args); } } free($1); delete $3; } | MZN_IDENTIFIER '(' comp_or_expr ')' '(' expr ')' { vector<Generator> gens; vector<Id*> ids; if ($3) { for (unsigned int i=0; i<$3->size(); i++) { if (Id* id = Expression::dyn_cast<Id>((*$3)[i].first)) { if ((*$3)[i].second) { ParserLocation loc = (*$3)[i].second->loc().parserLocation(); yyerror(&loc, parm, "illegal where expression in generator call"); } ids.push_back(id); } else { if (BinOp* boe = Expression::dyn_cast<BinOp>((*$3)[i].first)) { if (boe->lhs() && boe->rhs()) { Id* id = Expression::dyn_cast<Id>(boe->lhs()); if (id && boe->op() == BOT_IN) { ids.push_back(id); gens.push_back(Generator(ids,boe->rhs(),(*$3)[i].second)); ids = vector<Id*>(); } else if (id && boe->op() == BOT_EQ && ids.empty()) { ids.push_back(id); gens.push_back(Generator(ids,NULL,boe->rhs())); if ((*$3)[i].second) { gens.push_back(Generator(gens.size(),(*$3)[i].second)); } ids = vector<Id*>(); } else { ParserLocation loc = (*$3)[i].first->loc().parserLocation(); yyerror(&loc, parm, "illegal expression in generator call"); } } } else { ParserLocation loc = (*$3)[i].first->loc().parserLocation(); yyerror(&loc, parm, "illegal expression in generator call"); } } } } if (ids.size() != 0) { yyerror(&@3, parm, "illegal expression in generator call"); } ParserState* pp = static_cast<ParserState*>(parm); if (pp->hadError) { $$=NULL; } else { Generators g; g._g = gens; Comprehension* ac = new Comprehension(@$, $6,g,false); vector<Expression*> args; args.push_back(ac); $$=new Call(@$, $1, args); } free($1); delete $3; }comp_or_expr : comp_or_expr_head comma_or_nonecomp_or_expr_head : expr { $$=new vector<pair<Expression*,Expression*> >; if ($1) { $$->push_back(pair<Expression*,Expression*>($1,NULL)); } } | expr MZN_WHERE expr { $$=new vector<pair<Expression*,Expression*> >; if ($1 && $3) { $$->push_back(pair<Expression*,Expression*>($1,$3)); } } | comp_or_expr_head ',' expr { $$=$1; if ($$ && $3) $$->push_back(pair<Expression*,Expression*>($3,NULL)); } | comp_or_expr_head ',' expr MZN_WHERE expr { $$=$1; if ($$ && $3 && $5) $$->push_back(pair<Expression*,Expression*>($3,$5)); }let_expr : MZN_LET '{' let_vardecl_item_list '}' MZN_IN expr %prec PREC_ANNO { if ($3 && $6) { $$=new Let(@$, *$3, $6); delete $3; } else { $$=NULL; } } | MZN_LET '{' let_vardecl_item_list comma_or_semi '}' MZN_IN expr %prec PREC_ANNO { if ($3 && $7) { $$=new Let(@$, *$3, $7); delete $3; } else { $$=NULL; } }let_vardecl_item_list : let_vardecl_item { $$=new vector<Expression*>; $$->push_back($1); } | constraint_item { $$=new vector<Expression*>; if ($1) { ConstraintI* ce = $1->cast<ConstraintI>(); $$->push_back(ce->e()); ce->e(NULL); } } | let_vardecl_item_list comma_or_semi let_vardecl_item { $$=$1; if ($$ && $3) $$->push_back($3); } | let_vardecl_item_list comma_or_semi constraint_item { $$=$1; if ($$ && $3) { ConstraintI* ce = $3->cast<ConstraintI>(); $$->push_back(ce->e()); ce->e(NULL); } }comma_or_semi : ',' | ';'let_vardecl_item : ti_expr_and_id annotations { $$ = $1; if ($$) $$->toplevel(false); if ($$ && $2) $$->addAnnotations(*$2); delete $2; } | ti_expr_and_id annotations MZN_EQ expr { if ($1) $1->e($4); $$ = $1; if ($$) $$->loc(@$); if ($$) $$->toplevel(false); if ($$ && $2) $$->addAnnotations(*$2); delete $2; }annotations : /* empty */ { $$=NULL; } | ne_annotationsannotation_expr : expr_atom_head_nonstring { $$ = $1; } | string_expr { $$ = new Call(@1, ASTString("mzn_expression_name"), {$1}); }ne_annotations : MZN_COLONCOLON annotation_expr { $$=new std::vector<Expression*>(1); (*$$)[0] = $2; } | ne_annotations MZN_COLONCOLON annotation_expr { $$=$1; if ($$) $$->push_back($3); }id_or_quoted_op : MZN_IDENTIFIER { $$=$1; } | MZN_EQUIV_QUOTED { $$=strdup("'<->'"); } | MZN_IMPL_QUOTED { $$=strdup("'->'"); } | MZN_RIMPL_QUOTED { $$=strdup("'<-'"); } | MZN_OR_QUOTED { $$=strdup("'\\/'"); } | MZN_XOR_QUOTED { $$=strdup("'xor'"); } | MZN_AND_QUOTED { $$=strdup("'/\\'"); } | MZN_LE_QUOTED { $$=strdup("'<'"); } | MZN_GR_QUOTED { $$=strdup("'>'"); } | MZN_LQ_QUOTED { $$=strdup("'<='"); } | MZN_GQ_QUOTED { $$=strdup("'>='"); } | MZN_EQ_QUOTED { $$=strdup("'='"); } | MZN_NQ_QUOTED { $$=strdup("'!='"); } | MZN_IN_QUOTED { $$=strdup("'in'"); } | MZN_SUBSET_QUOTED { $$=strdup("'subset'"); } | MZN_SUPERSET_QUOTED { $$=strdup("'superset'"); } | MZN_UNION_QUOTED { $$=strdup("'union'"); } | MZN_DIFF_QUOTED { $$=strdup("'diff'"); } | MZN_SYMDIFF_QUOTED { $$=strdup("'symdiff'"); } | MZN_DOTDOT_QUOTED { $$=strdup("'..'"); } | MZN_PLUS_QUOTED { $$=strdup("'+'"); } | MZN_MINUS_QUOTED { $$=strdup("'-'"); } | MZN_MULT_QUOTED { $$=strdup("'*'"); } | MZN_POW_QUOTED { $$=strdup("'^'"); } | MZN_DIV_QUOTED { $$=strdup("'/'"); } | MZN_IDIV_QUOTED { $$=strdup("'div'"); } | MZN_MOD_QUOTED { $$=strdup("'mod'"); } | MZN_INTERSECT_QUOTED { $$=strdup("'intersect'"); } | MZN_NOT_QUOTED { $$=strdup("'not'"); } | MZN_PLUSPLUS_QUOTED { $$=strdup("'++'"); }