I. Introduction▲
Le framework .NET expose des classes permettant d'accéder au compilateur C#. Au cours de cet article, nous verrons comment utiliser ces classes afin de créer notre propre compilateur C#.
II. Interface graphique▲
Nous allons commencer par réaliser l'interface graphique de notre application en WPF. Ouvrez Visual Studio et sélectionnez Fichier - Nouveau projet, puis choisissez Application WPF et appelez le « Compilateur » :

Nous allons ensuite ajouter une TextBox dans notre fenêtre principale. Celle-ci nous servira à écrire le code qui devra être compilé. Puis nous ajouterons un TabControl contenant deux TabItem. Ces deux TabItem serviront à afficher le résultat de la compilation et la liste des erreurs relatives au code. Nous ajouterons également un Button afin de générer le code et l'exécuter si la génération s'est déroulée avec succès. Votre fenêtre devrait normalement (ou à peu de choses près) ressembler à ceci :

A présent, nous pouvons passer au chapitre suivant ;)
III. Implémentation du code▲
III-A. Présentation de la classe CSharpCodeProvider▲
Comme je vous le disais en introduction, le framework .NET contient des classes permettant d'accéder aux instances du générateur de code et donc de pouvoir créer son propre compilateur. Dans le cadre de cet article, nous allons nous intéresser de plus près à la classe CSharpCodeProvider.
Cette classe est une classe dérivée de la classe de base CodeDomProvider et fournit l'accès au compilateur de code C#.
L'équivalent existe pour les langages VB et JScript.
III-B. Compilation du code▲
En premier lieu, nous allons ajouter au code behind, les instructions using suivantes :
usingSystem.CodeDom.Compiler;usingMicrosoft.CSharp;
Nous allons ensuite créer l'événement Click du Button Build en double-cliquant sur celui-ci depuis le fichier .xaml puis implémenter sa logique. Tout d'abord, nous allons effacer le contenu des TextBox des onglets :
//CleaningtxtItemOutputandtxtItemErrorstxtItemOutput
.Text="";txtItemErrors
.Text="";
On va ensuite créer une instance de CodeDomProvider pour le langage C# :
//CreateinstanceofCodeDomProviderCodeDomProvider provider
=CSharpCodeProvider.CreateProvider("CSharp");
La prochaine étape sera de préciser que nous souhaitons générer un fichier exécutable et spécifier son nom. Pour y parvenir, nous devons utiliser la classe CompilerParameters représentant la liste des paramètres d'un compilateur :
//Nameof.exefilestringOutput="MyProgram.exe";CompilerParameters parameters
=newCompilerParameters();//Specifywewantan.exefileinsteadofa.dllparameters
.GenerateExecutable=true;//Nameofoutputassemblyparameters
.OutputAssembly=Output;
On passe maintenant à la partie « Compilation » en utilisant la méthode CompileAssemblyFromSource de l'objet provider. Cette méthode permet de compiler un assembly et renvoie un objet de type CompilerResults contenant le résultat de la compilation. Elle prend deux objets en paramètres. Tout d'abord un objet de type CompileParameters que nous avons créé précédemment puis un tableau de string contenant les sources à compiler.
CompilerResults results
=provider.CompileAssemblyFromSource(parameters,txtCodeSource.Text);
La dernière étape consiste à vérifier si l'objet results contient des erreurs de compilation et le cas échéant, à l'indiquer dans l'onglet Output et afficher le détail dans l'onglet Errors :
if(results.Errors.Count>0){txtItemOutput
.Text=results.Errors.Count+"error(s).SeeErrorsMenu.";foreach(CompilerError CompErrinresults.Errors){txtItemErrors
.Text=txtItemErrors.Text+"Linenumber"+CompErr.Line+",ErrorNumber:"+CompErr.ErrorNumber+",'"+CompErr.ErrorText+";"+Environment
.NewLine+Environment.NewLine;}}
III-C. Exécution du code▲
Afin de pouvoir exécuter votre code, une nouvelle instruction using doit être ajouté à votre fichier .xaml :
usingSystem.Diagnostics;
Cette instruction nous permet d'accéder à la classe Process, Nous allons ajouter une condition else gérant le cas où la compilation s'est déroulée sans erreurs :
else{//SuccessfulCompiletxtItemOutput
.Text="Compilesuccessful!";Process
.Start(Output);}
C'est aussi simple que ça :)
Voici le programme complet :
privatevoidBuild_Click(objectsender,RoutedEventArgs e){//CleaningtxtItemOutputandtxtItemErrorstxtItemOutput
.Text="";txtItemErrors
.Text="";//CreateinstanceofCodeDomProviderCodeDomProvider provider
=CSharpCodeProvider.CreateProvider("CSharp");//Nameof.exefilestringOutput="MyProgram.exe";CompilerParameters parameters
=newCompilerParameters();//Specifywewantan.exefileinsteadofa.dllparameters
.GenerateExecutable=true;//Nameofoutputassemblyparameters
.OutputAssembly=Output;CompilerResults results
=provider.CompileAssemblyFromSource(parameters,txtCodeSource.Text);if(results.Errors.Count>0){txtItemOutput
.Text=results.Errors.Count+"error(s).SeeErrorsMenu.";foreach(CompilerError CompErrinresults.Errors){txtItemErrors
.Text=txtItemErrors.Text+"Linenumber"+CompErr.Line+",ErrorNumber:"+CompErr.ErrorNumber+",'"+CompErr.ErrorText+";"+Environment
.NewLine+Environment.NewLine;}}else{//SuccessfulCompiletxtItemOutput
.Text="Compilesuccessful!";Process
.Start(Output);}}
Allez ! On se fait le classique Hello World ? :)
Exécutez votre programme et copier coller le code suivant dans la TextBox source :
usingSystem;namespaceHelloWorld{classHelloWorld{staticvoidMain(string[]args){Console
.WriteLine("HelloWorld!");Console
.ReadLine();}}}
Normalement, vous devriez obtenir ceci :


La compilation et l'exécution se sont bien déroulées et en vérifiant dans le dossier bin/Debug de votre projet, un fichier .exe a bien été généré. Vous pouvez également modifier le code source de façon à générer une erreur et voir comment se comporte le programme.
IV. Conclusion▲
Dans cet article, nous avons vu qu'il n'était pas bien compliqué de réaliser un compilateur C#. Il ne vous reste plus qu'à l'améliorer à votre sauce en ajoutant d'autres fonctionnalités telles que la coloration syntaxique, la gestion des tabulations, etc..
V. Remerciements▲
Je tiens à remercier xxx et xxx pour la relecture attentive de cet article ainsi que les corrections apportées.




