PIPS
sc_gram.y
Go to the documentation of this file.
1 /*
2 
3  $Id: sc_gram.y 1647 2016-07-01 11:57:57Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of Linear/C3 Library.
8 
9  Linear/C3 Library is free software: you can redistribute it and/or modify it
10  under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  Linear/C3 Library is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with Linear/C3 Library. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 
25 
26 %{
27 
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31 
32 #include "boolean.h"
33 #include "arithmetique.h"
34 #include "vecteur.h"
35 #include "contrainte.h"
36 #include "sc.h"
37 
38 extern int syst_error(char*);
39 extern int syst_lex(void);
40 
41 bool syst_syntax_error;
42 
43 Psysteme ps_yacc;
44 
45 Value fac; /* facteur multiplicatif suivant qu'on analyse un terme*/
46  /* introduit par un moins (-1) ou par un plus (1) */
47 
48 int sens; /* indique le sens de l'inegalite
49  sens = -1 ==> l'operateur est soit > ,soit >=,
50  sens = 1 ==> l'operateur est soit <, soit <= */
51 short int cote; /* booleen indiquant quel membre est en cours d'analyse*/
52 
53 Value b1, b2; /* element du vecteur colonne du systeme donne par l'analyse*/
54  /* d'une contrainte */
55 
56 Pcontrainte eq; /* pointeur sur l'egalite ou l'inegalite
57  courante */
58 
59 extern Pvecteur cp ; /* pointeur sur le membre courant */
60 
61 short int operat; /* dernier operateur rencontre */
62 
63 
64 /*code des operateurs de comparaison */
65 
66 #define OPINF 1
67 #define OPINFEGAL 2
68 #define OPEGAL 3
69 #define OPSUPEGAL 4
70 #define OPSUP 5
71 #define DROIT 1
72 #define GAUCHE 2
73 /* #define NULL 0 */
74 %}
75 
76 %union {
77  Value Value;
78  Variable Variable;
79 }
80 
81 /* explicit types: Value may be larger than a pointer (e.g. long long)
82  */
83 %type <Value> const
84 %type <Variable> ident
85 
86 %token ACCFERM /* accolade fermante */
87 %token ACCOUVR /* accolade ouvrante */
88 %term <Value> CONSTANTE /* constante entiere sans signe */
89 %token EGAL /* signe == */
90 %term <Variable> IDENT /* identificateur de variable */
91 %token INF /* signe < */
92 %token INFEGAL /* signe <= */
93 %token MOINS /* signe - */
94 %token PLUS /* signe + */
95 %token SUP /* signe > */
96 %token SUPEGAL /* signe >= */
97 %token VAR /* mot reserve VAR introduisant la liste de variables */
98 %token VIRG /* signe , */
99 
100 
101 %%
102 system : inisys defvar ACCOUVR l_eq virg_opt ACCFERM
103  ;
104 
105 inisys :
106  { /* initialisation des parametres du systeme */
107  /* et initialisation des variables */
108  ps_yacc = sc_new();
109  init_globals();
110  syst_syntax_error = false;
111  }
112  ;
113 
114 defvar : VAR l_var
115  { /* remise en ordre des vecteurs de base */
116  Pbase b;
117  b = ps_yacc->base;
118  ps_yacc->base = base_reversal(b);
119  vect_rm(b);
120  }
121  ;
122 
123 l_var : newid
124  | l_var virg_opt newid
125  ;
126 
127 l_eq : eq
128  | l_eq VIRG eq
129  |
130  ;
131 
132 eq : debeq multi_membre op membre fin_mult_membre feq
133  ;
134 
135 debeq :
136  {
137  fac = VALUE_ONE;
138  sens = 1;
139  cote = GAUCHE;
140  b1 = 0;
141  b2 = 0;
142  operat = 0;
143  cp = NULL;
144  eq = contrainte_new();
145  }
146  ;
147 
148 feq :{
149 
150  contrainte_free(eq);
151  }
152  ;
153 
154 membre : addop terme
155  | { fac = VALUE_ONE;} terme
156  | membre addop terme
157  ;
158 
159 terme : const ident
160  {
161  if (cote==DROIT) fac = value_uminus(fac);
162  /* ajout du couple (ident,const) a la contrainte courante */
163  vect_add_elem(&(eq->vecteur),$2,value_mult(fac,$1));
164  /* duplication du couple (ident,const)
165  de la combinaison lineaire traitee */
166  if (operat)
167  vect_add_elem(&cp,(Variable) $2,
168  value_uminus(value_mult(fac,$1)));
169  }
170  | const
171  {
172  Value p = value_mult(fac,$1);
173  if (cote==DROIT) {
174  value_addto(b1, p);
175  value_substract(b2, p);
176  } else {
177  value_substract(b1, p);
178  value_addto(b2, p);
179  }
180  }
181  | ident
182  {
183  if (cote==DROIT) fac = value_uminus(fac);
184  /* ajout du couple (ident,1) a la contrainte courante */
185  vect_add_elem (&(eq->vecteur),(Variable) $1,fac);
186  /* duplication du couple (ident,1) de la
187  combinaison lineaire traitee */
188  if (operat)
189  vect_add_elem(&cp,(Variable) $1,value_uminus(fac));
190  }
191  ;
192 
193 ident : IDENT { $$ = rec_ident(ps_yacc, $1); }
194  ;
195 
196 newid : IDENT { new_ident(ps_yacc,$1); }
197  ;
198 
199 /* I'm pessimistic for long long here...
200  * should rather return a pointer to a Value stored somewhere...
201  */
202 const : CONSTANTE
203  {
204  $$ = $1;
205  }
206  ;
207 
208 op : INF
209  { cote = DROIT;
210  sens = 1;
211  operat = OPINF;
212  cp = NULL;
213  b2 = VALUE_ZERO; }
214  | INFEGAL
215  { cote = DROIT;
216  sens = 1;
217  operat = OPINFEGAL;
218  cp = NULL;
219  b2 = VALUE_ZERO;}
220  | EGAL
221  { cote = DROIT;
222  sens = 1;
223  operat = OPEGAL;
224  cp = NULL;
225  b2 = VALUE_ZERO;
226  }
227  | SUP
228  { cote = DROIT;
229  sens = -1;
230  operat = OPSUP;
231  cp = NULL;
232  b2 = VALUE_ZERO;}
233  | SUPEGAL
234  { cote = DROIT;
235  sens = -1;
236  operat = OPSUPEGAL;
237  cp = NULL;
238  b2 = VALUE_ZERO;}
239 ;
240 
241 addop : PLUS
242  { fac = VALUE_ONE; }
243  | MOINS
244  { fac = VALUE_MONE; }
245  ;
246 
247 multi_membre : membre
248  | multi_membre op membre fin_mult_membre
249  ;
250 
251 fin_mult_membre :
252  {
253  vect_add_elem(&(eq->vecteur),TCST,value_uminus(b1));
254  switch (operat)
255  {
256  case OPINF:
257  creer_ineg(ps_yacc,eq,sens);
258  vect_add_elem(&(eq->vecteur),TCST,VALUE_ONE);
259  break;
260  case OPINFEGAL:
261  creer_ineg(ps_yacc,eq,sens);
262  break;
263  case OPSUPEGAL:
264  creer_ineg(ps_yacc,eq,sens);
265  break;
266  case OPSUP:
267  creer_ineg(ps_yacc,eq,sens);
268  vect_add_elem (&(eq->vecteur),TCST,VALUE_ONE);
269  break;
270  case OPEGAL:
271  creer_eg(ps_yacc,eq);
272  break;
273  }
274 
275  eq = contrainte_new();
276  eq->vecteur = cp;
277  b1 = b2;
278 
279  }
280  ;
281 
282 virg_opt : VIRG
283  |
284  ;
285 %%
286