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