Commit 25820b21715ce6cfbb2528f8eb487b17502489c6

Authored by Salvador Abreu
1 parent 5564dda3
Exists in master

added flatzinc parser from minizinc 1.6 distrib

fzn-parser/.gitignore 0 โ†’ 100644
... ... @@ -0,0 +1 @@
  1 +flatzinc.output flatzinc.tab.c lex.yy.c fzp
... ...
fzn-parser/Makefile 0 โ†’ 100644
... ... @@ -0,0 +1,39 @@
  1 +EXEEXT=
  2 +
  3 +EXE_FILE = fzp$(EXEEXT)
  4 +SRC =
  5 +OBJ = flatzinc.tab.o
  6 +GENCFILES = flatzinc.tab.c lex.yy.c
  7 +OTHER = flatzinc.output
  8 +
  9 +# NOTE: we need to pass the `-l' flag to ensure the scanner internal
  10 +# variable `yylineno' is available.
  11 +#
  12 +LEX = flex
  13 +LEXFLAGS = -l
  14 +LEXLIB =
  15 +
  16 +YACC = bison
  17 +YACCFLAGS = -v
  18 +
  19 +CC = gcc
  20 +CFLAGS = -g -O
  21 +RM = /bin/rm -f
  22 +
  23 +$(EXE_FILE): $(OBJ)
  24 + $(CC) $(CFLAGS) -o $(EXE_FILE) $(OBJ) $(LEXLIB)
  25 +
  26 +flatzinc.tab.c: flatzinc.y lex.yy.c
  27 + $(YACC) $(YACCFLAGS) flatzinc.y
  28 +
  29 +lex.yy.c: flatzinc.l
  30 + $(LEX) $(LEXFLAGS) flatzinc.l
  31 +
  32 +clean:
  33 + $(RM) $(OBJ) $(GENCFILES) $(OTHER) core
  34 +
  35 +clobber: clean
  36 + $(RM) $(EXE_FILE)
  37 +
  38 +.PHONY: distclean
  39 +distclean: clobber
... ...
fzn-parser/flatzinc.l 0 โ†’ 100644
... ... @@ -0,0 +1,109 @@
  1 +/* Lexer for FlatZinc.
  2 + * Nick Nethercote, started May 2007.
  3 + *
  4 + * This file is in the public domain, and can be used without copyright
  5 + * restrictions.
  6 + */
  7 +
  8 +%{
  9 +#include <string.h>
  10 +%}
  11 +
  12 + /* Regular expressions for attributed tokens. */
  13 +ident [A-Za-z][A-Za-z0-9_]*
  14 +underscore_ident _*[A-Za-z][A-Za-z0-9_]*
  15 +string_literal \"[^"\n]*\"
  16 +int_literal -?[0-9]+|-?0x[0-9A-Fa-f]+|-?0o[0-7]+
  17 +float_literal -?[0-9]+\.[0-9]+|-?[0-9]+\.[0-9]+[Ee][-+]?[0-9]+|-?[0-9]+[Ee][-+]?[0-9]+
  18 +
  19 +%%
  20 +
  21 + /* Reserved words */
  22 +"array" { return ARRAY; }
  23 +"bool" { return BOOL; }
  24 +"constraint" { return CONSTRAINT;}
  25 +"false" { return FALSE; }
  26 +"float" { return FLOAT; }
  27 +"int" { return INT; }
  28 +"minimize" { return MINIMIZE; }
  29 +"maximize" { return MAXIMIZE; }
  30 +"of" { return OF; }
  31 +"predicate" { return PREDICATE; }
  32 +"satisfy" { return SATISFY; }
  33 +"set" { return SET; }
  34 +"solve" { return SOLVE; }
  35 +"true" { return TRUE; }
  36 +"var" { return VAR; }
  37 +
  38 +\.\. { return DOTDOT; }
  39 +:: { return COLONCOLON;}
  40 +
  41 + /* Attributed tokens */
  42 +{ident} {
  43 + yylval.string_val = strdup(yytext);
  44 + return IDENT;
  45 + }
  46 +{underscore_ident} {
  47 + yylval.string_val = strdup(yytext);
  48 + return UNDERSCORE_IDENT;
  49 +}
  50 +{string_literal} {
  51 + yylval.string_val = strdup(yytext);
  52 + return STRING_LITERAL;
  53 + }
  54 +{int_literal} {
  55 + /*
  56 + ** atoi() doesn't recognise our hex and octal numbers, so we must
  57 + ** handle them ourselves.
  58 + **
  59 + ** XXX: this code doesn't detect if the integer literals overflow an
  60 + ** 'int'. (In particular, 'atoi' doesn't detect overflow errors,
  61 + ** but 'strtol' does, so that could be used for the decimal integer
  62 + ** case.)
  63 + **
  64 + ** XXX: I think this code will incorrectly parse negative octal and
  65 + ** hexadecimal numbers -- the two conditions will fail due to the
  66 + ** leading '-', so 'atoi' will be invoked, which will fail, and
  67 + ** yylval.int_val will be set to something bogus (probably zero).
  68 + */
  69 + if ('0' == yytext[0] && 'x' == yytext[1]) {
  70 + int i = 2, x = 0;
  71 + while ('\0' != yytext[i]) {
  72 + x *= 16;
  73 + if ('0' <= yytext[i] && yytext[i] <= '9') {
  74 + x += (yytext[i] - '0');
  75 + } else {
  76 + x += (yytext[i] - 'a' + 10);
  77 + }
  78 + i++;
  79 + }
  80 + yylval.int_val = x;
  81 +
  82 + } else if ('0' == yytext[0] && 'o' == yytext[1]) {
  83 + int i = 2, x = 0;
  84 + while ('\0' != yytext[i]) {
  85 + x *= 8;
  86 + x += (yytext[i] - '0');
  87 + i++;
  88 + }
  89 + yylval.int_val = x;
  90 +
  91 + } else {
  92 + yylval.int_val = atoi(yytext);
  93 + }
  94 + return INT_LITERAL;
  95 + }
  96 +{float_literal} {
  97 + yylval.float_val = atof(yytext);
  98 + return FLOAT_LITERAL;
  99 + }
  100 +
  101 + /* Skip newlines, whitespace and comments, return any non-matched
  102 + * character. */
  103 +\n ;
  104 +[ \t] ;
  105 +%.* ;
  106 +. { return yytext[0]; }
  107 +
  108 +%%
  109 +
... ...
fzn-parser/flatzinc.y 0 โ†’ 100644
... ... @@ -0,0 +1,238 @@
  1 +// Parser for FlatZinc 1.1.
  2 +// Authors: Nick Nethercote
  3 +// Julien Fischer
  4 +//
  5 +// NOTE: the parser produced by the following grammar does not ensure
  6 +// that expressions are type correct. Further type-checking after parsing
  7 +// is required for this.
  8 +//
  9 +// This file is in the public domain, and can be used without copyright
  10 +// restrictions.
  11 +
  12 +%{
  13 +#include <stdio.h>
  14 +#include <stdlib.h>
  15 +%}
  16 +
  17 +
  18 +// Possible values for attributed tokens.
  19 +%union {
  20 + char* string_val;
  21 + int int_val;
  22 + double float_val;
  23 +};
  24 +
  25 +// Token kinds
  26 +%token <int_val> INT_LITERAL
  27 + <string_val> STRING_LITERAL IDENT UNDERSCORE_IDENT
  28 + <float_val> FLOAT_LITERAL
  29 + ARRAY BOOL CONSTRAINT FALSE FLOAT INT MAXIMIZE MINIMIZE OF
  30 + PREDICATE SATISFY SET SOLVE TRUE VAR DOTDOT COLONCOLON
  31 +
  32 +%%
  33 +
  34 +//---------------------------------------------------------------------------
  35 +// Model top-level
  36 +//---------------------------------------------------------------------------
  37 +
  38 +// Nb: these rules are left-recursive, which is good for Yacc as they run in
  39 +// constant stack space. Earlier versions were right-recursive, and this
  40 +// caused stack overflows on large models. The error recovery isn't great,
  41 +// but it's better than none.
  42 +
  43 +model : pred_decl_items var_decl_items constraint_items model_end
  44 +
  45 +pred_decl_items : pred_decl_items pred_decl_item ';'
  46 + | pred_decl_items error ';' { yyerrok; }
  47 + | /* empty */
  48 +
  49 +var_decl_items : var_decl_items var_decl_item ';'
  50 + | /* empty */
  51 +
  52 +constraint_items: constraint_items constraint_item ';'
  53 + | /* empty */
  54 +
  55 +model_end : solve_item ';'
  56 +
  57 +
  58 +//---------------------------------------------------------------------------
  59 +// Items
  60 +//---------------------------------------------------------------------------
  61 +
  62 +pred_decl_item:
  63 + PREDICATE IDENT '(' pred_decl_args ')'
  64 +
  65 +var_decl_item:
  66 + VAR non_array_ti_expr_tail ':' ident_anns var_decl_item2
  67 + | non_array_ti_expr_tail ':' ident_anns '=' expr
  68 + | ARRAY '[' INT_LITERAL DOTDOT INT_LITERAL ']' OF array_decl_tail
  69 +
  70 +var_decl_item2:
  71 + '=' expr
  72 + | /*empty*/
  73 +
  74 +array_decl_tail:
  75 + non_array_ti_expr_tail ':' ident_anns '=' array_literal
  76 + | VAR non_array_ti_expr_tail ':' ident_anns array_decl_tail2
  77 +
  78 +array_decl_tail2:
  79 + '=' array_literal
  80 + | /*empty*/
  81 +
  82 +ident_anns:
  83 + IDENT annotations
  84 + | UNDERSCORE_IDENT annotations
  85 +
  86 +constraint_item:
  87 + CONSTRAINT constraint_elem annotations
  88 +
  89 +constraint_elem:
  90 + IDENT '(' exprs ')'
  91 +
  92 +solve_item:
  93 + SOLVE annotations solve_kind
  94 +
  95 +solve_kind:
  96 + SATISFY
  97 + | MINIMIZE expr
  98 + | MAXIMIZE expr
  99 +
  100 +//---------------------------------------------------------------------------
  101 +// Predicate parameters
  102 +//---------------------------------------------------------------------------
  103 +
  104 +pred_decl_args:
  105 + pred_decl_arg "," pred_decl_args
  106 + | pred_decl_arg
  107 +
  108 +pred_decl_arg:
  109 + non_array_ti_expr_tail ':' IDENT
  110 + | VAR non_array_ti_expr_tail ':' IDENT
  111 + | ARRAY '[' pred_arg_array_index ']' OF pred_arg_array_tail ':' IDENT
  112 +
  113 +pred_arg_array_index:
  114 + INT
  115 + | INT_LITERAL DOTDOT INT_LITERAL
  116 +
  117 +pred_arg_array_tail:
  118 + non_array_ti_expr_tail
  119 + | VAR non_array_ti_expr_tail
  120 +
  121 +//---------------------------------------------------------------------------
  122 +// Type-Inst Expression Tails
  123 +//---------------------------------------------------------------------------
  124 +
  125 +non_array_ti_expr_tail:
  126 + scalar_ti_expr_tail
  127 + | set_ti_expr_tail
  128 +
  129 +scalar_ti_expr_tail:
  130 + bool_ti_expr_tail
  131 + | int_ti_expr_tail
  132 + | float_ti_expr_tail
  133 +
  134 +bool_ti_expr_tail:
  135 + BOOL
  136 +
  137 +int_ti_expr_tail:
  138 + INT
  139 + | INT_LITERAL DOTDOT INT_LITERAL
  140 + | '{' int_literals '}'
  141 +
  142 +int_literals:
  143 + INT_LITERAL ',' int_literals
  144 + | INT_LITERAL
  145 +
  146 +float_ti_expr_tail:
  147 + FLOAT
  148 + | FLOAT_LITERAL DOTDOT FLOAT_LITERAL
  149 +
  150 +set_ti_expr_tail:
  151 + SET OF int_ti_expr_tail
  152 +
  153 +//---------------------------------------------------------------------------
  154 +// Expressions
  155 +//---------------------------------------------------------------------------
  156 +
  157 +exprs:
  158 + expr ',' exprs
  159 + | expr
  160 +
  161 +expr:
  162 + bool_literal
  163 + | INT_LITERAL
  164 + | FLOAT_LITERAL
  165 + | STRING_LITERAL
  166 + | set_literal
  167 + | array_literal
  168 + | array_access_expr
  169 + | IDENT
  170 + | UNDERSCORE_IDENT
  171 + | IDENT '(' exprs ')' /* An annotation value with > 0 arguments. */
  172 +
  173 +bool_literal: FALSE | TRUE
  174 +
  175 +set_literal:
  176 + '{' exprs '}'
  177 + | '{' '}'
  178 + | INT_LITERAL DOTDOT INT_LITERAL
  179 +
  180 +array_literal:
  181 + '[' exprs ']'
  182 + | '[' ']'
  183 +
  184 +array_access_expr: IDENT '[' INT_LITERAL ']'
  185 + | UNDERSCORE_IDENT '[' INT_LITERAL ']'
  186 +
  187 +//---------------------------------------------------------------------------
  188 +// Annotations
  189 +//---------------------------------------------------------------------------
  190 +
  191 +annotations:
  192 + COLONCOLON expr annotations
  193 + | /* empty */
  194 +
  195 +%%
  196 +
  197 +#include "lex.yy.c"
  198 +
  199 +char* filename;
  200 +
  201 +int main(int argc, char *argv[])
  202 +{
  203 + if (argc != 2) {
  204 + fprintf(stderr, "Usage: %s <file.fzn>\n", argv[0]);
  205 + exit(1);
  206 + }
  207 +
  208 + filename = argv[1];
  209 + yyin = fopen(filename, "r");
  210 + if (yyin == NULL) {
  211 + fprintf(stderr, "cannot open file: '%s'\n", filename);
  212 + exit(1);
  213 + }
  214 +
  215 + yyparse();
  216 + return 0;
  217 +}
  218 +
  219 +int yyerror(char *s)
  220 +{
  221 + if (0 == strcmp(yytext, "")) {
  222 + fprintf(stderr,
  223 + "%s:%d: %s before end of file\n", filename, yylineno, s);
  224 + } else {
  225 + fprintf(stderr,
  226 + "%s:%d: %s before '%s'\n", filename, yylineno, s, yytext);
  227 + }
  228 + return 0;
  229 +}
  230 +
  231 +/*
  232 +** This is only defined so the Flex library isn't needed.
  233 +*/
  234 +int yywrap()
  235 +{
  236 + return 1;
  237 +}
  238 +
... ...