4 $Id: spec.y 1361 2016-07-01 11:57:40Z coelho $
6 Copyright 1989-2016 MINES ParisTech
8 This file is part of NewGen.
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.
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.
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/>.
29 #include "newgen_include.h"
31 #define YYERROR_VERBOSE 1 /* better error messages by bison */
33 extern int genspec_input(void);
34 extern void genspec_error(const char*);
35 extern int check_not_keyword(char *); /* in build.c */
37 struct gen_binding Domains[MAX_DOMAIN];
40 /* UPDATE_OP checks whether the just read OPerator is compatible with
41 the current one. If not, an ERROR_MSG is signaled. */
43 void update_op(int op, char * error_msg)
45 if( Current_op == UNDEF_OP ) {
48 else if( Current_op == ARROW_OP ) {
49 user( error_msg, (char *)NULL ) ;
51 else if(Current_op != op ) {
52 user( error_msg, (char *)NULL ) ;
78 %term <name> GRAM_FILE
82 union domain *domain ;
83 struct domainlist *domainlist ;
84 struct namelist *namelist ;
85 struct intlist *intlist ;
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
99 : {Number_imports = 0;} Imports Externals Definitions {
106 : Externals GRAM_EXTERNAL Name SEMI_COLUMN {
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 ) ;
121 Imports : Imports GRAM_IMPORT Name FROM File SEMI_COLUMN {
125 dp = (union domain *)alloc( sizeof( union domain )) ;
126 dp->ba.type = IMPORT_DT ;
127 dp->im.filename = $5 ;
128 new_binding( $3, dp ) ;
140 : Definitions 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);
152 : TABULATED { $$ = 1; }
156 Domain : Simple Constructed {
157 /* A BASIS type with just one field is considered as an
160 if( $2 == NULL && $1->ba.type != BASIS_DT )
163 struct domainlist *dlp ;
166 dlp = (struct domainlist *)
167 alloc( sizeof( struct domainlist ));
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 ;
176 if( $$->co.op == OR_OP && Read_spec_mode )
179 Current_op = UNDEF_OP ;
183 /* This is sugar for an OR node with domains of type unit.*/
186 struct domainlist *dlp =
187 (struct domainlist *)alloc( sizeof( struct domainlist )) ;
190 $$ = (union domain *)
191 alloc( sizeof( union domain )) ;
192 $$->co.type = CONSTRUCTED_DT ;
194 $$->co.components = dlp ;
196 if( Read_spec_mode ) $$->co.first = 0 ;
198 for( ; $2 != NULL ; $2 = $2->cdr, dlp = dlp->cdr ) {
201 (union domain *)alloc( sizeof( union domain )) ;
205 (struct domainlist *)alloc( sizeof( struct domainlist ));
206 dlp->domain->ba.type = BASIS_DT ;
207 dlp->domain->ba.constructor = $2->name ;
209 dlp->domain->ba.constructand = (struct gen_binding *)UNIT_TYPE_NAME ;
214 Simple : Persistant Basis {
215 ($$ = $2)->ba.persistant = $1 ;
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 ;
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 ;
230 | Persistant Basis LR RR {
231 char *below = (char *)$2->ba.constructand ;
233 ($$ = $2)->se.type = SET_DT ;
234 $$->se.persistant = $1 ;
235 $$->se.constructor = $2->ba.constructor ;
236 $$->se.element = $2->ba.constructand ;
238 (strcmp( below, "string" ) == 0) ? set_string :
239 (strcmp( below, "int" ) == 0) ? set_int :
253 $$ = (union domain *)alloc( sizeof( union domain )) ;
254 $$->ba.type = BASIS_DT ;
255 $$->ba.constructor = $1 ;
257 $$->ba.constructand = (struct gen_binding *)$1 ;
261 $$ = (union domain *)alloc( sizeof( union domain )) ;
262 $$->ba.type = BASIS_DT ;
263 $$->ba.constructor = $1 ;
265 $$->ba.constructand = (struct gen_binding *)$3 ;
270 : AND Simple Constructed {
272 $$ = (struct domainlist *)alloc( sizeof( struct domainlist ));
275 update_op( AND_OP, "OR prohibited in an AND constructor\n" ) ;
277 | OR Simple Constructed {
279 $$ = (struct domainlist *)alloc( sizeof( struct domainlist ));
282 update_op( OR_OP, "AND prohibited in an OR constructor\n" ) ;
285 $$ = (struct domainlist *)alloc( sizeof( struct domainlist ));
288 update_op( ARROW_OP, "-> is a unary constructor\n" ) ;
296 : Name COMMA Namelist {
298 $$ = (struct namelist *)alloc( sizeof( struct namelist )) ;
304 $$ = (struct namelist *)alloc( sizeof( struct namelist )) ;
311 : LB Int RB Dimensions {
313 $$ = (struct intlist *)alloc( sizeof( struct intlist )) ;
319 $$ = (struct intlist *)alloc( sizeof( struct intlist )) ;
325 Int : GRAM_INT {$$ = $1;}
329 check_not_keyword( $1 ) ;
335 /* Syntax error routines called by yacc. */
337 void genspec_error(const char * s)
341 user( "%s before ", s ) ;
343 while( (c=genspec_input()) != 0 )
344 fprintf( stderr, "%c", c ) ;