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 :

Utilisation de Arg.parse


Sujet :

Caml

  1. #1
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    402
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 402
    Points : 337
    Points
    337
    Par défaut Utilisation de Arg.parse
    Bonjour,

    Je souhaiterais utiliser le Arg.parse pour parser les arguments envoyes a mon executable.

    Je l'utilise tel que :

    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
     
    open Sys;;
    open Array;;
    open List;;
    open Arg;;
     
    let nb = "";;
     
    let my_func nb = match nb with
      | "2" -> print_string "appel binair"
      | "10" -> print_string "appel decimal"
      | _ -> print_string "Error : bad argument"
    ;;
     
    let main () = Arg.parse [("-l", Arg.String( fun toto -> my_func toto ), "./my_func -l argument1")];;
     
    let _ = main ()
    mais j'utilise mal le Arg.String ... pour l'instant ca ne fait rien :/ je ne sais pas comment l'utiliser.

    Merci de votre aide.

  2. #2
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2010
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Octobre 2010
    Messages : 22
    Points : 39
    Points
    39
    Par défaut
    As tu lu la doc du module Arg ?
    Notamment la signature :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    val parse : (key * spec * doc) list -> anon_fun -> usage_msg -> unit
    Il te manque anon_fun et usage_msg, non ?
    Et puis pourquoi vouloir utiliser Arg.String alors que tu cherches à passer des entiers, Arg.Int me semble plus adapté. Je te met un exemple d'utilisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    let _ = 
      let mode = ref 0 in
      Arg.parse ["-l", Arg.Set_int mode, "2 pour le binaire, 10 pour le décimal",fun _ -> (), "usage : "];
      print_endline (string_of_int !mode)

  3. #3
    LLB
    LLB est déconnecté
    Membre expérimenté
    Inscrit en
    Mars 2002
    Messages
    967
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 967
    Points : 1 410
    Points
    1 410
    Par défaut
    Citation Envoyé par zouuc Voir le message
    let _ = main ()
    Pourquoi cette ligne ? Tu appelles main et tu ignores sa valeur de retour. En l'occurrence, tu te fais avoir par l'application partielle (et ta fonction main renvoie une fonction). Prends l'habitude de faire plutôt comme ça :

    Le compilateur peut alors t'aider et te montrer ton erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Error: This expression has type Arg.anon_fun -> Arg.usage_msg -> unit
           but an expression was expected of type unit

  4. #4
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    402
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 402
    Points : 337
    Points
    337
    Par défaut
    merci d'avoir repondu

    En fait je vois pas comment faire l'appel a ma fonction my_func dans le Arg.parse
    Si ma fonction est déclaré plus haut ça ne pause aucun problème ?
    Donc admettons que je veuille faire appel a cette fonction a la place de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Arg.parse ["-l", Arg.Set_int mode, "2 pour le binaire, 10 pour le décimal",fun _ -> (), "usage : "];
    ça donnerait quoi ?

    Une autre question, si j'utilise Arg.Int a la place de Arg.Set_int ça change quelque chose ?

    Je ne cache rien, je suis une bille en CAML, je débute, je ne comprend pas toute la donc non plus, et les messages d'erreur en CAML (je vais p-e loin) je ne les trouve pas tres explicite ^^

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2010
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Octobre 2010
    Messages : 22
    Points : 39
    Points
    39
    Par défaut
    Il te faut comprendre le typage, sans ça tu n'iras pas très loin. Il faut dire qu'avec Arg tu ne commences pas par le plus facile.
    Si tu regardes la différence entre Arg.Int et Arg.Set_int au niveau de leurs types :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    | Int of (int -> unit)	(*	Call the function with an int argument	*)
    | Set_int of int ref	(*	Set the reference to the int argument	*)
    tu vois que Int prend en paramètre une fonction, qui elle même prend un entier en paramètre et renvoie unit, c'est à dire rien: à priori elle aura un effet de bord, soit un print, soit positionner une référence, etc. Le cas le plus fréquent étant de vouloir positionner une référence que l'on ira lire par la suite, Set_int permet de faire directement cela, en prenant en paramètre une référence sur un entier.

  6. #6
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Bonsoir,

    Une autre question, si j'utilise Arg.Int a la place de Arg.Set_int ça change quelque chose ?
    La réponse est dans la définition du module Arg : le constructeur Int est associé à une fonction de type int -> unit alors que Set_int reçoit une référence sur un entier (type int ref). Donc, oui, ces deux constructeurs ne s'utilisent pas de la même façon... sachant que Int est le plus général.

    Cordialement,
    Cacophrène

  7. #7
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    402
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 402
    Points : 337
    Points
    337
    Par défaut
    merci pour vos réponses.

    Si j'ai bien compris, pour faire appel a une fonction my_func int -> unit, qui prend donc un int en paramètre et retourne un unit, je devrais plutôt utiliser le Arg.Int ?
    Ne pourrais-je pas faire quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    let mode = ref 0 in
     Arg.parse ["-obase", Arg.Set_int mode, "2 pour le binaire, 10 pour le décimal", my_func mode, "usage : "];
    mais j'ai un probleme sur mode apparemment

    @aubanel :
    a quoi correspond :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print_endline (string_of_int !mode)
    ? car on a déjà
    (key * spec * doc) list -> anon_fun -> usage_msg -> unit
    au dessus non ?

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2010
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Octobre 2010
    Messages : 22
    Points : 39
    Points
    39
    Par défaut
    zouuc,
    il te faut revenir au besoin. Déterminer ce que tu cherches à faire avant de choisir comment tu vas le faire.Si tu souhaites avoir deux options (ce qui serait mieux que -l 2 et -l 10) et à ensuite savoir laquelle a été passée en paramètre, tu auras qq chose du style:
    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
     
    let bin = ref false in
    let dec = ref false in
    let _ =
       Arg.parse ["-bin",Arg.Set bin, "sets mode to binary";
                      "-dec", Arg.set dec,"sets mode to decimal"]
                     (fun _ -> () )
                     "use either -bin, either -dec (mandatory and exclusive)"
      ;
    (* Ici la parse a été fait, les instructions suivantes peuvent donc accéder aux valeurs de !bin et !dec, vérifions que les options sont bien spécifiées et exlusives*)
      match (!bin,!dec) with
      | true,true -> failwith("-bin and -dec are exlusive")
      | false,false -> failwith("you must specify either -bin, either -dec")
      | true, false -> traitement_bin ()
      | false, true -> traitement_dec ()
    Concernant tes questions, le problèmem sur le mode vient en fait du my_func mode: le type de ce paramètre est sensé être string -> unit, c'est à dire une fonction qui prend un string et ne renvoie rien. Donc à moins que le type de ta fonction myfunc ne soit : int ref -> (string-> unit) (une fonction qui prendrait une référence sur un entier et renverrait une fonction prenant en paramètre une string et renvoyant unit), ce dont je doute fortement, le typage n'est pas respecté, d'où ton erreur. Ce paramètre, anon_fun, à prioir tu n'en as pas besoin. Si tu lis bien la doc, il sert à traiter les paramètres qui n'ont pas été reconnus dans les motifs (key * spec * doc) list. Donc le mieux est de les jeter, en utilisant une fonction anonyme qui prend "n'importe quoi" et n'en fait rien, soit : (fun _ -> () )

    À propos du
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print_endline (string_of_int !mode)
    , il est séparé du Arg.parse par un ;. Il est possible de chaîner dans le temps par un opérateur de séquence (en l’occurrence ;) plusieurs valuers de type unit pour n'en faire qu'une seule et unique valuer de type unit. En terme de typage, la fonction ( ; ) a le prototype unit -> unit -> unit : prend deux units en paramètre et renvoie un unit.

  9. #9
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    402
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 402
    Points : 337
    Points
    337
    Par défaut
    Merci encore aubanel pour cette aide !

    J'y suis presque, mais il me reste des erreurs (encore un manque d’expérience flagrant en CAML ...)

    Voici mon code :
    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
     
    open Sys;;
    open Array;;
    open List;;
    open Arg;;
     
    let my_func nb = match nb with
      | 2 -> print_string "appel a binair"
      | 8 -> print_string "appel a octal" 
      | 10 -> print_string "appel a decimal" 
      | 16 -> print_string "appel a hexadecimal"
      | _ -> failwith("./bistro -obase argument1")
    ;;
     
    let mode = ref 0 in
    let main () = 
      Arg.parse ["-l", Arg.Set_int mode, "2 pour le binaire, 10 pour le décimal", fun _ -> (), "usage : "];
     
      my_func mode ()
     
    let _ = main ()
    Donc j'utilise le mode en ref, que je passerais a my_func qui est une int -> unit
    après le parsage je lance my_func mode (j’espère que c'est la bonne syntaxe)
    La fonction traite le paramètre.

    Enfin je fais appel a mon main mais c'est ici que ça plante ... Je dois mal terminer une ligne dans le parsage mais quand je tente de rajouter des ; ou des ;; ça ne marche pas plus :/
    Ou ca peut venir de mon appel de main ??

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2010
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Octobre 2010
    Messages : 22
    Points : 39
    Points
    39
    Par défaut
    Tous les exemples que je t'ai donnés sont à mettre dans un fichier, et non dans l'interpréteur, donc pas de ;; La séquence ;; demande à l'interpréteur d'interpréter tout ce qui le précède.

    Ton problème vient du fait que ta fonction my_func attend un int, or tu lui passes count en paramètre, qui n'est pas un int mais un int ref. L'opérateur pour déréférencer est !, essaye donc de passer !count au lieu de count tout seul ...

    Sinon, pour ton appel à main, je te conseille comme dit plus haut (et à contre de mes exemples), d'écrire
    De la sorte, tu t'assures que la fonction main renvoie bien unit.

  11. #11
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    402
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 402
    Points : 337
    Points
    337
    Par défaut
    Merci, je comprend mieux pour le deferencement, j'ai donc utliser le ! devant l'argument.

    Mais j'ai toujours une erreure de syntaxe sur la ligne du main et je ne comprend pas pourquoi

    let est souligne etant comme une syntax error et je ne vois pas pourquoi du coup ??

  12. #12
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2010
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Octobre 2010
    Messages : 22
    Points : 39
    Points
    39
    Par défaut
    Alors il y a des erreurs qui viennent de chez moi :
    au top level est une erreur
    et il y en a d'autres de ton côté, tu confonds avec C ou java en séparant les paramètres lors de l'appel de fonction par des virgules alors qu'en caml ce sont simplement des espaces, et le crochet fermant en théorie la liste consituant le premier argument de Arg.parse est mal placé.
    Essaye comme ça, ça devrait mieux marcher :
    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
     
     
    let my_func nb = match nb with
      | 2 -> print_endline "appel a binaire"
      | 8 -> print_endline "appel a octal" 
      | 10 -> print_endline "appel a decimal" 
      | 16 -> print_endline "appel a hexadecimal"
      | _ -> failwith("./bistro -obase argument1")
     
     
    let mode = ref 0 
     
    let main () = 
            Arg.parse ["-l", Arg.Set_int mode, "2 pour le binaire, 10 pour le
            décimal"] (fun _ -> ()) "usage : ";
     
      my_func !mode 
     
    let _ = main ()
    Sinon en français on écrit binaire.

  13. #13
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    402
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 402
    Points : 337
    Points
    337
    Par défaut
    Merci pour ton aide ! ca marche au poil merci

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

Discussions similaires

  1. Bonne utilisation de "parse", "eval", etc
    Par A. D. dans le forum R
    Réponses: 2
    Dernier message: 12/10/2011, 09h47
  2. Réponses: 0
    Dernier message: 25/01/2011, 12h34
  3. PARSE ARG et PARSE VAR
    Par sam01 dans le forum z/OS
    Réponses: 3
    Dernier message: 17/12/2008, 16h02
  4. Utiliser des variables dans un parsing
    Par blackj dans le forum Langage
    Réponses: 1
    Dernier message: 15/12/2006, 22h04
  5. [NumberFormat] : utilisation de la methode parse()
    Par richard_34b dans le forum Collection et Stream
    Réponses: 11
    Dernier message: 20/10/2004, 15h07

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