2020-10-27 20:54:39
 
/* analyseur syntaxique pour le langage Julia */
 
%{
  open Ast
  open Lexing
%}
 
/* liste des tokens */
 
%token EOF
%token NEWLINE
 
%token RETURN ASSIGN END
 
%token FOR WHILE
%token ELSE ELSEIF IF
%token FUNCTION
%token MUTABLE STRUCT
 
%token <int64> CST
%token <string> IDENT
%token <string> STRING
 
%token ADD SUB MUL MOD POW
%token EQ DIFF LT LE GE GT
%token AND OR
 
%token SEMICOLON COMMA COLON DOT DOUBLECOLON
%token LPAR RPAR
 
%token <string> IDENT_PARG
%token <int64> ENTIER_PARG
%token <string> PARD_IDENT
%token <int64 * string> ENTIER_IDENT
 
%token NOT
 
%token TRUE FALSE
 
/* prioritées et associativitées des tokens */
 
%nonassoc RETURN
 
%nonassoc WHILE TRUE STRING LPAR IF IDENT_PARG IDENT FOR FALSE ENTIER_PARG ENTIER_IDENT CST
 
%right ASSIGN
%left OR
%left AND
%left EQ DIFF LT LE GE GT
%left ADD SUB
%left MUL MOD
%nonassoc UNARY_MINUS NOT
%right POW
%left DOT
 
/* point d'entrée */
%start file
 
/* type de retour */
%type <Ast.fichier> file
 
%%
 
file:
  decls = decl*
  EOF 
    { decls }
;
 
decl:
  | e = expr SEMICOLON
    { Dexpr e }
  | f = fonction
    { Dfun f }
  | s = structure
    { Dstruct s }
;
 
expr:
  e = expr_desc
    { {desc = e; loc = $startpos, $endpos} }
;
 
expr_desc:
  | SUB e = expr %prec UNARY_MINUS
    { Eunop (Uneg, e) }
  | NOT e = expr
    { Eunop (Unot, e) }
  | x = CST
    { Ecst (Cint x) }
  | s = STRING
    { Ecst (Cstring s) }
  | TRUE
    { Ecst (Cbool true) }
  | FALSE
    { Ecst (Cbool false) }
  | e = ENTIER_IDENT
    { Eentier_ident (fst e, snd e) } 
  | x = ENTIER_PARG b = bloc1 RPAR
    { Eentier_parg_bloc (x, b) }
  | LPAR b = bloc1 RPAR
    { Ebloc b }
  | LPAR e = expr id = PARD_IDENT
    { Epard_ident (e, id) }
  | id = IDENT_PARG l = separated_list(COMMA, expr) RPAR
    { Ecall (id, l) }
  | e1 = expr op = binop e2 = expr
    { Ebinop (e1, op, e2) }
  | l = lvalue ASSIGN e = expr
    { Eassign (l, e) }
  | l = lvalue
    { Elvalue l }
  | RETURN e=expr
    { Ereturn (Some e) }
  | RETURN
    { Ereturn None }
  | f = for_
    { f }
  | x = while_
    { x }
  | l = expr_bloc_if(IF) 
   { Eif(l) } 
;
 
%inline non_unit_expr:
  e = non_unit_expr_desc
    { {desc = e; loc = $startpos, $endpos} : expr}
;
non_unit_expr_desc:
  | x = CST
    { Ecst (Cint x) }
  | s = STRING
    { Ecst (Cstring s) }
  | TRUE
    { Ecst (Cbool true) }
  | FALSE
    { Ecst (Cbool false) }
  | e = ENTIER_IDENT
    { Eentier_ident (fst e, snd e) } 
  | x = ENTIER_PARG b = bloc1 RPAR
    { Eentier_parg_bloc (x, b) }
  | LPAR b = bloc1 RPAR
    { Ebloc b }
  | LPAR e = expr id = PARD_IDENT
    { Epard_ident (e, id) }
  | id = IDENT_PARG l = separated_list(COMMA, expr) RPAR
    { Ecall (id, l) }
  | e1 = non_unit_expr op = binop e2 = expr
    { Ebinop (e1, op, e2) }
  | l = non_unit_lvalue ASSIGN e = expr
    { Eassign (l, e) }
  | l = non_unit_lvalue
    { Elvalue l }
  | RETURN e=expr
    { Ereturn (Some e) }
  | RETURN
    { Ereturn None }
  | f = for_
    { f } 
  | x = while_
    { x }
  | l = expr_bloc_if(IF)
    { Eif(l) }
 
;
 
for_:
  FOR id = IDENT ASSIGN e1 = expr x = expr_bloc_loop(COLON)
    { Efor(id, e1, fst x, snd x) } 
 
while_:
  x = expr_bloc_loop(WHILE)
    { Ewhile(fst x, snd x) } 
 
expr_bloc_if(X):
  X e = expr l = else_
    { (Some e, []) :: l } 
  | X  e1 = expr e2 = non_unit_expr b = ioption(preceded(SEMICOLON, bloc)) l = else_
    { (Some e1, e2 :: (match b with None -> [] | Some x -> x)) ::  l }
  | X  e = expr SEMICOLON b = bloc l = else_
    { (Some e, b) :: l  }
;
 
expr_bloc_loop(X):
  X e = expr END
    { (e, []) }
  | X e1 = expr e2 = non_unit_expr b = ioption(preceded(SEMICOLON, bloc)) END
  { (e1, e2 :: (match b with None -> [] | Some l -> l))}
  | X e = expr SEMICOLON b = bloc END
    { (e, b) }
;
 
else_:
  | END
    { [] }
  | ELSE b=bloc END
    { [ None, b ] }
  | l = expr_bloc_if(ELSEIF)
    { l } 
;
 
%inline lvalue:
  | s = IDENT
    { LvalueIdent s } 
  | e = expr DOT id = IDENT
    { LvalueStruct (e, id) }
;
 
%inline non_unit_lvalue:
  | s = IDENT
    { LvalueIdent s }
  | e = non_unit_expr DOT id = IDENT
    { LvalueStruct (e, id) } 
;
 
%inline binop:
  | ADD {Badd} | SUB {Bsub} | MUL {Bmul} | MOD {Bmod} | POW {Bpow}
  | EQ {Beq} | DIFF {Bdiff} | LT {Blt} | LE {Ble} | GE {Bge} | GT {Bgt}
  | AND {Band} | OR {Bor}
;
 
bloc:
 
  l = separated_nonempty_list(SEMICOLON, ioption(expr))
  { 
    List.fold_right (fun x cur -> match x with | None -> cur | Some v -> v :: cur) l []
  }
;
 
fonction:
  FUNCTION id = IDENT_PARG l = separated_list(COMMA, param) RPAR t = option(preceded(DOUBLECOLON, IDENT)) b = bloc END SEMICOLON
    { 
      {
        loc = $startpos, $endpos;
        desc = (id, l, t, b)
      } : fonction
    }
;
 
param:
  id = IDENT t = preceded(DOUBLECOLON, IDENT)?
  { 
    {loc = $startpos, $endpos; desc = id, t } : param 
    }
;
 
bloc1:
  e = expr f = option(preceded(SEMICOLON, bloc))
  {  e :: (match f with | None -> [] | Some l -> l) }
;
 
structure:
  m = MUTABLE? STRUCT id=IDENT l = separated_nonempty_list(SEMICOLON, param?) END SEMICOLON
  { {desc = (match m with | None -> false | _ -> true), id, l;
    loc = $startpos, $endpos } : structure }
;
 
Invalid Email or Password