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

Delphi Discussion :

Lecture d'un fichier texte et exécution de commandes - Structure if else


Sujet :

Delphi

  1. #1
    Membre à l'essai
    Inscrit en
    Avril 2003
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 14
    Points : 23
    Points
    23
    Par défaut Lecture d'un fichier texte et exécution de commandes - Structure if else
    Bonjour à tous,


    Je suis en train d'écrire un petit interpréteur de commande provenant d'un fichier texte.

    Le fichier texte est donc une succession de commande définie au travers de différents mots clés (PRINT, MSG, GET_FILE, CLOSE, ....).

    Je lis donc ligne par ligne ce fichier, recherche le mot clé et ses paramètres, et exécute la fonction Delphi appropriée. Jusque là tout va bien.

    J'ai besoin d'implanter des tests conditionnels du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    IF EXIST_FILE (AAAA)
      IF IS_RUNNING(BBBB)
        PRINT CCCC
      ELSE
        PRINT DDDD
    ELSE
      PRINT EEEE
    IF_END
    Sur plusieurs niveaux (maximum 3) et je suis coincé dans l'algorithme.

    Auriez-vous des idées ? Ca m'arrangerait d'éviter des outils lourds...

    Merci d'avance!

  2. #2
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    Bonjour !

    Intéressant comme sujet. Je dirais que la première chose à faire serait de bien te mettre d'accord avec toi-même sur la syntaxe de ton script (ton fichier texte). Je dis ça parce que l'exemple que tu as posté, il me semble qu'il devrait plutôt s'écrire comme ça (mais peut-être que je me trompe) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    IF EXIST_FILE (AAAA)
      IF IS_RUNNING(BBBB)
        PRINT CCCC
      ELSE
        PRINT DDDD
      IF_END
    ELSE
      PRINT EEEE
    IF_END
    Est-ce que tu es libre de définir toi-même ta syntaxe ou est-elle imposée au départ ?
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  3. #3
    Membre à l'essai
    Inscrit en
    Avril 2003
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 14
    Points : 23
    Points
    23
    Par défaut
    Ah oui effectivement j'avais pas fermé le premier if...

    Effectivement la syntaxe m'est imposée, c'est une reprise d'un programme que j'avais trouvé il y a quelques années mais sans sources disponibles et introuvable aujourd'hui...

    Donc l'exemple que j'ai donné, avec ta correction, est bien la bonne syntaxe et est reprise dans tout le fichier dès lors qu'il y a des conditions.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    IF EXIST_FILE (AAAA)
      IF IS_RUNNING(BBBB)
        PRINT CCCC
      ELSE
        PRINT DDDD
      IF_END
    ELSE
      PRINT EEEE
    IF_END
    J'ai pu reprendre et coder la totalité des fonctions que j'utilise, seulement problème d'algorithmie (j'imagine récursif) avec les conditions.

  4. #4
    Membre averti Avatar de pascalCH
    Homme Profil pro
    Formateur en informatique
    Inscrit en
    Juillet 2006
    Messages
    187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 66
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Formateur en informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2006
    Messages : 187
    Points : 369
    Points
    369
    Par défaut
    Citation Envoyé par Roland Chastain Voir le message
    Intéressant comme sujet. Je dirais que la première chose à faire serait de bien te mettre d'accord avec toi-même sur la syntaxe de ton script (ton fichier texte).
    Comme le dit Roland, la syntaxe initiale est essentielle pour savoir comment exécuter les instructions.
    le point le plus intéressant est qu'apparemment, l'ordre des instructions est important et que des fonctions peuvent positionner des variables réutilisables par d'autres un peu plus loin, on est proche de la notion de script.

    Au bout du compte, il s'agit de réécrire un command.com, bel exercice !
    La nature fait des choses extraordinaires, observons la et restons humble, on ne nous demande pas de refaire le monde mais juste de reproduire virtuellement des choses existantes ....

    et n'oubliez pas si vous aimez et quand vous avez la réponse

  5. #5
    Membre à l'essai
    Inscrit en
    Avril 2003
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 14
    Points : 23
    Points
    23
    Par défaut
    Effectivement le but est de produire un langage de script assez basique, qui me permet de mettre à jour mes programmes (c'est le même code à chaque fois, seul l'emplacement du fichier / le nom du programme / la clé de registre diffère) mais avec certaines conditions à remplir, d'où l'implantation des structures if .. else ..end

  6. #6
    Membre actif Avatar de Basile le disciple
    Homme Profil pro
    étudiant Centrale Supélec
    Inscrit en
    Avril 2013
    Messages
    147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : étudiant Centrale Supélec

    Informations forums :
    Inscription : Avril 2013
    Messages : 147
    Points : 279
    Points
    279
    Par défaut
    Bonjour à tous,

    J'ai aussi trouvé ce sujet très intéressant et j'ai essayé d'en faire autant. Voici un programme qui permet d'afficher en titre de fenêtre "Hello" ou "Salut" en rentrant du code(S pour "Salut" et H pour "Hello") dans un TMemo. Il permet de gérer les conditions imbriquées. Par contre, comme je ne connaissais pas les conditions à mettre, je me suis contenté de gérer :
    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
    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
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
     
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
     
    type
      TForm1 = class(TForm)
        Memo1: TMemo;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Déclarations privées }
        ligne : integer;                      //ligne qui doit être exécutée
        procedure EXECUTE(var l : integer);   // execute une instruction
        procedure IFF(var l : integer);       //execute une condition
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.EXECUTE(var l : integer);
    begin
      if Memo1.Lines[l] <> '' then
      begin
        if Memo1.Lines[l][1]+Memo1.Lines[l][2] = 'IF' then    //Si code IF -> appele IFF
        begin
          IFF(l);
        end else
        if Memo1.Lines[l][1] = 'S' then         //Si code S -> affiche Salut
        begin
          Caption:='Salut';
        end else
        if Memo1.Lines[l][1] = 'H' then         //Si code H -> affiche Hello
        begin
          Caption:='Hello';
        end;
      end;
    end;
     
    procedure TForm1.IFF(var l : integer);
    var i,j : integer;
        L_ELSE,L_IF_END : integer;      //ligne du ELSE et du IF_END de la condition
        Nb_IF : integer;                //Nombre de if imbriqué
        S : string;
        Bool : boolean;                 //valeur de la condition
    begin
        Nb_IF:=1;
        //recherche de la ligne du ELSE
        S:='';
        For i:=l+1 to Memo1.lines.Count do
        begin
          if Memo1.Lines[i] <> '' then
          begin
            S:='';                                                       //
            S:=Memo1.Lines[i][1]+Memo1.Lines[i][2]+Memo1.Lines[i][3];    //recherche un if imbriqué
            if S = 'IF ' then Nb_IF:=Nb_IF+1;                            //
            S:='';
            For j:=1 to 4 do s:=s+Memo1.Lines[i][j];
            if S = 'ELSE' then
            begin
              Nb_IF:=Nb_IF-1;
     
              if Nb_IF = 0 then
              begin
                L_ELSE:=i;
                break;
              end;
            end;
          end;
        end;
     
      //recherche de la ligne du IF_END
      Nb_IF:=1;
      S:='';
      For i:=L_ELSE+1 to Memo1.lines.Count do
      begin
        if Memo1.Lines[i] <> '' then
        begin
          S:='';                                                       //
          S:=Memo1.Lines[i][1]+Memo1.Lines[i][2]+Memo1.Lines[i][3];    //recherche un if imbriqué
          if S = 'IF ' then Nb_IF:=Nb_IF+1;                            //
          S:='';
          For j:=1 to 6 do s:=s+Memo1.Lines[i][j];
          if S = 'IF_END' then
          begin
            Nb_IF:=Nb_IF-1;
            if Nb_IF = 0 then
            begin
              L_IF_END:=i;
              break;
            end;
          end;
        end;
      end;
     
      //valeur du if
      bool:=false;
      S:='';
      For j:=4 to 7 do  S:=S+Memo1.Lines[l][j];
      if S = 'TRUE' then bool:=true;
     
      //Execution du THEN
      if bool = true then
      begin
        For i:=l+1 to L_ELSE-1 do
        begin
          if i >= Ligne then
          begin
            EXECUTE(i);
            Ligne:=Ligne+1;
          end;
        end;
      end;
      //execution du else
      if bool = false then
      begin
        For i:=L_ELSE+1 to L_IF_END-1 do
        begin
          if i >= Ligne then
          begin
            EXECUTE(i);
            Ligne:=Ligne+1;
          end;
        end;
      end;
     Ligne:=L_IF_END;
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    var i : integer;
    begin
      For i:=0 to Memo1.Lines.Count do
      begin
        if i >= Ligne then
        begin;
          EXECUTE(i);
          Ligne:=Ligne+1;
        end;
      end;
      Ligne:=0;
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      Ligne:=0;
    end;
     
    end.
    J'ai fait pas mal d'essais mais il y a tellement de possibilités qu'il soit possible que ce programme ne marche pas à tous les coups.
    N'ayant jamais trop bossé les chaînes de caractères, je pense que l'on peut simplifier pas mal de choses comme par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      For j:=1 to 6 do s:=s+Memo1.Lines[i][j];
          if S = 'IF_END' then

  7. #7
    Membre à l'essai
    Inscrit en
    Avril 2003
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 14
    Points : 23
    Points
    23
    Par défaut
    Voici ci-dessous un fichier test avec quelques fonctions que j'ai fini d'implanter.

    Toutes les fonctions devant retourner une valeur retournent celle-ci dans VAR, il faut l'affecter à une autre si on veut la réutiliser.

    Présence d'une structure IF / IFNOT / IF que je n'arrive pas à gérer correctement.....


    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
     
     
    [SCRIPT]
    'Récupération de l'emplacement du fichier à remplacer dans le registre
    GET_REG_KEY "HKEY_CURRENT_USER\SOFTWARE\MONAPPLI" "ExePath" 
    $PATH %VAR%
     
    ' Récupération de la version enregistrée précédemment de l'application
    GET_REG_KEY "HKEY_CURRENT_USER\SOFTWARE\MONAPPLI" "Version" 
    ' Affectation à VAR2 de la valeur actuelle de version 
    $VAR2 %VAR%
     
    ' Recherche de la dernière version de l'application (exe) présente sur un serveur Web
    ' Fonction Get : (via TIDHttp) : récupère le fichier sur le serveur Web (HOST) et le met dans TMP_PATH
    GET "%HOST%/MONAPPLI.exe" "%TMP_PATH%"
     
    ' Si fichier bien récupéré, vérif de sa version
    IF FILE_EXIST "%TMP_PATH%\MONAPPLI.exe"  
      GET_FILE_VERSION "%TMP_PATH%\truc.exe"
     ' Affectation à UPDATE de la version récupérée
      $UPDATE %VAR%
      ' comparaison des version des exe via les variables VAR2 et UPDATE
      IFNOT IS_EQUAL %VAR2% %UPDATE%
         PRINT "Versions différentes" 
         IF IS_RUNNING "MonAppli.exe"
    	  ' On la tue
    	   KILL "MonAppli.exe"
         IF_END	
     
         'On supprime le fichier local d'execution de MonAppli
         DELETE "%PATH%\MonAppli.exe" 	
         ' On déplace le fichier exe du dossier tmp vers le dossier réel de l'appli
         MOVE "%TMP_PATH%\MonAppli.exe" "%PATH%\Monappli.exe"
         'Enregistrement de la version dans le registre
         SET_REG_KEY "HKEY_CURRENT_USER\SOFTWARE\MONAPPLI" "Version" %UPDATE%
         PRINT "Enregistrement dans le registre effectué"   
         PRINT "L'application à correctement été mis à jour !" 	
      ELSE
         PRINT "Versions à jour"
         CLOSE   
      IF_END
    ELSE
      PRINT "Fichier MonAppli.exe introuvable"
    IF_END
     
    [SCRIPT_END]

  8. #8
    Membre à l'essai
    Inscrit en
    Avril 2003
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 14
    Points : 23
    Points
    23
    Par défaut
    Et voici la trame du code Delphi sur lequel je coince ...

    FormActivate

    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
     
    procedure TForm_Main.FormActivate(Sender: TObject);
    begin 
      // Récupération du nom du fichier
      nomfichierscript := ParamStr(1);
     
      if FileExists(nomfichierscript) then
      begin
          // Ouverture du fichier
          OuvreEtLitFichierScript(nomfichierscript);
          // Lecture séquentielle de celui-ci
          // Pour chaque ligne, vérificatino du mot CLE (premier mot avant premier espace)
          // Pour chaque mot cle, exécution de la fonction liée
      end
      else
        Memo1.Lines.Add('Fichier script introuvable');
    end;
    OuvreEtLitFichierScript
    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
     
    procedure TForm_Main.OuvreEtLitFichierScript(fichierScript : String);
    var
      f_script : TextFile;
      textlu   : string;
      commence_traitement : Boolean;
    begin
     AssignFile(f_script , fichierScript );
      Reset(f_script);
      while not Eof(f_script) do
      begin
        ReadLn(f_script, textlu);
        // On commence le traitement si on rencontre la balise [SCRIPT]
        // On l'arrête à la balise [SCRIPT_END]
        if (trim(StripCharsInSet(textlu)) = '[SCRIPT]') then
           commence_traitement := true
        else
          if (trim(StripCharsInSet(textlu)) = '[SCRIPT_END]') then
             commence_traitement := false
          else
          if commence_traitement then
          begin
             // Pour chaque ligne du fichier, exécution de la fonction associée
              if (trim(StripCharsInSet(textlu)) <> '') then
                TraiteLigne(textlu);
          end;
     
      end;
      // Fermeture du fichier lu
      CloseFile(f_script);
    end;
    TraiteLigne(ligne : String); // C'est dans cette fonction que je dois gérer les conditions
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
        l_ligne := ExplodeToListString(ligne,' ');
        if l_ligne.Count > 0 then
        begin
          commande := l_ligne[0];
          if niveauDeIf = 0 then
             TraiteLigneDetail(commande,l_ligne)
          else
          begin
              // Doit gérer les niveaux de if imbriqués
          end; 
       end;
    TraiteLigneDetail(commande : String; l_ligne : TStringList);
    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
     
    var
      param1, param2, param3 : String;
      prem_car : String;
    begin
       prem_car := LeftStr(commande,1);
     
          if LeftStr(commande,1) = '''' then
          begin
            // Ligne commentaire
          end
          else
          begin
            if LeftStr(commande,1) = '$' then
            begin
               // Ligne d'affectation de variables
               if l_variablesDollards.IndexOf(commande) <> -1 then   //  On vérifie que la variable soit dans la liste des variables définies
               begin
                 if l_ligne.Count > 1 then
                 begin
                    // Affectation de la variable
                    param1 := l_ligne[1];
     
                    TraiteVariable(commande,param1);   // Affectation de la variable demandée
                 end
                 else
                 begin
                   Memo1.Lines.Add('Erreur de paramètre : ' + commande);
                 end;
     
               end
               else
               begin
                Memo1.Lines.Add('Variable inconnue : ' + commande);
              end;
     
            end
            else
            begin
              if l_ligne.Count > 1 then
               param1 := l_ligne[1];
     
              if l_ligne.Count > 2 then
               param2 := l_ligne[2];
     
              if l_ligne.Count > 3 then
               param3 := l_ligne[3];
     
              if l_commandes.IndexOf(commande) <> -1 then   //  On vérifie que la commande soit dans la liste des commandes définies
              begin
                TraiteCommande(commande,param1,param2, param3);
              end
              else
              begin
                Memo1.Lines.Add('Commande inconnue : ' + commande);
              end;
            end;
          end;
    TraiteCommande(commande : String;param1 : String = '';param2 : String = '';param3 : String = '') // Je n'ai pas mis le code de toutes les commandes sinon c'est très long...
    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
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
     
    begin
        // Si param1,param2 ou param3 contient le nom d'une variable entre % -> on la remplace par sa valeur
      param1 := RemplaceVarParSaValeur(param1);
      param2 := RemplaceVarParSaValeur(param2);
      param3 := RemplaceVarParSaValeur(param3);
     
     
      CASE StringToCaseSelect(commande, Commandes) OF
        1 :     // MSG
        begin     
            if param1 <> '' then
            begin
              //Application.MessageBox (pwidechar(param1), pwidechar(script_title), MB_OK)    // [smbOK]
              MessageDlg(param1,mtInformation,[mbOK],MB_OK);
              Result := true;
             //ShowMessage(param1)
            end
            else
            begin
               Memo1.Lines.Add(commande + ' : paramètre incorrect ' +  param1);
               Result := false;
            end;      
        end;
     
        4 :   // PRINT
        begin     
          // On affiche dans le mémo le paramètre 1 spécifié
           if param1 <> '' then
             Memo1.Lines.Add(param1)
           else
             Memo1.Lines.Add(commande + ' : paramètre incorrect ' +  param1);
           Result := true;
        end;  
     
        5 :   // FILE_EXIST
        begin
          if doitexecuter then
          begin
            if param1 <> '' then
            begin
                if FileExists(param1) then
                  result := true
                else
                  result := false;
            end
            else
            begin
                Memo1.Lines.Add(commande + ' : paramètre incorrect ' +  param1);
                Result := true;
            end;
          end;
        end;
     
     
        6 :   // GET_FILE_VERSION
        begin     
             // Renvoi la taille d'un fichier
             if param1 <> '' then
             begin
                script_VAR := FileVersion(param1);
                Result := true;
             end
             else
             begin
                Memo1.Lines.Add(commande + ' : paramètre incorrect ' +  param1);
                Result := false;
             end;
          end; 
     
         10 :  // CLOSE
         begin      
            // Fermeture de lapplication de MAJ
            Close;
            Result := true;    
        end;   
     
        13 : // IF
        begin
           inc(niveauDeIf);
           if TraiteCommande(param1, param2, param3) = true then
           begin
                 // Condition vrai -> on doit exécuter jusqu'au else ou end_if
           end
           else
           begin
                // Le test est faux -> on exécute du else si existant
           end; 
     
        end;
     
        14 : // ELSE
        begin      
            // Pas encore trouvé....
        end; 
     
        15 : // IF_END
        begin
            dec(niveauDeIf);
        end;
     
        16 : // IFNOT
        begin
             inc(niveauDeIf);
             if TraiteCommande(param1, param2, param3) = true then
             begin
               // Le test est vrai -> on va sur le prochain ELSE ou le IF_END 
             end
             else
             begin
                // Le test est faux -> on doit exécuter jusqu'au else ou end_if
             end;         
     
        end;
     
    end

  9. #9
    Membre actif Avatar de Basile le disciple
    Homme Profil pro
    étudiant Centrale Supélec
    Inscrit en
    Avril 2013
    Messages
    147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : étudiant Centrale Supélec

    Informations forums :
    Inscription : Avril 2013
    Messages : 147
    Points : 279
    Points
    279
    Par défaut
    Même si la gestion du IFNOT n'est pas trop compliquée, vous ne pourriez pas changer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    IFNOT IS_EQUAL %VAR2% %UPDATE%
    en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    IF IS_INEQUAL %VAR2% %UPDATE%
    ?

  10. #10
    Membre à l'essai
    Inscrit en
    Avril 2003
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 14
    Points : 23
    Points
    23
    Par défaut
    Le problème est que le programme actuel utilise déjà cette syntaxe pour son fichier script (programme dont je n'ai pas les sources et qui ne fonctionne pas sous Win 2008) donc je dois faire avec...

    Le but n'est pas de remplacer tous les programmes de mises à jour que j'utilise dans tous les environnements mais uniquement dans les environnements qui posent problème (en tout cas dans un premier temps) et donc en gardant le même fichier de définition du script.

  11. #11
    Membre actif Avatar de Basile le disciple
    Homme Profil pro
    étudiant Centrale Supélec
    Inscrit en
    Avril 2013
    Messages
    147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : étudiant Centrale Supélec

    Informations forums :
    Inscription : Avril 2013
    Messages : 147
    Points : 279
    Points
    279
    Par défaut
    J'ai rajouté IFNOT et IS_EQUAL dans mon programme en l'optimisant un peu grâce à Pos :

    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
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
     
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
     
    type
      TForm1 = class(TForm)
        Memo1: TMemo;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Déclarations privées }
        ligne : integer;                      //ligne qui doit être exécutée
        procedure EXECUTE(var l : integer);   // execute une instruction
        procedure IFF(var l : integer);       //execute une condition
        function SearchBool(l : integer) : boolean;
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.EXECUTE(var l : integer);
    begin
      if Memo1.Lines[l] <> '' then
      begin
        if Pos('IF',Memo1.Lines[l]) <> 0 then    //Si code IF -> appele IFF
        begin
          IFF(l);
        end else
        if Memo1.Lines[l][1] = 'S' then         //Si code S -> affiche Salut
        begin
          Caption:='Salut';
        end else
        if Memo1.Lines[l][1] = 'H' then         //Si code H -> affiche Hello
        begin
          Caption:='Hello';
        end;
      end;
    end;
     
    procedure TForm1.IFF(var l : integer);
    var i,j : integer;
        L_ELSE,L_IF_END : integer;      //ligne du ELSE et du IF_END de la condition
        Nb_IF : integer;                //Nombre de if imbriqué
        S : string;
        Bool : boolean;                 //valeur de la condition
    begin
        Nb_IF:=1;
        bool:=SearchBool(l);
        if Pos('IFNOT',Memo1.lines[l]) <> 0 then bool:=not bool;
        //recherche de la ligne du ELSE
        For i:=l+1 to Memo1.lines.Count do
        begin
          if Memo1.Lines[i] <> '' then
          begin
            if (Pos('IF ',Memo1.Lines[i]) <> 0) or (Pos('IFNOT ',Memo1.Lines[i]) <> 0)  then inc(Nb_IF);   //recherche d'un IF imbriqué
            if Pos('ELSE',Memo1.Lines[i]) <> 0 then
            begin
              dec(Nb_IF);
              if Nb_IF = 0 then
              begin
                L_ELSE:=i;
                break;
              end;
            end;
          end;
        end;
     
      //recherche de la ligne du IF_END
      Nb_IF:=1;
      For i:=L_ELSE+1 to Memo1.lines.Count do
      begin
        if Memo1.Lines[i] <> '' then
        begin
          if (Pos('IF ',Memo1.Lines[i]) <> 0) or (Pos('IFNOT ',Memo1.Lines[i]) <> 0) then inc(Nb_IF);   //recherche d'un IF imbriqué
          if Pos('IF_END',Memo1.Lines[i]) <> 0 then
          begin
            dec(Nb_IF);
            if Nb_IF = 0 then
            begin
              L_IF_END:=i;
              break;
            end;
          end;
        end;
      end;
     
      //Execution du THEN
      if bool then
      begin
        For i:=l+1 to L_ELSE-1 do
        begin
          if i >= Ligne then
          begin
            EXECUTE(i);
            Ligne:=Ligne+1;
          end;
        end;
      end;
      //execution du else
      if not bool then
      begin
        For i:=L_ELSE+1 to L_IF_END-1 do
        begin
          if i >= Ligne then
          begin
            EXECUTE(i);
            Ligne:=Ligne+1;
          end;
        end;
      end;
     Ligne:=L_IF_END;
    end;
    //
    procedure TForm1.Button1Click(Sender: TObject);
    var i : integer;
    begin
      For i:=0 to Memo1.Lines.Count do
      begin
        if i >= Ligne then
        begin;
          EXECUTE(i);
          Ligne:=Ligne+1;
        end;
      end;
      Ligne:=0;
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      Ligne:=0;
    end;
     
    function TForm1.SearchBool(l : integer) : boolean;
    var p : integer;
    begin
      if Pos('IS_EQUAL',Memo1.lines[l]) <> 0 then                        //IS_EQUAL n'est qu'un essai  :)
      begin
        p:=Pos('IS_EQUAL',Memo1.lines[l])+Length('IS_EQUAL');
        if strtoint(Memo1.Lines[l][p+1]) = strtoint(Memo1.Lines[l][p+3]) then result:=true else result:=false;
      end;
    end;
     
    end.

  12. #12
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    @cedr

    Dans le code que tu as posté, il me semble que tu cherches à traiter les conditions comme des commandes. La bonne méthode ne serait-elle pas plutôt de s'intéresser d'abord aux conditions, de façon à faire le tri entre les commandes qui doivent être traitées et celles qui doivent être ignorées ? Si j'ai le temps dans la journée j'essaierai de proposer un exemple de code.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  13. #13
    Membre à l'essai
    Inscrit en
    Avril 2003
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 14
    Points : 23
    Points
    23
    Par défaut
    @Roland : Effectivement j'essaie d'exécuter les conditions comme des commandes, là j'essaie d'adapter mais bloque... j'attends donc avec impatience ton exemple!

    @Basile : j'ai essayé d'adapter ton code : tu pars d'un Memo que tu parcours pour trouver les lignes des IF_END / ELSE et tu exécutes ce qui est entre ces parties. Je suis embêté car je lis mon fichier séquentiellement, ligne par ligne. Après je pourrais faire pas mal de boucle sur mon fichier pour simuler ce fonctionnement mais je suis pas sur que ce soit la meilleure solution, ou encore déverser le fichier dans un TMemo pour reprendre ton traitement -> hésitation...

  14. #14
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    Pas si facile !

    Allez, pour lancer la discussion, je propose une solution, bien que je n'en sois pas très satisfait, 1° parce qu'elle est peut-être plus compliquée qu'il ne faut (je ne te cache pas que j'y ai laissé quelques neurones), 2° parce qu'elle ne traite pas correctement le cas où il y a plusieurs conditions juxtaposées.

    Mais sur l'exemple que tu as donné, ça paraît fonctionner.

    Première étape, j'élimine les lignes" [SCRIPT]" et "[SCRIPT END]" et tout ce qu'il y aurait éventuellement en dehors.

    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
    program Project1;
     
    {$APPTYPE CONSOLE}
     
    {$R *.res}
     
    uses
      System.SysUtils, System.Classes;
     
    (*
      Première étape. On ne conserve que le texte compris entre les lignes
      "[SCRIPT]" et "[SCRIPT END]".
      On en profite pour supprimer l'indentation, les commentaires et les lignes
      vides, pour ne plus avoir à s'en soucier par la suite.
    *)
     
    var
      liste1, liste2: TStringList;
      i: integer;
      s: string;
     
    begin
      liste1 := TStringList.Create;
      liste2 := TStringList.Create;
     
      liste1.LoadFromFile(ParamStr(1));
     
      i := 0;
      while not (Pos('[SCRIPT]', liste1.Strings[i]) = 1) do
        Inc(i);
      Inc(i);
     
      while not (Pos('[SCRIPT_END]', liste1.Strings[i]) = 1) do
      begin
        s := Trim(liste1.Strings[i]);
        if (s <> '') and (s[1] <> '''') then
          liste2.Add(s);
        Inc(i);
      end;
     
      liste2.SaveToFile('1.txt');
     
      liste1.Free;
      liste2.Free;
    end.
    A ce moment-là, ton script ressemble à ça :

    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
    GET_REG_KEY "HKEY_CURRENT_USER\SOFTWARE\MONAPPLI" "ExePath"
    $PATH %VAR%
    GET_REG_KEY "HKEY_CURRENT_USER\SOFTWARE\MONAPPLI" "Version"
    $VAR2 %VAR%
    GET "%HOST%/MONAPPLI.exe" "%TMP_PATH%"
    IF FILE_EXIST "%TMP_PATH%\MONAPPLI.exe"
    GET_FILE_VERSION "%TMP_PATH%\truc.exe"
    $UPDATE %VAR%
    IFNOT IS_EQUAL %VAR2% %UPDATE%
    PRINT "Versions différentes"
    IF IS_RUNNING "MonAppli.exe"
    KILL "MonAppli.exe"
    IF_END
    DELETE "%PATH%\MonAppli.exe"
    MOVE "%TMP_PATH%\MonAppli.exe" "%PATH%\Monappli.exe"
    SET_REG_KEY "HKEY_CURRENT_USER\SOFTWARE\MONAPPLI" "Version" %UPDATE%
    PRINT "Enregistrement dans le registre effectué"
    PRINT "L'application à correctement été mis à jour !"
    ELSE
    PRINT "Versions à jour"
    CLOSE
    IF_END
    ELSE
    PRINT "Fichier MonAppli.exe introuvable"
    IF_END
    Deuxième étape, suppression des lignes à ignorer dans le script, en fonction de la valeur des conditions :

    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
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    program Project2;
     
    {$APPTYPE CONSOLE}
     
    {$R *.res}
     
    uses
      System.SysUtils, System.Classes, System.Math;
     
    (*
      Deuxième étape. Suppression des lignes à ignorer en fonction des conditions.
     
      N.B. La solution ci-dessous ne fonctionne que s'il y a une seule condition,
      ce qui est la cas du script donné en exemple.
    *)
     
    function ValeurExpression(const aExpression: string): boolean;
    const
      V: array[0..1] of boolean = (FALSE, TRUE);
    begin
      result := TRUE;
      //result := FALSE;
      //result := V[Random(2)];
    end;
     
    type
      TData = record
        iIf,
        iElse,
        iEnd,
        iEtage: integer;
        sExpression: string;
      end;
     
    var
      liste1, liste2, debug: TStringList;
      data: array[1..100]of TData;
      index, dernier_index: integer;
      etage, dernier_etage: integer;
      i, j, k, l: integer;
     
    begin
      Randomize;
     
      liste1 := TStringList.Create;
      liste2 := TStringList.Create;
     
      liste1.LoadFromFile('1.txt');
     
      index := 0;
      dernier_index := 0;
      etage := 0;
      dernier_etage := 0;
     
      for i := 0 to liste1.Count - 1 do
      begin
        if (Pos('IF', liste1.Strings[i]) = 1)
        and not (Pos('IF_END', liste1.Strings[i]) = 1) then
        (*
          Ici je ne distingue pas entre IF et IFNOT.
        *)
        begin
          Inc(index);
          dernier_index := Max(index, dernier_index);
          Inc(etage);
          dernier_etage := Max(etage, dernier_etage);
     
          data[index].iIf := i;
          data[index].iElse := 0;
          data[index].iEnd := 0;
          data[index].iEtage := etage;
          data[index].sExpression := Copy(
            liste1.Strings[i],
            3,
            Length(liste1.Strings[i]) - 2
          );
        end;
        if Pos('ELSE', liste1.Strings[i]) = 1 then
        begin
          data[index].iElse := i;
        end;
        if Pos('IF_END', liste1.Strings[i]) = 1 then
        begin
          data[index].iEnd := i;
     
          Dec(index);
          Dec(etage);
        end;
      end;
     
      for etage := dernier_etage downto 1 do
        for index := 1 to dernier_index do
          if data[index].iEtage = etage then
          begin
             liste1.Strings[data[index].iIf] := Concat(''''{, Format('(%d)', [index])}, liste1.Strings[data[index].iIf]);
             liste1.Strings[data[index].iEnd] := Concat(''''{, Format('(%d)', [index])}, liste1.Strings[data[index].iEnd]);
     
             if data[index].iElse <> 0 then
               liste1.Strings[data[index].iElse] := Concat(''''{, Format('(%d)', [index])}, liste1.Strings[data[index].iElse]);
     
             if ValeurExpression(data[index].sExpression) then
             begin
               if data[index].iElse <> 0 then
                 for k := data[index].iElse + 1 to data[index].iEnd - 1 do
                   liste1.Strings[k] := Concat(''''{, Format('(%d)', [index])}, liste1.Strings[k]);
             end else
             begin
               if data[index].iElse <> 0 then
                 l := data[index].iElse
               else
                 l := data[index].iEnd;
               for k := data[index].iIf + 1 to l - 1 do
                 liste1.Strings[k] := Concat(''''{, Format('(%d)', [index])}, liste1.Strings[k]);
             end;
          end;
     
      debug := TStringList.Create;
      for i := 1 to dernier_index do
        with data[i] do
          debug.Add(Format(
            '%d %d %d %d [%s]',
            [i, iIf, iElse, iEnd, sExpression]
          ));
      debug.SaveToFile('debug.txt');
     
      for i := 0 to liste1.Count - 1 do
        if Copy(liste1.Strings[i], 1, 1) <> '''' then
          liste2.Add(liste1.Strings[i]);
     
      liste2.SaveToFile('2.txt');
     
      liste1.Free;
      liste2.Free;
      debug.Free;
    end.
    Voici le résultat :

    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
    GET_REG_KEY "HKEY_CURRENT_USER\SOFTWARE\MONAPPLI" "ExePath"
    $PATH %VAR%
    GET_REG_KEY "HKEY_CURRENT_USER\SOFTWARE\MONAPPLI" "Version"
    $VAR2 %VAR%
    GET "%HOST%/MONAPPLI.exe" "%TMP_PATH%"
    'IF FILE_EXIST "%TMP_PATH%\MONAPPLI.exe"
    GET_FILE_VERSION "%TMP_PATH%\truc.exe"
    $UPDATE %VAR%
    'IFNOT IS_EQUAL %VAR2% %UPDATE%
    PRINT "Versions différentes"
    'IF IS_RUNNING "MonAppli.exe"
    KILL "MonAppli.exe"
    'IF_END
    DELETE "%PATH%\MonAppli.exe"
    MOVE "%TMP_PATH%\MonAppli.exe" "%PATH%\Monappli.exe"
    SET_REG_KEY "HKEY_CURRENT_USER\SOFTWARE\MONAPPLI" "Version" %UPDATE%
    PRINT "Enregistrement dans le registre effectué"
    PRINT "L'application à correctement été mis à jour !"
    'ELSE
    'PRINT "Versions à jour"
    'CLOSE
    'IF_END
    'ELSE
    'PRINT "Fichier MonAppli.exe introuvable"
    'IF_END
    Et en supprimant les lignes mises en commentaire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      for i := 0 to liste1.Count - 1 do
        if Copy(liste1.Strings[i], 1, 1) <> '''' then
          liste2.Add(liste1.Strings[i]);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    GET_REG_KEY "HKEY_CURRENT_USER\SOFTWARE\MONAPPLI" "ExePath"
    $PATH %VAR%
    GET_REG_KEY "HKEY_CURRENT_USER\SOFTWARE\MONAPPLI" "Version"
    $VAR2 %VAR%
    GET "%HOST%/MONAPPLI.exe" "%TMP_PATH%"
    GET_FILE_VERSION "%TMP_PATH%\truc.exe"
    $UPDATE %VAR%
    PRINT "Versions différentes"
    KILL "MonAppli.exe"
    DELETE "%PATH%\MonAppli.exe"
    MOVE "%TMP_PATH%\MonAppli.exe" "%PATH%\Monappli.exe"
    SET_REG_KEY "HKEY_CURRENT_USER\SOFTWARE\MONAPPLI" "Version" %UPDATE%
    PRINT "Enregistrement dans le registre effectué"
    PRINT "L'application à correctement été mis à jour !"
    Tu n'as plus qu'à exécuter les actions une par une.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  15. #15
    Membre à l'essai
    Inscrit en
    Avril 2003
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 14
    Points : 23
    Points
    23
    Par défaut
    Code très intéressant.

    Je viens de tenter de le mettre en place mais il manque je crois un point important, c'est qu'il peut y avoir des conditions if résultantes de traitement précédent, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    IFNOT IS_EQUAL %VAR2% %UPDATE%
    provenant de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     GET_FILE_VERSION "%TMP_PATH%\truc.exe"
     ' Affectation à UPDATE de la version récupérée
      $UPDATE %VAR%
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    GET_REG_KEY "HKEY_CURRENT_USER\SOFTWARE\MONAPPLI" "Version" 
    ' Affectation à VAR2 de la valeur actuelle de version 
    $VAR2 %VAR%

    On doit donc gérer les commandes précédentes pour savoir si le test sera vrai / faux.

    De plus beaucoup de conditions IF contienne des variables affectées précédemment et donc à remplacer par leur valeur, par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    IF FILE_EXIST "%PATH%\MonAppli.exe"
    PATH vient de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    GET_REG_KEY "HKEY_CURRENT_USER\SOFTWARE\MonAppli" "ExePath" 
    $PATH %VAR%

  16. #16
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    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 419
    Points : 5 818
    Points
    5 818
    Par défaut
    Salut

    je pense que tu n'échapperas pas à l'utilisation de l'arbre binaire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
                    IF
                  /    \
    expression          \   
    booléenne            \
                          THEN
                        /      \
             instructions   ELSE
                               /
                        instructions
    à toi de le construire en première lecture et ensuite de le parcourir au fur et à mesure de tes instructions
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  17. #17
    Membre à l'essai
    Inscrit en
    Avril 2003
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Avril 2003
    Messages : 14
    Points : 23
    Points
    23
    Par défaut
    Aurait-on un exemple de cette construction d'arbre quelque part sur le site ?

  18. #18
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    Pour ma part, j'ai essayé d'améliorer mon programme mais je me suis perdu dans des complications.

    J'essaierai d'y revenir plus tard, si personne n'a proposé une solution, mais pour le moment je déclare forfait.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  19. #19
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    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 419
    Points : 5 818
    Points
    5 818
    Par défaut
    salut

    pour commencer faut créer les différents type de node

    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
     
    unit Unodes;
    interface
    Type
      Tnode = Class
        Name : String;
        Constructor Create(aName : String);
      End;
      TnodeClass = Class of  Tnode;
     
      TnodeIf = Class(Tnode)
      End;
      TnodeThen = Class(Tnode)
      End;
      TnodeVar = Class(Tnode)
      End;
      ....
      procedure registerNodeByName(classe: TnodeClass);
      function getNodeByName(nom: string): TnodeClass;
     
      var
        NodesByName : TStringList;
     implementation
     
    // Enregistrer une classe
    procedure registerNodeByName(classe: TnodeClass);
    begin
      // Ajout de la classe si elle n'est pas déjà référencée
      if (classByName.IndexOf(classe.ClassName) = -1) then
      begin
        classByName.AddObject(classe.ClassName,TObject(classe));
      end;
    end;
     
    // Obtenir une classe par son nom
    function getNodeByName(nom: string): TnodeClass;
    var
      i : integer;
    begin
      // Recherche dans la liste des classByName
      i := classByName.IndexOf(nom);
      // si pas trouvé, on renvoie nil
      if (i = -1) then
      begin
        result := nil;
      end
      // si trouvé, on renvoie la classe associée
      else
      begin
        result := TnodeClass(classByName.objects[i]);
      end
    end;
     
      Constructor Tnode.Create(aName : String);
      Begin
        Name     := aName;
      End;
      ....
    { // Au début de l'application, enregistrer les classes  :
    NodesByName := TStringList.Create;
    registerNodeByName(MaClasse1);
    // Utilisation :
    ...
    getNodeByName(NomReCherche).Name
    ...
    // Fin d'application, libérer classByName
    NodesByName.Free;
    }
    end.

    ensuite la base d'un arbre binaire ... faudra surement améliorer l'arbre mais ceci n'est qu'une base

    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
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
     
    //////////////////////////////////////
    ///
    //////////////////////////////////////
    Unit UArbreBinaire
    Interface
      uses Unodes
     
      Tnoeud = class
      private
        Node : TNode ;
        gauche,droite : noeud ;
        constructor create(aNode : TNode) ;
        destructor  destroy ;
        procedure   ajoutGauche(aNode : TNode) ;
        procedure   ajoutdroite(aNode : TNode) ;
      end ;
     
      Tarbre = class
      private
         tete,courant : noeud ;
      public
        constructor create(aNode : TNode) ;
        destructor  destroy ;
        procedure   ajouter(aNode : TNode;G : Boolean) ;
        function    compter_noeuds(posit : noeud) : integer ;
        function    compter_niveaux(posit : noeud) : integer ;
        function    egal_a(arbre2 : Tarbre) : boolean ;
     
      end ;
     var
       Arbre : Tarbre;
     
    implementation
      //////////////////////////////////////////////
      constructor Tnoeud.create(aName : string) ;
      begin
        Name:=aName ;
        gauche:=nil ;droite:=nil ;
      end ;
     
      destructor Tnoeud.destroy ;
      begin
        Node.free;
        if gauche<>nil then
          gauche.free;
        if droite<>nil then
          droite.free;
      end ;
     
      procedure Tnoeud.ajoutGauche(aNode : TNode) ;
      begin
       if gauche<>nil then
         gauche.ajoutGauche(aNode)
       else
         gauche:=Tnoeud.create(aNode) ;
      end;
     
      procedure Tnoeud.ajoutDroite(aNode : TNode) ;
      begin
       if droite<>nil then
         droite.ajoutDroite(aNode)
       else
         droite:=Tnoeud.create(aNode) ;
      end;
     
     function Tnoeud.egal_a(noeud2 : Tnoeud) : boolean ;
     begin
      if (self=nil) and (noeud2=nil) then
         egal_a:=true
      else
      if ((self<>nil) and (noeud2=nil)) or
         ((self=nil) and (noeud2<>nil)) or
         (Node.name<>noeud2.Node.name) then
           egal_a:=false
      else
        egal_a:=gauche.egal_a(noeud2.gauche) and droite.egal_a(noeud2.droite) ;
     end ;
     //////////////////////////////////////////////
    constructor Tarbre.create(aNode : TNode) ;
    begin
      tete:= Tnoeud.create(aNode) ;
      courant:=tete ;
    end ;
     
    destructor Tarbre.destroy ;
    begin
      courant:=nil ;
      tete.free ;
    end ;
     
     
    procedure Tarbre.ajouter(aName : string;G : Boolean) ;
    begin
      if G Then
        tete.ajoutGauche(aName)
      else
        tete.ajoutDroite(aName)  ;
    end ;
     
    function Tarbre.compter_noeuds(posit : noeud) : integer ;
    begin
    if posit=nil then compter_noeuds:=0
    else
       compter_noeuds:=1+compter_noeuds(posit.gauche)+compter_noeuds(posit.droite) ;
    end ;
     
    function Tarbre.compter_niveaux(posit : noeud) : integer ;
    var ng,nd : integer ;
    begin
     if posit=nil then
       compter_niveaux:=0
     else
       begin
         ng:=1+compter_niveaux(posit.gauche) ;
         nd:=1+compter_niveaux(posit.droite) ;
         compter_niveaux:=max(ng,nd) ;
       end ;
    end ;
     
    function Tarbre.egal_a(arbre2 : Tarbre) : boolean ;
    begin
      if (self=nil) and (arbre2=nil) then
        egal_a:=true
      else
      if (self=nil) and (arbre2<>nil) then
        egal_a:=false
      else
      if (self<>nil) and (arbre2=nil) then
        egal_a:=false
      else
        egal_a:=tete.egal_a(arbre2.tete) ;
    end ;
     
    end.
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  20. #20
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 419
    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 419
    Points : 5 818
    Points
    5 818
    Par défaut
    salut

    en réfléchissant l'arbre devrais avoir plutôt cette tête là

    Nom : if.png
Affichages : 212
Taille : 16,2 Ko
    donc lors de la construction de ton arbre on vois bien
    que l'on place la plupart des instruction sur la gauche du nœud précédent
    Dans le cas du if c'est un peut différent
    on voit que la condition vrai est a gauche et la fausse est a droite (ELSE)
    lorsque l'on arrive au END_IF il faut remonter au IF précédent et mettre le END_IF a droite de son IF
    voila une fois structuré de cette façon je pense qu'il sera plus facile d'utiliser les différente commande

    dans un blocs Instruction tu peut bien sur retrouver un IF END_IF mais aussi des COMMANDE avec des PARAMS
    des VARIABLE , des CONST si tu en as ... et plein d'autre truc sympa auquel j'ai pas pensé

    sur le même principe tu peut réaliser des boucles
    Nom : while.png
Affichages : 212
Taille : 13,8 Ko
    je te laisse remplir ton arbre à partir de ton source ... je pense que le principe est là
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

Discussions similaires

  1. lecture d'un fichier texte vers un tableau de structure
    Par syki.mail dans le forum MATLAB
    Réponses: 2
    Dernier message: 12/06/2012, 20h38
  2. lecture d'un fichier texte
    Par benahpets dans le forum MFC
    Réponses: 5
    Dernier message: 22/06/2005, 11h50
  3. [C#] Lecture d'un fichier texte (farfelu)
    Par choas dans le forum Windows Forms
    Réponses: 3
    Dernier message: 11/04/2005, 14h33
  4. Lecture d'un fichier Texte
    Par jcharles dans le forum Bases de données
    Réponses: 8
    Dernier message: 27/10/2004, 14h58
  5. Stockage de données & lecture d'un fichier texte
    Par petitours dans le forum C++Builder
    Réponses: 6
    Dernier message: 13/03/2004, 14h05

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