Si vous avez déja poser la question suivante: Comment un langage de programmation est-il programmé ? Cet article vous aidera sans doute pour répondre à vos attentes.
Il existe grossièrement deux types de langages en terme d’exécution:
- les langages compilés
- les langages interprétés
Il existe aussi un troisième type: les langages intermédiaires qui sont compilés pour une machine virtuelle, comme Java et son bytecode destiné à la JVM. Bien que, maintenant, le bytecode soit traduit vers du code machine via le compilateur JIT (Just In Time). D’ailleurs, on a tendance à classer Java dans le premier groupe, mais ce n’est pas aussi simple.
Les premiers utilisent un compilateur qui traduit le code source vers un code machine en particulier. Les seconds utilisent un interpréteur qui va lire à la volée le code source et exécuter le programme dans la foulée. Les langages compilés ne peuvent pas produire des programmes modifiables à la volée, il faut systématiquement passer par l’étape de compilation pour obtenir une exécution.
Les langages interprétés, comme Python, peuvent produire des programmes modifiables au runtime. Il suffit de modifier un fichier de code source (sous certaines conditions) et lorsque le programme exécute à nouveau son contenu, il est à nouveau analysé et exécuté.
Pour produire un compilateur, il faut le programmer. C’est un logiciel qui a la particularité de produire un exécutable. Il existe différentes méthodes pour en développer un. En fait, en général, un développeur n’écrit pas un logiciel pour une machine ou un système (sauf dans des cas précis), mais pour un compilateur qui va s’en charger pour lui. En général, un compilateur comprend plusieurs modules: le scanner, le parseur et l’analyse syntaxique, l’analyse sémantique, un générateur de code abstrait (génération sous forme d’arbre), l’optimiseur, le générateur de code machine. Il faudra rajouter le linker qui permet de gérer les dépendances du code et j’en passe. C’est assez complexe à écrire et le nombre d’ingénieurs capables d’en écrire un est assez restreint.
Pour produire un interpréteur, c’est un peu plus simple en théorie car il n’est pas nécessaire dans ce cas de générer un code binaire. L’interpréteur est un programme en général compilé. Ce n’est pas toujours le cas, car vous pouvez écrire un interpréteur avec un langage interprété, une sorte de poupée russe.
Il est possible donc d’écrire un compilateur ou un interpréteur avec n’importe quel langage, à priori. Vous avez d’ailleurs des cours sur internet pour programmer un compilateur C en Java, par exemple. Seulement, certains langages ne sont pas adaptés. Java et Python par exemple ne sont pas adaptés. Beaucoup sont écrits en C ou C++ car ils datent d’une époque ou ces langages étaient les plus simples ou plutôt les plus pratiques. Il est préférable d’utiliser des langages comme Ocaml, Rust, Scala, etc. Ces langages implantent le paradigme fonctionnel et à ce titre offrent du sucre syntaxique adapté et des fonctionnalités qui permettent d’assurer une certaines sûreté d’exécution, et c’est très important lorsque l’on écrit un compilateur. Ensuite, il faut choisir le langage en fonction de la plateforme ciblée pour la compilation des programmes qui seront produits avec le langage, bien qu’il soit possible de faire de la compilation canadienne (cross compilation). D’ailleurs il est nécessaire de passer par ce biais lorsque l’on construit une nouvelle plateforme. D’ailleurs, si l’on prend la machine virtuelle Java, son compilateur de référence est écrit en C++ en grande partie.
Si l’on prend l’exemple de Rust, la première version de son compilateur a été écrite avec Ocaml. Par la suite, le compilateur a été écrit à nouveau en Rust puis compilé avec le compilateur initial pour le rendre auto-porté.
Programmer, comme vous dites, ou plutôt concevoir, un langage de programmation n’est pas un exercice trivial. Voici un lien vers un tutorial assez simple pour dégrossir le procédé. Il faut de toute façon définir une grammaire et vous trouverez des outils sur Internet qui permettent de créer un petit langage sans trop avoir à coder, mais il ne faut pas s’attendre à ce que ce dernier soit très subtil.
La question nous pousse vers une autre. Qui est arrivé en premier: la machine ou le logiciel ? Je penche plus pour le logiciel car il a fallu des machines pour exécuter rapidement des algorithmes. Sans le besoin de logiciel, la machine ne servirait pas à grand chose. D’autres personnes pensent le contraire. C’est un peu l’oeuf ou la poule, quoiqu’en lisant l’histoire des mathématiques…