%{ open Misc open Signature open Names open Ident open Types open Location open Minils let mk_exp = mk_exp ~loc:(current_loc()) let mk_node = mk_node ~loc:(current_loc()) let mk_equation p e = mk_equation ~loc:(current_loc()) p e let mk_type name desc = mk_type_dec ~loc:(current_loc()) ~type_desc: desc name let mk_var name ty = mk_var_dec name ty %} %token DOT LPAREN RPAREN LBRACE RBRACE COLON SEMICOL %token EQUAL EQUALEQUAL BARBAR COMMA BAR LET TEL %token CONSTRUCTOR %token NAME %token INT %token FLOAT %token BOOL %token CHAR %token STRING %token PRAGMA %token TYPE FUN NODE RETURNS VAR OPEN %token FBY PRE SWITCH WHEN EVERY %token OR STAR NOT %token AMPERSAND %token AMPERAMPER %token AUTOMATON %token PRESENT %token RESET %token STATE %token UNLESS %token UNTIL %token EMIT %token LAST %token IF %token THEN %token ELSE %token DEFAULT %token DO %token CONTINUE %token CASE %token CONTRACT %token ASSUME %token ENFORCE %token WITH %token INLINED %token AT %token PREFIX %token INFIX0 %token INFIX1 %token INFIX2 %token SUBTRACTIVE %token INFIX3 %token INFIX4 %token EOF %nonassoc prec_ident %left IF ELSE %right ARROW %nonassoc EVERY %left OR %left AMPERSAND %left INFIX0 EQUAL %right INFIX1 %left INFIX2 SUBTRACTIVE %left STAR INFIX3 %left INFIX4 %right prefixs %right FBY %right PRE %right LAST %right prec_apply %left DOT %start program %type program %% /*TODO deal with when merge and co*/ /*TODO add arrow ?*/ /*TODO be happy with the tools*/ /** Tools **/ /* Redefinitions */ %inline option_list(x) : l=list(x) {l} %inline list(x) : l=nonempty_list(x) {l} %inline option_slist(S, x) : l=separated_list(S, x) {l} %inline slist(S, x) : l=separated_nonempty_list(S, x) {l} %inline nuple(L, R, S, x) : L h=x S t=slist(S,x) R { h::t } %inline stuple(S, x) : LPAREN h=x S t=slist(S,x) RPAREN { h::t } %inline tuple(x) : t=stuple(COMMA,x) { t } %inline option2(P,x) : /* empty */ { None } | P v=x { Some(v)} qualified(x) : | n=x { Name(n) } %prec prec_ident | m=CONSTRUCTOR DOT n=x { Modname({ qual = m; id = n }) } structure(field): s=nuple(LBRACE, RBRACE, SEMICOL, field) {s} program: | pragma_headers open_modules type_decs node_decs EOF {{ p_pragmas = List.rev $1; p_opened = List.rev $2; p_types = $3; p_nodes = $4; p_consts = []}} /*TODO consts dans program*/ pragma_headers: l=option_list(pragma) {l} pragma: p=PRAGMA {p} open_modules: l=option_list(opens) {l} opens: OPEN c=CONSTRUCTOR {c} ident: n=NAME | LPAREN n=infix RPAREN | LPAREN n=prefix RPAREN { n } field_type : n=NAME COLON t=type_ident { (n, t) } type_ident: NAME { Tid(Name($1)) } type_decs: t=option_list(type_dec) {t} type_dec: | TYPE n=NAME { mk_type n Type_abs } | TYPE n=NAME EQUAL e=slist(BAR,NAME) { mk_type n (Type_enum e) } | TYPE n=NAME EQUAL s=structure(field_type) { mk_type n (Type_struct s) } node_decs: ns=option_list(node_dec) {ns} node_dec: NODE id=ident LPAREN args=params RPAREN RETURNS LPAREN out=params RPAREN vars=loc_vars LET eqs=equs TEL { mk_node ~input: args ~output: out ~local: vars ~eq: eqs id } params: p=option_slist(SEMICOL, var) {p} loc_vars: | /* empty */ { [] } | VAR vs=slist(SEMICOL, var) { vs } var: | ns=slist(COMMA, NAME) COLON t=type_ident { List.map (fun id -> mk_var id t) ns } equs: e=option_slist(SEMICOL, equ) ?SEMICOL {e} equ: p=pat EQUAL e=exp { mk_eq p e } pat: | n=NAME {Evarpat (ident_of_name n)} | LPAREN p=slist(COMMA, pat) RPAREN {Etuplepat p} longname: l=qualified(ident) {l} constructor: | ln=qualified(CONSTRUCTOR) {ln} | b=BOOL { Name(if b then "true" else "false") } const: | INT { Cint($1) } | FLOAT { Cfloat($1) } | constructor { Cconstr($1) } exps: LPAREN e=option_slist(COMMA, exp) RPAREN {e} tuple_exp: LPAREN e=option_slist(COMMA, exp) RPAREN {e} field_exp: longname EQUAL exp { ($1, $3) } simple_exp: | NAME { mk_exp (Evar (ident_of_name $1)) } | c=const { mk_exp (Econst c) } | s=structure(field_exp) { mk_exp (Estruct s) } | t=tuple_exp { mk_exp (Etuple t) } | LPAREN e=exp RPAREN { e } exp: | e=simple_exp { e } | const FBY exp { make_exp (Efby(Some($1),$3)) } | PRE exp { make_exp (Efby(None,$2)) } | longname LPAREN exps RPAREN %prec prec_apply { make_exp (Eapp(make_app $1 Ino, $3)) } | INLINED longname LPAREN exps RPAREN %prec prec_apply { make_exp (Eapp(make_app $2 Irec, $4)) } | e1=exp op=infix e2=exp { make_exp (Eop(Name(op), [e1; e2])) } | op=prefix e=exp %prec prefixs { make_exp (Eop(Name(op), [e])) } | IF exp THEN exp ELSE exp { make_exp (Eifthenelse($2, $4, $6)) } | exp DOT longname { make_exp (Efield($1, $3)) } %inline infix: | op=INFIX0 | op=INFIX1 | op=INFIX2 | op=INFIX3 | op=INFIX4 { op } | STAR { "*" } | EQUAL { "=" } | EQUALEQUAL { "==" } | AMPERSAND { "&" } | AMPERAMPER { "&&" } | OR { "or" } | BARBAR { "||" } prefix: | op = PREFIX { op } | NOT { "not" } | op = SUBTRACTIVE { "~" ^ op } /*TODO test 3 * -2 and co */ %%