Commits

Shlomi Fish  committed bed454d

Add the lp_rlp files.

  • Participants
  • Parent commits 4642f01

Comments (0)

Files changed (3)

+rem flex -L -l lp_rlp.l
+flex -L lp_rlp.l
+rem sed -e "s/^#line.*//g" lex.yy.c >lp_rlp.h
+sed -e "s/yy/lp_yy/g" lex.yy.c | sed -e "s/^#line.*//g" >lp_rlp.h
+rem copy lex.yy.c lp_rlp.h
+del lex.yy.c
+
+bison --no-lines -y lp_rlp.y
+sed -e "s/yy/lp_yy/g" y.tab.c >lp_rlp.c
+rem copy y.tab.c lp_rlp.c
+del y.tab.c
+WS1  [ \t]
+WS2  [ \t\r\n]
+LT   [A-Za-z]
+KR   [A-Za-z0-9_\[\]\{\}/.&#$%~'@^]
+DI   [0-9]
+INNM {DI}+
+NM   (({DI}+\.?{DI}*)|(\.{DI}+))([Ee][-+]?{DI}+)?
+VR   {LT}{KR}*(<{KR}+>)?
+OPEQ =
+OPLE [<]=?
+OPGE [>]=?
+EOW  $|[*+-;<=>]|{WS2}+
+INF  {WS2}*[-+][Ii][Nn][Ff]([Ii][Nn][Ii][Tt]([Ee]|[Yy]))?{EOW}
+S_OP [-+ \t\n\r]+
+MIN  [mM][iI][nN]([iI][mM][iI][zZsS][eE])?{WS1}*:
+MAX  [mM][aA][xX]([iI][mM][iI][zZsS][eE])?{WS1}*:
+INT  ^{WS1}*[Ii][Nn][Tt]([Ee][Gg][Ee][Rr])?
+BIN  ^{WS1}*[Bb][Ii][Nn]([Aa][Rr][Yy])?
+SEC  ^{WS1}*([Ss][Ee][Cc])|([Ss][Ee][Mm][Ii]-[Cc][Oo][Nn][Tt][Ii][Nn][Uu][Oo][Uu][Ss])|([Ss][Ee][Mm][Ii])|([Ss][Ee][Mm][Ii][Ss])
+SOS  ^{WS1}*([Ss][Oo][Ss][12]*)|([Ss][Ee][Tt][Ss])
+FREE ^{WS1}*[Ff][Rr][Ee][Ee]
+LBL  {VR}{WS1}*:
+SOSD {LBL}:
+
+/*
+   made reentrant with help of
+   http://www.usualcoding.eu/post/2007/09/03/Building-a-reentrant-parser-in-C-with-Flex/Bison
+*/
+
+/*
+   Note that a minimum version of flex is needed to be able to compile this.
+   Older version don't know the reentrant code.
+   Version 2.5.4 is not enough. Probably at least v2.5.31 is needed. Tested with v2.5.35
+*/
+
+/*
+** We want the scanner to be reentrant, therefore generate no global variables.
+** That what the 'reentrant' option is for.
+** 'bison-bridge' is used to create a bison compatible scanner and share yylval
+*/
+
+%option reentrant bison-bridge
+%option noyywrap
+%option yylineno
+
+%start COMMENT
+%start LINECOMMENT
+
+%%
+<INITIAL>"/*" {
+  BEGIN COMMENT;
+} /* begin skip comment */
+
+<COMMENT>"*/" {
+  BEGIN INITIAL;
+} /* end skip comment */
+
+<COMMENT>. {
+}
+
+<COMMENT>\n {
+}
+
+<COMMENT>\r {
+}
+
+<INITIAL>"//" {
+  BEGIN LINECOMMENT;
+} /* begin skip LINECOMMENT */
+
+<LINECOMMENT>\n {
+  BEGIN INITIAL;
+} /* end skip LINECOMMENT */
+
+<LINECOMMENT>\r {
+  BEGIN INITIAL;
+} /* end skip LINECOMMENT */
+
+<LINECOMMENT>. {
+}
+
+<INITIAL>{WS2}+ {
+}
+
+<INITIAL>"," {
+  parse_parm *pp = PARM;
+
+  pp->lineno = yylineno;
+  return(COMMA);
+}
+
+<INITIAL>{MIN} {
+  parse_parm *pp = PARM;
+
+  pp->lineno = yylineno;
+  return(MINIMISE);
+}
+
+<INITIAL>{MAX} {
+  parse_parm *pp = PARM;
+
+  pp->lineno = yylineno;
+  return(MAXIMISE);
+}
+
+<INITIAL>{INNM} {
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pp->lineno = yylineno;
+  pv->f = atof((char *)yytext);
+  return(INTCONS);
+} /* f contains the last float */
+
+<INITIAL>{NM} {
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pp->lineno = yylineno;
+  pv->f = atof((char *)yytext);
+  return(CONS);
+} /* f contains the last float */
+
+<INITIAL>{INF} {
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+  char *ptr, c;
+
+  pp->lineno = yylineno;
+  pv->f = DEF_INFINITE;
+  pv->Sign = 0;
+  ptr = (char *)yytext;
+  while (isspace(*ptr)) ptr++;
+  if(*ptr == '-')
+    pv->Sign = 1;
+  if(yyleng > 0) {
+    c = yytext[yyleng - 1];
+    if(!isalnum(c))
+      unput(c);
+  }
+  return(INF);
+} /* f contains the last float */
+
+<INITIAL>{S_OP} {
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+  int x;
+
+  pp->lineno = yylineno;
+  pv->Sign = 0;
+  for(x = 0; x < yyleng; x++)
+    if(yytext[x] == '-' || yytext[x] == '+')
+      pv->Sign = (pv->Sign == (yytext[x] == '+'));
+  return (TOK_SIGN);
+  /* Sign is TRUE if the sign-string
+     represents a '-'. Otherwise Sign
+     is FALSE */
+}
+
+<INITIAL>{INT} {
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pp->lineno = yylineno;
+  if((!pv->Within_int_decl) && (!pv->Within_sec_decl) && (!pv->Within_sos_decl) && (!pv->Within_free_decl)) {
+    pv->Within_int_decl = 1;
+    pv->Within_sos_decl1 = FALSE;
+  }
+  return(SEC_INT);
+}
+
+<INITIAL>{BIN} {
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pp->lineno = yylineno;
+  if((!pv->Within_int_decl) && (!pv->Within_sec_decl) && (!pv->Within_sos_decl) && (!pv->Within_free_decl)) {
+    pv->Within_int_decl = 2;
+    pv->Within_sos_decl1 = FALSE;
+  }
+  return(SEC_BIN);
+}
+
+<INITIAL>{SEC} {
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pp->lineno = yylineno;
+  if((!pv->Within_int_decl) && (!pv->Within_sec_decl) && (!pv->Within_sos_decl) && (!pv->Within_free_decl)) {
+    pv->Within_sec_decl = TRUE;
+    pv->Within_sos_decl1 = FALSE;
+  }
+  return(SEC_SEC);
+}
+
+<INITIAL>{SOS} {
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pp->lineno = yylineno;
+  if(!pv->Within_sos_decl)
+    pv->SOStype0 = (short)atoi(((char *)yytext) + 3);
+  if((!pv->Within_int_decl) && (!pv->Within_sec_decl) && (!pv->Within_sos_decl) && (!pv->Within_free_decl))
+    pv->Within_sos_decl = TRUE;
+  return(SEC_SOS);
+}
+
+<INITIAL>{SOSD} {
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pp->lineno = yylineno;
+  FREE(pv->Last_var);
+  pv->Last_var = strdup((char *)yytext);
+  pv->Last_var[strlen(pv->Last_var) - 2] = 0;
+  return(SOSDESCR);
+}
+
+<INITIAL>{FREE} {
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pp->lineno = yylineno;
+  if((!pv->Within_int_decl) && (!pv->Within_sec_decl) && (!pv->Within_sos_decl) && (!pv->Within_free_decl)) {
+    pv->Within_free_decl = TRUE;
+    pv->Within_sos_decl1 = FALSE;
+  }
+  return(SEC_FREE);
+}
+
+<INITIAL>{LBL} {
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+  char *ptr;
+
+  pp->lineno = yylineno;
+  FREE(pv->Last_var);
+  pv->Last_var = strdup((char *)yytext);
+  ptr = pv->Last_var + strlen(pv->Last_var);
+  ptr[-1] = ' ';
+  while ((--ptr >= pv->Last_var) && (isspace(*ptr)))
+    *ptr = 0;
+  return(VARIABLECOLON);
+}
+
+<INITIAL>{VR} {
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pp->lineno = yylineno;
+  FREE(pv->Last_var);
+  pv->Last_var = strdup((char *)yytext);
+  return(VAR);
+}
+
+<INITIAL>":" {
+  parse_parm *pp = PARM;
+
+  pp->lineno = yylineno;
+  return (COLON);
+}
+
+<INITIAL>"*" {
+  parse_parm *pp = PARM;
+
+  pp->lineno = yylineno;
+  return(AR_M_OP);
+}
+
+<INITIAL>{OPEQ} {
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pp->lineno = yylineno;
+  pv->OP = *yytext;
+  return(RE_OPEQ);
+}
+
+<INITIAL>{OPLE} {
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pp->lineno = yylineno;
+  pv->OP = *yytext;
+  return(RE_OPLE);
+}
+
+<INITIAL>{OPGE} {
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pp->lineno = yylineno;
+  pv->OP = *yytext;
+  return(RE_OPGE);
+}
+
+<INITIAL>";" {
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pp->lineno = yylineno;
+  pv->Within_int_decl = pv->Within_sec_decl = pv->Within_sos_decl = pv->Within_free_decl = FALSE;
+  check_int_sec_sos_free_decl(pp, (int) pv->Within_int_decl, (int) pv->Within_sec_decl, (int) pv->Within_sos_decl, (int) pv->Within_free_decl);
+  return(END_C);
+}
+
+<INITIAL>. {
+  parse_parm *pp = PARM;
+
+  pp->lineno = yylineno;
+  report(NULL, CRITICAL, "LEX ERROR : %s lineno %d\n", yytext, yylineno);
+  return(UNDEFINED);
+}
+
+%%
+/* ========================================================================= */
+/* NAME  : lp_rlp.y                                                          */
+/* ========================================================================= */
+
+/*
+   made reentrant with help of
+   http://www.usualcoding.eu/post/2007/09/03/Building-a-reentrant-parser-in-C-with-Flex/Bison
+*/
+
+/*
+   Note that a minimum version of bison is needed to be able to compile this.
+   Older version don't know the reentrant code.
+   Version 1.35 is not enough. v1.875 could be ok. Tested with v2.3
+*/
+
+%pure-parser
+%parse-param {parse_parm *parm}
+%parse-param {void *scanner}
+%lex-param {yyscan_t *scanner}
+
+%token VAR CONS INTCONS VARIABLECOLON INF SEC_INT SEC_BIN SEC_SEC SEC_SOS SOSDESCR SEC_FREE TOK_SIGN AR_M_OP RE_OPEQ RE_OPLE RE_OPGE END_C COMMA COLON MINIMISE MAXIMISE UNDEFINED
+
+
+%{
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#define scanner yyscanner
+#define PARM yyget_extra(yyscanner)
+#define YYSTYPE int
+#define YY_EXTRA_TYPE parse_parm *
+#define YY_FATAL_ERROR(msg) lex_fatal_error(PARM, yyscanner, msg)
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result = lp_input((void *) PARM, buf, max_size);
+#define yyerror read_error
+
+#include "lpkit.h"
+#include "yacc_read.h"
+
+typedef struct parse_vars_s
+{
+  read_modeldata_func *lp_input;
+  void *userhandle;
+  char HadVar, HadVar0, HadVar1, HadVar2, HasAR_M_OP, HadConstraint, Had_lineair_sum, Had_lineair_sum0, do_add_row, HadSign, OP, Sign, isign, isign0, make_neg;
+  char state, state0;
+  char Within_int_decl;  /* TRUE when we are within an char declaration */
+  char Within_bin_decl;  /* TRUE when we are within an bin declaration */
+  char Within_sec_decl;  /* TRUE when we are within a sec declaration */
+  char Within_sos_decl;  /* TRUE when we are within a sos declaration */
+  char Within_sos_decl1;
+  char Within_free_decl; /* TRUE when we are within a free declaration */
+  short SOStype, SOStype0;        /* SOS type */
+  int SOSNr;
+  int SOSweight;         /* SOS weight */
+  char *Last_var, *Last_var0;
+  REAL f, f0, f1;
+} parse_vars;
+
+#ifdef FORTIFY
+# include "lp_fortify.h"
+#endif
+
+/* let's please C++ users */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined MSDOS || defined __MSDOS__ || defined WINDOWS || defined _WINDOWS || defined WIN32 || defined _WIN32
+#define YY_NO_UNISTD_H
+
+static int isatty(int f)
+{
+  return(FALSE);
+}
+
+#if !defined _STDLIB_H
+# define _STDLIB_H
+#endif
+#endif
+
+static int __WINAPI lp_input_yyin(void *fpin, char *buf, int max_size)
+{
+  int result;
+
+  result = fread( (char*)buf, sizeof(char), max_size, (FILE *)fpin);
+
+  return(result);
+}
+
+static int __WINAPI lp_input(void *vpp, char *buf, int max_size)
+{
+  parse_parm *pp = (parse_parm *) vpp;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+  int result;
+
+  result = pv->lp_input(pv->userhandle, buf, max_size);
+  if (result < 0)
+    lex_fatal_error(pp, pp->scanner, "read() in flex scanner failed");
+  return(result);
+}
+
+#ifdef __cplusplus
+};
+#endif
+
+#include "lp_rlp.h"
+
+#undef yylval
+
+%}
+
+%start inputfile
+%%
+
+EMPTY: /* EMPTY */
+                ;
+
+inputfile       :
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pv->isign = 0;
+  pv->make_neg = 0;
+  pv->Sign = 0;
+  pv->HadConstraint = FALSE;
+  pv->HadVar = pv->HadVar0 = FALSE;
+}
+                  objective_function
+                  constraints
+                  int_bin_sec_sos_free_declarations
+                ;
+
+/* start objective_function */
+
+/*
+
+ objective_function: MAXIMISE real_of | MINIMISE real_of | real_of;
+ real_of:            lineair_sum END_C;
+ lineair_sum:        EMPTY | x_lineair_sum;
+
+*/
+
+objective_function:   MAXIMISE real_of
+{
+  set_obj_dir(PARM, TRUE);
+}
+                    | MINIMISE real_of
+{
+  set_obj_dir(PARM, FALSE);
+}
+                    | real_of
+                ;
+
+real_of:            lineair_sum
+                    END_C
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  add_row(pp);
+  pv->HadConstraint = FALSE;
+  pv->HadVar = pv->HadVar0 = FALSE;
+  pv->isign = 0;
+  pv->make_neg = 0;
+}
+                ;
+
+lineair_sum:          EMPTY
+                    | x_lineair_sum
+                ;
+
+/* end objective_function */
+
+
+
+/* start constraints */
+
+/*
+
+ constraints:        EMPTY | x_constraints;
+ x_constraints:      constraint | x_constraints constraint;
+ constraint:         real_constraint | VARIABLECOLON real_constraint;
+ real_constraint:    x_lineair_sum2 RE_OP x_lineair_sum3 optionalrange END_C;
+ optionalrange:      EMPTY | RE_OP cons_term RHS_STORE;
+ RE_OP:              RE_OPEQ | RE_OPLE | RE_OPGE;
+ cons_term:          x_SIGN REALCONS | INF;
+ x_lineair_sum2:     EMPTY | x_lineair_sum3;
+ x_lineair_sum3:     x_lineair_sum | INF RHS_STORE;
+ x_lineair_sum:      x_lineair_sum1;
+ x_lineair_sum1:     x_lineair_term | x_lineair_sum1 x_lineair_term;
+ x_lineair_term:     x_SIGN x_lineair_term1;
+ x_lineair_term1:    REALCONS | optional_AR_M_OP VAR;
+ x_SIGN:             EMPTY | TOK_SIGN;
+ REALCONS:           INTCONS | CONS;
+ optional_AR_M_OP:   EMPTY | AR_M_OP;
+
+*/
+
+constraints:      EMPTY
+                | x_constraints
+                ;
+
+x_constraints   : constraint
+                | x_constraints
+                  constraint
+                ;
+
+constraint      : real_constraint
+                | VARIABLECOLON
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  if(!add_constraint_name(pp, pv->Last_var))
+    YYABORT;
+  pv->HadConstraint = TRUE;
+}
+                  real_constraint
+                ;
+
+real_constraint : x_lineair_sum2
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pv->HadVar1 = pv->HadVar0;
+  pv->HadVar0 = FALSE;
+}
+                  RE_OP
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  if(!store_re_op(pp, pv->OP, (int) pv->HadConstraint, (int) pv->HadVar, (int) pv->Had_lineair_sum))
+    YYABORT;
+  pv->make_neg = 1;
+  pv->f1 = 0;
+}
+                  x_lineair_sum3
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pv->Had_lineair_sum0 = pv->Had_lineair_sum;
+  pv->Had_lineair_sum = TRUE;
+  pv->HadVar2 = pv->HadVar0;
+  pv->HadVar0 = FALSE;
+  pv->do_add_row = FALSE;
+  if(pv->HadConstraint && !pv->HadVar ) {
+    /* it is a range */
+    /* already handled */
+  }
+  else if(!pv->HadConstraint && pv->HadVar) {
+    /* it is a bound */
+
+    if(!store_bounds(pp, TRUE))
+      YYABORT;
+  }
+  else {
+    /* it is a row restriction */
+    if(pv->HadConstraint && pv->HadVar)
+      store_re_op(pp, '\0', (int) pv->HadConstraint, (int) pv->HadVar, (int) pv->Had_lineair_sum); /* makes sure that data stored in temporary buffers is treated correctly */
+    pv->do_add_row = TRUE;
+  }
+}
+                  optionalrange
+                  END_C
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  if((!pv->HadVar) && (!pv->HadConstraint)) {
+    yyerror(pp, pp->scanner, "parse error");
+    YYABORT;
+  }
+  if(pv->do_add_row)
+    add_row(pp);
+  pv->HadConstraint = FALSE;
+  pv->HadVar = pv->HadVar0 = FALSE;
+  pv->isign = 0;
+  pv->make_neg = 0;
+  null_tmp_store(pp, TRUE);
+}
+                ;
+
+optionalrange:    EMPTY
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  if((!pv->HadVar1) && (pv->Had_lineair_sum0))
+    if(!negate_constraint(pp))
+      YYABORT;
+}
+                | RE_OP
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pv->make_neg = 0;
+  pv->isign = 0;
+  if(pv->HadConstraint)
+    pv->HadVar = pv->Had_lineair_sum = FALSE;
+  pv->HadVar0 = FALSE;
+  if(!store_re_op(pp, (char) ((pv->OP == '<') ? '>' : (pv->OP == '>') ? '<' : pv->OP), (int) pv->HadConstraint, (int) pv->HadVar, (int) pv->Had_lineair_sum))
+    YYABORT;
+}
+                  cons_term
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pv->f -= pv->f1;
+}
+                  RHS_STORE
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  if((pv->HadVar1) || (!pv->HadVar2) || (pv->HadVar0)) {
+    yyerror(pp, pp->scanner, "parse error");
+    YYABORT;
+  }
+
+  if(pv->HadConstraint && !pv->HadVar ) {
+    /* it is a range */
+    /* already handled */
+    if(!negate_constraint(pp))
+      YYABORT;
+  }
+  else if(!pv->HadConstraint && pv->HadVar) {
+    /* it is a bound */
+
+    if(!store_bounds(pp, TRUE))
+      YYABORT;
+  }
+}
+                ;
+
+x_lineair_sum2:   EMPTY
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  /* to allow a range */
+  /* constraint: < max */
+  if(!pv->HadConstraint) {
+    yyerror(pp, pp->scanner, "parse error");
+    YYABORT;
+  }
+  pv->Had_lineair_sum = FALSE;
+}
+                | x_lineair_sum3
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pv->Had_lineair_sum = TRUE;
+}
+                ;
+
+x_lineair_sum3  :  x_lineair_sum
+                | INF
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pv->isign = pv->Sign;
+}
+                  RHS_STORE
+                ;
+
+x_lineair_sum:
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pv->state = pv->state0 = 0;
+}
+                x_lineair_sum1
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  if (pv->state == 1) {
+    /* RHS_STORE */
+    if (    (pv->isign0 || !pv->make_neg)
+        && !(pv->isign0 && !pv->make_neg)) /* but not both! */
+      pv->f0 = -pv->f0;
+    if(pv->make_neg)
+      pv->f1 += pv->f0;
+    if(!rhs_store(pp, pv->f0, (int) pv->HadConstraint, (int) pv->HadVar, (int) pv->Had_lineair_sum))
+      YYABORT;
+  }
+}
+                ;
+
+x_lineair_sum1  : x_lineair_term
+                | x_lineair_sum1
+                  x_lineair_term
+                ;
+
+x_lineair_term  : x_SIGN
+                  x_lineair_term1
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  if ((pv->HadSign || pv->state == 1) && (pv->state0 == 1)) {
+    /* RHS_STORE */
+    if (    (pv->isign0 || !pv->make_neg)
+        && !(pv->isign0 && !pv->make_neg)) /* but not both! */
+      pv->f0 = -pv->f0;
+    if(pv->make_neg)
+      pv->f1 += pv->f0;
+    if(!rhs_store(pp, pv->f0, (int) pv->HadConstraint, (int) pv->HadVar, (int) pv->Had_lineair_sum))
+      YYABORT;
+  }
+  if (pv->state == 1) {
+    pv->f0 = pv->f;
+    pv->isign0 = pv->isign;
+  }
+  if (pv->state == 2) {
+    if((pv->HadSign) || (pv->state0 != 1)) {
+     pv->isign0 = pv->isign;
+     pv->f0 = 1.0;
+    }
+    if (    (pv->isign0 || pv->make_neg)
+        && !(pv->isign0 && pv->make_neg)) /* but not both! */
+      pv->f0 = -pv->f0;
+    if(!var_store(pp, pv->Last_var, pv->f0, (int) pv->HadConstraint, (int) pv->HadVar, (int) pv->Had_lineair_sum)) {
+      yyerror(pp, pp->scanner, "var_store failed");
+      YYABORT;
+    }
+    pv->HadConstraint |= pv->HadVar;
+    pv->HadVar = pv->HadVar0 = TRUE;
+  }
+  pv->state0 = pv->state;
+}
+                ;
+
+x_lineair_term1 : REALCONS
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pv->state = 1;
+}
+                | optional_AR_M_OP
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  if ((pv->HasAR_M_OP) && (pv->state != 1)) {
+    yyerror(pp, pp->scanner, "parse error");
+    YYABORT;
+  }
+}
+                  VAR
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pv->state = 2;
+}
+                ;
+
+RE_OP: RE_OPEQ | RE_OPLE | RE_OPGE
+                ;
+
+cons_term:        x_SIGN
+                  REALCONS
+                | INF
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pv->isign = pv->Sign;
+}
+                ;
+
+/* end constraints */
+
+
+/* start common for objective & constraints */
+
+REALCONS: INTCONS | CONS
+                ;
+
+x_SIGN:           EMPTY
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pv->isign = 0;
+  pv->HadSign = FALSE;
+}
+                | TOK_SIGN
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pv->isign = pv->Sign;
+  pv->HadSign = TRUE;
+}
+                ;
+
+optional_AR_M_OP: EMPTY
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pv->HasAR_M_OP = FALSE;
+}
+                | AR_M_OP
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pv->HasAR_M_OP = TRUE;
+}
+                ;
+
+RHS_STORE:        EMPTY
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  if (    (pv->isign || !pv->make_neg)
+      && !(pv->isign && !pv->make_neg)) /* but not both! */
+    pv->f = -pv->f;
+  if(!rhs_store(pp, pv->f, (int) pv->HadConstraint, (int) pv->HadVar, (int) pv->Had_lineair_sum))
+    YYABORT;
+  pv->isign = 0;
+}
+                ;
+
+/* end common for objective & constraints */
+
+
+
+/* start int_bin_sec_sos_free_declarations */
+
+int_bin_sec_sos_free_declarations:
+                  EMPTY
+                | real_int_bin_sec_sos_free_decls
+                ;
+
+real_int_bin_sec_sos_free_decls: int_bin_sec_sos_free_declaration
+                | real_int_bin_sec_sos_free_decls int_bin_sec_sos_free_declaration
+                ;
+
+SEC_INT_BIN_SEC_SOS_FREE: SEC_INT | SEC_BIN | SEC_SEC | SEC_SOS | SEC_FREE
+                ;
+
+int_bin_sec_sos_free_declaration:
+                  SEC_INT_BIN_SEC_SOS_FREE
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  pv->Within_sos_decl1 = pv->Within_sos_decl;
+}
+                  x_int_bin_sec_sos_free_declaration
+                ;
+
+xx_int_bin_sec_sos_free_declaration:
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  if((!pv->Within_int_decl) && (!pv->Within_sec_decl) && (!pv->Within_sos_decl1) && (!pv->Within_free_decl)) {
+    yyerror(pp, pp->scanner, "parse error");
+    YYABORT;
+  }
+  pv->SOStype = pv->SOStype0;
+  check_int_sec_sos_free_decl(pp, (int) pv->Within_int_decl, (int) pv->Within_sec_decl, (int) (pv->Within_sos_decl1 = (pv->Within_sos_decl1 ? 1 : 0)), (int) pv->Within_free_decl);
+}
+                  optionalsos
+                  vars
+                  optionalsostype
+                  END_C
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  if((pv->Within_sos_decl1) && (pv->SOStype == 0))
+  {
+    yyerror(pp, pp->scanner, "Unsupported SOS type (0)");
+    YYABORT;
+  }
+}
+                ;
+
+x_int_bin_sec_sos_free_declaration:
+                  xx_int_bin_sec_sos_free_declaration
+                | x_int_bin_sec_sos_free_declaration xx_int_bin_sec_sos_free_declaration
+                ;
+
+optionalsos:      EMPTY
+                | SOSDESCR
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  FREE(pv->Last_var0);
+  pv->Last_var0 = strdup(pv->Last_var);
+}
+                  sosdescr
+                ;
+
+optionalsostype:  EMPTY
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  if(pv->Within_sos_decl1) {
+    set_sos_type(pp, pv->SOStype);
+    set_sos_weight(pp, (double) pv->SOSweight, 1);
+  }
+}
+                | RE_OPLE
+                  INTCONS
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  if((pv->Within_sos_decl1) && (!pv->SOStype))
+  {
+    set_sos_type(pp, pv->SOStype = (short) (pv->f + .1));
+  }
+  else
+  {
+    yyerror(pp, pp->scanner, "SOS type not expected");
+    YYABORT;
+  }
+}
+                optionalSOSweight
+                ;
+
+optionalSOSweight:EMPTY
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  set_sos_weight(pp, (double) pv->SOSweight, 1);
+}
+                | COLON
+                  INTCONS
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  set_sos_weight(pp, pv->f, 1);
+}
+                ;
+
+vars:             EMPTY
+                | x_vars
+                ;
+
+x_vars          : onevarwithoptionalweight
+                | x_vars
+                  optionalcomma
+                  onevarwithoptionalweight
+                ;
+
+optionalcomma:    EMPTY
+                | COMMA
+                ;
+
+variable:         EMPTY
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  if(pv->Within_sos_decl1 == 1)
+  {
+    char buf[16];
+
+    pv->SOSweight++;
+    sprintf(buf, "SOS%d", pv->SOSweight);
+    storevarandweight(pp, buf);
+
+    check_int_sec_sos_free_decl(pp, (int) pv->Within_int_decl, (int) pv->Within_sec_decl, 2, (int) pv->Within_free_decl);
+    pv->Within_sos_decl1 = 2;
+    pv->SOSNr = 0;
+  }
+
+  storevarandweight(pp, pv->Last_var);
+
+  if(pv->Within_sos_decl1 == 2)
+  {
+    pv->SOSNr++;
+    set_sos_weight(pp, (double) pv->SOSNr, 2);
+  }
+}
+                ;
+
+variablecolon:
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  if(!pv->Within_sos_decl1) {
+    yyerror(pp, pp->scanner, "parse error");
+    YYABORT;
+  }
+  if(pv->Within_sos_decl1 == 1) {
+    FREE(pv->Last_var0);
+    pv->Last_var0 = strdup(pv->Last_var);
+  }
+  if(pv->Within_sos_decl1 == 2)
+  {
+    storevarandweight(pp, pv->Last_var);
+    pv->SOSNr++;
+    set_sos_weight(pp, (double) pv->SOSNr, 2);
+  }
+}
+                ;
+
+sosweight:        EMPTY
+{
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  if(pv->Within_sos_decl1 == 1)
+  {
+    char buf[16];
+
+    pv->SOSweight++;
+    sprintf(buf, "SOS%d", pv->SOSweight);
+    storevarandweight(pp, buf);
+
+    check_int_sec_sos_free_decl(pp, (int) pv->Within_int_decl, (int) pv->Within_sec_decl, 2, (int) pv->Within_free_decl);
+    pv->Within_sos_decl1 = 2;
+    pv->SOSNr = 0;
+
+    storevarandweight(pp, pv->Last_var0);
+    pv->SOSNr++;
+  }
+
+  set_sos_weight(pp, pv->f, 2);
+}
+                ;
+
+sosdescr:         EMPTY
+{ /* SOS name */
+  parse_parm *pp = PARM;
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+  if(pv->Within_sos_decl1 == 1)
+  {
+    parse_parm *pp = PARM;
+    parse_vars *pv = (parse_vars *) pp->parse_vars;
+
+    storevarandweight(pp, pv->Last_var0);
+    set_sos_type(pp, pv->SOStype);
+    check_int_sec_sos_free_decl(pp, (int) pv->Within_int_decl, (int) pv->Within_sec_decl, 2, (int) pv->Within_free_decl);
+    pv->Within_sos_decl1 = 2;
+    pv->SOSNr = 0;
+    pv->SOSweight++;
+  }
+}
+                ;
+
+onevarwithoptionalweight:
+                  VAR
+                  variable
+                | VARIABLECOLON
+                  variablecolon
+                  INTCONSorVARIABLE
+                ;
+
+INTCONSorVARIABLE:REALCONS /* INTCONS */
+                  sosweight
+                | sosdescr
+                  x_onevarwithoptionalweight
+                ;
+
+x_onevarwithoptionalweight:
+                  VAR
+                  variable
+                | VARIABLECOLON
+                  variablecolon
+                  REALCONS /* INTCONS */
+                  sosweight
+                ;
+
+/* end int_bin_sec_sos_free_declarations */
+
+%%
+
+static void yy_delete_allocated_memory(parse_parm *pp)
+{
+  parse_vars *pv = (parse_vars *) pp->parse_vars;
+  /* free memory allocated by flex. Otherwise some memory is not freed.
+     This is a bit tricky. There is not much documentation about this, but a lot of
+     reports of memory that keeps allocated */
+
+  /* If you get errors on this function call, just comment it. This will only result
+     in some memory that is not being freed. */
+
+# if defined YY_CURRENT_BUFFER
+    /* flex defines the macro YY_CURRENT_BUFFER, so you should only get here if lp_rlp.h is
+       generated by flex */
+    /* lex doesn't define this macro and thus should not come here, but lex doesn't has
+       this memory leak also ...*/
+
+#  if 0
+    /* older versions of flex */
+    yy_delete_buffer(YY_CURRENT_BUFFER); /* comment this line if you have problems with it */
+    yy_init = 1; /* make sure that the next time memory is allocated again */
+    yy_start = 0;
+#  else
+    /* As of version 2.5.9 Flex  */
+    yylex_destroy(pp->scanner); /* comment this line if you have problems with it */
+#  endif
+# endif
+
+  FREE(pv->Last_var);
+  FREE(pv->Last_var0);
+}
+
+static int parse(parse_parm *pp)
+{
+  return(yyparse(pp, pp->scanner));
+}
+
+lprec *read_lp1(lprec *lp, void *userhandle, read_modeldata_func read_modeldata, int verbose, char *lp_name)
+{
+  parse_vars *pv;
+  lprec *lp1 = NULL;
+
+  CALLOC(pv, 1, parse_vars);
+  if (pv != NULL) {
+    parse_parm pp;
+
+    memset(&pp, 0, sizeof(pp));
+    pp.parse_vars = (void *) pv;
+
+    yylex_init(&pp.scanner);
+    yyset_extra(&pp, pp.scanner);
+
+    yyset_in((FILE *) userhandle, pp.scanner);
+    yyset_out(NULL, pp.scanner);
+    pv->lp_input = read_modeldata;
+    pv->userhandle = userhandle;
+    lp1 = yacc_read(lp, verbose, lp_name, parse, &pp, yy_delete_allocated_memory);
+    FREE(pv);
+  }
+  return(lp1);
+}
+
+lprec * __WINAPI read_lp(FILE *filename, int verbose, char *lp_name)
+{
+  return(read_lp1(NULL, filename, lp_input_yyin, verbose, lp_name));
+}
+
+lprec * __WINAPI read_lpex(void *userhandle, read_modeldata_func read_modeldata, int verbose, char *lp_name)
+{
+  return(read_lp1(NULL, userhandle, read_modeldata, verbose, lp_name));
+}
+
+lprec *read_LP1(lprec *lp, char *filename, int verbose, char *lp_name)
+{
+  FILE *fpin;
+
+  if((fpin = fopen(filename, "r")) != NULL) {
+    lp = read_lp1(lp, fpin, lp_input_yyin, verbose, lp_name);
+    fclose(fpin);
+  }
+  else
+    lp = NULL;
+  return(lp);
+}
+
+lprec * __WINAPI read_LP(char *filename, int verbose, char *lp_name)
+{
+  return(read_LP1(NULL, filename, verbose, lp_name));
+}
+
+MYBOOL __WINAPI LP_readhandle(lprec **lp, FILE *filename, int verbose, char *lp_name)
+{
+  if(lp != NULL)
+    *lp = read_lp1(*lp, filename, lp_input_yyin, verbose, lp_name);
+
+  return((lp != NULL) && (*lp != NULL));
+}