/* == Prolog AST-stream term Scanner for FlatZinc ============================= * * (C) 2015 Salvador Abreu * * ---------------------------------------------------------------------------- * Based on the Lexer for FlatZinc. * Nick Nethercote, started May 2007. * * This file is in the public domain, and can be used without copyright * restrictions. */ %{ #include %} /* Regular expressions for attributed tokens. */ ident [A-Za-z][A-Za-z0-9_]* underscore_ident _*[A-Za-z][A-Za-z0-9_]* string_literal \"[^"\n]*\" int_literal -?[0-9]+|-?0x[0-9A-Fa-f]+|-?0o[0-7]+ float_literal -?[0-9]+\.[0-9]+|-?[0-9]+\.[0-9]+[Ee][-+]?[0-9]+|-?[0-9]+[Ee][-+]?[0-9]+ %% /* Reserved words */ "array" { return ARRAY; } "bool" { return BOOL; } "constraint" { return CONSTRAINT;} "false" { return FALSE; } "float" { return FLOAT; } "int" { return INT; } "minimize" { return MINIMIZE; } "maximize" { return MAXIMIZE; } "of" { return OF; } "predicate" { return PREDICATE; } "satisfy" { return SATISFY; } "set" { return SET; } "solve" { return SOLVE; } "true" { return TRUE; } "var" { return VAR; } \.\. { return DOTDOT; } :: { return COLONCOLON;} /* Attributed tokens */ {ident} { yylval.id = strdup(yytext); return IDENT; } {underscore_ident} { yylval.id = strdup(yytext); return UNDERSCORE_IDENT; } {string_literal} { yylval.lit.sval = strdup(yytext); return STRING_LITERAL; } {int_literal} { /* ** atoi() doesn't recognise our hex and octal numbers, so we must ** handle them ourselves. ** ** XXX: this code doesn't detect if the integer literals overflow an ** 'int'. (In particular, 'atoi' doesn't detect overflow errors, ** but 'strtol' does, so that could be used for the decimal integer ** case.) ** ** XXX: I think this code will incorrectly parse negative octal and ** hexadecimal numbers -- the two conditions will fail due to the ** leading '-', so 'atoi' will be invoked, which will fail, and ** yylval.int_val will be set to something bogus (probably zero). */ if ('0' == yytext[0] && 'x' == yytext[1]) { int i = 2, x = 0; while ('\0' != yytext[i]) { x *= 16; if ('0' <= yytext[i] && yytext[i] <= '9') { x += (yytext[i] - '0'); } else { x += (yytext[i] - 'a' + 10); } i++; } yylval.lit.ival = x; } else if ('0' == yytext[0] && 'o' == yytext[1]) { int i = 2, x = 0; while ('\0' != yytext[i]) { x *= 8; x += (yytext[i] - '0'); i++; } yylval.lit.ival = x; } else { yylval.lit.ival = atoi(yytext); } return INT_LITERAL; } {float_literal} { yylval.lit.rval = atof(yytext); return FLOAT_LITERAL; } /* Skip newlines, whitespace and comments, return any non-matched * character. */ \n ; [ \t] ; %.* ; . { return yytext[0]; } %%