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

Langage Delphi Discussion :

Analyseur syntaxique de formule


Sujet :

Langage Delphi

  1. #1
    Membre régulier
    Inscrit en
    Novembre 2002
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 8
    Par défaut Analyseur syntaxique de formule
    Bonjour.

    Je doit écrire un logiciel, qui calcul un montant en fonction d'une formule choisie par l'utilisateur. Par exemple :

    3 * NBKM + 5 * NBJOURS + 2 * (TAUX1 + TAUX2)

    L'utilisateur peut saisir ce qu'il veut, mais je dois m'assurer que ce soit quelque chose de correct :
    - Pas d'erreur de syntaxe
    - toutes les "expressions" doivent être "reconnues" ("NBKM" est un "mot clé", qui peut se traduire par un champ de base de donnée par exemple).

    J'imagine que ce genre de chose doit exister, et qu'il est inutile de réinventer la poudre.

    De plus, je ne devrait pas non plus avoir de formule trop compliquées. Peut être des fonctions simples comme "Somme", mais pas au delà.

    Auriez vous des pistes, ou des méthodes pour faire cela ?

    Merci d'avance.



  2. #2
    Expert éminent
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    oui ça "doit" exister ... mais si tu veux t'amuser à le code toi même, voici le principe :

    1) tu vas faire une première fonction qui permet de lire un "token" dans la chaine

    en gros c'est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     case NextChar of
      '0'..'9': GetNumber;
      '+','*','-','/','(',')':GetChar;
      'A'..'Z','a'..'z': GetName;
      else SyntaxError;
     end;
    je te laisse imaginer les boucles du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    function getNumber:string;
    begin
     Result:='';
     while nextChar in ['0'..'9'] do Result:=Result+ReadChar;
    end;
    donc ces fonctions vont te permettre d'identifier les éléments de ton expression :

    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
     
     // 3 * NBKM + 5 * NBJOURS + 2 * (TAUX1 + TAUX2) 
     3
     *
     NBKM
     +
     5
     *
     NBJOURS
     +
     2 
     *
     (
     TAUX1
     +
     TAUX2
     )
    de là il te faut une fonction en trois étapes qui va lire les "token"

    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
     
    function expression:single;
    var
     t1:single;
     op:string;
     t2:single;
    begin
     t1:=terme;
     while (token='+')or(token='-') do begin
      op:=token;
      NextToken;
      t2:=terme;
      if (op='+') then t1:=t1+t2 else t1:=t1-t2;
     end;
     result:=t1;
    end;
    de la même façon la fonction "produit" va repérer les "*" et les "/"

    et au final, la fonction valeur
    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
     
    function valeur:single;
    begin
     if token='NBJOURS' then 
      result:=... 
     else
     if token='NBKM' then 
      result:=... 
     else
     if token='(' then begin
      readtoken;
      result:=expression(); // appel réentrant de la première fonction
      if token<>')' then syntaxerror;
     end else begin
      result:=StrToFloat(token);
     end;
     readtoken;
    end;
    Voilà l'idée générale
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Membre émérite Avatar de b_reda31
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 899
    Par défaut
    Bonsoir,
    En ce qui concérne l'analyse syntaxique,si vous avez des notions de compilation vous pouvez vous baser sur les grammaires
    En définissant la grammaire de la formule que vous devez vérifier,il est possible de créer un analyseur syntaxique (Procédures récursives,analyseur LL ou LR...etc).
    L'analyseur vous permettra de vérifier si un mot (que formera l'utilisateur)appartient au langage (votre formule) ou non.

    Voici grossomodo la grammaire qui génére votre formule :

    Exp->(Exp) / Exp+Exp / Exp*Exp / id .


    PS:Si vous opter pour la méthode des procédures récursives,il faudra modifier cette grammaire (car elle est récursive gauche)

  4. #4
    Membre régulier
    Inscrit en
    Novembre 2002
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 8
    Par défaut
    Merci pour ces pistes.

    Je ne me sens pas trop capable de m'attaquer à la grammaire.

    Par contre, les fonctions me plaisent pas mal. J'avais d'ailleurs commencé à réfléchir à une solution de ce genre.

    Je pensais également créer une sorte d'arbre. Chaque noeud de l'arbre étant une expression, chaque expression étant elle même composée de sous-expressions, avec au plus fin, des expressions élémentaires :


    3 * NBKM + 5 * NBJOURS + 2 * (TAUX1 + TAUX2)

    --> 3 * NBKM
    ------> 3
    ------> NBKM

    --> 5 * NBJOURS
    ------> 5
    ------> NBJOURS

    --> 2 * (TAUX1 + TAUX2)
    ------> 2
    ------> TAUX1 + TAUX2
    --------------> TAUX1
    --------------> TAUX2

  5. #5
    Membre éclairé Avatar de petitprince
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juillet 2006
    Messages
    322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juillet 2006
    Messages : 322
    Par défaut
    Il y a peut être plus simple: SynEdit...
    Je suis en train de mettre au point un petit utilitaire pour produire des "highlighters" pour SynEdit...
    Si tu es patient, je pense le finir dans quelques semaines, sinon tu peux utiliser SynGen, livré avec les composants de SynEdit.
    En espérant t'avoir aidé un peu

  6. #6
    Membre Expert

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Billets dans le blog
    1
    Par défaut
    SynEdit n'est utilise que pour faire la coloration syntaxique d'un texte or ici on veut d'une part vérifier la syntaxe et d'autre part exécuter les formules entrées par l'utilisateur.

  7. #7
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 488
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 488
    Par défaut
    salut

    il y a plus simple
    va sur le site de jhon colibri ancien responsable
    de l'excellent magazine pascalisime
    il y a les source d'un analyseur


    @+ phil

  8. #8
    Invité
    Invité(e)
    Par défaut
    Google "delphi parser formula"

    Le 1er résultat est une page de liens sur efg :
    http://www.efg2.com/Lab/Library/Delp...ns/Parsers.htm

    Le code suivant extrait du MicroCalc TP3 semble très proche du besoin:

    http://www.geocities.com/SiliconVall...crocalcpas.txt

    Cordialement

  9. #9
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 074
    Par défaut
    Citation Envoyé par FANDOR Voir le message
    peut se traduire par un champ de base de donnée par exemple
    Si c'est toujours le cas, tu peux simplement faire un outil qui permet de saisir la partie SELECT, et toi tu génère un SQL (jointure compris) qui lance ce calcul

    Ma fonction Explode permet de transformer la chaine
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    3 * NBKM + 5 * NBJOURS + 2 * (TAUX1 + TAUX2)
    en un tableau, avec le paramètre KeepSeparators à True

    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
     3
     *
     NBKM
     +
     5
     *
     NBJOURS
     +
     2 
     *
     (
     TAUX1
     +
     TAUX2
     )
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  10. #10
    Membre régulier
    Inscrit en
    Novembre 2002
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 8
    Par défaut
    Citation Envoyé par anapurna Voir le message
    salut

    il y a plus simple
    va sur le site de jhon colibri ancien responsable
    de l'excellent magazine pascalisime
    il y a les source d'un analyseur


    @+ phil
    Citation Envoyé par papadrago
    Google "delphi parser formula"

    Le 1er résultat est une page de liens sur efg :
    http://www.efg2.com/Lab/Library/Delp...ns/Parsers.htm

    Le code suivant extrait du MicroCalc TP3 semble très proche du besoin:

    http://www.geocities.com/SiliconVall...crocalcpas.txt

    Cordialement
    Merci pour ces liens.

    Je pense que je vais trouver mon bonheur dans tout cela.
    L'arbre de J Colibri ressemble beaucoup à ce que j'essayais de faire.

    Merci.

Discussions similaires

  1. Analyseur syntaxique descendant
    Par jalam dans le forum Langages de programmation
    Réponses: 6
    Dernier message: 02/01/2007, 08h15
  2. Analyseur Syntaxique Expression Booléenne
    Par Invité dans le forum Langage
    Réponses: 8
    Dernier message: 01/10/2006, 10h57
  3. Analyseur syntaxique HTML
    Par roudoudouduo dans le forum Outils
    Réponses: 5
    Dernier message: 03/07/2006, 16h52
  4. analyseur syntaxique
    Par tomy29 dans le forum Langage
    Réponses: 11
    Dernier message: 11/01/2006, 12h45
  5. [Conception] Analyseur Syntaxique
    Par guu dans le forum Général Java
    Réponses: 7
    Dernier message: 03/01/2006, 12h28

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