IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Caml Discussion :

Aide pour déboguer un analyseur lexical


Sujet :

Caml

  1. #1
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 43
    Points : 65
    Points
    65
    Par défaut Aide pour déboguer un analyseur lexical
    Voila je débute en Ocaml et j'ai eu envie de coder une application pour tracer les fonctions mathématiques, j'ai donc commencé par coder un analyseur lexical, et étant nouveau j'ai beaucoup de mal a trouver le bogue qui c'est glissé dans mon code j'ai du mal a utiliser ocamlDebug . voila donc mon Code si une ame charitable voulait bien m'aider sa serait gentil.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    open Str;;
    open Printf;;
    type achaine = {chaine:string; mutable courant:int; taille:int};;
    type token =
        TEOS of unit            (**lexeme représentant la fin de l'expression*)
        |TInt of int            (**lexeme representant un entier             *)
        |TFloat of float        (**lexeme representant un flotant            *)
        |TVar of string         (**lexeme représentant une variable          *)
        |TOp_Bin of string      (**lexeme représentant un opérateur binaire  *)
        |TOp_Unr of string      (**lexeme représentant un opérateur unaire   *)
        |TFonction of string ;; (**lexeme représentant une fonction de base  *)
    (* avance : achaine -> unit*)
    let avance a = a.courant<-a.courant + 1;;
    (* avance : achaine -> unit*)
    let avancen a n = a.courant<-a.courant + n;;
    (* extraitVar : char -> string *)
    let extraitVar x = String.make 1 x;;
     
    (* regex permetant de tester si le début d'une chaine de caractere contient un
     * fonction connue de l'analyseur                                       *)
     
    let foncRegex = 
        Str.regexp "\\(exp\\|ln\\|log\\|sin\\|cos\\|tan\\|cotan\\|arcsin\\|arccos\\|arctan\\|arccotan\\|ch\\|sh\\|th\\|coth\\|argch\\|argsh\\|argth\\|argcoth\\|sqrt\\)" ;;
    (* Regex Permetant de tester si le début d'une chaine de caractère contient un
     * Float *)
    let floatRegex = Str.regexp "[0-9]+\\.[0-9]+" ;;
    (* Regex permetant de tester si le début d'une cahine de caractere contient un
     * entier*)
    let intRegex = Str.regexp "[0-9]+";;
    (* Vérifier d'abord les Floats avant les Int*)
     
    exception ParseError;;
    exception FParseError;;
    (*ilexer achaine->token list*)
    let rec ilexer s =
        let fExtraction = 
        (* test succesivement les différentes regex et renvoie le lexeme qui
         * convient selon la situation en avançant le point courant de la
         * chaine*)
            let extraction c = match c with 
                (* Fonction qui a pour vocation d'extraire les opérateur binaires,
                 *  Unaires et les variables *)
                'x' | 'y'                    -> avance s; TVar (extraitVar c)
                |'+' | '-' | '*' | '^' | '/' -> avance s; TOp_Bin (String.make 1 c)
                |'(' | ')'                   -> avance s; TOp_Unr (String.make 1 c)
                | _                          -> raise ParseError 
            in if ( Str.string_match foncRegex s.chaine s.courant ) = true then 
                let a = (Str.matched_string (s.chaine)) in 
                avancen s (String.length a) ;
                TFonction a 
            else if ( Str.string_match floatRegex s.chaine s.courant ) = true then
                let a = (Str.matched_string (s.chaine)) in
                avancen s (String.length a);
                TFloat (float_of_string a)
            else if ( Str.string_match intRegex s.chaine s.courant ) = true then
                let a = (Str.matched_string (s.chaine)) in 
                avancen s (String.length a);
                TInt (int_of_string a)
            else
               try let b = String.get s.chaine s.courant in extraction b
               with ParseError -> failwith "Erreur format"
        in  
            if s.courant < s.taille then 
                let a = fExtraction in
                 a :: (ilexer s) 
            else [TEOS ()];; 
    (* lexer : string -> token list *)
    let lexer s =
        let cl={chaine = s; courant = 0; taille = String.length s } in ilexer cl;;
    (*printlistlexer : token list -> unit ()*)
    donc Merci d'avance pour votre aide et bonne journée

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Points : 1 104
    Points
    1 104
    Par défaut
    Quel est le message d'erreur ou le comportement inattendu ? Quelle entrée donnes-tu qui produit un mauvais résultat ? As-tu une entrée qui produit un résultat correct ?

  3. #3
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 43
    Points : 65
    Points
    65
    Par défaut
    J'ai un stack overflow quelque soit le type de chaine que je passe en parametre a la fonction lexer.
    le programme tourne en rond et la fonction fextration renvoie un TInt tout le temp comme si le test sur les fonction et les Floats echoué a chaque fois je l'ai ai testé pourtant je pense que les regex sont juste.
    de plus la variable s.courant reste bloqué a 0 pendant tout la durée du programme.
    Voila ce matin j'ai essaye d'utiliser le déboguer mais le programme ne s'arrête jamais sur les break points que je mets et quand je mets
    break @ analyse 45
    il me mets un break points 5 ou 6 lignes plus loin

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Points : 1 104
    Points
    1 104
    Par défaut
    Tu es sûr que c'est bien ce que tu obtiens ?

    J'ai testé ton code, et je n'arrive pas à reproduire ce comportement.

    # lexer "";;
    Exception: Invalid_argument "index out of bounds".
    # lexer "1";;
    - : token list = [TEOS ()]
    # lexer "1+";;
    - : token list = [TInt 1; TEOS ()]
    # lexer "(1+x)";;
    - : token list = [TOp_Unr "("; TInt 1; TOp_Bin "+"; TVar "x"; TEOS ()]
    # lexer "(1+x+3.)";;
    Exception: Failure "Erreur format".
    # lexer "(1+x+3.0)";;
    - : token list =
    [TOp_Unr "("; TInt 1; TOp_Bin "+"; TVar "x"; TOp_Bin "+"; TFloat 3.; TEOS ()]
    # lexer "(1+x+3.0)y";;
    - : token list =
    [TOp_Unr "("; TInt 1; TOp_Bin "+"; TVar "x"; TOp_Bin "+"; TFloat 3.;
    TOp_Unr ")"; TEOS ()]
    Voilà les résultats que j'obtiens. Aucun "stack overflow", quelques "Erreur format", et des résultats auxquels ils manquent le dernier lexème la plupart du temps.

    Ce bug (disparition du dernier lexème) peut être corrigé en corrigeant une erreur de ton programme : fExtraction n'y est pas une fonction. Tu déclares "let fExtraction = ...", code qui est évalué immédiatement, et qui effectue donc toutes les manipulations décrites, en particulier l'avancée dans l'entrée. Du coup, comme tu avances avant de vérifier la position, le dernier caractère disparaît : au moment du dernier caractère, tu avances, donc ça sort de la limite, et ensuite tu testes donc il croit que c'est la fin.

    Pour corriger, c'est simple, il suffit de définir fExtraction comme une fonction, dont le corps sera évalué non pas à l'endroit de sa définition, mais au moment de son appel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    let fExtraction () =
     ...
    in
    ...
    let a = fExtraction () in a :: ilexer s
    Ainsi, fExtraction est une fonction qui prend l'argument "()", et qui ne sera évaluée que dans la branche "then" du test "if s.courant < s.taille".



    Par ailleurs, ta méthode pour lexer est assez archaïque. En OCaml on utiliserait plutôt des structures de données plus adaptées à la récursion et au parcours en retirant des éléments du début, comme :
    - des listes
    - des flots (Stream.t)

    Avec les flots, il existe même une bibliothèque qui te fait le travail gratuitement, Genlex.

  5. #5
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 43
    Points : 65
    Points
    65
    Par défaut
    Merci Beaucoup pour ta réponse, je suis Etudiant et j'ai surtout appris a programmer de manière impérative, j'essaye d'apprendre Ocaml depuis 15 jours et je sais que Ocamlex fait sa gratuitement mais j'avais envie d'essayer pour apprendre.
    Sinon merci de m'avoir signalé que la méthode était archaïques j'en prend note et je vais essayer de l'améliorer dans les prochains jours merci.
    Bonne Continuation et encore merci pour la réponse rapide a la question.
    Je marque comme résolu

  6. #6
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    Citation Envoyé par dillinger91 Voir le message
    Merci Beaucoup pour ta réponse, je suis Etudiant et j'ai surtout appris a programmer de manière impérative, j'essaye d'apprendre Ocaml depuis 15 jours et je sais que Ocamlex fait sa gratuitement mais j'avais envie d'essayer pour apprendre.
    Oui oui, ocamllex fait sa gratuitement parce que OCaml est gratuit. Tu n'as pas besoin de payer l'INRIA pour le télécharger.

    Dénonce l'abruti qui t'a dit une connerie pareille, et on mettra les pendules à l'heure !
    When Colt produced the first practical repeating handgun, it gave rise to the saying God created men, but Colt made them equal.

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Points : 1 104
    Points
    1 104
    Par défaut
    Je suppose qu'il utilisait "gratuitement" dans le même sens que dans mon message, à savoir « sans effort d'implémentation de notre côté ».

  8. #8
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    J'ai bien compris, mais c'est justement celà qui est faux. Tu dois toujours gérer explicitement, et si possible proprement, tous un tas de merdes qui peuvent survenir... ou ton analyseur sera inutilisable.
    When Colt produced the first practical repeating handgun, it gave rise to the saying God created men, but Colt made them equal.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Aide pour déboguer
    Par Kluzot dans le forum Débuter
    Réponses: 2
    Dernier message: 18/02/2011, 09h17
  2. aide pour créer un analyseur
    Par safy05 dans le forum Débuter
    Réponses: 2
    Dernier message: 13/10/2010, 21h02
  3. [Flex] Méthode pour écrire un analyseur lexical
    Par sousan dans le forum Générateurs de compilateur
    Réponses: 2
    Dernier message: 15/02/2009, 10h34
  4. Analyseur lexical et syntaxique pour Caml
    Par ali-dev85 dans le forum Caml
    Réponses: 3
    Dernier message: 31/01/2009, 13h39
  5. Aide pour déboguer un code
    Par raou123 dans le forum Assembleur
    Réponses: 3
    Dernier message: 12/04/2006, 13h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo