Project

General

Profile

Download (15 KB) Statistics
| Branch: | Tag: | Revision:
1
/* ----------------------------------------------------------------------------
2
 * SchedMCore - A MultiCore Scheduling Framework
3
 * Copyright (C) 2009-2011, ONERA, Toulouse, FRANCE - LIFL, Lille, FRANCE
4
 *
5
 * This file is part of Prelude
6
 *
7
 * Prelude is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public License
9
 * as published by the Free Software Foundation ; either version 2 of
10
 * the License, or (at your option) any later version.
11
 *
12
 * Prelude is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY ; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this program ; if not, write to the Free Software
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20
 * USA
21
 *---------------------------------------------------------------------------- */
22

    
23
%{
24
open LustreSpec
25
open Corelang
26
open Dimension
27
open Utils
28

    
29
let mktyp x = mktyp (Location.symbol_rloc ()) x
30
let mkclock x = mkclock (Location.symbol_rloc ()) x
31
let mkvar_decl x = mkvar_decl (Location.symbol_rloc ()) x
32
let mkexpr x = mkexpr (Location.symbol_rloc ()) x
33
let mkeq x = mkeq (Location.symbol_rloc ()) x
34
let mkassert x = mkassert (Location.symbol_rloc ()) x
35
let mktop_decl x = mktop_decl (Location.symbol_rloc ()) x
36
let mkpredef_call x = mkpredef_call (Location.symbol_rloc ()) x
37
let mkpredef_unary_call x = mkpredef_unary_call (Location.symbol_rloc ()) x
38

    
39
let mkdim_int i = mkdim_int (Location.symbol_rloc ()) i
40
let mkdim_bool b = mkdim_bool (Location.symbol_rloc ()) b
41
let mkdim_ident id = mkdim_ident (Location.symbol_rloc ()) id
42
let mkdim_appl f args = mkdim_appl (Location.symbol_rloc ()) f args
43
let mkdim_ite i t e = mkdim_ite (Location.symbol_rloc ()) i t e
44

    
45
let add_node loc own msg hashtbl name value =
46
  try
47
    match (Hashtbl.find hashtbl name).top_decl_desc, value.top_decl_desc with
48
    | Node _        , ImportedNode _ when own   -> ()
49
    | ImportedNode _, _                         -> Hashtbl.add hashtbl name value
50
    | Node _        , _                         -> raise (Corelang.Error (loc, Corelang.Already_bound_symbol msg))
51
    | _                                         -> assert false
52
  with
53
    Not_found                                   -> Hashtbl.add hashtbl name value
54

    
55

    
56
let add_symbol loc msg hashtbl name value =
57
 if Hashtbl.mem hashtbl name
58
 then raise (Corelang.Error (loc, Corelang.Already_bound_symbol msg))
59
 else Hashtbl.add hashtbl name value
60

    
61
let check_symbol loc msg hashtbl name =
62
 if not (Hashtbl.mem hashtbl name)
63
 then raise (Corelang.Error (loc, Corelang.Unbound_symbol msg))
64
 else ()
65

    
66
%}
67

    
68
%token <int> INT
69
%token <string> REAL
70
%token <float> FLOAT
71
%token AUTOMATON STATE UNTIL UNLESS RESTART RESUME LAST
72
%token STATELESS ASSERT OPEN QUOTE FUNCTION
73
%token <string> IDENT
74
%token <LustreSpec.expr_annot> ANNOT
75
%token <LustreSpec.node_annot> NODESPEC
76
%token LBRACKET RBRACKET LCUR RCUR LPAR RPAR SCOL COL COMMA COLCOL 
77
%token AMPERAMPER BARBAR NOT POWER
78
%token IF THEN ELSE
79
%token UCLOCK DCLOCK PHCLOCK TAIL
80
%token MERGE FBY WHEN WHENNOT EVERY
81
%token NODE LET TEL RETURNS VAR IMPORTED SENSOR ACTUATOR WCET TYPE CONST
82
%token STRUCT ENUM
83
%token TINT TFLOAT TREAL TBOOL TCLOCK
84
%token RATE DUE
85
%token EQ LT GT LTE GTE NEQ
86
%token AND OR XOR IMPL
87
%token MULT DIV MOD
88
%token MINUS PLUS UMINUS
89
%token PRE ARROW
90
%token PROTOTYPE LIB
91
%token EOF
92

    
93
%nonassoc COMMA
94
%left MERGE IF
95
%nonassoc ELSE
96
%right ARROW FBY
97
%left WHEN WHENNOT UCLOCK DCLOCK PHCLOCK
98
%right COLCOL
99
%right IMPL
100
%left OR XOR BARBAR
101
%left AND AMPERAMPER
102
%left NOT
103
%nonassoc INT
104
%nonassoc EQ LT GT LTE GTE NEQ
105
%left MINUS PLUS
106
%left MULT DIV MOD
107
%left UMINUS
108
%left POWER
109
%left PRE LAST
110
%nonassoc RBRACKET
111
%nonassoc LBRACKET
112

    
113
%start prog
114
%type <Corelang.top_decl list> prog
115
%start header
116
%type <bool -> Corelang.top_decl list> header
117

    
118
%%
119

    
120
prog:
121
 open_list typ_def_list top_decl_list EOF { $1 @ (List.rev $3) }
122

    
123
header:
124
 open_list typ_def_list top_decl_header_list EOF { (fun own -> ($1 @ (List.rev ($3 own)))) }
125

    
126
open_list:
127
  { [] }
128
| open_lusi open_list { $1 :: $2 }
129

    
130
open_lusi:
131
| OPEN QUOTE IDENT QUOTE { mktop_decl (Open (true, $3))}
132
| OPEN LT IDENT GT { mktop_decl (Open (false, $3)) }
133

    
134
top_decl_list:
135
  top_decl {[$1]}
136
| top_decl_list top_decl {$2::$1}
137

    
138

    
139
top_decl_header_list:
140
  top_decl_header {(fun own -> [$1 own]) }
141
| top_decl_header_list top_decl_header {(fun own -> ($2 own)::($1 own)) }
142

    
143
state_annot:
144
  FUNCTION { true }
145
| NODE { false }
146

    
147
top_decl_header:
148
| CONST cdecl_list { let top = mktop_decl (Consts (List.rev $2)) in fun _ -> top }
149
| nodespec_list state_annot IDENT LPAR vdecl_list SCOL_opt RPAR RETURNS LPAR vdecl_list SCOL_opt RPAR  prototype_opt in_lib_opt SCOL
150
    {let nd = mktop_decl (ImportedNode
151
                            {nodei_id = $3;
152
                             nodei_type = Types.new_var ();
153
                             nodei_clock = Clocks.new_var true;
154
                             nodei_inputs = List.rev $5;
155
                             nodei_outputs = List.rev $10;
156
			     nodei_stateless = $2;
157
			     nodei_spec = $1;
158
			     nodei_prototype = $13;
159
			     nodei_in_lib = $14;})
160
    in
161
    (let loc = Location.symbol_rloc () in 
162
     fun own -> add_node loc own ("node " ^ $3) node_table $3 nd; nd) }
163

    
164
prototype_opt:
165
 { None }
166
| PROTOTYPE IDENT { Some $2}
167

    
168
in_lib_opt:
169
{ None }
170
| LIB IDENT {Some $2} 
171

    
172
top_decl:
173
| CONST cdecl_list { mktop_decl (Consts (List.rev $2)) }
174
| nodespec_list state_annot IDENT LPAR vdecl_list SCOL_opt RPAR RETURNS LPAR vdecl_list SCOL_opt RPAR SCOL_opt locals LET eq_list TEL 
175
    {let eqs, asserts, annots = $16 in
176
     let nd = mktop_decl (Node
177
                            {node_id = $3;
178
                             node_type = Types.new_var ();
179
                             node_clock = Clocks.new_var true;
180
                             node_inputs = List.rev $5;
181
                             node_outputs = List.rev $10;
182
                             node_locals = List.rev $14;
183
			     node_gencalls = [];
184
			     node_checks = [];
185
			     node_asserts = asserts; 
186
                             node_eqs = eqs;
187
			     node_dec_stateless = $2;
188
			     node_stateless = None;
189
			     node_spec = $1;
190
			     node_annot = match annots with [] -> None | _ -> Some annots})
191
     in
192
     let loc = Location.symbol_rloc () in
193
     add_node loc true ("node " ^ $3) node_table $3 nd; nd}
194

    
195
nodespec_list:
196
 { None }
197
| NODESPEC nodespec_list { (function None -> (fun s1 -> Some s1) | Some s2 -> (fun s1 -> Some (LustreSpec.merge_node_annot s1 s2))) $2 $1 }
198

    
199
typ_def_list:
200
    /* empty */ {}
201
| typ_def SCOL typ_def_list {$1;$3}
202

    
203
typ_def:
204
  TYPE IDENT EQ typeconst {
205
    try
206
      let loc = Location.symbol_rloc () in
207
      add_symbol loc ("type " ^ $2) type_table (Tydec_const $2) (Corelang.get_repr_type $4)
208
    with Not_found-> assert false }
209
| TYPE IDENT EQ ENUM LCUR tag_list RCUR { Hashtbl.add type_table (Tydec_const $2) (Tydec_enum ($6 (Tydec_const $2))) }
210
| TYPE IDENT EQ STRUCT LCUR field_list RCUR { Hashtbl.add type_table (Tydec_const $2) (Tydec_struct ($6 (Tydec_const $2))) }
211

    
212
array_typ_decl:
213
                            { fun typ -> typ }
214
 | POWER dim array_typ_decl { fun typ -> $3 (Tydec_array ($2, typ)) }
215

    
216
typeconst:
217
  TINT array_typ_decl  { $2 Tydec_int }
218
| TBOOL array_typ_decl { $2 Tydec_bool  }
219
| TREAL array_typ_decl { $2 Tydec_real  }
220
| TFLOAT array_typ_decl { $2 Tydec_float }
221
| IDENT array_typ_decl { 
222
        let loc = Location.symbol_rloc () in
223
	check_symbol loc ("type " ^ $1) type_table (Tydec_const $1); $2 (Tydec_const $1) }
224
| TBOOL TCLOCK  { Tydec_clock Tydec_bool }
225
| IDENT TCLOCK  { Tydec_clock (Tydec_const $1) }
226

    
227
tag_list:
228
  IDENT
229
  { let loc = Location.symbol_rloc () in 
230
    (fun t -> 
231
      add_symbol loc ("tag " ^ $1) tag_table $1 t; $1 :: []) }
232
| tag_list COMMA IDENT
233
      {       
234
	let loc = Location.symbol_rloc () in
235
	(fun t -> add_symbol loc ("tag " ^ $3)tag_table $3 t; $3 :: ($1 t)) 
236
      }
237
      
238
field_list:
239
  { (fun t -> []) }
240
| field_list IDENT COL typeconst SCOL
241
      {
242
	let loc = Location.symbol_rloc () in
243
	(fun t -> add_symbol loc ("field " ^ $2) field_table $2 t; ($1 t) @ [ ($2, $4) ]) }
244
      
245
eq_list:
246
  { [], [], [] }
247
| eq eq_list {let eql, assertl, annotl = $2 in ($1::eql), assertl, annotl}
248
| assert_ eq_list {let eql, assertl, annotl = $2 in eql, ($1::assertl), annotl}
249
| ANNOT eq_list {let eql, assertl, annotl = $2 in eql, assertl, $1@annotl}
250
| automaton eq_list {let eql, assertl, annotl = $2 in ($1::eql), assertl, annotl}
251

    
252
automaton:
253
 AUTOMATON IDENT handler_list { failwith "not implemented" }
254

    
255
handler_list:
256
     { [] }
257
| handler handler_list { $1::$2 }
258

    
259
handler:
260
 STATE IDENT ARROW unless_list locals LET eq_list TEL until_list { () }
261

    
262
unless_list:
263
    { [] }
264
| unless unless_list { $1::$2 }
265

    
266
until_list:
267
    { [] }
268
| until until_list { $1::$2 }
269

    
270
unless:
271
  UNLESS expr RESTART IDENT { }
272
| UNLESS expr RESUME IDENT  { }
273

    
274
until:
275
  UNTIL expr RESTART IDENT { }
276
| UNTIL expr RESUME IDENT  { }
277

    
278
assert_:
279
| ASSERT expr SCOL {mkassert ($2)}
280

    
281
eq:
282
       ident_list      EQ expr SCOL {mkeq (List.rev $1,$3)}
283
| LPAR ident_list RPAR EQ expr SCOL {mkeq (List.rev $2,$5)}
284

    
285
tuple_expr:
286
    expr COMMA expr {[$3;$1]}
287
| tuple_expr COMMA expr {$3::$1}
288

    
289
// Same as tuple expr but accepting lists with single element
290
array_expr:
291
  expr {[$1]}
292
| expr COMMA array_expr {$1::$3}
293

    
294
dim_list:
295
  dim RBRACKET { fun base -> mkexpr (Expr_access (base, $1)) }
296
| dim RBRACKET LBRACKET dim_list { fun base -> $4 (mkexpr (Expr_access (base, $1))) }
297

    
298
expr:
299
/* constants */
300
  INT {mkexpr (Expr_const (Const_int $1))}
301
| REAL {mkexpr (Expr_const (Const_real $1))}
302
| FLOAT {mkexpr (Expr_const (Const_float $1))}
303
/* Idents or type enum tags */
304
| IDENT {
305
  if Hashtbl.mem tag_table $1
306
  then mkexpr (Expr_const (Const_tag $1))
307
  else mkexpr (Expr_ident $1)}
308
| LPAR ANNOT expr RPAR
309
    {update_expr_annot $3 $2}
310
| LPAR expr RPAR
311
    {$2}
312
| LPAR tuple_expr RPAR
313
    {mkexpr (Expr_tuple (List.rev $2))}
314

    
315
/* Array expressions */
316
| LBRACKET array_expr RBRACKET { mkexpr (Expr_array $2) }
317
| expr POWER dim { mkexpr (Expr_power ($1, $3)) }
318
| expr LBRACKET dim_list { $3 $1 }
319

    
320
/* Temporal operators */
321
| PRE expr 
322
    {mkexpr (Expr_pre $2)}
323
| expr ARROW expr 
324
    {mkexpr (Expr_arrow ($1,$3))}
325
| expr FBY expr 
326
    {(*mkexpr (Expr_fby ($1,$3))*)
327
      mkexpr (Expr_arrow ($1, mkexpr (Expr_pre $3)))}
328
| expr WHEN IDENT 
329
    {mkexpr (Expr_when ($1,$3,tag_true))}
330
| expr WHENNOT IDENT
331
    {mkexpr (Expr_when ($1,$3,tag_false))}
332
| expr WHEN IDENT LPAR IDENT RPAR
333
    {mkexpr (Expr_when ($1, $5, $3))}
334
| MERGE IDENT handler_expr_list
335
    {mkexpr (Expr_merge ($2,$3))}
336

    
337
/* Applications */
338
| IDENT LPAR expr RPAR
339
    {mkexpr (Expr_appl ($1, $3, None))}
340
| IDENT LPAR expr RPAR EVERY IDENT
341
    {mkexpr (Expr_appl ($1, $3, Some ($6, tag_true)))}
342
| IDENT LPAR expr RPAR EVERY IDENT LPAR IDENT RPAR
343
    {mkexpr (Expr_appl ($1, $3, Some ($8, $6))) }
344
| IDENT LPAR tuple_expr RPAR
345
    {mkexpr (Expr_appl ($1, mkexpr (Expr_tuple (List.rev $3)), None))}
346
| IDENT LPAR tuple_expr RPAR EVERY IDENT
347
    {mkexpr (Expr_appl ($1, mkexpr (Expr_tuple (List.rev $3)), Some ($6, tag_true))) }
348
| IDENT LPAR tuple_expr RPAR EVERY IDENT LPAR IDENT RPAR
349
    {mkexpr (Expr_appl ($1, mkexpr (Expr_tuple (List.rev $3)), Some ($8, $6))) }
350

    
351
/* Boolean expr */
352
| expr AND expr 
353
    {mkpredef_call "&&" [$1;$3]}
354
| expr AMPERAMPER expr 
355
    {mkpredef_call "&&" [$1;$3]}
356
| expr OR expr 
357
    {mkpredef_call "||" [$1;$3]}
358
| expr BARBAR expr 
359
    {mkpredef_call "||" [$1;$3]}
360
| expr XOR expr 
361
    {mkpredef_call "xor" [$1;$3]}
362
| NOT expr 
363
    {mkpredef_unary_call "not" $2}
364
| expr IMPL expr 
365
    {mkpredef_call "impl" [$1;$3]}
366

    
367
/* Comparison expr */
368
| expr EQ expr 
369
    {mkpredef_call "=" [$1;$3]}
370
| expr LT expr 
371
    {mkpredef_call "<" [$1;$3]}
372
| expr LTE expr 
373
    {mkpredef_call "<=" [$1;$3]}
374
| expr GT expr 
375
    {mkpredef_call ">" [$1;$3]}
376
| expr GTE  expr 
377
    {mkpredef_call ">=" [$1;$3]}
378
| expr NEQ expr 
379
    {mkpredef_call "!=" [$1;$3]}
380

    
381
/* Arithmetic expr */
382
| expr PLUS expr 
383
    {mkpredef_call "+" [$1;$3]}
384
| expr MINUS expr 
385
    {mkpredef_call "-" [$1;$3]}
386
| expr MULT expr 
387
    {mkpredef_call "*" [$1;$3]}
388
| expr DIV expr 
389
    {mkpredef_call "/" [$1;$3]}
390
| MINUS expr %prec UMINUS
391
  {mkpredef_unary_call "uminus" $2}
392
| expr MOD expr 
393
    {mkpredef_call "mod" [$1;$3]}
394

    
395
/* If */
396
| IF expr THEN expr ELSE expr
397
    {mkexpr (Expr_ite ($2, $4, $6))}
398

    
399
handler_expr_list:
400
   { [] }
401
| handler_expr handler_expr_list { $1 :: $2 }
402

    
403
handler_expr:
404
 LPAR IDENT ARROW expr RPAR { ($2, $4) }
405

    
406
signed_const_array:
407
| signed_const { [$1] }
408
| signed_const COMMA signed_const_array { $1 :: $3 }
409

    
410
signed_const_struct:
411
| IDENT EQ signed_const { [ ($1, $3) ] }
412
| IDENT EQ signed_const COMMA signed_const_struct { ($1, $3) :: $5 }
413

    
414
signed_const:
415
  INT {Const_int $1}
416
| REAL {Const_real $1}
417
| FLOAT {Const_float $1}
418
| IDENT {Const_tag $1}
419
| MINUS INT {Const_int (-1 * $2)}
420
| MINUS REAL {Const_real ("-" ^ $2)}
421
| MINUS FLOAT {Const_float (-1. *. $2)}
422
| LCUR signed_const_struct RCUR { Const_struct $2 }
423
| LBRACKET signed_const_array RBRACKET { Const_array $2 }
424

    
425
dim:
426
   INT { mkdim_int $1 }
427
| LPAR dim RPAR { $2 }
428
| IDENT { mkdim_ident $1 }
429
| dim AND dim 
430
    {mkdim_appl "&&" [$1;$3]}
431
| dim AMPERAMPER dim 
432
    {mkdim_appl "&&" [$1;$3]}
433
| dim OR dim 
434
    {mkdim_appl "||" [$1;$3]}
435
| dim BARBAR dim 
436
    {mkdim_appl "||" [$1;$3]}
437
| dim XOR dim 
438
    {mkdim_appl "xor" [$1;$3]}
439
| NOT dim 
440
    {mkdim_appl "not" [$2]}
441
| dim IMPL dim 
442
    {mkdim_appl "impl" [$1;$3]}
443

    
444
/* Comparison dim */
445
| dim EQ dim 
446
    {mkdim_appl "=" [$1;$3]}
447
| dim LT dim 
448
    {mkdim_appl "<" [$1;$3]}
449
| dim LTE dim 
450
    {mkdim_appl "<=" [$1;$3]}
451
| dim GT dim 
452
    {mkdim_appl ">" [$1;$3]}
453
| dim GTE  dim 
454
    {mkdim_appl ">=" [$1;$3]}
455
| dim NEQ dim 
456
    {mkdim_appl "!=" [$1;$3]}
457

    
458
/* Arithmetic dim */
459
| dim PLUS dim 
460
    {mkdim_appl "+" [$1;$3]}
461
| dim MINUS dim 
462
    {mkdim_appl "-" [$1;$3]}
463
| dim MULT dim 
464
    {mkdim_appl "*" [$1;$3]}
465
| dim DIV dim 
466
    {mkdim_appl "/" [$1;$3]}
467
| MINUS dim %prec UMINUS
468
  {mkdim_appl "uminus" [$2]}
469
| dim MOD dim 
470
    {mkdim_appl "mod" [$1;$3]}
471
/* If */
472
| IF dim THEN dim ELSE dim
473
    {mkdim_ite $2 $4 $6}
474

    
475
locals:
476
  {[]}
477
| VAR vdecl_list SCOL {$2}
478

    
479
vdecl_list:
480
    vdecl {$1}
481
| vdecl_list SCOL vdecl {$3 @ $1}
482

    
483
vdecl:
484
/* Useless no ?*/    ident_list
485
    {List.map mkvar_decl 
486
        (List.map (fun id -> (id, mktyp Tydec_any, mkclock Ckdec_any, false)) $1)}
487

    
488
| ident_list COL typeconst clock 
489
    {List.map mkvar_decl (List.map (fun id -> (id, mktyp $3, $4, false)) $1)}
490
| CONST ident_list COL typeconst /* static parameters don't have clocks */
491
    {List.map mkvar_decl (List.map (fun id -> (id, mktyp $4, mkclock Ckdec_any, true)) $2)}
492

    
493
cdecl_list:
494
  cdecl SCOL { [$1] }
495
| cdecl_list cdecl SCOL { $2::$1 }
496

    
497
cdecl:
498
    IDENT EQ signed_const {
499
      let c = {
500
	const_id = $1;
501
	const_loc = Location.symbol_rloc ();
502
        const_type = Types.new_var ();
503
	const_value = $3;
504
      } in
505
      Hashtbl.add consts_table $1 c; c
506
    }
507

    
508
clock:
509
    {mkclock Ckdec_any}
510
| when_list
511
    {mkclock (Ckdec_bool (List.rev $1))}
512

    
513
when_cond:
514
    WHEN IDENT {($2, tag_true)}
515
| WHENNOT IDENT {($2, tag_false)}
516
| WHEN IDENT LPAR IDENT RPAR {($4, $2)}
517

    
518
when_list:
519
    when_cond {[$1]}
520
| when_list when_cond {$2::$1}
521

    
522
ident_list:
523
  IDENT {[$1]}
524
| ident_list COMMA IDENT {$3::$1}
525

    
526
SCOL_opt:
527
    SCOL {} | {}
(38-38/48)