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 :

Une RPN plus élégante


Sujet :

Caml

  1. #1
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut Une RPN plus élégante
    Bonjour à tous,

    je fais pour l'exercice un petit interpréteur RPN (Reverse Polish Notation). Mon premier brouillon fonctionne, mais je le trouve un peu … brouillon .

    Ma pile est une float list reference ; et mes opérateurs des records contenant la commande utilisateur (string), le nombre d'opérandes (int) et l'opérateur (float list -> float list).

    Je lis dans ma console une ligne. Si elle est interprétable en float, je l'empile sur ma pile globale ; et sinon je cherche dans la liste des opérateurs celui qui convient et l'applique (j'extrais le bon nombre d'éléments de la pile, les encapsule dans une float list, les passe à l'opérateur et empile le(s) résultat(s)).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    let generic_operator op =
    	let rec pop_operands acc = function
    	| 0 -> acc
    	| k -> pop_operands (pop() :: acc) (pred k)
    	in
    	List.iter push ( op.f (pop_operands [] op.dim) )

    Ce n'est pas très élégant, n'est-ce pas ? De plus, si je veux ajouter des fonctionnalités ésotériques (variables, GUI, etc.) je dois bidouiller de manière pas vraiment orthodoxe.

    Je viens donc à la pèche aux conseils. Quelles structures de données me conseillez-vous ?

    Merci beaucoup.

  2. #2
    Membre émérite
    Avatar de SpiceGuid
    Homme Profil pro
    Inscrit en
    Juin 2007
    Messages
    1 704
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 704
    Points : 2 991
    Points
    2 991
    Par défaut Nouvelle pile expérimentale
    Pour ta pile tu peux essayer ça :

    Code OCaml : 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
    module BraunStack =
       struct
          type 'a env =
             | Empty
             | Braun of 'a env * 'a * 'a env
          exception
             IndexOutOfBounds
          let rec push x = function
             | Empty -> Braun(Empty,x,Empty) 
             | Braun(l,y,r) -> Braun(push y r,x,l)        
          let rec pop l r =
             match l with
             | Empty -> r
             | Braun(a,x,b) -> Braun(r,x,pop a b)     
          let rec nth n = function           
             | Empty -> raise IndexOutOfBounds
             | Braun(l,x,r) ->
                if n = 0 then x
                else if n land 1 = 0 then nth (n lsr 1) l            
                else nth (n lsr 1 - 1) r
       end

    Avantages
    • le pop ne déclenche pas d'exception parce que tu lui passes en argument les branches l et r du Braun à dépiler
    • le top ne déclenche pas d'exception non plus car c'est le 'a d'un Braun
    • l'accès au n-ième élément se fait en Θ(ln n)

    Inconvénients
    • le push se fait en Θ(ln n)

  3. #3
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    Merci de ton conseil ; mais la pile que j'emploie est le seul élément qui me convient (si ce n'est qu'elle n'accepte que les flottants). La RPN n'a besoin que des quelques premiers éléments de la pile.

    En revanche, comment stocker des objets différents de manière efficace pour mon moteur RPN (peut être plus élégamment qu'un bête Num of float | Var of string | Unk of string) ?

    Une autre question : comment gérer de manière générale les opérateurs ? Autrement qu'avec ocamllex ?


    Merci.

Discussions similaires

  1. Réponses: 2
    Dernier message: 25/05/2009, 10h26
  2. Comparer une valeur à plus ou moins quelque chose...?
    Par Thierry8 dans le forum Langage
    Réponses: 4
    Dernier message: 11/10/2005, 14h17
  3. néophyte, faire une requête plus courte
    Par LE NEINDRE dans le forum Requêtes
    Réponses: 8
    Dernier message: 10/10/2005, 10h44
  4. [JFrame] Création d'une fenetre plus grande que l'ecran
    Par thetoctoc dans le forum Agents de placement/Fenêtres
    Réponses: 2
    Dernier message: 23/09/2004, 12h05
  5. [Tomcat] migration vers une version plus récente
    Par butcher dans le forum Tomcat et TomEE
    Réponses: 4
    Dernier message: 31/10/2003, 22h46

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