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