PIPS
sl_gram.y
Go to the documentation of this file.
1 
2 /* explicit types: Value may be larger than a pointer (e.g. long long)
3  */
4 %type <Value> const
5 %type <Variable> ident
6 
7 %{
8 
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 
13 #include "boolean.h"
14 #include "arithmetique.h"
15 #include "vecteur.h"
16 #include "contrainte.h"
17 #include "sc.h"
18 #include "union.h"
19 
20 extern int slx_lex();
21 extern int slx_error();
22 extern char * slx_text;
23 extern Psysteme ps_yacc;
24 bool syntax_error;
25 Value valcst;
26 extern Value fac; /* facteur multiplicatif suivant qu'on analyse un terme*/
27  /* introduit par un moins (-1) ou par un plus (1) */
28 extern int sens; /* indique le sens de l'inegalite
29  sens = -1 ==> l'operateur est soit > ,soit >=,
30  sens = 1 ==> l'operateur est soit <, soit <= */
31 extern short int cote; /* booleen indiquant quel membre est en cours d'analyse*/
32 extern Value b1, b2; /* element du vecteur colonne du systeme donne
33  par l'analyse d'une contrainte */
34 extern Pcontrainte eq; /* pointeur sur l'egalite ou l'inegalite courante */
35 extern Pvecteur cp ; /* pointeur sur le membre courant */
36 extern short int operat; /* dernier operateur rencontre */
37 
38 extern Pcontrainte p_eg_fin;
39 extern Pcontrainte p_ineg_fin;
40 extern Pvecteur p_pred;
41 extern Pvecteur p_membre_courant;
42 Psyslist sl_yacc; Pbase ba_yacc; Variable va_yacc;
43 
44 /*code des operateurs de comparaison */
45 #define OPINF 1
46 #define OPINFEGAL 2
47 #define OPEGAL 3
48 #define OPSUPEGAL 4
49 #define OPSUP 5
50 #define DROIT 1
51 #define GAUCHE 2
52 /* #define NULL 0 */
53 
54 %}
55 
56 %token ACCFERM /* accolade fermante */ 1
57 %token ACCOUVR /* accolade ouvrante */ 2
58 %token CONSTANTE /* constante entiere sans signe a recuperer dans yytext */ 3
59 %token EGAL /* signe == */ 4
60 %token IDENT /* identificateur de variable a recuperer dans yytext */ 5
61 %token INF /* signe < */ 6
62 %token INFEGAL /* signe <= */ 7
63 %token MOINS /* signe - */ 8
64 %token PLUS /* signe + */ 9
65 %token SUP /* signe > */ 10
66 %token SUPEGAL /* signe >= */ 11
67 %token VAR /* mot reserve VAR introduisant la liste de variables */ 12
68 %token VIRG /* signe , */ 13
69 
70 %union {
71  Value Value;
72  Variable Variable;
73 }
74 
75 %%
76 
77 s_list : inisl defvar l_sys endsl
78  ;
79 
80 inisl :
81  { /* Initialisation de la liste des systemes */
82  sl_yacc = NULL;
83  syntax_error = false;
84  }
85  ;
86 
87 endsl :
88  { /* Fin de la list des systemes */
89  vect_rm( (Pvecteur) ba_yacc ); ba_yacc = NULL;
90  }
91  ;
92 
93 defvar : VAR l_var
94  ;
95 
96 l_var : newid
97  | l_var VIRG newid
98  ;
99 
100 newid : IDENT
101  {
102  if(!base_contains_variable_p(ba_yacc, (Variable) slx_text))
103  ba_yacc = vect_add_variable(ba_yacc, (Variable) strdup(slx_text));
104  }
105  ;
106 
107 l_sys : system
108  | system l_sys
109  ;
110 
111 system : inisys ACCOUVR l_eq virg_opt ACCFERM endsys
112  ;
113 
114 inisys :
115  { /* initialisation des parametres de la liste de systemes */
116  /* et initialisation des variables */
117  ps_yacc = sc_new();
118  init_globals();
119  }
120  ;
121 
122 endsys :
123  {
124  /* on rajoute le systeme trouve a la liste */
125  if (ps_yacc != NULL) {
126  ps_yacc->base = NULL;
127  sc_creer_base( ps_yacc );
128  }
129  sl_yacc = sl_append_system_first( sl_yacc, ps_yacc );
130  }
131  ;
132 
133 
134 l_eq : eq
135  | l_eq VIRG eq
136  |
137  ;
138 
139 eq : debeq multi_membre op membre fin_mult_membre feq
140  ;
141 
142 debeq :
143  {
144  fac = VALUE_ONE;
145  sens = 1;
146  cote = GAUCHE;
147  b1 = 0;
148  b2 = 0;
149  operat = 0;
150  cp = NULL;
151  eq = contrainte_new();
152  }
153  ;
154 
155 feq :
156  {
157  contrainte_free(eq);
158  }
159  ;
160 
161 membre : addop terme
162  | { fac = VALUE_ONE;} terme
163  | membre addop terme
164  ;
165 
166 terme : const ident
167  {
168  if (cote==DROIT)
169  value_oppose(fac);
170 
171  /* ajout du couple (ident,const) a la contrainte courante */
172  vect_add_elem(&(eq->vecteur), (Variable) $2,value_mult(fac,$1));
173  /* duplication du couple (ident,const) de la combinaison lineaire
174  traitee*/
175  if (operat) vect_add_elem(&cp,(Variable) $2,
176  value_uminus(value_mult(fac,$1)));
177  }
178  | const
179  {
180  Value v = value_mult(fac,$1);
181  if (cote==DROIT)
182  {
183  value_addto(b1,v); value_substract(b2,v);
184  }
185  else
186  {
187  value_addto(b2,v); value_substract(b1,v);
188  }
189  }
190  | ident
191  {
192  if (cote==DROIT) value_oppose(fac);
193 
194  /* ajout du couple (ident,1) a la contrainte courante */
195  vect_add_elem (&(eq->vecteur),(Variable) $1,fac);
196  /* duplication du couple (ident,1) de la combinaison lineaire traitee */
197  if (operat) vect_add_elem(&cp,(Variable) $1,value_uminus(fac));
198  }
199  ;
200 
201 ident : IDENT
202  {
203  va_yacc = base_find_variable_name(ba_yacc,
204  (Variable) slx_text,
205  variable_default_name);
206  if(VARIABLE_UNDEFINED_P(va_yacc)) {
207  (void) fprintf(stderr,
208  "Variable %s not declared. Add it to the VAR list!\n",
209  variable_default_name((Variable) slx_text));
210  exit(1);
211  }
212  $$ = va_yacc;
213  }
214  ;
215 
216 const : CONSTANTE
217  { sscan_Value(slx_text, &valcst);
218  $$ = (Value) valcst;
219  }
220  ;
221 
222 op : INF
223  {
224  cote = DROIT;
225  sens = 1;
226  operat = OPINF;
227  cp = NULL;
228  b2 = 0;
229  }
230  | INFEGAL
231  {
232  cote = DROIT;
233  sens = 1;
234  operat = OPINFEGAL;
235  cp = NULL;
236  b2 = 0;
237  }
238  | EGAL
239  {
240  cote = DROIT;
241  sens = 1;
242  operat = OPEGAL;
243  cp = NULL;
244  b2 = 0;
245  }
246  | SUP
247  {
248  cote = DROIT;
249  sens = -1;
250  operat = OPSUP;
251  cp = NULL;
252  b2 = 0;
253  }
254  | SUPEGAL
255  {
256  cote = DROIT;
257  sens = -1;
258  operat = OPSUPEGAL;
259  cp = NULL;
260  b2 = 0;
261  }
262  ;
263 addop : PLUS
264  { fac = VALUE_ONE; }
265  | MOINS
266  { fac = VALUE_MONE; }
267  ;
268 
269 multi_membre : membre
270  | multi_membre op membre fin_mult_membre
271  ;
272 
273 fin_mult_membre :
274  {
275  vect_add_elem(&(eq->vecteur),TCST,value_uminus(b1));
276  switch (operat) {
277  case OPINF:
278  creer_ineg(ps_yacc,eq,sens);
279  vect_add_elem(&(eq->vecteur),TCST,VALUE_ONE);
280  break;
281  case OPINFEGAL:
282  creer_ineg(ps_yacc,eq,sens);
283  break;
284  case OPSUPEGAL:
285  creer_ineg(ps_yacc,eq,sens);
286  break;
287  case OPSUP:
288  creer_ineg(ps_yacc,eq,sens);
289  vect_add_elem (&(eq->vecteur),TCST,VALUE_ONE);
290  break;
291  case OPEGAL:
292  creer_eg(ps_yacc,eq);
293  break;
294  }
295 
296  eq = contrainte_new();
297  eq->vecteur = cp;
298  b1 = b2;
299  }
300  ;
301 
302 virg_opt : VIRG
303  |
304  ;
305 
306 %%
307 
308 int slx_error(char * s)
309 {
310  /* procedure minimum de recouvrement d'erreurs */
311  int c;
312  (void) fprintf(stderr, "%s near %s\n",s, slx_text);
313  while ((c = getchar()) != EOF) putchar(c);
314  syntax_error = true;
315  return 0;
316 }