#open "langage";;
#open "alex";;
let rec analyse_programme s = Programme(analyse_prog s)
and analyse_prog = function
  | [< analyse_phrase ph; analyse_prog p >] -> ph :: p
  | [< 'Symbole `.` >] -> []
and analyse_phrase = function
  | [< 'Mot "pour"; 'Mot s; paramètres variables; suite_d'ordres ordres >] ->
     Pour (s, {Paramètres = variables; Corps = ordres})
  | [< ordre ord >] -> Ordre ord
and paramètres = function
  | [< 'Symbole `:`; 'Mot s; paramètres l >] -> s::l  | [<>] -> []
and ordre = function
  | [< '(Mot "avance" | Mot "av"); expression e >] -> Av e
  | [< '(Mot "recule" | Mot "re"); expression e >] -> Re e
  | [< '(Mot "droite" | Mot "td"); expression e >] -> Td e
  | [< '(Mot "gauche" | Mot "tg"); expression e >] -> Tg e
  | [< '(Mot "baisse_crayon" | Mot "bc") >] -> Bc
  | [< '(Mot "lève_crayon" | Mot "lc") >] -> Lc
  | [< '(Mot "vide_écran" | Mot "ve") >] -> Ve
  | [< 'Mot "stop" >] -> Stop
  | [< 'Mot "si"; expression e1; 'Symbole `>`; 'Symbole `=`; expression e2;
        liste_d'ordres alors; liste_d'ordres sinon >] -> Si (e1, e2, alors, sinon) 
  | [< '(Mot "répète" | Mot "rep");        expression e; liste_d'ordres l >] -> Rep (e,l)
  | [< 'Mot f; liste_d'expressions exprs >] -> Exécute (f, exprs)
and liste_d'ordres = function
  | [< 'Symbole `[`; suite_d'ordres l; 'Symbole `]` >] -> l
and suite_d'ordres = function
  | [< ordre ord; suite_d'ordres l >] -> ord::l
  | [<>] -> []
and nombre = function
  | [< 'Symbole `-`; nombre n >] ->
     begin match n with
     | Entier i -> Entier (-i)
     | Flottant f -> Flottant (-. f)
     end
  | [< 'Constante_entière i >] -> Entier i
  | [< 'Constante_flottante f >] -> Flottant f
and expression_simple = function
  | [< nombre n >] -> Constante n
  | [< 'Symbole `:`; 'Mot var >] -> Variable var
  | [< 'Symbole `(`; expression e; 'Symbole `)` >] -> e
and expression = function
  | [< expression_simple e; (reste_de_l'expression e) e' >] -> e'
and reste_de_l'expression e = function
  | [< 'Symbole `+`; expression e2 >] -> Somme (e, e2)
  | [< 'Symbole `*`; expression e2 >] -> Produit (e, e2)
  | [< 'Symbole `-`; expression e2 >] -> Différence (e, e2)
  | [< 'Symbole `/`; expression e2 >] -> Quotient (e, e2)
  | [< >] -> e
and liste_d'expressions = function
  | [< expression exp; liste_d'expressions l >] -> exp::l
  | [<>] -> [];;
