(** Analyse syntaxique **) (* Analyse lexcicale *) #open "genlex";; let rec list_of_stream the_stream = try let (t,q)=stream_get the_stream in t::(list_of_stream q) with Parse_error -> [] | Parse_failure -> [] ;; let lexer chaîne = list_of_stream (make_lexer ["("; ")"; "-"; "+"; "/"; "*"; "^"] (stream_of_string chaîne));; (* lexer "7 * (5 - 2)";; *) (* Analyse syntaxique *) type Tree = |tree_int of int | tree_float of float |tree_plus of Tree*Tree | tree_moins of Tree*Tree |tree_mult of Tree*Tree | tree_divi of Tree*Tree |tree_expo of Tree*Tree | tree_oppo of Tree ;; let read lexemes = let reste=ref lexemes and fin=(Kwd "fin") in let avancer()=(reste:=tl !reste) and terminal_courant ()=match !reste with |[] -> fin |premier::_ -> premier in let rec read_Input()= let expr=read_expr() in read_eof expr and read_expr()= read_Restexpr (read_nb()) and read_nb()=match terminal_courant() with |Int nb -> avancer(); tree_int nb |Float nb -> avancer(); tree_float nb |_ -> failwith "Erreur : manque un nombre" and read_Restexpr arbre =match terminal_courant() with |Kwd "+" -> avancer(); read_Restexpr (tree_plus(arbre, read_nb())) |Kwd "-" -> avancer(); read_Restexpr (tree_moins(arbre, read_nb())) |Kwd "*" -> avancer(); read_Restexpr (tree_mult(arbre, read_nb())) |Kwd "/" -> avancer(); read_Restexpr (tree_divi(arbre, read_nb())) |_ -> arbre and read_eof arbre = if terminal_courant()=fin then arbre else failwith "Pas de fin" in read_Input();; let read_fct lexemes = let fin=(Kwd "fin") in let avancer (_,liste) = match liste with |[] -> (fin,liste) |t::q -> (t,q) and terminal_courant = function |[] -> fin |premier::_ -> premier in let rec read_Input lex_liste= let expr=(let (a,new)=read_nb (Int 0, lex_liste) in read_Restexpr a new) in (if (fst expr)=fin then (snd expr) else failwith "Pas de fin") and read_nb couple = let (x,l)=avancer couple in match x with |Int nb -> (tree_int nb,avancer (x,l)) |Float nb -> (tree_float nb,avancer (x,l)) |_ -> failwith "Erreur : manque un nombre" and read_Restexpr arbre (x,l) = match x with |Kwd "+" -> (let (b,new)=read_nb (x,l) in read_Restexpr (tree_plus(arbre, b)) new) |Kwd "-" -> (let (b,new)=read_nb (x,l) in read_Restexpr (tree_moins(arbre, b)) new) |Kwd "*" -> (let (b,new)=read_nb (x,l) in read_Restexpr (tree_mult(arbre, b)) new) |Kwd "/" -> (let (b,new)=read_nb (x,l) in read_Restexpr (tree_divi(arbre, b)) new) |_ -> (x,arbre) in read_Input lexemes;; read_fct (lexer "1 - 2 + 3");;