1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
type variable = string and typvar = string
type valeur =
| Entier of int
| Reel of float
| Booleen of bool
type expr =
| Val of valeur
| Somme of expr * expr (* a+b *)
| Mult of expr * expr (* a*b *)
| Non of expr
| Ou of expr * expr
| Et of expr * expr
| Egal of expr * expr (* e1=e2 ? *)
| PlusGrand of expr * expr (* e1 > e2 ? *)
| Ifte of expr * expr * expr (* Si e1 Alors e2 Sinon e3 *)
| Var of variable (* décommenter pour q2 *)
| Def of variable * expr * expr (* Soit x = e1 dans e2 *)
(* décommenter pour q4 *)
| Fonction of variable * expr (* x -> e *) (* décommenter pour q6 *)
type type_ =
| TEntier
| TReel
| TBooleen
(* | TVar of typvar (* alpha, beta *)
| TFonction of type_ * type_ *)
(*************** Parser (+Genlex) ************)
open Genlex
let lexer = make_lexer ["+";"*";"(";")";"soit";"Soit";"dans";"=";
"non";"ou";"et";">";"vrai";"faux";"->";
"Si";"si";"Alors";"alors";"Sinon";"sinon"]
let rec stream_to_list s =
match Stream.peek s with
| None -> []
| Some a -> Stream.junk s;a::(stream_to_list s)
exception Syntax_error of string * token list
(* TODO :
utiliser camlp4 pour pouvoir utiliser directement "parser" les Stream !
*)
let parse liste = (* liste : token list *)
let rec parse_expr =
function
| (Int n)::r -> (Val (Entier n)),r
| (Float x)::r -> (Val (Reel x)),r
| (Kwd "vrai")::r -> (Val (Booleen true)),r
| (Kwd "faux")::r -> (Val (Booleen false)),r
| (Kwd "non")::r ->
let e,fin = parse_expr r in (Non e),fin
| (Kwd "(")::r -> parse_closing r
(* parenthèse ouvrante : déléguer. *)
| (Kwd "Si")::r | (Kwd "si")::r -> parse_if r
| (Ident s)::r -> (Var s),r (* décommenter pour q2 *)
| (Kwd "Soit")::r | (Kwd "soit")::r -> parse_let r
(* décommenter pour q4 *)
(* définition : déléguer. *)
| e -> raise (Syntax_error ("expr",e))
and parse_closing expr =
(* expr dans des parenthèses. Rq : on peut en fermer trop.*)
let (e,l) = parse_full expr in
match l with
| (Kwd ")")::r -> (e,r)
| _ -> raise (Syntax_error ("closing",l))
and parse_let = (* décommenter pour q4 *)
function
| (Ident s)::(Kwd "=")::r ->
begin
let e1,ein = parse_expr r in
match ein with
| (Kwd "dans")::rr ->
let e2,fin = parse_expr rr in Def(s,e1,e2),fin
| _ -> raise (Syntax_error ("dans",ein))
end
| e -> raise (Syntax_error ("let",e))
and parse_if expr =
let (e,l) = parse_expr expr in
match l with
| (Kwd "Alors")::r | (Kwd "alors")::r -> parse_then e r
| _ -> raise (Syntax_error ("if",expr))
and parse_then test expr =
let etrue,l = parse_expr expr in
match l with
| (Kwd "Sinon")::r | (Kwd "sinon")::r ->
let efalse,fin = parse_expr r in Ifte (test,etrue,efalse),fin
| _ -> raise (Syntax_error ("then",l))
and parse_full expr = (* expr complète *)
let (e1,l) = parse_expr expr in
match l with
| [] -> e1,l
| (Kwd ")")::_ -> e1,l (* parenthèse fermante remontée à parse_closing. *)
| (Kwd "+")::r -> let e2,rr = parse_full r in (Somme (e1,e2)),rr
| (Kwd "*")::r -> let e2,rr = parse_full r in (Mult (e1,e2)),rr
| (Kwd "ou")::r -> let e2,rr = parse_full r in (Ou (e1,e2)),rr
| (Kwd "et")::r -> let e2,rr = parse_full r in (Et (e1,e2)),rr
| (Kwd "=")::r -> let e2,rr = parse_full r in (Egal (e1,e2)),rr
| (Kwd ">")::r -> let e2,rr = parse_full r in (PlusGrand (e1,e2)),rr
| (Kwd "->")::r -> let e2,rr = parse_full r in
begin (* décommenter pour q6 *)
match e1 with
| Var s -> (Fonction (s,e2)),rr
| _ -> raise (Syntax_error ("fun",r))
end
| _ -> raise (Syntax_error ("full",l))
in fst (parse_full liste)
let string_to_expr s = parse (stream_to_list (lexer (Stream.of_string s))) |
Partager