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 :
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).
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 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)
Partager