this repo has no description
at develop 50 kB view raw
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2 3/* 4 * Main authors: 5 * Guido Tack <guido.tack@monash.edu> 6 */ 7 8/* This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 11 12%define api.pure 13 14%parse-param {void *parm} 15 16%define api.header.include {<minizinc/parser.tab.hh>} 17 18%lex-param {void* SCANNER} 19%{ 20#define SCANNER static_cast<ParserState*>(parm)->yyscanner 21#include <iostream> 22#include <fstream> 23#include <map> 24#include <cerrno> 25 26namespace MiniZinc{ class ParserLocation; } 27#define YYLTYPE MiniZinc::ParserLocation 28#define YYLTYPE_IS_DECLARED 1 29#define YYLTYPE_IS_TRIVIAL 0 30 31#define YYMAXDEPTH 10000 32#define YYINITDEPTH 10000 33 34#include <minizinc/parser.hh> 35#include <minizinc/file_utils.hh> 36 37using namespace std; 38using namespace MiniZinc; 39 40#define YYLLOC_DEFAULT(Current, Rhs, N) \ 41 (Current).filename(Rhs[1].filename()); \ 42 (Current).first_line(Rhs[1].first_line()); \ 43 (Current).first_column(Rhs[1].first_column()); \ 44 (Current).last_line(Rhs[N].last_line()); \ 45 (Current).last_column(Rhs[N].last_column()); 46 47int mzn_yyparse(void*); 48int mzn_yylex(YYSTYPE*, YYLTYPE*, void* scanner); 49int mzn_yylex_init (void** scanner); 50int mzn_yylex_destroy (void* scanner); 51int mzn_yyget_lineno (void* scanner); 52void mzn_yyset_extra (void* user_defined ,void* yyscanner ); 53 54extern int yydebug; 55 56void yyerror(YYLTYPE* location, void* parm, const string& str) { 57 ParserState* pp = static_cast<ParserState*>(parm); 58 Model* m = pp->model; 59 while (m->parent() != NULL) { 60 m = m->parent(); 61 pp->err << "(included from file '" << m->filename() << "')" << endl; 62 } 63 pp->err << location->toString() << ":" << endl; 64 pp->printCurrentLine(location->first_column(),location->last_column()); 65 pp->err << "Error: " << str << std::endl; 66 pp->hadError = true; 67 pp->syntaxErrors.push_back(SyntaxError(Location(*location), str)); 68} 69 70bool notInDatafile(YYLTYPE* location, void* parm, const string& item) { 71 ParserState* pp = static_cast<ParserState*>(parm); 72 if (pp->isDatafile) { 73 yyerror(location,parm,item+" item not allowed in data file"); 74 return false; 75 } 76 return true; 77} 78 79Expression* createDocComment(const ParserLocation& loc, const std::string& s) { 80 std::vector<Expression*> args(1); 81 args[0] = new StringLit(loc, s); 82 Call* c = new Call(Location(loc), constants().ann.doc_comment, args); 83 c->type(Type::ann()); 84 return c; 85} 86 87Expression* createArrayAccess(const ParserLocation& loc, Expression* e, std::vector<std::vector<Expression*> >& idx) { 88 Expression* ret = e; 89 for (unsigned int i=0; i<idx.size(); i++) { 90 ret = new ArrayAccess(Location(loc), ret, idx[i]); 91 } 92 return ret; 93} 94 95 96 97%} 98 99%union { long long int iValue; char* sValue; bool bValue; double dValue; 100 MiniZinc::Item* item; 101 MiniZinc::VarDecl* vardeclexpr; 102 std::vector<MiniZinc::VarDecl*>* vardeclexpr_v; 103 MiniZinc::TypeInst* tiexpr; 104 std::vector<MiniZinc::TypeInst*>* tiexpr_v; 105 MiniZinc::Expression* expression; 106 std::vector<MiniZinc::Expression*>* expression_v; 107 std::vector<std::vector<MiniZinc::Expression*> >* expression_vv; 108 std::vector<std::vector<std::vector<MiniZinc::Expression*> > >* expression_vvv; 109 MiniZinc::Generator* generator; 110 std::vector<MiniZinc::Generator>* generator_v; 111 std::vector<std::string>* string_v; 112 std::vector<std::pair<MiniZinc::Expression*,MiniZinc::Expression*> >* expression_p; 113 MiniZinc::Generators* generators; 114 } 115 116%locations 117%define parse.error verbose 118 119%initial-action 120{ 121 GCLock lock; 122 @$.filename(ASTString(static_cast<ParserState*>(parm)->filename)); 123} 124 125%token <iValue> MZN_INTEGER_LITERAL "integer literal" MZN_BOOL_LITERAL "bool literal" 126%token <dValue> MZN_FLOAT_LITERAL "float literal" 127%token <sValue> MZN_IDENTIFIER "identifier" MZN_QUOTED_IDENTIFIER "quoted identifier" MZN_STRING_LITERAL "string literal" 128%token <sValue> MZN_STRING_QUOTE_START "interpolated string start" MZN_STRING_QUOTE_MID "interpolated string middle" MZN_STRING_QUOTE_END "interpolated string end" 129%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" 130 131%token MZN_VAR "var" MZN_PAR "par" 132 133%token MZN_ABSENT "<>" 134%token MZN_ANN "ann" 135%token MZN_ANNOTATION "annotation" 136%token MZN_ANY "any" 137%token MZN_ARRAY "array" 138%token MZN_BOOL "bool" 139%token MZN_CASE "case" 140%token MZN_CONSTRAINT "constraint" 141%token MZN_DEFAULT "default" 142%token MZN_ELSE "else" 143%token MZN_ELSEIF "elseif" 144%token MZN_ENDIF "endif" 145%token MZN_ENUM "enum" 146%token MZN_FLOAT "float" 147%token MZN_FUNCTION "function" 148%token MZN_IF "if" 149%token MZN_INCLUDE "include" 150%token MZN_INFINITY "infinity" 151%token MZN_INT "int" 152%token MZN_LET "let" 153%token MZN_LIST "list" 154%token <bValue> MZN_MAXIMIZE "maximize" 155%token <bValue> MZN_MINIMIZE "minimize" 156%token MZN_OF "of" 157%token MZN_OPT "opt" 158%token MZN_SATISFY "satisfy" 159%token MZN_OUTPUT "output" 160%token MZN_PREDICATE "predicate" 161%token MZN_RECORD "record" 162%token MZN_SET "set" 163%token MZN_SOLVE "solve" 164%token MZN_STRING "string" 165%token MZN_TEST "test" 166%token MZN_THEN "then" 167%token MZN_TUPLE "tuple" 168%token MZN_TYPE "type" 169%token MZN_UNDERSCORE "_" 170%token MZN_VARIANT_RECORD "variant_record" 171%token MZN_WHERE "where" 172 173%token MZN_LEFT_BRACKET "[" 174%token MZN_LEFT_2D_BRACKET "[|" 175%token MZN_RIGHT_BRACKET "]" 176%token MZN_RIGHT_2D_BRACKET "|]" 177 178// Used to signal an error when parsing a MiniZinc file 179// that contains identifiers starting with _ 180%token FLATZINC_IDENTIFIER 181 182%token MZN_INVALID_INTEGER_LITERAL "invalid integer literal" 183%token MZN_INVALID_FLOAT_LITERAL "invalid float literal" 184%token MZN_UNTERMINATED_STRING "unterminated string" 185%token MZN_END_OF_LINE_IN_STRING "end of line inside string literal" 186%token MZN_INVALID_NULL "null character" 187 188%token END 0 "end of file" 189 190%token MZN_EQUIV "<->" 191%token MZN_IMPL "->" MZN_RIMPL "<-" 192%token MZN_OR "\\/" MZN_XOR "xor" 193%token MZN_AND "/\\" 194%token MZN_LE "<" MZN_GR ">" MZN_LQ "<=" MZN_GQ ">=" MZN_EQ "=" MZN_NQ "!=" MZN_WEAK_EQ "~=" 195%token MZN_IN "in" MZN_SUBSET "subset" MZN_SUPERSET "superset" 196%token MZN_UNION "union" MZN_DIFF "diff" MZN_SYMDIFF "symdiff" 197%token MZN_DOTDOT ".." 198%token MZN_PLUS "+" MZN_MINUS "-" MZN_WEAK_PLUS "~+" MZN_WEAK_MINUS "~-" 199%token MZN_MULT "*" MZN_DIV "/" MZN_IDIV "div" MZN_MOD "mod" MZN_INTERSECT "intersect" MZN_WEAK_MULT "~*" 200%token MZN_POW "^" 201%token MZN_NOT "not" 202%token MZN_PLUSPLUS "++" 203%token MZN_COLONCOLON "::" 204 205%right PREC_ANNO 206%left MZN_EQUIV 207%left MZN_IMPL MZN_RIMPL 208%left MZN_OR MZN_XOR 209%left MZN_AND 210%nonassoc MZN_LE MZN_GR MZN_LQ MZN_GQ MZN_EQ MZN_NQ MZN_WEAK_EQ 211%nonassoc MZN_IN MZN_SUBSET MZN_SUPERSET 212%left MZN_UNION MZN_DIFF MZN_SYMDIFF MZN_INTERSECT 213%nonassoc MZN_DOTDOT 214%left MZN_PLUS MZN_MINUS MZN_WEAK_PLUS MZN_WEAK_MINUS 215%left MZN_MULT MZN_DIV MZN_IDIV MZN_MOD MZN_WEAK_MULT 216%left MZN_POW 217%nonassoc MZN_NOT 218%left MZN_PLUSPLUS 219%left MZN_QUOTED_IDENTIFIER 220%left MZN_COLONCOLON 221 222%token MZN_EQUIV_QUOTED "'<->'" 223%token MZN_IMPL_QUOTED "'->'" MZN_RIMPL_QUOTED "'<-'" 224%token MZN_OR_QUOTED "'\\/'" MZN_XOR_QUOTED "'xor'" 225%token MZN_AND_QUOTED "'/\\'" 226%token MZN_LE_QUOTED "'<'" MZN_GR_QUOTED "'>'" MZN_LQ_QUOTED "'<='" MZN_GQ_QUOTED "'>='" MZN_EQ_QUOTED "'='" MZN_NQ_QUOTED "'!='" 227%token MZN_IN_QUOTED "'in'" MZN_SUBSET_QUOTED "'subset'" MZN_SUPERSET_QUOTED "'superset'" 228%token MZN_UNION_QUOTED "'union'" MZN_DIFF_QUOTED "'diff'" MZN_SYMDIFF_QUOTED "'symdiff'" 229%token MZN_DOTDOT_QUOTED "'..'" 230%token MZN_PLUS_QUOTED "'+'" MZN_MINUS_QUOTED "'-'" 231%token MZN_MULT_QUOTED "'*'" MZN_DIV_QUOTED "'/'" MZN_IDIV_QUOTED "'div'" MZN_MOD_QUOTED "'mod'" MZN_INTERSECT_QUOTED "'intersect'" 232%token MZN_POW_QUOTED "'^'" 233%token MZN_NOT_QUOTED "'not'" 234%token MZN_COLONCOLON_QUOTED "'::'" 235%token MZN_PLUSPLUS_QUOTED "'++'" 236 237%type <item> item item_tail include_item vardecl_item assign_item constraint_item solve_item output_item predicate_item annotation_item function_item 238 239%type <vardeclexpr> ti_expr_and_id ti_expr_and_id_or_anon let_vardecl_item 240%type <vardeclexpr_v> params params_list params_list_head 241%type <tiexpr> ti_expr base_ti_expr base_ti_expr_tail 242%type <tiexpr_v> ti_expr_list ti_expr_list_head 243 244%type <expression> expr expr_atom_head expr_atom_head_nonstring array_access_expr 245%type <expression> set_expr string_expr string_quote_rest annotation_expr 246%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 247 248%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 249%type <expression_vv> simple_array_literal_2d_list array_access_tail 250%type <expression_vvv> simple_array_literal_3d_list 251 252%type <generators> comp_tail 253%type <generator> generator generator_eq 254%type <generator_v> generator_list generator_list_head 255%type <string_v> id_list id_list_head 256 257%type <expression_p> comp_or_expr comp_or_expr_head 258 259%type <expression_v> annotations ne_annotations 260 261%type <iValue> quoted_op 262 263%type <sValue> id_or_quoted_op 264 265%type <bValue> opt_opt 266 267%% 268 269/********************************/ 270/* main goal and item lists */ 271/********************************/ 272 273model : item_list 274 275item_list : 276 /* empty */ 277 | item_list_head semi_or_none 278 279item_list_head: 280 item 281 { 282 ParserState* pp = static_cast<ParserState*>(parm); 283 if ($1) { 284 pp->model->addItem($1); 285 GC::unlock(); 286 GC::lock(); 287 } 288 } 289 | doc_file_comments item 290 { 291 ParserState* pp = static_cast<ParserState*>(parm); 292 if ($2) { 293 pp->model->addItem($2); 294 GC::unlock(); 295 GC::lock(); 296 } 297 } 298 | item_list_head ';' item 299 { 300 ParserState* pp = static_cast<ParserState*>(parm); 301 if ($3) { 302 pp->model->addItem($3); 303 GC::unlock(); 304 GC::lock(); 305 } 306 } 307 | item_list_head ';' doc_file_comments item 308 { 309 ParserState* pp = static_cast<ParserState*>(parm); 310 if ($4) { 311 pp->model->addItem($4); 312 GC::unlock(); 313 GC::lock(); 314 } 315 } 316 | item error_item_start 317{ yyerror(&@2, parm, "unexpected item, expecting ';' or end of file"); YYERROR; } 318 | error ';' item 319 320doc_file_comments: 321 MZN_DOC_FILE_COMMENT 322 { 323 ParserState* pp = static_cast<ParserState*>(parm); 324 if (pp->parseDocComments && $1) { 325 pp->model->addDocComment($1); 326 } 327 free($1); 328 } 329 | doc_file_comments MZN_DOC_FILE_COMMENT 330 { 331 ParserState* pp = static_cast<ParserState*>(parm); 332 if (pp->parseDocComments && $2) { 333 pp->model->addDocComment($2); 334 } 335 free($2); 336 } 337 338semi_or_none : | ';' 339 340item : MZN_DOC_COMMENT item_tail 341 { $$ = $2; 342 ParserState* pp = static_cast<ParserState*>(parm); 343 if (FunctionI* fi = Item::dyn_cast<FunctionI>($$)) { 344 if (pp->parseDocComments) { 345 fi->ann().add(createDocComment(@1,$1)); 346 } 347 } else if (VarDeclI* vdi = Item::dyn_cast<VarDeclI>($$)) { 348 if (pp->parseDocComments) { 349 vdi->e()->addAnnotation(createDocComment(@1,$1)); 350 } 351 } else { 352 yyerror(&@2, parm, "documentation comments are only supported for function, predicate and variable declarations"); 353 } 354 free($1); 355 } 356 | item_tail 357 { $$ = $1; } 358 359item_tail : 360 include_item 361 { $$=notInDatafile(&@$,parm,"include") ? $1 : NULL; } 362 | vardecl_item 363 { $$=notInDatafile(&@$,parm,"variable declaration") ? $1 : NULL; } 364 | assign_item 365 | constraint_item 366 { $$=notInDatafile(&@$,parm,"constraint") ? $1 : NULL; } 367 | solve_item 368 { $$=notInDatafile(&@$,parm,"solve") ? $1 : NULL; } 369 | output_item 370 { $$=notInDatafile(&@$,parm,"output") ? $1 : NULL; } 371 | predicate_item 372 { $$=notInDatafile(&@$,parm,"predicate") ? $1 : NULL; } 373 | function_item 374 { $$=notInDatafile(&@$,parm,"predicate") ? $1 : NULL; } 375 | annotation_item 376 { $$=notInDatafile(&@$,parm,"annotation") ? $1 : NULL; } 377 378error_item_start : MZN_INCLUDE | MZN_ENUM | MZN_OUTPUT 379 | MZN_CONSTRAINT | MZN_SOLVE | MZN_PREDICATE | MZN_FUNCTION | MZN_TEST 380 | MZN_ANNOTATION 381 382include_item : 383 MZN_INCLUDE MZN_STRING_LITERAL 384 { ParserState* pp = static_cast<ParserState*>(parm); 385 map<string,Model*>::iterator ret = pp->seenModels.find($2); 386 IncludeI* ii = new IncludeI(@$,ASTString($2)); 387 $$ = ii; 388 if (ret == pp->seenModels.end()) { 389 Model* im = new Model; 390 im->setParent(pp->model); 391 im->setFilename($2); 392 string fpath = FileUtils::dir_name(pp->filename); 393 string fbase = FileUtils::base_name(pp->filename); 394 if (fpath=="") 395 fpath="./"; 396 ParseWorkItem pm(im, ii, fpath, $2); 397 pp->files.push_back(pm); 398 ii->m(im); 399 pp->seenModels.insert(pair<string,Model*>($2,im)); 400 } else { 401 ii->m(ret->second, false); 402 } 403 free($2); 404 } 405 406vardecl_item : 407 ti_expr_and_id annotations 408 { if ($1 && $2) $1->addAnnotations(*$2); 409 if ($1) 410 $$ = new VarDeclI(@$,$1); 411 delete $2; 412 } 413 | ti_expr_and_id annotations MZN_EQ expr 414 { if ($1) $1->e($4); 415 if ($1 && $2) $1->addAnnotations(*$2); 416 if ($1) 417 $$ = new VarDeclI(@$,$1); 418 delete $2; 419 } 420 | MZN_ENUM MZN_IDENTIFIER 421 { 422 TypeInst* ti = new TypeInst(@$,Type::parsetint()); 423 ti->setIsEnum(true); 424 VarDecl* vd = new VarDecl(@$,ti,$2); 425 free($2); 426 $$ = new VarDeclI(@$,vd); 427 } 428 | MZN_ENUM MZN_IDENTIFIER MZN_EQ '{' enum_id_list '}' 429 { 430 TypeInst* ti = new TypeInst(@$,Type::parsetint()); 431 ti->setIsEnum(true); 432 SetLit* sl = new SetLit(@$, *$5); 433 VarDecl* vd = new VarDecl(@$,ti,$2,sl); 434 free($2); 435 delete $5; 436 $$ = new VarDeclI(@$,vd); 437 } 438 | MZN_ENUM MZN_IDENTIFIER MZN_EQ MZN_LEFT_BRACKET string_lit_list MZN_RIGHT_BRACKET 439 { 440 TypeInst* ti = new TypeInst(@$,Type::parsetint()); 441 ti->setIsEnum(true); 442 vector<Expression*> args; 443 args.push_back(new ArrayLit(@$,*$5)); 444 Call* sl = new Call(@$, constants().ids.anonEnumFromStrings, args); 445 VarDecl* vd = new VarDecl(@$,ti,$2,sl); 446 free($2); 447 delete $5; 448 $$ = new VarDeclI(@$,vd); 449 } 450 | MZN_ENUM MZN_IDENTIFIER MZN_EQ MZN_IDENTIFIER '(' expr ')' 451 { 452 TypeInst* ti = new TypeInst(@$,Type::parsetint()); 453 ti->setIsEnum(true); 454 vector<Expression*> args; 455 args.push_back($6); 456 Call* sl = new Call(@$, ASTString($4), args); 457 VarDecl* vd = new VarDecl(@$,ti,$2,sl); 458 free($2); 459 free($4); 460 $$ = new VarDeclI(@$,vd); 461 } 462 463string_lit_list : 464 // empty 465 { $$ = new std::vector<Expression*>(); } 466 | MZN_STRING_LITERAL 467 { $$ = new std::vector<Expression*>(); 468 $$->push_back(new StringLit(@$, $1)); free($1); 469 } 470 | string_lit_list ',' MZN_STRING_LITERAL 471 { $$ = $1; 472 if ($$) $$->push_back(new StringLit(@$, $3)); 473 free($3); 474 } 475 476enum_id_list : 477 // empty 478 { $$ = new std::vector<Expression*>(); } 479 | MZN_IDENTIFIER 480 { $$ = new std::vector<Expression*>(); 481 $$->push_back(new Id(@$,$1,NULL)); free($1); 482 } 483 | enum_id_list ',' MZN_IDENTIFIER 484 { $$ = $1; if ($$) $$->push_back(new Id(@$,$3,NULL)); free($3); } 485 486assign_item : 487 MZN_IDENTIFIER MZN_EQ expr 488 { $$ = new AssignI(@$,$1,$3); 489 free($1); 490 } 491 492constraint_item : 493 MZN_CONSTRAINT expr 494 { $$ = new ConstraintI(@$,$2);} 495 | MZN_CONSTRAINT MZN_COLONCOLON string_expr expr 496 { $$ = new ConstraintI(@$,$4); 497 if ($4 && $3) 498 $$->cast<ConstraintI>()->e()->ann().add(new Call(@2, ASTString("mzn_constraint_name"), {$3})); 499 } 500 501solve_item : 502 MZN_SOLVE annotations MZN_SATISFY 503 { $$ = SolveI::sat(@$); 504 if ($$ && $2) $$->cast<SolveI>()->ann().add(*$2); 505 delete $2; 506 } 507 | MZN_SOLVE annotations MZN_MINIMIZE expr 508 { $$ = SolveI::min(@$,$4); 509 if ($$ && $2) $$->cast<SolveI>()->ann().add(*$2); 510 delete $2; 511 } 512 | MZN_SOLVE annotations MZN_MAXIMIZE expr 513 { $$ = SolveI::max(@$,$4); 514 if ($$ && $2) $$->cast<SolveI>()->ann().add(*$2); 515 delete $2; 516 } 517 518output_item : 519 MZN_OUTPUT expr 520 { $$ = new OutputI(@$,$2);} 521 522predicate_item : 523 MZN_PREDICATE MZN_IDENTIFIER params annotations operation_item_tail 524 { if ($3) $$ = new FunctionI(@$,$2,new TypeInst(@$, 525 Type::varbool()),*$3,$5); 526 if ($$ && $4) $$->cast<FunctionI>()->ann().add(*$4); 527 free($2); 528 delete $3; 529 delete $4; 530 } 531 | MZN_TEST MZN_IDENTIFIER params annotations operation_item_tail 532 { if ($3) $$ = new FunctionI(@$,$2,new TypeInst(@$, 533 Type::parbool()),*$3,$5); 534 if ($$ && $4) $$->cast<FunctionI>()->ann().add(*$4); 535 free($2); 536 delete $3; 537 delete $4; 538 } 539 540function_item : 541 MZN_FUNCTION ti_expr ':' id_or_quoted_op params annotations operation_item_tail 542 { if ($5) $$ = new FunctionI(@$,$4,$2,*$5,$7); 543 if ($$ && $6) $$->cast<FunctionI>()->ann().add(*$6); 544 free($4); 545 delete $5; 546 delete $6; 547 } 548 | ti_expr ':' MZN_IDENTIFIER '(' params_list ')' annotations operation_item_tail 549 { if ($5) $$ = new FunctionI(@$,$3,$1,*$5,$8); 550 if ($$ && $7) $$->cast<FunctionI>()->ann().add(*$7); 551 free($3); 552 delete $5; 553 delete $7; 554 } 555 556annotation_item : 557 MZN_ANNOTATION MZN_IDENTIFIER params 558 { 559 TypeInst* ti=new TypeInst(@1,Type::ann()); 560 if ($3==NULL || $3->empty()) { 561 VarDecl* vd = new VarDecl(@$,ti,$2); 562 $$ = new VarDeclI(@$,vd); 563 } else { 564 $$ = new FunctionI(@$,$2,ti,*$3,NULL); 565 } 566 free($2); 567 delete $3; 568 } 569 | MZN_ANNOTATION MZN_IDENTIFIER params MZN_EQ expr 570 { TypeInst* ti=new TypeInst(@1,Type::ann()); 571 if ($3) $$ = new FunctionI(@$,$2,ti,*$3,$5); 572 delete $3; 573 } 574 575operation_item_tail : 576 /*empty*/ 577 { $$=NULL; } 578 | MZN_EQ expr 579 { $$=$2; } 580 581params : 582 /* empty */ 583 { $$=new vector<VarDecl*>(); } 584 | '(' params_list ')' 585 { $$=$2; } 586 | '(' error ')' 587 { $$=new vector<VarDecl*>(); } 588 589params_list : 590 /* empty */ 591 { $$=new vector<VarDecl*>(); } 592 | params_list_head comma_or_none 593 { $$=$1; } 594 595params_list_head : 596 ti_expr_and_id_or_anon 597 { $$=new vector<VarDecl*>(); 598 if ($1) $1->toplevel(false); 599 if ($1) $$->push_back($1); } 600 | params_list_head ',' ti_expr_and_id_or_anon 601 { $$=$1; 602 if ($3) $3->toplevel(false); 603 if ($1 && $3) $1->push_back($3); } 604 605comma_or_none : | ',' 606 607ti_expr_and_id_or_anon : 608 ti_expr_and_id 609 { $$=$1; } 610 | ti_expr 611 { if ($1) $$=new VarDecl(@$, $1, ""); } 612 613ti_expr_and_id : 614 ti_expr ':' MZN_IDENTIFIER 615 { if ($1 && $3) $$ = new VarDecl(@$, $1, $3); 616 free($3); 617 } 618 619ti_expr_list : ti_expr_list_head comma_or_none 620 { $$=$1; } 621 622ti_expr_list_head : 623 ti_expr 624 { $$=new vector<TypeInst*>(); $$->push_back($1); } 625 | ti_expr_list_head ',' ti_expr 626 { $$=$1; if ($1 && $3) $1->push_back($3); } 627 628ti_expr : 629 base_ti_expr 630 | MZN_ARRAY MZN_LEFT_BRACKET ti_expr_list MZN_RIGHT_BRACKET MZN_OF base_ti_expr 631 { 632 $$ = $6; 633 if ($$ && $3) $$->setRanges(*$3); 634 delete $3; 635 } 636 | MZN_LIST MZN_OF base_ti_expr 637 { 638 $$ = $3; 639 std::vector<TypeInst*> ti(1); 640 ti[0] = new TypeInst(@$,Type::parint()); 641 if ($$) $$->setRanges(ti); 642 } 643 644base_ti_expr : 645 base_ti_expr_tail 646 { $$ = $1; 647 } 648 | MZN_OPT base_ti_expr_tail 649 { $$ = $2; 650 if ($$) { 651 Type tt = $$->type(); 652 tt.ot(Type::OT_OPTIONAL); 653 $$->type(tt); 654 } 655 } 656 | MZN_PAR opt_opt base_ti_expr_tail 657 { $$ = $3; 658 if ($$ && $2) { 659 Type tt = $$->type(); 660 tt.ot(Type::OT_OPTIONAL); 661 $$->type(tt); 662 } 663 } 664 | MZN_VAR opt_opt base_ti_expr_tail 665 { $$ = $3; 666 if ($$) { 667 Type tt = $$->type(); 668 tt.ti(Type::TI_VAR); 669 if ($2) tt.ot(Type::OT_OPTIONAL); 670 $$->type(tt); 671 } 672 } 673 | opt_opt MZN_SET MZN_OF base_ti_expr_tail 674 { $$ = $4; 675 if ($$) { 676 Type tt = $$->type(); 677 tt.st(Type::ST_SET); 678 if ($1) tt.ot(Type::OT_OPTIONAL); 679 $$->type(tt); 680 } 681 } 682 | MZN_PAR opt_opt MZN_SET MZN_OF base_ti_expr_tail 683 { $$ = $5; 684 if ($$) { 685 Type tt = $$->type(); 686 tt.st(Type::ST_SET); 687 if ($2) tt.ot(Type::OT_OPTIONAL); 688 $$->type(tt); 689 } 690 } 691 | MZN_VAR opt_opt MZN_SET MZN_OF base_ti_expr_tail 692 { $$ = $5; 693 if ($$) { 694 Type tt = $$->type(); 695 tt.ti(Type::TI_VAR); 696 tt.st(Type::ST_SET); 697 if ($2) tt.ot(Type::OT_OPTIONAL); 698 $$->type(tt); 699 } 700 } 701 702opt_opt: 703 /* nothing */ 704 { $$ = false; } 705 | MZN_OPT 706 { $$ = true; } 707 708base_ti_expr_tail : 709 MZN_INT 710 { $$ = new TypeInst(@$,Type::parint()); } 711 | MZN_BOOL 712 { $$ = new TypeInst(@$,Type::parbool()); } 713 | MZN_FLOAT 714 { $$ = new TypeInst(@$,Type::parfloat()); } 715 | MZN_STRING 716 { $$ = new TypeInst(@$,Type::parstring()); } 717 | MZN_ANN 718 { $$ = new TypeInst(@$,Type::ann()); } 719 | set_expr 720 { if ($1) $$ = new TypeInst(@$,Type(),$1); } 721 | MZN_TI_IDENTIFIER 722 { $$ = new TypeInst(@$,Type::top(), 723 new TIId(@$, $1)); 724 free($1); 725 } 726 | MZN_TI_ENUM_IDENTIFIER 727 { $$ = new TypeInst(@$,Type::parint(), 728 new TIId(@$, $1)); 729 free($1); 730 } 731 732array_access_expr_list : array_access_expr_list_head comma_or_none 733 734array_access_expr_list_head : 735 array_access_expr 736 { $$=new std::vector<MiniZinc::Expression*>; $$->push_back($1); } 737 | array_access_expr_list_head ',' array_access_expr 738 { $$=$1; if ($$ && $3) $$->push_back($3); } 739 740array_access_expr : 741 expr 742 { $$ = $1; } 743 | MZN_DOTDOT 744 { $$=new SetLit(@$, IntSetVal::a(-IntVal::infinity(),IntVal::infinity())); } 745 | MZN_DOTDOT expr 746 { if ($2==NULL) { 747 $$ = NULL; 748 } else if ($2->isa<IntLit>()) { 749 $$=new SetLit(@$, IntSetVal::a(-IntVal::infinity(),$2->cast<IntLit>()->v())); 750 } else { 751 $$=new BinOp(@$, IntLit::a(-IntVal::infinity()), BOT_DOTDOT, $2); 752 } 753 } 754 | expr MZN_DOTDOT 755 { if ($1==NULL) { 756 $$ = NULL; 757 } else if ($1->isa<IntLit>()) { 758 $$=new SetLit(@$, IntSetVal::a($1->cast<IntLit>()->v(),IntVal::infinity())); 759 } else { 760 $$=new BinOp(@$, $1, BOT_DOTDOT, IntLit::a(IntVal::infinity())); 761 } 762 } 763 764 765expr_list : expr_list_head comma_or_none 766 767expr_list_head : 768 expr 769 { $$=new std::vector<MiniZinc::Expression*>; $$->push_back($1); } 770 | expr_list_head ',' expr 771 { $$=$1; if ($$ && $3) $$->push_back($3); } 772 773/// 774 775set_expr : 776 expr_atom_head 777 | set_expr MZN_COLONCOLON annotation_expr 778 { if ($1 && $3) $1->addAnnotation($3); $$=$1; } 779 | set_expr MZN_UNION set_expr 780 { $$=new BinOp(@$, $1, BOT_UNION, $3); } 781 | set_expr MZN_DIFF set_expr 782 { $$=new BinOp(@$, $1, BOT_DIFF, $3); } 783 | set_expr MZN_SYMDIFF set_expr 784 { $$=new BinOp(@$, $1, BOT_SYMDIFF, $3); } 785 | set_expr MZN_DOTDOT set_expr 786 { if ($1==NULL || $3==NULL) { 787 $$ = NULL; 788 } else if ($1->isa<IntLit>() && $3->isa<IntLit>()) { 789 $$=new SetLit(@$, IntSetVal::a($1->cast<IntLit>()->v(),$3->cast<IntLit>()->v())); 790 } else { 791 $$=new BinOp(@$, $1, BOT_DOTDOT, $3); 792 } 793 } 794 | MZN_DOTDOT_QUOTED '(' expr ',' expr ')' 795 { if ($3==NULL || $5==NULL) { 796 $$ = NULL; 797 } else if ($3->isa<IntLit>() && $5->isa<IntLit>()) { 798 $$=new SetLit(@$, IntSetVal::a($3->cast<IntLit>()->v(),$5->cast<IntLit>()->v())); 799 } else { 800 $$=new BinOp(@$, $3, BOT_DOTDOT, $5); 801 } 802 } 803 | set_expr MZN_INTERSECT set_expr 804 { $$=new BinOp(@$, $1, BOT_INTERSECT, $3); } 805 | set_expr MZN_PLUSPLUS set_expr 806 { $$=new BinOp(@$, $1, BOT_PLUSPLUS, $3); } 807 | set_expr MZN_PLUS set_expr 808 { $$=new BinOp(@$, $1, BOT_PLUS, $3); } 809 | set_expr MZN_MINUS set_expr 810 { $$=new BinOp(@$, $1, BOT_MINUS, $3); } 811 | set_expr MZN_MULT set_expr 812 { $$=new BinOp(@$, $1, BOT_MULT, $3); } 813 | set_expr MZN_DIV set_expr 814 { $$=new BinOp(@$, $1, BOT_DIV, $3); } 815 | set_expr MZN_IDIV set_expr 816 { $$=new BinOp(@$, $1, BOT_IDIV, $3); } 817 | set_expr MZN_MOD set_expr 818 { $$=new BinOp(@$, $1, BOT_MOD, $3); } 819 | set_expr MZN_POW set_expr 820 { $$=new BinOp(@$, $1, BOT_POW, $3); } 821 | set_expr MZN_WEAK_PLUS set_expr 822 { vector<Expression*> args; 823 args.push_back($1); args.push_back($3); 824 $$=new Call(@$, ASTString("~+"), args); 825 } 826 | set_expr MZN_WEAK_MINUS set_expr 827 { vector<Expression*> args; 828 args.push_back($1); args.push_back($3); 829 $$=new Call(@$, ASTString("~-"), args); 830 } 831 | set_expr MZN_WEAK_MULT set_expr 832 { vector<Expression*> args; 833 args.push_back($1); args.push_back($3); 834 $$=new Call(@$, ASTString("~*"), args); 835 } 836 | set_expr MZN_WEAK_EQ set_expr 837 { vector<Expression*> args; 838 args.push_back($1); args.push_back($3); 839 $$=new Call(@$, ASTString("~="), args); 840 } 841 | set_expr MZN_QUOTED_IDENTIFIER set_expr 842 { vector<Expression*> args; 843 args.push_back($1); args.push_back($3); 844 $$=new Call(@$, $2, args); 845 free($2); 846 } 847 | MZN_PLUS set_expr %prec MZN_NOT 848 { $$=new UnOp(@$, UOT_PLUS, $2); } 849 | MZN_MINUS set_expr %prec MZN_NOT 850 { if ($2 && $2->isa<IntLit>()) { 851 $$ = IntLit::a(-$2->cast<IntLit>()->v()); 852 } else if ($2 && $2->isa<FloatLit>()) { 853 $$ = FloatLit::a(-$2->cast<FloatLit>()->v()); 854 } else { 855 $$=new UnOp(@$, UOT_MINUS, $2); 856 } 857 } 858 859/// 860 861expr : 862 expr_atom_head 863 | expr MZN_COLONCOLON annotation_expr 864 { if ($1 && $3) $1->addAnnotation($3); $$=$1; } 865 | expr MZN_EQUIV expr 866 { $$=new BinOp(@$, $1, BOT_EQUIV, $3); } 867 | expr MZN_IMPL expr 868 { $$=new BinOp(@$, $1, BOT_IMPL, $3); } 869 | expr MZN_RIMPL expr 870 { $$=new BinOp(@$, $1, BOT_RIMPL, $3); } 871 | expr MZN_OR expr 872 { $$=new BinOp(@$, $1, BOT_OR, $3); } 873 | expr MZN_XOR expr 874 { $$=new BinOp(@$, $1, BOT_XOR, $3); } 875 | expr MZN_AND expr 876 { $$=new BinOp(@$, $1, BOT_AND, $3); } 877 | expr MZN_LE expr 878 { $$=new BinOp(@$, $1, BOT_LE, $3); } 879 | expr MZN_GR expr 880 { $$=new BinOp(@$, $1, BOT_GR, $3); } 881 | expr MZN_LQ expr 882 { $$=new BinOp(@$, $1, BOT_LQ, $3); } 883 | expr MZN_GQ expr 884 { $$=new BinOp(@$, $1, BOT_GQ, $3); } 885 | expr MZN_EQ expr 886 { $$=new BinOp(@$, $1, BOT_EQ, $3); } 887 | expr MZN_NQ expr 888 { $$=new BinOp(@$, $1, BOT_NQ, $3); } 889 | expr MZN_IN expr 890 { $$=new BinOp(@$, $1, BOT_IN, $3); } 891 | expr MZN_SUBSET expr 892 { $$=new BinOp(@$, $1, BOT_SUBSET, $3); } 893 | expr MZN_SUPERSET expr 894 { $$=new BinOp(@$, $1, BOT_SUPERSET, $3); } 895 | expr MZN_UNION expr 896 { $$=new BinOp(@$, $1, BOT_UNION, $3); } 897 | expr MZN_DIFF expr 898 { $$=new BinOp(@$, $1, BOT_DIFF, $3); } 899 | expr MZN_SYMDIFF expr 900 { $$=new BinOp(@$, $1, BOT_SYMDIFF, $3); } 901 | expr MZN_DOTDOT expr 902 { if ($1==NULL || $3==NULL) { 903 $$ = NULL; 904 } else if ($1->isa<IntLit>() && $3->isa<IntLit>()) { 905 $$=new SetLit(@$, IntSetVal::a($1->cast<IntLit>()->v(),$3->cast<IntLit>()->v())); 906 } else { 907 $$=new BinOp(@$, $1, BOT_DOTDOT, $3); 908 } 909 } 910 | MZN_DOTDOT_QUOTED '(' expr ',' expr ')' 911 { if ($3==NULL || $5==NULL) { 912 $$ = NULL; 913 } else if ($3->isa<IntLit>() && $5->isa<IntLit>()) { 914 $$=new SetLit(@$, IntSetVal::a($3->cast<IntLit>()->v(),$5->cast<IntLit>()->v())); 915 } else { 916 $$=new BinOp(@$, $3, BOT_DOTDOT, $5); 917 } 918 } 919 | expr MZN_INTERSECT expr 920 { $$=new BinOp(@$, $1, BOT_INTERSECT, $3); } 921 | expr MZN_PLUSPLUS expr 922 { $$=new BinOp(@$, $1, BOT_PLUSPLUS, $3); } 923 | expr MZN_PLUS expr 924 { $$=new BinOp(@$, $1, BOT_PLUS, $3); } 925 | expr MZN_MINUS expr 926 { $$=new BinOp(@$, $1, BOT_MINUS, $3); } 927 | expr MZN_MULT expr 928 { $$=new BinOp(@$, $1, BOT_MULT, $3); } 929 | expr MZN_DIV expr 930 { $$=new BinOp(@$, $1, BOT_DIV, $3); } 931 | expr MZN_IDIV expr 932 { $$=new BinOp(@$, $1, BOT_IDIV, $3); } 933 | expr MZN_MOD expr 934 { $$=new BinOp(@$, $1, BOT_MOD, $3); } 935 | expr MZN_POW expr 936 { $$=new BinOp(@$, $1, BOT_POW, $3); } 937 | expr MZN_WEAK_PLUS expr 938 { vector<Expression*> args; 939 args.push_back($1); args.push_back($3); 940 $$=new Call(@$, ASTString("~+"), args); 941 } 942 | expr MZN_WEAK_MINUS expr 943 { vector<Expression*> args; 944 args.push_back($1); args.push_back($3); 945 $$=new Call(@$, ASTString("~-"), args); 946 } 947 | expr MZN_WEAK_MULT expr 948 { vector<Expression*> args; 949 args.push_back($1); args.push_back($3); 950 $$=new Call(@$, ASTString("~*"), args); 951 } 952 | expr MZN_WEAK_EQ expr 953 { vector<Expression*> args; 954 args.push_back($1); args.push_back($3); 955 $$=new Call(@$, ASTString("~="), args); 956 } 957 | expr MZN_QUOTED_IDENTIFIER expr 958 { vector<Expression*> args; 959 args.push_back($1); args.push_back($3); 960 $$=new Call(@$, $2, args); 961 free($2); 962 } 963 | MZN_NOT expr %prec MZN_NOT 964 { $$=new UnOp(@$, UOT_NOT, $2); } 965 | MZN_PLUS expr %prec MZN_NOT 966 { if (($2 && $2->isa<IntLit>()) || ($2 && $2->isa<FloatLit>())) { 967 $$ = $2; 968 } else { 969 $$=new UnOp(@$, UOT_PLUS, $2); 970 } 971 } 972 | MZN_MINUS expr %prec MZN_NOT 973 { if ($2 && $2->isa<IntLit>()) { 974 $$ = IntLit::a(-$2->cast<IntLit>()->v()); 975 } else if ($2 && $2->isa<FloatLit>()) { 976 $$ = FloatLit::a(-$2->cast<FloatLit>()->v()); 977 } else { 978 $$=new UnOp(@$, UOT_MINUS, $2); 979 } 980 } 981 982 983expr_atom_head : 984 expr_atom_head_nonstring 985 { $$=$1; } 986 | string_expr 987 { $$=$1; } 988 989expr_atom_head_nonstring : 990 '(' expr ')' 991 { $$=$2; } 992 | '(' expr ')' array_access_tail 993 { if ($4) $$=createArrayAccess(@$, $2, *$4); delete $4; } 994 | MZN_IDENTIFIER 995 { $$=new Id(@$, $1, NULL); free($1); } 996 | MZN_IDENTIFIER array_access_tail 997 { if ($2) $$=createArrayAccess(@$, new Id(@1,$1,NULL), *$2); 998 free($1); delete $2; } 999 | MZN_UNDERSCORE 1000 { $$=new AnonVar(@$); } 1001 | MZN_UNDERSCORE array_access_tail 1002 { if ($2) $$=createArrayAccess(@$, new AnonVar(@$), *$2); 1003 delete $2; } 1004 | MZN_BOOL_LITERAL 1005 { $$=constants().boollit(($1!=0)); } 1006 | MZN_INTEGER_LITERAL 1007 { $$=IntLit::a($1); } 1008 | MZN_INFINITY 1009 { $$=IntLit::a(IntVal::infinity()); } 1010 | MZN_FLOAT_LITERAL 1011 { $$=FloatLit::a($1); } 1012 | MZN_ABSENT 1013 { $$=constants().absent; } 1014 | set_literal 1015 | set_literal array_access_tail 1016 { if ($2) $$=createArrayAccess(@$, $1, *$2); 1017 delete $2; } 1018 | set_comp 1019 | set_comp array_access_tail 1020 { if ($2) $$=createArrayAccess(@$, $1, *$2); 1021 delete $2; } 1022 | simple_array_literal 1023 | simple_array_literal array_access_tail 1024 { if ($2) $$=createArrayAccess(@$, $1, *$2); 1025 delete $2; } 1026 | simple_array_literal_2d 1027 | simple_array_literal_2d array_access_tail 1028 { if ($2) $$=createArrayAccess(@$, $1, *$2); 1029 delete $2; } 1030 | simple_array_comp 1031 | simple_array_comp array_access_tail 1032 { if ($2) $$=createArrayAccess(@$, $1, *$2); 1033 delete $2; } 1034 | if_then_else_expr 1035 | if_then_else_expr array_access_tail 1036 { if ($2) $$=createArrayAccess(@$, $1, *$2); 1037 delete $2; } 1038 | let_expr 1039 | call_expr 1040 | call_expr array_access_tail 1041 { if ($2) $$=createArrayAccess(@$, $1, *$2); 1042 delete $2; } 1043 1044string_expr: 1045 MZN_STRING_LITERAL 1046 { $$=new StringLit(@$, $1); free($1); } 1047 | MZN_STRING_QUOTE_START string_quote_rest 1048 { $$=new BinOp(@$, new StringLit(@$, $1), BOT_PLUSPLUS, $2); 1049 free($1); 1050 } 1051 1052string_quote_rest: 1053 expr_list_head MZN_STRING_QUOTE_END 1054 { if ($1) $$=new BinOp(@$, new Call(@$, ASTString("format"), *$1), BOT_PLUSPLUS, new StringLit(@$,$2)); 1055 free($2); 1056 delete $1; 1057 } 1058 | expr_list_head MZN_STRING_QUOTE_MID string_quote_rest 1059 { if ($1) $$=new BinOp(@$, new Call(@$, ASTString("format"), *$1), BOT_PLUSPLUS, 1060 new BinOp(@$, new StringLit(@$,$2), BOT_PLUSPLUS, $3)); 1061 free($2); 1062 delete $1; 1063 } 1064 1065array_access_tail : 1066 MZN_LEFT_BRACKET array_access_expr_list MZN_RIGHT_BRACKET 1067 { $$=new std::vector<std::vector<Expression*> >(); 1068 if ($2) { 1069 $$->push_back(*$2); 1070 delete $2; 1071 } 1072 } 1073 | array_access_tail MZN_LEFT_BRACKET array_access_expr_list MZN_RIGHT_BRACKET 1074 { $$=$1; 1075 if ($$ && $3) { 1076 $$->push_back(*$3); 1077 delete $3; 1078 } 1079 } 1080 1081set_literal : 1082 '{' '}' 1083 { $$ = new SetLit(@$, std::vector<Expression*>()); } 1084 | '{' expr_list '}' 1085 { if ($2) $$ = new SetLit(@$, *$2); 1086 delete $2; } 1087 1088set_comp : 1089 '{' expr '|' comp_tail '}' 1090 { if ($4) $$ = new Comprehension(@$, $2, *$4, true); 1091 delete $4; 1092 } 1093 1094comp_tail : 1095 generator_list 1096 { if ($1) $$=new Generators; $$->_g = *$1; delete $1; } 1097 1098generator_list : generator_list_head comma_or_none 1099 1100generator_list_head : 1101 generator 1102 { $$=new std::vector<Generator>; if ($1) $$->push_back(*$1); delete $1; } 1103 | generator_eq 1104 { $$=new std::vector<Generator>; if ($1) $$->push_back(*$1); delete $1; } 1105 | generator_eq MZN_WHERE expr 1106 { $$=new std::vector<Generator>; 1107 if ($1) $$->push_back(*$1); 1108 if ($1 && $3) $$->push_back(Generator($$->size(),$3)); 1109 delete $1; 1110 } 1111 | generator_list_head ',' generator 1112 { $$=$1; if ($$ && $3) $$->push_back(*$3); delete $3; } 1113 | generator_list_head ',' generator_eq 1114 { $$=$1; if ($$ && $3) $$->push_back(*$3); delete $3; } 1115 | generator_list_head ',' generator_eq MZN_WHERE expr 1116 { $$=$1; 1117 if ($$ && $3) $$->push_back(*$3); 1118 if ($$ && $3 && $5) $$->push_back(Generator($$->size(),$5)); 1119 delete $3; 1120 } 1121 1122generator : 1123 id_list MZN_IN expr 1124 { if ($1 && $3) $$=new Generator(*$1,$3,NULL); else $$=NULL; delete $1; } 1125 | id_list MZN_IN expr MZN_WHERE expr 1126 { if ($1 && $3) $$=new Generator(*$1,$3,$5); else $$=NULL; delete $1; } 1127generator_eq : 1128 MZN_IDENTIFIER MZN_EQ expr 1129 { if ($3) $$=new Generator({$1},NULL,$3); else $$=NULL; free($1); } 1130 1131id_list : id_list_head comma_or_none 1132 1133id_list_head : 1134 MZN_IDENTIFIER 1135 { $$=new std::vector<std::string>; $$->push_back($1); free($1); } 1136 | id_list_head ',' MZN_IDENTIFIER 1137 { $$=$1; if ($$ && $3) $$->push_back($3); free($3); } 1138 1139simple_array_literal : 1140 MZN_LEFT_BRACKET MZN_RIGHT_BRACKET 1141 { $$=new ArrayLit(@$, std::vector<MiniZinc::Expression*>()); } 1142 | MZN_LEFT_BRACKET expr_list MZN_RIGHT_BRACKET 1143 { if ($2) $$=new ArrayLit(@$, *$2); delete $2; } 1144 1145simple_array_literal_2d : 1146 MZN_LEFT_2D_BRACKET MZN_RIGHT_2D_BRACKET 1147 { $$=new ArrayLit(@$, std::vector<std::vector<Expression*> >()); } 1148 | MZN_LEFT_2D_BRACKET simple_array_literal_2d_list MZN_RIGHT_2D_BRACKET 1149 { if ($2) { 1150 $$=new ArrayLit(@$, *$2); 1151 for (unsigned int i=1; i<$2->size(); i++) 1152 if ((*$2)[i].size() != (*$2)[i-1].size()) 1153 yyerror(&@2, parm, "syntax error, all sub-arrays of 2d array literal must have the same length"); 1154 delete $2; 1155 } else { 1156 $$ = NULL; 1157 } 1158 } 1159 | MZN_LEFT_2D_BRACKET simple_array_literal_2d_list '|' MZN_RIGHT_2D_BRACKET 1160 { if ($2) { 1161 $$=new ArrayLit(@$, *$2); 1162 for (unsigned int i=1; i<$2->size(); i++) 1163 if ((*$2)[i].size() != (*$2)[i-1].size()) 1164 yyerror(&@2, parm, "syntax error, all sub-arrays of 2d array literal must have the same length"); 1165 delete $2; 1166 } else { 1167 $$ = NULL; 1168 } 1169 } 1170 | MZN_LEFT_2D_BRACKET simple_array_literal_3d_list MZN_RIGHT_2D_BRACKET 1171 { 1172 if ($2) { 1173 std::vector<std::pair<int,int> > dims(3); 1174 dims[0] = std::pair<int,int>(1,static_cast<int>($2->size())); 1175 if ($2->size()==0) { 1176 dims[1] = std::pair<int,int>(1,0); 1177 dims[2] = std::pair<int,int>(1,0); 1178 } else { 1179 dims[1] = std::pair<int,int>(1,static_cast<int>((*$2)[0].size())); 1180 if ((*$2)[0].size()==0) { 1181 dims[2] = std::pair<int,int>(1,0); 1182 } else { 1183 dims[2] = std::pair<int,int>(1,static_cast<int>((*$2)[0][0].size())); 1184 } 1185 } 1186 std::vector<Expression*> a; 1187 for (int i=0; i<dims[0].second; i++) { 1188 if ((*$2)[i].size() != dims[1].second) { 1189 yyerror(&@2, parm, "syntax error, all sub-arrays of 3d array literal must have the same length"); 1190 } else { 1191 for (int j=0; j<dims[1].second; j++) { 1192 if ((*$2)[i][j].size() != dims[2].second) { 1193 yyerror(&@2, parm, "syntax error, all sub-arrays of 3d array literal must have the same length"); 1194 } else { 1195 for (int k=0; k<dims[2].second; k++) { 1196 a.push_back((*$2)[i][j][k]); 1197 } 1198 } 1199 } 1200 } 1201 } 1202 $$ = new ArrayLit(@$,a,dims); 1203 delete $2; 1204 } else { 1205 $$ = NULL; 1206 } 1207 } 1208 1209simple_array_literal_3d_list : 1210 '|' '|' 1211 { $$=new std::vector<std::vector<std::vector<MiniZinc::Expression*> > >; 1212 } 1213 | '|' simple_array_literal_2d_list '|' 1214 { $$=new std::vector<std::vector<std::vector<MiniZinc::Expression*> > >; 1215 if ($2) $$->push_back(*$2); 1216 delete $2; 1217 } 1218 | simple_array_literal_3d_list ',' '|' simple_array_literal_2d_list '|' 1219 { $$=$1; 1220 if ($$ && $4) $$->push_back(*$4); 1221 delete $4; 1222 } 1223 1224simple_array_literal_2d_list : 1225 expr_list 1226 { $$=new std::vector<std::vector<MiniZinc::Expression*> >; 1227 if ($1) $$->push_back(*$1); 1228 delete $1; 1229 } 1230 | simple_array_literal_2d_list '|' expr_list 1231 { $$=$1; if ($$ && $3) $$->push_back(*$3); delete $3; } 1232 1233simple_array_comp : 1234 MZN_LEFT_BRACKET expr '|' comp_tail MZN_RIGHT_BRACKET 1235 { if ($4) $$=new Comprehension(@$, $2, *$4, false); 1236 delete $4; 1237 } 1238 1239if_then_else_expr : 1240 MZN_IF expr MZN_THEN expr MZN_ENDIF 1241 { 1242 std::vector<Expression*> iexps; 1243 iexps.push_back($2); 1244 iexps.push_back($4); 1245 $$=new ITE(@$, iexps, NULL); 1246 } 1247 | MZN_IF expr MZN_THEN expr elseif_list MZN_ELSE expr MZN_ENDIF 1248 { 1249 std::vector<Expression*> iexps; 1250 iexps.push_back($2); 1251 iexps.push_back($4); 1252 if ($5) { 1253 for (unsigned int i=0; i<$5->size(); i+=2) { 1254 iexps.push_back((*$5)[i]); 1255 iexps.push_back((*$5)[i+1]); 1256 } 1257 } 1258 $$=new ITE(@$, iexps,$7); 1259 delete $5; 1260 } 1261 1262elseif_list : 1263 { $$=new std::vector<MiniZinc::Expression*>; } 1264 | elseif_list MZN_ELSEIF expr MZN_THEN expr 1265 { $$=$1; if ($$ && $3 && $5) { $$->push_back($3); $$->push_back($5); } } 1266 1267quoted_op : 1268 MZN_EQUIV_QUOTED 1269 { $$=BOT_EQUIV; } 1270 | MZN_IMPL_QUOTED 1271 { $$=BOT_IMPL; } 1272 | MZN_RIMPL_QUOTED 1273 { $$=BOT_RIMPL; } 1274 | MZN_OR_QUOTED 1275 { $$=BOT_OR; } 1276 | MZN_XOR_QUOTED 1277 { $$=BOT_XOR; } 1278 | MZN_AND_QUOTED 1279 { $$=BOT_AND; } 1280 | MZN_LE_QUOTED 1281 { $$=BOT_LE; } 1282 | MZN_GR_QUOTED 1283 { $$=BOT_GR; } 1284 | MZN_LQ_QUOTED 1285 { $$=BOT_LQ; } 1286 | MZN_GQ_QUOTED 1287 { $$=BOT_GQ; } 1288 | MZN_EQ_QUOTED 1289 { $$=BOT_EQ; } 1290 | MZN_NQ_QUOTED 1291 { $$=BOT_NQ; } 1292 | MZN_IN_QUOTED 1293 { $$=BOT_IN; } 1294 | MZN_SUBSET_QUOTED 1295 { $$=BOT_SUBSET; } 1296 | MZN_SUPERSET_QUOTED 1297 { $$=BOT_SUPERSET; } 1298 | MZN_UNION_QUOTED 1299 { $$=BOT_UNION; } 1300 | MZN_DIFF_QUOTED 1301 { $$=BOT_DIFF; } 1302 | MZN_SYMDIFF_QUOTED 1303 { $$=BOT_SYMDIFF; } 1304 | MZN_PLUS_QUOTED 1305 { $$=BOT_PLUS; } 1306 | MZN_MINUS_QUOTED 1307 { $$=BOT_MINUS; } 1308 | MZN_MULT_QUOTED 1309 { $$=BOT_MULT; } 1310 | MZN_POW_QUOTED 1311 { $$=BOT_POW; } 1312 | MZN_DIV_QUOTED 1313 { $$=BOT_DIV; } 1314 | MZN_IDIV_QUOTED 1315 { $$=BOT_IDIV; } 1316 | MZN_MOD_QUOTED 1317 { $$=BOT_MOD; } 1318 | MZN_INTERSECT_QUOTED 1319 { $$=BOT_INTERSECT; } 1320 | MZN_PLUSPLUS_QUOTED 1321 { $$=BOT_PLUSPLUS; } 1322 | MZN_NOT_QUOTED 1323 { $$=-1; } 1324 1325quoted_op_call : 1326 quoted_op '(' expr ',' expr ')' 1327 { if ($1==-1) { 1328 $$=NULL; 1329 yyerror(&@3, parm, "syntax error, unary operator with two arguments"); 1330 } else { 1331 $$=new BinOp(@$, $3,static_cast<BinOpType>($1),$5); 1332 } 1333 } 1334 | quoted_op '(' expr ')' 1335 { int uot=-1; 1336 switch ($1) { 1337 case -1: 1338 uot = UOT_NOT; 1339 break; 1340 case BOT_MINUS: 1341 uot = UOT_MINUS; 1342 break; 1343 case BOT_PLUS: 1344 uot = UOT_PLUS; 1345 break; 1346 default: 1347 yyerror(&@3, parm, "syntax error, binary operator with unary argument list"); 1348 break; 1349 } 1350 if (uot==-1) 1351 $$=NULL; 1352 else { 1353 if (uot==UOT_PLUS && $3 && ($3->isa<IntLit>() || $3->isa<FloatLit>())) { 1354 $$ = $3; 1355 } else if (uot==UOT_MINUS && $3 && $3->isa<IntLit>()) { 1356 $$ = IntLit::a(-$3->cast<IntLit>()->v()); 1357 } else if (uot==UOT_MINUS && $3 && $3->isa<FloatLit>()) { 1358 $$ = FloatLit::a(-$3->cast<FloatLit>()->v()); 1359 } else { 1360 $$=new UnOp(@$, static_cast<UnOpType>(uot),$3); 1361 } 1362 } 1363 } 1364 1365call_expr : 1366 MZN_IDENTIFIER '(' ')' 1367 { $$=new Call(@$, $1, std::vector<Expression*>()); free($1); } 1368 | quoted_op_call 1369 | MZN_IDENTIFIER '(' comp_or_expr ')' 1370 { 1371 if ($3!=NULL) { 1372 bool hadWhere = false; 1373 std::vector<Expression*> args; 1374 for (unsigned int i=0; i<$3->size(); i++) { 1375 if ((*$3)[i].second) { 1376 yyerror(&@3, parm, "syntax error, 'where' expression outside generator call"); 1377 hadWhere = true; 1378 $$=NULL; 1379 } 1380 args.push_back((*$3)[i].first); 1381 } 1382 if (!hadWhere) { 1383 $$=new Call(@$, $1, args); 1384 } 1385 } 1386 free($1); 1387 delete $3; 1388 } 1389 | MZN_IDENTIFIER '(' comp_or_expr ')' '(' expr ')' 1390 { 1391 vector<Generator> gens; 1392 vector<Id*> ids; 1393 if ($3) { 1394 for (unsigned int i=0; i<$3->size(); i++) { 1395 if (Id* id = Expression::dyn_cast<Id>((*$3)[i].first)) { 1396 if ((*$3)[i].second) { 1397 ParserLocation loc = (*$3)[i].second->loc().parserLocation(); 1398 yyerror(&loc, parm, "illegal where expression in generator call"); 1399 } 1400 ids.push_back(id); 1401 } else { 1402 if (BinOp* boe = Expression::dyn_cast<BinOp>((*$3)[i].first)) { 1403 if (boe->lhs() && boe->rhs()) { 1404 Id* id = Expression::dyn_cast<Id>(boe->lhs()); 1405 if (id && boe->op() == BOT_IN) { 1406 ids.push_back(id); 1407 gens.push_back(Generator(ids,boe->rhs(),(*$3)[i].second)); 1408 ids = vector<Id*>(); 1409 } else if (id && boe->op() == BOT_EQ && ids.empty()) { 1410 ids.push_back(id); 1411 gens.push_back(Generator(ids,NULL,boe->rhs())); 1412 if ((*$3)[i].second) { 1413 gens.push_back(Generator(gens.size(),(*$3)[i].second)); 1414 } 1415 ids = vector<Id*>(); 1416 } else { 1417 ParserLocation loc = (*$3)[i].first->loc().parserLocation(); 1418 yyerror(&loc, parm, "illegal expression in generator call"); 1419 } 1420 } 1421 } else { 1422 ParserLocation loc = (*$3)[i].first->loc().parserLocation(); 1423 yyerror(&loc, parm, "illegal expression in generator call"); 1424 } 1425 } 1426 } 1427 } 1428 if (ids.size() != 0) { 1429 yyerror(&@3, parm, "illegal expression in generator call"); 1430 } 1431 ParserState* pp = static_cast<ParserState*>(parm); 1432 if (pp->hadError) { 1433 $$=NULL; 1434 } else { 1435 Generators g; g._g = gens; 1436 Comprehension* ac = new Comprehension(@$, $6,g,false); 1437 vector<Expression*> args; args.push_back(ac); 1438 $$=new Call(@$, $1, args); 1439 } 1440 free($1); 1441 delete $3; 1442 } 1443 1444comp_or_expr : comp_or_expr_head comma_or_none 1445 1446comp_or_expr_head : 1447 expr 1448 { $$=new vector<pair<Expression*,Expression*> >; 1449 if ($1) { 1450 $$->push_back(pair<Expression*,Expression*>($1,NULL)); 1451 } 1452 } 1453 | expr MZN_WHERE expr 1454 { $$=new vector<pair<Expression*,Expression*> >; 1455 if ($1 && $3) { 1456 $$->push_back(pair<Expression*,Expression*>($1,$3)); 1457 } 1458 } 1459 | comp_or_expr_head ',' expr 1460 { $$=$1; if ($$ && $3) $$->push_back(pair<Expression*,Expression*>($3,NULL)); } 1461 | comp_or_expr_head ',' expr MZN_WHERE expr 1462 { $$=$1; if ($$ && $3 && $5) $$->push_back(pair<Expression*,Expression*>($3,$5)); } 1463 1464let_expr : 1465 MZN_LET '{' let_vardecl_item_list '}' MZN_IN expr %prec PREC_ANNO 1466 { if ($3 && $6) { 1467 $$=new Let(@$, *$3, $6); delete $3; 1468 } else { 1469 $$=NULL; 1470 } 1471 } 1472 | MZN_LET '{' let_vardecl_item_list comma_or_semi '}' MZN_IN expr %prec PREC_ANNO 1473 { if ($3 && $7) { 1474 $$=new Let(@$, *$3, $7); delete $3; 1475 } else { 1476 $$=NULL; 1477 } 1478 } 1479 1480let_vardecl_item_list : 1481 let_vardecl_item 1482 { $$=new vector<Expression*>; $$->push_back($1); } 1483 | constraint_item 1484 { $$=new vector<Expression*>; 1485 if ($1) { 1486 ConstraintI* ce = $1->cast<ConstraintI>(); 1487 $$->push_back(ce->e()); 1488 ce->e(NULL); 1489 } 1490 } 1491 | let_vardecl_item_list comma_or_semi let_vardecl_item 1492 { $$=$1; if ($$ && $3) $$->push_back($3); } 1493 | let_vardecl_item_list comma_or_semi constraint_item 1494 { $$=$1; 1495 if ($$ && $3) { 1496 ConstraintI* ce = $3->cast<ConstraintI>(); 1497 $$->push_back(ce->e()); 1498 ce->e(NULL); 1499 } 1500 } 1501 1502comma_or_semi : ',' | ';' 1503 1504let_vardecl_item : 1505 ti_expr_and_id annotations 1506 { $$ = $1; 1507 if ($$) $$->toplevel(false); 1508 if ($$ && $2) $$->addAnnotations(*$2); 1509 delete $2; 1510 } 1511 | ti_expr_and_id annotations MZN_EQ expr 1512 { if ($1) $1->e($4); 1513 $$ = $1; 1514 if ($$) $$->loc(@$); 1515 if ($$) $$->toplevel(false); 1516 if ($$ && $2) $$->addAnnotations(*$2); 1517 delete $2; 1518 } 1519 1520annotations : 1521 /* empty */ 1522 { $$=NULL; } 1523 | ne_annotations 1524 1525annotation_expr : 1526 expr_atom_head_nonstring 1527 { $$ = $1; } 1528 | string_expr 1529 { $$ = new Call(@1, ASTString("mzn_expression_name"), {$1}); } 1530 1531ne_annotations : 1532 MZN_COLONCOLON annotation_expr 1533 { $$=new std::vector<Expression*>(1); 1534 (*$$)[0] = $2; 1535 } 1536 | ne_annotations MZN_COLONCOLON annotation_expr 1537 { $$=$1; if ($$) $$->push_back($3); } 1538 1539id_or_quoted_op : 1540 MZN_IDENTIFIER 1541 { $$=$1; } 1542 | MZN_EQUIV_QUOTED 1543 { $$=strdup("'<->'"); } 1544 | MZN_IMPL_QUOTED 1545 { $$=strdup("'->'"); } 1546 | MZN_RIMPL_QUOTED 1547 { $$=strdup("'<-'"); } 1548 | MZN_OR_QUOTED 1549 { $$=strdup("'\\/'"); } 1550 | MZN_XOR_QUOTED 1551 { $$=strdup("'xor'"); } 1552 | MZN_AND_QUOTED 1553 { $$=strdup("'/\\'"); } 1554 | MZN_LE_QUOTED 1555 { $$=strdup("'<'"); } 1556 | MZN_GR_QUOTED 1557 { $$=strdup("'>'"); } 1558 | MZN_LQ_QUOTED 1559 { $$=strdup("'<='"); } 1560 | MZN_GQ_QUOTED 1561 { $$=strdup("'>='"); } 1562 | MZN_EQ_QUOTED 1563 { $$=strdup("'='"); } 1564 | MZN_NQ_QUOTED 1565 { $$=strdup("'!='"); } 1566 | MZN_IN_QUOTED 1567 { $$=strdup("'in'"); } 1568 | MZN_SUBSET_QUOTED 1569 { $$=strdup("'subset'"); } 1570 | MZN_SUPERSET_QUOTED 1571 { $$=strdup("'superset'"); } 1572 | MZN_UNION_QUOTED 1573 { $$=strdup("'union'"); } 1574 | MZN_DIFF_QUOTED 1575 { $$=strdup("'diff'"); } 1576 | MZN_SYMDIFF_QUOTED 1577 { $$=strdup("'symdiff'"); } 1578 | MZN_DOTDOT_QUOTED 1579 { $$=strdup("'..'"); } 1580 | MZN_PLUS_QUOTED 1581 { $$=strdup("'+'"); } 1582 | MZN_MINUS_QUOTED 1583 { $$=strdup("'-'"); } 1584 | MZN_MULT_QUOTED 1585 { $$=strdup("'*'"); } 1586 | MZN_POW_QUOTED 1587 { $$=strdup("'^'"); } 1588 | MZN_DIV_QUOTED 1589 { $$=strdup("'/'"); } 1590 | MZN_IDIV_QUOTED 1591 { $$=strdup("'div'"); } 1592 | MZN_MOD_QUOTED 1593 { $$=strdup("'mod'"); } 1594 | MZN_INTERSECT_QUOTED 1595 { $$=strdup("'intersect'"); } 1596 | MZN_NOT_QUOTED 1597 { $$=strdup("'not'"); } 1598 | MZN_PLUSPLUS_QUOTED 1599 { $$=strdup("'++'"); }