(** Analyse syntaxique **) (* Analyse lexcicale *) open Genlex;; let rec list_of_stream = parser | [< 'a; q = list_of_stream >] -> a::q | [< >] -> [] ;; 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 = begin let (a,new) = read_nb (Int 0, lex_liste) in read_Restexpr a new end 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");;