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

Sepi Discussion :

Avancement de l'importeur d'unités Delphi


Sujet :

Sepi

  1. #1
    Expert éminent

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    juin 2004
    Messages
    4 516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : juin 2004
    Messages : 4 516
    Points : 9 999
    Points
    9 999
    Par défaut Avancement de l'importeur d'unités Delphi
    Bon ben pour ceux qui ont déjà regardé à SepiImportsSystem.pas, ils se sont peut-être déjà dit que OK, ça passait pour les quelques déclarations hyper de base de System.pas... Mais que s'il fallait importer tout Classes.pas comme ça... Ca allait être dur

    Donc, je me suis mis à développer un importeur d'unités Delphi : SepiUnitImporter. Il doit être capable de prendre en entrée une unité Delphi existante, et de ressortir une unité du type SepiImportsSystem, qui importe toute l'unité dans Delphi.

    Sur ce thread, je détaillerai l'avancement de cet importeur.

    Vous trouverez ci-joint un zip de ce projet. Pour l'instant, j'ai fait l'analyseur syntaxique (mon TFE m'a enfin servi ). Il est produit à partir d'une grammaire faite maison (ci-jointe et également dans le zip : DelphiIntf.gra, sauf que jointe elle est en txt), que je passe à la moulinette de mon générateur du TFE que j'ai un peu amélioré (beaucoup en fait).

    Et ça sort des .xml (pour l'instant, en interne, on a un beau n'arbre syntaxique objet) du type de celui-ci (c'est la partie "utile" de System : à la fin vous trouverez le super record TVarData qui contient des case ).

    Il est capable de passer sur Classes et TypInfo mais a encore des ratés sur SysUtils par exemple. (pour Classes il faut virer les {$IF} - pas {$IFDEF} - vers la fin de l'implémentation ; j'ai été fénéasse sur le pré-processeur )

    -------------------------------

    Pour ceux qui veulent piger le fichier .gra (qui est du texte), il y d'abord la description des lexèmes (terminaux) : à gauche son identifiant pour le code, à droite sa représentation.

    Après il y a la description des non-terminaux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ntNonTerminal (tab) NonTerminal [(tab) Simplify|AsText]
    (tab) Choix 1
    (tab) Choix 2
    (tab) [@]
    Le Simplify sert à indiquer à l'analyseur qu'une fois qu'il a construit un non-terminal comme ça, il le supprime et donne tous ses enfants à son parent : ça permet de linéariser facilement des récursions BNF à droite, ce qui pullule en analyse syntaxique LL(1).

    Le AsText sert uniquement à la production XML : s'il est présent, on affiche le texte de code complet que reprend le non-terminal.

    Dans les différents symboles d'un choix, on peut ajouter un * accollé à droite d'un symbole, et ce pour indiquer qu'il faut supprimer le symbole aussitôt qu'il est construit. Ca permet de se débarrasser des symboles inutiles. NB : on ne peut supprimer un non-terminal qui se simplifie .

    Le @ est utilisé pour signaler un choix vide.

    On peut aussi préfixer tout choix non-vide par un entier (positif ou négatif), qui indique sa priorité (par défaut toutes les priorités sont 0). En cas de conflits LL(1) entre deux choix, il est ainsi possible de choisir préférentiellement un choix qu'un autre (celui dont la priorité est la plus élevée).

    ------------------------------------

    Edit 1 : import des routines et de tous types - excepté les classes
    Edit 2 : import des classes et de leurs champs (pas les méthodes et propriétés)
    Edit 3 : tout est fait
    Edit 4 : un "post-processeur" élimine quelques erreurs triviales (TypeInfo sur des pointers, types sans nom et structures Windows)
    Fichiers attachés Fichiers attachés
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur exécutif du Scala Center à l'EPFL.
    Découvrez Mes tutoriels, ou mon logiciel phare FunLabyrinthe : un jeu de labyrinthe gratuit et personnalisable à l'infini avec des scripts Delphi-like.

  2. #2
    Expert éminent

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    juin 2004
    Messages
    4 516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : juin 2004
    Messages : 4 516
    Points : 9 999
    Points
    9 999
    Par défaut
    Mis à jour : le programme sait maintenant importer les déclarations de routines, ainsi que les déclarations de n'importe quel type, sauf les classes (mais interfaces bien).

    Il y a un fichier SepiImportsClasses.pas attaché qui montre ce qui sort directement d'un passage sur Classes.pas.
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur exécutif du Scala Center à l'EPFL.
    Découvrez Mes tutoriels, ou mon logiciel phare FunLabyrinthe : un jeu de labyrinthe gratuit et personnalisable à l'infini avec des scripts Delphi-like.

  3. #3
    Expert éminent

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    juin 2004
    Messages
    4 516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : juin 2004
    Messages : 4 516
    Points : 9 999
    Points
    9 999
    Par défaut
    Nouvelle mise à jour. Les classes sont désormais importées également, du moins leurs champs. Les méthodes et propriétés sont à venir.
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur exécutif du Scala Center à l'EPFL.
    Découvrez Mes tutoriels, ou mon logiciel phare FunLabyrinthe : un jeu de labyrinthe gratuit et personnalisable à l'infini avec des scripts Delphi-like.

  4. #4
    Expert éminent

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    juin 2004
    Messages
    4 516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : juin 2004
    Messages : 4 516
    Points : 9 999
    Points
    9 999
    Par défaut
    Nouvelle mise à jour.

    Tout est désormais importé, le mieux possible. Et l'analyseur passe sans problème sur SysUtils et Classes, et (presque) Windows.

    Pour Windows il faut virer 3 point-virgule Parce que sinon ma grammaire est complètement ambigüe, et je ne sais pas du tout comment faire pour qu'elle ne le soit pas.

    Bon bien sûr le code qui sort n'est pas prêt-à-compiler. Ce n'est pas possible. Il faut le remanier, un petit peu. Le mieux est de lancer une compilation, et de traiter chaque erreur.

    Ca suffira pour le moment. A terme, l'importeur devra être capable de lancer lui-même une compilation, et d'auto-corriger son propre code en fonction des 3 erreurs qu'il est susceptible de rencontrer (toutes à base de TypeInfo évidemment).
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur exécutif du Scala Center à l'EPFL.
    Découvrez Mes tutoriels, ou mon logiciel phare FunLabyrinthe : un jeu de labyrinthe gratuit et personnalisable à l'infini avec des scripts Delphi-like.

  5. #5
    Expert éminent

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    juin 2004
    Messages
    4 516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : juin 2004
    Messages : 4 516
    Points : 9 999
    Points
    9 999
    Par défaut
    J'ai ajouté un "post-processeur" qui élimine quelques erreurs triviales, à savoir tenter de récupérer les RTTI de pointeurs, types sans nom et structures Windows.

    Quelques structures de Windows ont quand même des RTTI, parce qu'elles contiennent une interface. On les détecte à l'exécution par des "Objet %s non trouvé".
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur exécutif du Scala Center à l'EPFL.
    Découvrez Mes tutoriels, ou mon logiciel phare FunLabyrinthe : un jeu de labyrinthe gratuit et personnalisable à l'infini avec des scripts Delphi-like.

  6. #6
    Expert éminent

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    juin 2004
    Messages
    4 516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : juin 2004
    Messages : 4 516
    Points : 9 999
    Points
    9 999
    Par défaut
    Alors l'importeur d'unités a été complètement récrit. Au lieu de faire une "transposition syntaxique", il compile véritablement l'unité Delphi en entrée.
    Pour ce faire, il a bien sûr besoin d'avoir compilé au préalable toute unité qui se trouverait dans les uses. C'est pour ça que non seulement il produit l'unité d'importation, mais aussi un fichier .scu qui est une unité compilée Sepi (uniquement la partie interface). Vous pouvez l'assimiler à un .dcu du Delphi, mais sans le code des méthodes.

    La grammaire utilisée a été très fort revue. Elle n'est d'ailleurs plus non-contextuelle. J'ai amélioré mon générateur LL(1) pour pouvoir faire :
    • Un compilateur étroit, ce qui est nécessaire pour faire de l'analyse contextuelle.
    • Une analyse contextuelle, ce qui est nécessaire entre autres pour les initialisations de tableaux et de records.
    • Du non-déterminisme, à coup de sortes de try, ce qui m'a semblé nécessaire pour (et en tout cas a grandement facilité) les déclarations de types énumérés - VS types étendue - et les directives appliquées à des types fonctions (voir en anecdote cet article).

    Le code de l'importeur (qu'on peut appeler maintenant compilateur) est plus OO, en attribuant à certains symboles grammaticaux une classe chargée de les compiler. Cette classe dérive toujours de TSepiNonTerminal.

    Vous pouvez télécharger le zip avec les sources et exécutables. Le programme SepiDelphiCompiler doit être lancé en ligne de commande avec en paramètre le nom du fichier .csv qui reprend les unités à compiler.
    4 fichiers .csv (à une seule colonne ^^) sont fournis, qui reprennent toutes les unités du dossier source\rtl\ de BDS 3.0 (Delphi 2005). Si vous avez une autre version, je crains que vous ne devrez modifier le source du programme (dans le .dpr, fonction FixSourceFileName). J'arrangerai ça plus tard. Le bon ordre est celui donné dans le fichier de commandes GenerateAll.bat, à savoir :
    1. SepiDelphiCompiler Windows.csv
    2. SepiDelphiCompiler SysUnits.csv
    3. SepiDelphiCompiler WinUnits.csv
    4. SepiDelphiCompiler CommonUnits.csv

    Pour Windows.csv, ça risque de prendre du temps (sur mon proc 1,6 GHz, ça met 50 secondes). Donc faites-le une fois histoire d'avoir les unités compilées, mais après faites vos tests sur les trois autres. Ces dernières vont nettement plus vite.

    Le chargement de Windows.scu, lorsqu'on compile sur les autres fichiers .csv, est extrêment rapide et ne consomme que très peu de mémoire, malgré sa lourdeur, grâce au lazy-mode de TSepiUnit, qui ne charge un enfant que lorsqu'il est demandé

    Ne vous étonnez pas s'il vous envoie des erreurs (quelques unes), c'est normal, ce sont des "known issues" Mais il n'y a aucune erreur fatale, ce qui lui permet de tout terminer.

    Trois fichiers ont demandé que je les "amende". Ils ont donc une version en .txt dans le zip. Il s'agit de : Classes.pas ({$IF} remplacé par {$IFDEF}) et CommCtrls et MMSystem (essayez de passer le compilateur sur leurs versions originales, et vous serez bien surpris de la syntaxe que vous découvrirez... Pire encore, si je vous dis que ça compile vraiment avec le compilo Delphi ).

    Après la compilation, trois fichiers sont générés pour chaque fichier .pas.
    • Un fichier SepiImportsXXX.pas dans Output\ (le fichier d'importation).
    • Un fichier .scu dans Cache\ (l'unité compilée).
    • Un fichier .txt dans Cache\ (plein d'infos sur l'unité compilée).
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur exécutif du Scala Center à l'EPFL.
    Découvrez Mes tutoriels, ou mon logiciel phare FunLabyrinthe : un jeu de labyrinthe gratuit et personnalisable à l'infini avec des scripts Delphi-like.

  7. #7
    Expert éminent

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    juin 2004
    Messages
    4 516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : juin 2004
    Messages : 4 516
    Points : 9 999
    Points
    9 999
    Par défaut
    L'importeur d'unité, SepiDelphiUnitImporter, est maintenant officiellement inséré dans le repository de Sepi, et fait donc partie intégrante du projet.

    Il a par ailleurs été pas mal amélioré depuis la dernière fois.
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur exécutif du Scala Center à l'EPFL.
    Découvrez Mes tutoriels, ou mon logiciel phare FunLabyrinthe : un jeu de labyrinthe gratuit et personnalisable à l'infini avec des scripts Delphi-like.

Discussions similaires

  1. Réponses: 3
    Dernier message: 23/12/2005, 17h21
  2. [Delphi] Pascal et unité "cartes"
    Par berserk7 dans le forum EDI
    Réponses: 11
    Dernier message: 27/10/2005, 14h12
  3. [Delphi 2005][Delphi 6] reference d'unité circulaire
    Par ludovic tambour dans le forum Langage
    Réponses: 12
    Dernier message: 11/05/2005, 17h28
  4. Problème unit CRT pour Faire du Pascal avec Delphi
    Par alexmorel dans le forum Débuter
    Réponses: 4
    Dernier message: 01/06/2004, 17h13
  5. Unité Delphi appelée à partir de JAVA
    Par babaahmed dans le forum API standards et tierces
    Réponses: 2
    Dernier message: 26/04/2003, 10h51

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