1
0
This repository has been archived on 2025-03-06. You can view files and clone it, but cannot push or open issues or pull requests.
Jip J. Dekker f2a1c4e389 Squashed 'software/mza/' content from commit f970a59b17
git-subtree-dir: software/mza
git-subtree-split: f970a59b177c13ca3dd8aaef8cc6681d83b7e813
2021-07-11 16:34:30 +10:00

413 lines
15 KiB
Plaintext

/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
* Guido Tack <guido.tack@monash.edu>
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
%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 <minizinc/parser.hh>
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<MiniZinc::ParserState*>(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<MiniZinc::ParserState*>(parm);
pp->stringBuffer = "";
}
void appendBufferString(void* parm, const char* s) {
MiniZinc::ParserState* pp =
static_cast<MiniZinc::ParserState*>(parm);
pp->stringBuffer += s;
}
void appendBufferChar(void* parm, char s) {
MiniZinc::ParserState* pp =
static_cast<MiniZinc::ParserState*>(parm);
pp->stringBuffer += s;
}
char* bufferData(void* parm) {
MiniZinc::ParserState* pp =
static_cast<MiniZinc::ParserState*>(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)); }
<doccomment>{
"*/" { 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)); }
<doccomment_file>{
"*/" { 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); }
<multilinecomment>{
"*/" { 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<MiniZinc::ParserState*>(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; }
<bracket_exp>")" { yy_pop_state(yyscanner); return *yytext; }
<quoted_exp>")" { 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)); }
<string,string_quote>[^\\"\xa\xd\x0]* { appendBufferString(yyget_extra(yyscanner), yytext); }
<string,string_quote>\\n { appendBufferChar(yyget_extra(yyscanner), '\n'); }
<string,string_quote>\\t { appendBufferChar(yyget_extra(yyscanner), '\t'); }
<string,string_quote>\\[\\'] { appendBufferChar(yyget_extra(yyscanner), yytext[1]); }
<string,string_quote>\\[\\"] { appendBufferChar(yyget_extra(yyscanner), yytext[1]); }
<string>\\"(" { yylval->sValue = bufferData(yyget_extra(yyscanner));
yy_push_state(quoted_exp,yyscanner); return MZN_STRING_QUOTE_START; }
<string_quote>\\"(" { yylval->sValue = bufferData(yyget_extra(yyscanner));
yy_push_state(quoted_exp,yyscanner); return MZN_STRING_QUOTE_MID; }
<string>\" { yylval->sValue = bufferData(yyget_extra(yyscanner));
yy_pop_state(yyscanner); return MZN_STRING_LITERAL; }
<string_quote>\" { yylval->sValue = bufferData(yyget_extra(yyscanner));
yy_pop_state(yyscanner); return MZN_STRING_QUOTE_END; }
<string,string_quote>. { return (unsigned char)yytext[0]; }
<string,string_quote>[\xa\xd\x0] { return MZN_END_OF_LINE_IN_STRING; }
<string,string_quote><<EOF>> { 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<MiniZinc::ParserState*>(yyget_extra(yyscanner));
return parm->fillBuffer(buf, size);
// work around warning that yyunput is unused
yyunput (0,buf,yyscanner);
}