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

Ada Discussion :

parser les entête Ada


Sujet :

Ada

  1. #1
    Invité
    Invité(e)
    Par défaut parser les entête Ada
    Bonjour,

    Je réalise un petit programme dans lequel je lis les entête de fichier *.ads *.adb *.ada pour établir les dépendances de composant Ada.

    Voici une courte note technique à l'attention des usagers.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Le programme va chercher les nom des unités dont dépend chaque composant en trouvant le mot réservé "with" et s'arrête dès qu'il trouve soit le mot réservé "package", soit le mot réservé "procedure" en respectant la case spécifiée ici.
    Est-ce que ça vous parait correct, suffisant comme description ?

    Voici mon code dans lequel j'invoque Gnat.Directory.operations.Wildcard_Iterator.
    Le programme est interfacer avec GtkAda.
    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
    -------------------
       --- Open project --
       -------------------
       procedure Open_Project
         (widget : access Gtk_Widget_Record'class;
          Main_Window : in Window_access) is
     
     
     
     
          procedure Action
            (Item  :        String;
             Index :        Positive;
             Quit  : in out Boolean) is
     
    	 File : File_Type;
    	 Line : String(1..256) := (others => Character'Val(32));
    	 Last : Natural;
     
          begin
    	 Put_Line("Item " & Positive'Image(Index) & ": " & item);	 
    	 Open(File, In_File, Item);
    	 while not End_Of_File(File) loop
    	    Get_Line(File, Line, Last);
    	    if Fixed.Index(Line(1..Last), "with") /= 0 then
    	       declare
    		  Position : Natural := Fixed.Index(Line(1..Last), "with") + 4;
    	       begin
    		  while Fixed.Index(Line, ",", Position) /= 0 loop
     
    		     Put_Line(Line(Position..Fixed.Index_Non_Blank(Line(Position..Fixed.Index(Line, ",") - 1), backward)));
     
    		     Position := Fixed.Index(Line, ",", Position) + 1;		     		     
    		  end loop;
    		  Put_Line(Line(Position..Fixed.Index_Non_Blank(Line(Position..Fixed.Index(Line, ";") - 1), backward)));
    	       end;
    	    end if;
    	    if Fixed.Index(Line(1..Last), "package") /= 0 or
    	      Fixed.Index(Line(1..Last), "procedure") /= 0 then
    	       exit;
    	    end if;
    	    Line := (others => Character'Val(32));
    	 end loop;
    	 Close(File);
     
          end Action;                                                   
     
          use Strings;      
       begin
          Main_Window.Project.Path := new String ' 
    	(File_Selection_Dialog(Title => "Open Project directory...",			      			       
    			       Default_Dir => "",
    			       Dir_Only => True,
    			       Must_Exist => True));
     
          if Main_Window.Project.Path'length = 0 then
    	 return;	 
          end if;
          Put_Line("Openning directory : " & Main_Window.Project.Path.all);
          declare
    	 procedure Wildcard_Iter is new Wildcard_Iterator(Action => Action);
          begin
    	 Wildcard_Iter(Main_Window.Project.Path.all & "/*.ad?");
          end;
     
       end Open_Project;
    Voici le résultat sur le répertoire src/lib de ce projet
    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
    F:\Axtracer>axtracer.exe
    Openning directory : F:\Axtracer\src\lib
    Item  1: F:\\Axtracer\src\lib\axt-main_window.adb
     Gdk.Drawable
     Gdk.Color
     Glib
     Gtk.Handlers
     Gtk.Widget
     Gtk.Enums
     Gtk.Main
     Gtk.Frame
     Gtk.Box
     Gtk.Menu_Bar
     Gtk.Menu
     Gtk.Menu_Item
     Pango.Layout
     Gtk.Style
     Glib.Error
     Gtk.Dialog
     Gtkada.File_Selection
     Text_Io
     Ada.Strings.Fixed
     Gnat.Directory_Operations
     GNAT.Directory_Operations.Iteration
    Item  2: F:\\Axtracer\src\lib\axt-main_window.ads
     Gdk.Pixbuf
     Gdk.GC
     Gdk.Rectangle
     Gtkada.Canvas
     Gtk.Window
    Item  3: F:\\Axtracer\src\lib\axt.ads
     System.Strings
    Item  4: F:\\Axtracer\src\lib\axtracer.adb
     Gtk.Main
    Item  5: F:\\Axtracer\src\lib\axtracer.ads
     Ada.Finalization
     Axt.Main_Window

    Merci pour vos réponses.

  2. #2
    Invité
    Invité(e)
    Par défaut Correction de la procedure Action pour accepter les déclaratiion sur plusieurs lignes.
    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
    procedure Action
            (Item  :        String;
             Index :        Positive;
             Quit  : in out Boolean) is
     
    	 File : File_Type;
    	 Line : String(1..256) := (others => Character'Val(32));
    	 Last : Natural;
    	 Position : Natural;
    	 Done : Boolean := True;
          begin
    	 Put_Line("Item " & Positive'Image(Index) & ": " & item);	 
    	 Open(File, In_File, Item);
    	 while not End_Of_File(File) loop
    	    Get_Line(File, Line, Last);
    	    if Done then
    	       if Fixed.Index(Line(1..Last), "with") /= 0 then	      	       
    		  Position := Fixed.Index(Line(1..Last), "with") + 4;
    		  Done := False;
    	       end if;	       
    	    else
    	       Position := Line'First;	       
    	    end if;
    	    if not Done then
    	       while Fixed.Index(Line, ",", Position) /= 0 loop
     
    		  Put_Line(Line(Position..Fixed.Index_Non_Blank(Line(Position..Fixed.Index(Line, ",") - 1), backward)));
     
    		  Position := Fixed.Index(Line, ",", Position) + 1;		     		     
    	       end loop;
     
    	       if Fixed.Index(Line, ";") /= 0 then
    		  Put_Line(Line(Position..Fixed.Index_Non_Blank(Line(Position..Fixed.Index(Line, ";") - 1), backward)));
    		  Done := True;
    	       end if;
    	    end if;
    	    if Fixed.Index(Line(1..Last), "package") /= 0 or
    	      Fixed.Index(Line(1..Last), "procedure") /= 0 then
    	       exit;
    	    end if;
    	    Line := (others => Character'Val(32));
    	 end loop;
    	 Close(File);
     
          end Action;

  3. #3
    Membre actif

    Homme Profil pro
    Mathématicien et développeur
    Inscrit en
    Mars 2012
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Mathématicien et développeur
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2012
    Messages : 132
    Points : 241
    Points
    241
    Billets dans le blog
    3
    Par défaut
    La définition me semble nickel.
    En fait, à quel genre de réponses t'attends-tu ?...
    Je remarque 2-3 détails:
    • Pourquoi
      au lieu de
      ?

    • Tu seras embêté avec les lignes de plus de 256 caractères.
      Autant se passer d'un "magic number" ->
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
       
      ...
      while not End_Of_File(File) loop
        declare
          Line: constant String:= Get_Line(File);
      ...
      Comme ça pas de "Last" ni d'embêtements avec la longueur...
    • Les "with" peuvent être écrits "With" ou "WITH" ou "wiTH" .
      Bref j'appliquerais la fonction "To_Lower"
    • Tu pourrais avoir plusieurs "with" sur la même ligne, ou "with" sur une ligne et le nom des unités sur d'autres... AMHA, j'essaierais de ramasser tous les noms pêle-mêle, oublier le nom quand c'est "with" ou "use" et sortir quand c'est "package", "procedure" ou "generic".

  4. #4
    Invité
    Invité(e)
    Par défaut
    Bonjour zerte,
    Merci pour ta réponse.
    Pour l'espace je peut rien faire, j'écris comme ça.
    Par contre les remarque suivante sont bonnes à prendre.
    Je vais ajouter un test de ligne de commentaire et roulez jeunesses.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Re- bonjour, ou bonjour....


    Donc, voici le code avec quelque correction...
    Je n'ai pas tout à fait suivi la dernière directive de Zerte ; En effet, je détecte toujours les include grâce au mot réservé with.
    Ca évite le redondance des use clause et les pragma.

    Les multiple "with" sur un liigne sont interdis, s'avez qu'à mettre une virgule.


    Je récupère d'abord le nom de l'unité courante, puis je relis le fichier pour récupérer les includes.

    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
    procedure Action
            (Item  :        String;
             Index :        Positive;
             Quit  : in out Boolean) is
     
    	 File : File_Type;	 
     
    	 Position : Natural;
    	 Done : Boolean := True;
    	 Unit_Name,
    	 Buffer : String_Access;	 	 
          begin
     
    	 Put_Line("Item " & Positive'Image(Index) & ": " & item);	 
    	 Open(File, In_File, Item);
     
             -- Getting current unit name.
     
    	 while not End_Of_File(File) loop
    	    declare
    	       Line : String := Get_Line(File);	       
    	       Is_Comment : Boolean := False;
    	    begin	       
    	       if Line'length /= 0 then		  
    		  if Fixed.Index(Line, "--") /= 0 then
    		     if Fixed.Index_Non_Blank(Line) = Fixed.Index(Line, "--") then
    			Is_Comment := True;
    		     end if;
    		  end if;
    		  if not Is_Comment then
    		     if Fixed.Index(To_Lower(Line), "package ") = 1 then
    			if Extension(Item) = "adb" then
    			   if Fixed.Index(To_Lower(Line), "is") /= 0 then
    			      Buffer := new String ' (Line(Fixed.Index(To_Lower(Line), "body")+4..Fixed.Index(To_Lower(Line), "is") - 1));
    			   else
    			      Buffer := new String ' (Line(Fixed.Index(To_Lower(Line), "body")+4..Line'last));
    			   end if;
    			   exit;
    			else
    			   if Fixed.Index(Line, "is") /= 0 then
    			      Buffer := new String ' (Line(Fixed.Index(To_Lower(Line), "package")+7..Fixed.Index(To_Lower(Line), "is") - 1));
    			   else
    			      Buffer := new String ' (Line(Fixed.Index(To_Lower(Line), "package")+7..Line'last));
    			      exit;
    			   end if;
    			end if;
    		     elsif Fixed.Index(To_Lower(Line), "procedure") = 1 then
    			if Fixed.Index(To_Lower(Line), "is") /= 0 then
    			   Buffer := new String ' (Line(Fixed.Index(To_Lower(Line), "procedure")+9..Fixed.Index(To_Lower(Line), "is") - 1));
    			else
    			   Buffer := new String ' (Line(Fixed.Index(To_Lower(Line), "procedure")+9..Line'last));
    			end if;		     
    			exit;
    		     end if;	       		  
    		  end if;
    	       end if;
    	    end;
    	 end loop;
    	 Unit_Name := new String ' (Buffer(Index_Non_Blank(Buffer.all)..Index_Non_Blank(Buffer.all, Backward)));
    	 Put_Line("Component named """ & Unit_Name.all & """ will be added to Graph");
    	 Reset(File);
     
            -- Getting all include.
     
    	 while not End_Of_File(File) loop
    	    declare
    	       Line : String :=  Get_Line(File);
    	       Is_Comment : Boolean := False;
    	    begin	       
    	       if Line'length /= 0 then
    		  if Fixed.Index(Line, "--") /= 0 then
    		     if Fixed.Index_Non_Blank(Line) = Fixed.Index(Line, "--") then
    			Is_Comment := True;
    		     end if;
    		  end if;
    		  if not Is_Comment then
    		     if Done then
    			if Fixed.Index(To_Lower(Line), "with") /= 0 then	      	       
    			   Position := Fixed.Index(To_Lower(Line), "with") + 4;
    			   Done := False;
    			end if;	       
    		     else
    			Position := Line'First;	       
    		     end if;
    		     if not Done then
    			while Fixed.Index(Line, ",", Position) /= 0 loop		     
    			   Buffer := new String ' (Line(Position..Fixed.Index_Non_Blank(Line(Position..Fixed.Index(Line, ",") - 1), backward)));
    			   Unit_Name := new String ' (Buffer(Index_Non_Blank(Buffer.all)..Index_Non_Blank(Buffer.all, Backward)));			   
    			   Put_Line("Unit named """ & Unit_Name.all & """ will be added to Graph");
    			   Position := Fixed.Index(Line, ",", Position) + 1;		     		     
    			end loop;
     
    			if Fixed.Index(Line, ";") /= 0 then
    			   Buffer := new String ' (Line(Position..Fixed.Index_Non_Blank(Line(Position..Fixed.Index(Line, ";") - 1), backward)));
    			   Unit_Name := new String ' (Buffer(Index_Non_Blank(Buffer.all)..Index_Non_Blank(Buffer.all, Backward)));			   
    			   Put_Line("Unit named """ & Unit_Name.all & """ will be added to Graph");
    			   Done := True;
    			end if;
    		     end if;
    		     if  Fixed.Index(To_Lower(Line), "package") = 1 or			  
    		       Fixed.Index(To_Lower(Line), "generic") = 1 or
    		       Fixed.Index(To_Lower(Line), "procedure") = 1 then
    			exit;
    		     end if;
    		     Line := (others => Character'Val(32));
    		  end if;
    	       end if;
    	    end;
    	 end loop;
    	 Close(File);
     
          end Action;
    Voici un gros fichier d'exemple :
    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
    -- with tata
    with Gdk.Drawable;                      use Gdk.Drawable;
    with Gdk.Color;                         use Gdk.Color;
    with Glib;                              use Glib;
    with Gtk.Handlers;        use Gtk.Handlers;
    pragma Elaborate_All(Gtk.Handlers);
    with Gtk.Widget;          use Gtk.Widget;
    with Gtk.Enums;           use Gtk.Enums;
    with Gtk.Main;
    with Gtk.Frame;                         use Gtk.Frame;
    with Gtk.Box;                           use Gtk.Box;
    with Gtk.Menu_Bar;                      use Gtk.Menu_Bar;
    with Gtk.Menu;                          use Gtk.Menu;
    with Gtk.Menu_Item;                     use Gtk.Menu_Item;
    with Pango.Layout;                      use Pango.Layout;
    with Gtk.Style;                         use Gtk.Style;
    with Glib.Error;                        use Glib.Error;
    with Gtk.Dialog;                        use Gtk.Dialog;
    with Gtkada.File_Selection;             use Gtkada.File_Selection;
     
    with Text_Io, -- un autre comment
      Ada.Strings.Fixed; -- package with
    -- this is comment.
    use Text_Io;
    use Ada.Strings, Ada.Strings.Fixed;
    with Gnat.Directory_Operations;         use Gnat.Directory_Operations;
    with GNAT.Directory_Operations.Iteration;use GNAT.Directory_Operations.Iteration;
    with Ada.Directories;                   use Ada.Directories;
    with Ada.Characters.Handling;           use Ada.Characters.Handling;
    -- others comment.
    package body Axt.Main_Window is
    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
    26
    Openning directory : F:\Axtracer\src\lib
    Item  1: F:\\Axtracer\src\lib\axt-main_window.adb
    Component named "Axt.Main_Window" will be added to Graph
    Unit named "Gdk.Drawable" will be added to Graph
    Unit named "Gdk.Color" will be added to Graph
    Unit named "Glib" will be added to Graph
    Unit named "Gtk.Handlers" will be added to Graph
    Unit named "Gtk.Widget" will be added to Graph
    Unit named "Gtk.Enums" will be added to Graph
    Unit named "Gtk.Main" will be added to Graph
    Unit named "Gtk.Frame" will be added to Graph
    Unit named "Gtk.Box" will be added to Graph
    Unit named "Gtk.Menu_Bar" will be added to Graph
    Unit named "Gtk.Menu" will be added to Graph
    Unit named "Gtk.Menu_Item" will be added to Graph
    Unit named "Pango.Layout" will be added to Graph
    Unit named "Gtk.Style" will be added to Graph
    Unit named "Glib.Error" will be added to Graph
    Unit named "Gtk.Dialog" will be added to Graph
    Unit named "Gtkada.File_Selection" will be added to Graph
    Unit named "Text_Io" will be added to Graph
    Unit named "Ada.Strings.Fixed" will be added to Graph
    Unit named "Gnat.Directory_Operations" will be added to Graph
    Unit named "GNAT.Directory_Operations.Iteration" will be added to Graph
    Unit named "Ada.Directories" will be added to Graph
    Unit named "Ada.Characters.Handling" will be added to Graph

  6. #6
    Membre actif

    Homme Profil pro
    Mathématicien et développeur
    Inscrit en
    Mars 2012
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Mathématicien et développeur
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2012
    Messages : 132
    Points : 241
    Points
    241
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par jovalise Voir le message
    Les multiple "with" sur un liigne sont interdis
    Interdit par qui ?

    C'est clair que c'est moche, mais si tu veux utiliser ton outil pour des sources Ada de toutes provenances, il faut aussi t'attendre à tout!

  7. #7
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Zerte Voir le message
    Interdit par qui ?

    C'est clair que c'est moche, mais si tu veux utiliser ton outil pour des sources Ada de toutes provenances, il faut aussi t'attendre à tout!
    Interdit par le programme
    En plus c'est moche.

    Merci Zerte.

  8. #8
    Membre actif

    Homme Profil pro
    Mathématicien et développeur
    Inscrit en
    Mars 2012
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Mathématicien et développeur
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2012
    Messages : 132
    Points : 241
    Points
    241
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par jovalise Voir le message
    Merci Zerte.
    De rien!

    [mode pinaille]
    Il n'y a pas d'"include" en Ada. Ce terme désigne des langages du Pléistocène qui ont une directive "include". Celle-ci, comme son nom l'indique, inclut un texte à l'endroit même de la directive.
    Le terme normalement utilisé pour Ada est "with'ed unit".
    Notamment est parfaitement équivalent à Ce n'est pas toujours le cas avec des "include"...
    [/mode pinaille]

  9. #9
    Invité
    Invité(e)
    Par défaut
    Bonjour Zerte,
    Citation Envoyé par Zerte Voir le message
    [mode pinaille]
    Oh, oui, c'est de la mauvaise fois.
    J'ai bien dit que je les détectais grâce au mot "with".
    J'aurais parlé "d'inclusion" ça passais un poil mieux ?
    J'ai pas voulu utiliser le mot "use" parce que c'est encore pas ça.
    C'est du "Withoning"

Discussions similaires

  1. Faire apparaître les entêtes d'un sous-état
    Par Le Pharaon dans le forum IHM
    Réponses: 3
    Dernier message: 10/07/2007, 12h52
  2. Réponses: 2
    Dernier message: 09/11/2006, 10h57
  3. [JTable] Ne pas afficher les entêtes de colonnes
    Par nicolas.pied dans le forum Composants
    Réponses: 2
    Dernier message: 27/01/2006, 11h22
  4. Réponses: 2
    Dernier message: 21/09/2005, 12h18
  5. [Apis]parser les arguments d'un programme Java
    Par sacofan dans le forum API standards et tierces
    Réponses: 4
    Dernier message: 06/08/2005, 14h32

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