/* -*- 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/. */ %option reentrant %option bison-bridge bison-locations %option noyywrap %option stack %{ #if defined __GNUC__ #pragma GCC diagnostic ignored "-Wunused-function" #pragma GCC diagnostic ignored "-Wunused-parameter" #pragma GCC diagnostic ignored "-Wsign-compare" #pragma GCC diagnostic ignored "-Wdeprecated" #elif defined _MSC_VER #pragma warning(push, 1) #endif namespace MiniZinc{ class ParserLocation; } #define YYLTYPE MiniZinc::ParserLocation #define YYLTYPE_IS_DECLARED 1 #define YYLTYPE_IS_TRIVIAL 0 #include int utf8len(const char* s) { int l=0; for (int i=0; s[i] != '\0'; i++) if ((s[i] & 0xc0) != 0x80) l++; return l; } int yy_input_proc(char* buf, int size, yyscan_t yyscanner); #define YY_INPUT(buf, result, max_size) \ result = yy_input_proc(buf, max_size, yyscanner); #define YY_USER_ACTION \ { MiniZinc::ParserState* parm = \ static_cast(yyget_extra(yyscanner)); \ yylloc->first_line(yylloc->last_line()); \ yylloc->first_column(yylloc->last_column()+1); \ if(parm->hadNewline) { \ parm->hadNewline=false; \ parm->lineStartPos += parm->nTokenNextStart; \ parm->nTokenNextStart=1; \ yylloc->last_line(yylloc->last_line()+1); \ yylloc->first_line(yylloc->last_line()); \ yylloc->first_column(1); \ } \ if(yytext[0] == '\n') { \ parm->hadNewline=true; \ parm->nTokenNextStart+=0; \ } else { \ parm->nTokenNextStart+=yyleng; \ } \ yylloc->last_column(yylloc->first_column()+utf8len(yytext)-1); \ } bool hexstrtointval(const char* s, long long int& v) { std::istringstream iss(s); iss >> std::hex >> v; return !iss.fail(); } bool octstrtointval(const char* s, long long int& v) { std::istringstream iss(s); iss >> std::oct >> v; return !iss.fail(); } bool fast_strtointval(const char* s, long long int& v) { MiniZinc::IntVal x = 0; try { for (; *s != '\0'; ++s) { x = (x*10) + (*s - '0'); } } catch (MiniZinc::ArithmeticError&) { return false; } v = x.toInt(); return true; } bool strtofloatval(const char* s, double& v) { std::istringstream iss(s); iss >> v; return !iss.fail(); } void clearBuffer(void* parm) { MiniZinc::ParserState* pp = static_cast(parm); pp->stringBuffer = ""; } void appendBufferString(void* parm, const char* s) { MiniZinc::ParserState* pp = static_cast(parm); pp->stringBuffer += s; } void appendBufferChar(void* parm, char s) { MiniZinc::ParserState* pp = static_cast(parm); pp->stringBuffer += s; } char* bufferData(void* parm) { MiniZinc::ParserState* pp = static_cast(parm); return strdup(pp->stringBuffer.c_str()); } %} %x string %x string_quote %x multilinecomment %x doccomment %x doccomment_file %s bracket_exp %s quoted_exp %% <*>\x0 { return MZN_INVALID_NULL; } \xa { } [ \f\xd\t] { /* ignore whitespace */ } "/**" { yy_push_state(doccomment,yyscanner); clearBuffer(yyget_extra(yyscanner)); } { "*/" { yylval->sValue = bufferData(yyget_extra(yyscanner)); yy_pop_state(yyscanner); return MZN_DOC_COMMENT; } [^*\xa]+ { appendBufferString(yyget_extra(yyscanner), yytext); } "*" { appendBufferString(yyget_extra(yyscanner), yytext); } \xa { appendBufferString(yyget_extra(yyscanner), yytext); } } "/***" { yy_push_state(doccomment_file,yyscanner); clearBuffer(yyget_extra(yyscanner)); } { "*/" { yylval->sValue = bufferData(yyget_extra(yyscanner)); yy_pop_state(yyscanner); return MZN_DOC_FILE_COMMENT; } [^*\xa]+ { appendBufferString(yyget_extra(yyscanner), yytext); } "*" { appendBufferString(yyget_extra(yyscanner), yytext); } \xa { appendBufferString(yyget_extra(yyscanner), yytext); } } "/*" { yy_push_state(multilinecomment,yyscanner); } { "*/" { yy_pop_state(yyscanner); } [^*\xa]+ { } "*" { } \xa { } } "[" { return MZN_LEFT_BRACKET; } "[|" { return MZN_LEFT_2D_BRACKET; } "]" { return MZN_RIGHT_BRACKET; } "|]" { return MZN_RIGHT_2D_BRACKET; } %[^\xa]* { /* ignore comments */ } "true" { yylval->iValue = 1; return MZN_BOOL_LITERAL; } "false" { yylval->iValue = 0; return MZN_BOOL_LITERAL; } 0[xX]([0-9a-fA-F]*\.[0-9a-fA-F]+|[0-9a-fA-F]+\.)([pP][+-]?[0-9]+)|(0[xX][0-9a-fA-F]+[pP][+-]?[0-9]+) { if (strtofloatval(yytext, yylval->dValue)) return MZN_FLOAT_LITERAL; else return MZN_INVALID_FLOAT_LITERAL; } 0[xX][0-9A-Fa-f]+ { if (hexstrtointval(yytext+2, yylval->iValue)) return MZN_INTEGER_LITERAL; else return MZN_INVALID_INTEGER_LITERAL; } 0o[0-7]+ { if (octstrtointval(yytext+2, yylval->iValue)) return MZN_INTEGER_LITERAL; else return MZN_INVALID_INTEGER_LITERAL; } [0-9]+ { if (fast_strtointval(yytext, yylval->iValue)) return MZN_INTEGER_LITERAL; else return MZN_INVALID_INTEGER_LITERAL; } [0-9]+\.[0-9]+ { if (strtofloatval(yytext, yylval->dValue)) return MZN_FLOAT_LITERAL; else return MZN_INVALID_FLOAT_LITERAL; } [0-9]+\.[0-9]+[Ee][+-]?[0-9]+ { if (strtofloatval(yytext, yylval->dValue)) return MZN_FLOAT_LITERAL; else return MZN_INVALID_FLOAT_LITERAL; } [0-9]+[Ee][+-]?[0-9]+ { if (strtofloatval(yytext, yylval->dValue)) return MZN_FLOAT_LITERAL; else return MZN_INVALID_FLOAT_LITERAL; } [:;|{},\[\]\.] { return *yytext; } \.\. { return MZN_DOTDOT; } "'\.\.'" { return MZN_DOTDOT_QUOTED; } :: { return MZN_COLONCOLON; } _ { return MZN_UNDERSCORE; } "ann" { return MZN_ANN; } "annotation" { return MZN_ANNOTATION; } "any" { return MZN_ANY; } "array" { return MZN_ARRAY; } "bool" { return MZN_BOOL; } "case" { return MZN_CASE; } "constraint" { return MZN_CONSTRAINT; } "default" { return MZN_DEFAULT; } "div" { return MZN_IDIV; } "'div'" { return MZN_IDIV_QUOTED; } "diff" { return MZN_DIFF; } "'diff'" { return MZN_DIFF_QUOTED; } "else" { return MZN_ELSE; } "elseif" { return MZN_ELSEIF; } "endif" { return MZN_ENDIF; } "enum" { return MZN_ENUM; } "float" { return MZN_FLOAT; } "function" { return MZN_FUNCTION; } "if" { return MZN_IF; } "include" { return MZN_INCLUDE; } "infinity" { return MZN_INFINITY; } "intersect" { return MZN_INTERSECT; } "'intersect'" { return MZN_INTERSECT_QUOTED; } "in" { return MZN_IN; } "'in'" { return MZN_IN_QUOTED; } "int" { return MZN_INT; } "let" { return MZN_LET; } "list" { return MZN_LIST; } "maximize" { yylval->bValue = false; return MZN_MAXIMIZE; } "minimize" { yylval->bValue = true; return MZN_MINIMIZE; } "mod" { return MZN_MOD; } "'mod'" { return MZN_MOD_QUOTED; } "not" { return MZN_NOT; } "'not'" { return MZN_NOT_QUOTED; } "of" { return MZN_OF; } "output" { return MZN_OUTPUT; } "opt" { return MZN_OPT; } "par" { return MZN_PAR; } "predicate" { return MZN_PREDICATE; } "record" { return MZN_RECORD; } "satisfy" { return MZN_SATISFY; } "set" { return MZN_SET; } "solve" { return MZN_SOLVE; } "string" { return MZN_STRING; } "subset" { return MZN_SUBSET; } "'subset'" { return MZN_SUBSET_QUOTED; } "superset" { return MZN_SUPERSET; } "'superset'" { return MZN_SUPERSET_QUOTED; } "symdiff" { return MZN_SYMDIFF; } "'symdiff'" { return MZN_SYMDIFF_QUOTED; } "test" { return MZN_TEST; } "then" { return MZN_THEN; } "tuple" { return MZN_TUPLE; } "type" { return MZN_TYPE; } "union" { return MZN_UNION; } "'union'" { return MZN_UNION_QUOTED; } "var" { return MZN_VAR; } "variant_record" { return MZN_VARIANT_RECORD; } "where" { return MZN_WHERE; } "xor" { return MZN_XOR; } "'xor'" { return MZN_XOR_QUOTED; } "+" { return MZN_PLUS; } "'+'" { return MZN_PLUS_QUOTED; } "-" { return MZN_MINUS; } "'-'" { return MZN_MINUS_QUOTED; } "*" { return MZN_MULT; } "'*'" { return MZN_MULT_QUOTED; } "/" { return MZN_DIV; } "'/'" { return MZN_DIV_QUOTED; } "^" { return MZN_POW; } "'^'" { return MZN_POW_QUOTED; } "++" { return MZN_PLUSPLUS; } "'++'" { return MZN_PLUSPLUS_QUOTED; } "<>" { return MZN_ABSENT; } "<" { return MZN_LE; } "'<'" { return MZN_LE_QUOTED; } "<=" { return MZN_LQ; } "'<='" { return MZN_LQ_QUOTED; } ">" { return MZN_GR; } "'>'" { return MZN_GR_QUOTED; } ">=" { return MZN_GQ; } "'>='" { return MZN_GQ_QUOTED; } "==" { return MZN_EQ; } "'=='" { return MZN_EQ_QUOTED; } "=" { return MZN_EQ; } "'='" { return MZN_EQ_QUOTED; } "!=" { return MZN_NQ; } "'!='" { return MZN_NQ_QUOTED; } "->" { return MZN_IMPL; } "'->'" { return MZN_IMPL_QUOTED; } "<-" { return MZN_RIMPL; } "'<-'" { return MZN_RIMPL_QUOTED; } "<->" { return MZN_EQUIV; } "'<->'" { return MZN_EQUIV_QUOTED; } "\\/" { return MZN_OR; } "'\\/'" { return MZN_OR_QUOTED; } "/\\" { return MZN_AND; } "'/\\'" { return MZN_AND_QUOTED; } "~+" { return MZN_WEAK_PLUS; } "~*" { return MZN_WEAK_MULT; } "~=" { return MZN_WEAK_EQ; } "~-" { return MZN_WEAK_MINUS; } "'~"[+*=-]"'" { yylval->sValue = strdup(yytext+1); yylval->sValue[strlen(yytext)-2] = 0; return MZN_IDENTIFIER; } "_objective" { yylval->sValue = strdup(yytext); return MZN_IDENTIFIER; } [A-Za-z][A-Za-z0-9_]* { yylval->sValue = strdup(yytext); return MZN_IDENTIFIER; } "'"[^\\'\xa\xd\x0]*"'" { yylval->sValue = strdup(yytext); return MZN_IDENTIFIER; } _[A-Za-z][A-Za-z0-9_]* { MiniZinc::ParserState* parm = static_cast(yyget_extra(yyscanner)); if (parm->isFlatZinc) { yylval->sValue = strdup(yytext); return MZN_IDENTIFIER; } else { return FLATZINC_IDENTIFIER; } } "\xE2\x88\x80" { yylval->sValue = strdup("forall"); return MZN_IDENTIFIER; } "\xE2\x88\x83" { yylval->sValue = strdup("exists"); return MZN_IDENTIFIER; } "\xE2\x88\x88" { return MZN_IN; } "\xE2\x8A\x86" { return MZN_SUBSET; } "\xE2\x8A\x87" { return MZN_SUPERSET; } "\xE2\x88\x9E" { return MZN_INFINITY; } "\xC2\xAC" { return MZN_NOT; } "\xE2\x86\x90" { return MZN_RIMPL; } "\xE2\x86\x92" { return MZN_IMPL; } "\xE2\x86\x94" { return MZN_EQUIV; } "\xE2\x88\xA7" { return MZN_AND; } "\xE2\x88\xA8" { return MZN_OR; } "\xE2\x89\xA0" { return MZN_NQ; } "\xE2\x89\xA4" { return MZN_LQ; } "\xE2\x89\xA5" { return MZN_GQ; } "\xE2\x88\xAA" { return MZN_UNION; } "\xE2\x88\xA9" { return MZN_INTERSECT; } $$[A-Za-z][A-Za-z0-9_]* { yylval->sValue = strdup(yytext+1); return MZN_TI_ENUM_IDENTIFIER; } $[A-Za-z][A-Za-z0-9_]* { yylval->sValue = strdup(yytext+1); return MZN_TI_IDENTIFIER; } "(" { yy_push_state(bracket_exp,yyscanner); return *yytext; } ")" { yy_pop_state(yyscanner); return *yytext; } ")" { yy_pop_state(yyscanner); yy_pop_state(yyscanner); yy_push_state(string_quote,yyscanner); clearBuffer(yyget_extra(yyscanner)); } \" { yy_push_state(string,yyscanner); clearBuffer(yyget_extra(yyscanner)); } [^\\"\xa\xd\x0]* { appendBufferString(yyget_extra(yyscanner), yytext); } \\n { appendBufferChar(yyget_extra(yyscanner), '\n'); } \\t { appendBufferChar(yyget_extra(yyscanner), '\t'); } \\[\\'] { appendBufferChar(yyget_extra(yyscanner), yytext[1]); } \\[\\"] { appendBufferChar(yyget_extra(yyscanner), yytext[1]); } \\"(" { yylval->sValue = bufferData(yyget_extra(yyscanner)); yy_push_state(quoted_exp,yyscanner); return MZN_STRING_QUOTE_START; } \\"(" { yylval->sValue = bufferData(yyget_extra(yyscanner)); yy_push_state(quoted_exp,yyscanner); return MZN_STRING_QUOTE_MID; } \" { yylval->sValue = bufferData(yyget_extra(yyscanner)); yy_pop_state(yyscanner); return MZN_STRING_LITERAL; } \" { yylval->sValue = bufferData(yyget_extra(yyscanner)); yy_pop_state(yyscanner); return MZN_STRING_QUOTE_END; } . { return (unsigned char)yytext[0]; } [\xa\xd\x0] { return MZN_END_OF_LINE_IN_STRING; } <> { yy_pop_state(yyscanner); return MZN_UNTERMINATED_STRING; } `[A-Za-z][A-Za-z0-9_]*` { yylval->sValue = strdup(yytext+1); yylval->sValue[strlen(yytext)-2] = 0; return MZN_QUOTED_IDENTIFIER; } . { return (unsigned char)yytext[0]; } %% int yy_input_proc(char* buf, int size, yyscan_t yyscanner) { MiniZinc::ParserState* parm = static_cast(yyget_extra(yyscanner)); return parm->fillBuffer(buf, size); // work around warning that yyunput is unused yyunput (0,buf,yyscanner); }