PIPS
spec.y
Go to the documentation of this file.
1 %{
2 /*
3 
4  $Id: spec.y 1361 2016-07-01 11:57:40Z coelho $
5 
6  Copyright 1989-2016 MINES ParisTech
7 
8  This file is part of NewGen.
9 
10  NewGen is free software: you can redistribute it and/or modify it under the
11  terms of the GNU General Public License as published by the Free Software
12  Foundation, either version 3 of the License, or any later version.
13 
14  NewGen 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. See the GNU General Public
17  License for more details.
18 
19  You should have received a copy of the GNU General Public License along with
20  NewGen. If not, see <http://www.gnu.org/licenses/>.
21 
22 */
23 
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 
28 #include "genC.h"
29 #include "newgen_include.h"
30 
31 #define YYERROR_VERBOSE 1 /* better error messages by bison */
32 
33 extern int genspec_input(void);
34 extern void genspec_error(const char*);
35 extern int check_not_keyword(char *); /* in build.c */
36 
37 struct gen_binding Domains[MAX_DOMAIN];
38 int Number_imports ;
39 
40 /* UPDATE_OP checks whether the just read OPerator is compatible with
41  the current one. If not, an ERROR_MSG is signaled. */
42 
43 void update_op(int op, char * error_msg)
44 {
45  if( Current_op == UNDEF_OP ) {
46  Current_op = op ;
47  }
48  else if( Current_op == ARROW_OP ) {
49  user( error_msg, (char *)NULL ) ;
50  }
51  else if(Current_op != op ) {
52  user( error_msg, (char *)NULL ) ;
53  }
54 }
55 
56 
57 %}
58 
59 %token COMMA
60 %token COLUMN
61 %token SEMI_COLUMN
62 %token AND
63 %token OR
64 %token ARROW
65 %token STAR
66 %token LB
67 %token RB
68 %token LR
69 %token RR
70 %token EQUAL
71 %token FROM
72 %token GRAM_EXTERNAL
73 %token GRAM_IMPORT
74 %token TABULATED
75 %token PERSISTANT
76 
77 %term <name> IDENT
78 %term <name> GRAM_FILE
79 %term <val> GRAM_INT
80 
81 %union {
82  union domain *domain ;
83  struct domainlist *domainlist ;
84  struct namelist *namelist ;
85  struct intlist *intlist ;
86  char *name ;
87  int val ;
88 }
89 
90 %type <namelist> Namelist
91 %type <intlist> Dimensions
92 %type <domain> Basis Simple Domain
93 %type <domainlist> Constructed
94 %type <name> Name File
95 %type <val> Int Tabulated Persistant
96 
97 %%
98 Specification
99  : {Number_imports = 0;} Imports Externals Definitions {
100  YYACCEPT ;
101  /*NOTREACHED*/
102  }
103  ;
104 
105 Externals
106  : Externals GRAM_EXTERNAL Name SEMI_COLUMN {
107  union domain *dp ;
108 
109  /*NOSTRICT*/
110  dp = (union domain *)alloc( sizeof( union domain )) ;
111  dp->ex.type = EXTERNAL_DT ;
112  dp->ex.read = (void *(*)(FILE*, int(*)(void))) NULL;
113  dp->ex.write = (void (*)(FILE*, void*)) NULL;
114  dp->ex.copy = (void*(*)(void*)) NULL;
115  dp->ex.free = (void (*)(void*)) NULL;
116  new_binding( $3, dp ) ;
117  }
118  |
119  ;
120 
121 Imports : Imports GRAM_IMPORT Name FROM File SEMI_COLUMN {
122  union domain *dp ;
123 
124  /*NOSTRICT*/
125  dp = (union domain *)alloc( sizeof( union domain )) ;
126  dp->ba.type = IMPORT_DT ;
127  dp->im.filename = $5 ;
128  new_binding( $3, dp ) ;
129  Number_imports++ ;
130  }
131  |
132  ;
133 
134 File : GRAM_FILE {
135  $$ = $1 ;
136  }
137  ;
138 
139 Definitions
140  : Definitions Definition
141  |
142  ;
143 
144 Definition
145  : Tabulated Name EQUAL Domain SEMI_COLUMN {
146  struct gen_binding * bp = new_binding($2, $4);
147  if ($1) bp->tabulated = gen_init_tabulated(bp-Domains);
148  }
149  ;
150 
151 Tabulated
152  : TABULATED { $$ = 1; }
153  | { $$ = 0 ; }
154  ;
155 
156 Domain : Simple Constructed {
157  /* A BASIS type with just one field is considered as an
158  AND_OP. */
159 
160  if( $2 == NULL && $1->ba.type != BASIS_DT )
161  $$ = $1 ;
162  else {
163  struct domainlist *dlp ;
164 
165  /*NOSTRICT*/
166  dlp = (struct domainlist *)
167  alloc( sizeof( struct domainlist ));
168  dlp->domain = $1 ;
169  dlp->cdr = $2 ;
170  /*NOSTRICT*/
171  $$ = (union domain *)alloc( sizeof( union domain )) ;
172  $$->co.type = CONSTRUCTED_DT ;
173  $$->co.components = dlp ;
174  $$->co.op = ($2 == NULL) ? AND_OP : Current_op ;
175 
176  if( $$->co.op == OR_OP && Read_spec_mode )
177  $$->co.first = 0 ;
178 
179  Current_op = UNDEF_OP ;
180  }
181  }
182  | LR Namelist RR {
183  /* This is sugar for an OR node with domains of type unit.*/
184 
185  /*NOSTRICT*/
186  struct domainlist *dlp =
187  (struct domainlist *)alloc( sizeof( struct domainlist )) ;
188 
189  /*NOSTRICT*/
190  $$ = (union domain *)
191  alloc( sizeof( union domain )) ;
192  $$->co.type = CONSTRUCTED_DT ;
193  $$->co.op = OR_OP ;
194  $$->co.components = dlp ;
195 
196  if( Read_spec_mode ) $$->co.first = 0 ;
197 
198  for( ; $2 != NULL ; $2 = $2->cdr, dlp = dlp->cdr ) {
199  /*NOSTRICT*/
200  dlp->domain =
201  (union domain *)alloc( sizeof( union domain )) ;
202  dlp->cdr =
203  ($2->cdr == NULL) ?
204  NULL :
205  (struct domainlist *)alloc( sizeof( struct domainlist ));
206  dlp->domain->ba.type = BASIS_DT ;
207  dlp->domain->ba.constructor = $2->name ;
208  /*NOSTRICT*/
209  dlp->domain->ba.constructand = (struct gen_binding *)UNIT_TYPE_NAME ;
210  }
211  }
212  ;
213 
214 Simple : Persistant Basis {
215  ($$ = $2)->ba.persistant = $1 ;
216  }
217  | Persistant Basis STAR {
218  ($$ = $2)->li.type = LIST_DT ;
219  $$->li.persistant = $1 ;
220  $$->li.constructor = $2->ba.constructor ;
221  $$->li.element = $2->ba.constructand ;
222  }
223  | Persistant Basis Dimensions {
224  ($$ = $2)->ar.type = ARRAY_DT ;
225  $$->ar.persistant = $1 ;
226  $$->ar.constructor = $2->ba.constructor ;
227  $$->ar.element = $2->ba.constructand ;
228  $$->ar.dimensions = $3 ;
229  }
230  | Persistant Basis LR RR {
231  char *below = (char *)$2->ba.constructand ;
232 
233  ($$ = $2)->se.type = SET_DT ;
234  $$->se.persistant = $1 ;
235  $$->se.constructor = $2->ba.constructor ;
236  $$->se.element = $2->ba.constructand ;
237  $$->se.what =
238  (strcmp( below, "string" ) == 0) ? set_string :
239  (strcmp( below, "int" ) == 0) ? set_int :
240  set_pointer ;
241  }
242  ;
243 
244 Persistant
245  : PERSISTANT {
246  $$ = 1 ;
247  }
248  | {$$ = 0;}
249  ;
250 
251 Basis : Name {
252  /*NOSTRICT*/
253  $$ = (union domain *)alloc( sizeof( union domain )) ;
254  $$->ba.type = BASIS_DT ;
255  $$->ba.constructor = $1 ;
256  /*NOSTRICT*/
257  $$->ba.constructand = (struct gen_binding *)$1 ;
258  }
259  | Name COLUMN Name {
260  /*NOSTRICT*/
261  $$ = (union domain *)alloc( sizeof( union domain )) ;
262  $$->ba.type = BASIS_DT ;
263  $$->ba.constructor = $1 ;
264  /*NOSTRICT*/
265  $$->ba.constructand = (struct gen_binding *)$3 ;
266  }
267  ;
268 
269 Constructed
270  : AND Simple Constructed {
271  /*NOSTRICT*/
272  $$ = (struct domainlist *)alloc( sizeof( struct domainlist ));
273  $$->domain = $2 ;
274  $$->cdr = $3 ;
275  update_op( AND_OP, "OR prohibited in an AND constructor\n" ) ;
276  }
277  | OR Simple Constructed {
278  /*NOSTRICT*/
279  $$ = (struct domainlist *)alloc( sizeof( struct domainlist ));
280  $$->domain = $2 ;
281  $$->cdr = $3 ;
282  update_op( OR_OP, "AND prohibited in an OR constructor\n" ) ;
283  }
284  | ARROW Simple {
285  $$ = (struct domainlist *)alloc( sizeof( struct domainlist ));
286  $$->domain = $2 ;
287  $$->cdr = NULL ;
288  update_op( ARROW_OP, "-> is a unary constructor\n" ) ;
289  }
290  | {
291  $$ = NULL ;
292  }
293  ;
294 
295 Namelist
296  : Name COMMA Namelist {
297  /*NOSTRICT*/
298  $$ = (struct namelist *)alloc( sizeof( struct namelist )) ;
299  $$->name = $1 ;
300  $$->cdr = $3 ;
301  }
302  | Name {
303  /*NOSTRICT*/
304  $$ = (struct namelist *)alloc( sizeof( struct namelist )) ;
305  $$->name = $1 ;
306  $$->cdr = NULL ;
307  }
308  ;
309 
310 Dimensions
311  : LB Int RB Dimensions {
312  /*NOSTRICT*/
313  $$ = (struct intlist *)alloc( sizeof( struct intlist )) ;
314  $$->val = $2 ;
315  $$->cdr = $4 ;
316  }
317  | LB Int RB {
318  /*NOSTRICT*/
319  $$ = (struct intlist *)alloc( sizeof( struct intlist )) ;
320  $$->val = $2 ;
321  $$->cdr = NULL ;
322  }
323  ;
324 
325 Int : GRAM_INT {$$ = $1;}
326  ;
327 
328 Name : IDENT {
329  check_not_keyword( $1 ) ;
330  $$ = $1;
331  }
332  ;
333 %%
334 
335 /* Syntax error routines called by yacc. */
336 
337 void genspec_error(const char * s)
338 {
339  int c;
340 
341  user( "%s before ", s ) ;
342 
343  while( (c=genspec_input()) != 0 )
344  fprintf( stderr, "%c", c ) ;
345 
346  exit( 1 ) ;
347 }
348