-- RECONNAISSEUR POUR DES EXPRESSIONS SIMPLES.
--
-- SYNTAXE :    calc   ::=    E* '='
--              E      ::=    num (op num)* '='
--              op     ::=     '+' | '_' | '*'
--
-- LEXICOGRAPHIE :    num       ::=    chiffre+
--                   chiffre    ::=   '0' | ... | '9'
--                   separ      ::=    ' ' | retour-ligne
--
-- procedure tester_calc ;
--    . teste si une entrée et correcte
--    . leve erreur_syntaxique si ce n'est pas le cas
--    . utilise la fonction lire_mot
--
-- function lire_mot return TOKEN
--    . reconnait un mot a partir du premier caractere non reconnu de la ligne
--    . leve erreur_lexicale si la reconnaissance est impossible
--    . utilise la fonction lire
--
-- function lire_car return character ;
--    . lit un caractere


with text_io; use text_io;

procedure reconnaitre is
type TOKEN is (NUM, PLUS, MOINS, MULT, EGAL,FF);
cc : character;
erreur_lexicale, erreur_syntaxique : exception;

-- pour l'évaluation
subtype Indice is Character range '0'..'9';
Chiffres: constant array(Indice) of Natural := (0,1,2,3,4,5,6,7,8,9);

-- FONCTION LIRE_CAR
function lire_car return character is
begin
   if  end_of_file then return ASCII.NUL;
   elsif  end_of_line then skip_line ; return ASCII.LF;
   else get(cc); return cc ; end if;
end lire_car;

-- FONCTION LIRE_MOT
function lire_mot return Token is
begin
   -- on saute les separateurs
   while cc = ' ' or cc=ASCII.LF loop cc := lire_car; end loop;
   case cc is
      when '0'..'9' => cc := lire_car;
                       while cc in '0'..'9'  loop cc := lire_car; end loop;
                       return(NUM);
      when  '+'  =>   cc := lire_car; return(PLUS);
      when  '-'  =>   cc := lire_car; return(MOINS);
      when  '*'  =>   cc := lire_car; return(MULT);
      when '='   =>   cc := lire_car; return (EGAL);
      when ASCII.NUL  =>   return (FF);
      when others =>   raise erreur_lexicale;
   end case;
end lire_mot ;


procedure tester_calc is

   mot_cour : token;

begin
   mot_cour:= lire_mot;
     while mot_cour = NUM loop
     mot_cour:= lire_mot;
     while mot_cour = PLUS or mot_cour = MOINS or mot_cour = MULT loop
        mot_cour:= lire_mot;
        if mot_cour /= NUM then raise erreur_syntaxique ; end if;
        mot_cour:= lire_mot;
     end loop;
    if mot_cour /= EGAL then raise erreur_syntaxique ;end if;
    mot_cour:= lire_mot;
    end loop ;
  if mot_cour /= EGAL then raise erreur_syntaxique ;end if;
  mot_cour:= lire_mot;
 if mot_cour /= FF then raise erreur_syntaxique ;end if;
 Put_Line("fin de session - merci d'avoir utilise LACA") ;
end tester_calc;

-- CORPS DE RECONNAITRE
begin
cc := lire_car ;   -- pour respect invariant de lire_mot
tester_calc ;

exception
   when erreur_lexicale => put_line ("erreur lexicale");
   when erreur_syntaxique => put_line ("erreur syntaxique");

end reconnaitre ;
