Quand quelqu'un écrit un nouveau langage de programmation, dans quoi l'écrit-il?


162

Veuillez excuser mon ignorance. Je suis en train d'essayer PHP et je me mouille les pieds en naviguant SO, et je me sens obligé de poser une question que je me pose depuis des années:

Lorsque vous écrivez un tout nouveau langage de programmation, dans quoi l'écrivez-vous ?

Cela semble probablement vraiment idiot pour vous tous les programmeurs, pour qui j'ai un immense respect, mais c'est une chose déroutante pour moi. Que faire? Dites-vous qu'aujourd'hui je vais inventer un nouveau langage! puis allumez ... Bloc-notes? Est-ce que tous les compilateurs sont construits sur des langages déjà existants, de telle sorte que l'on pourrait déranger tous les langages de programmation jamais conçus sur un monstrueux arbre de ramification qui a finalement abouti à ... Je ne sais pas, quelque chose de vieux?

Avec ma faible intelligence, je trouve cela fascinant ... S'il vous plaît, éduquez-moi!

Réponses:


193

Ce n'est pas une question stupide. C'est une excellente question.

Comme déjà répondu, la réponse courte est: "Une autre langue".

Eh bien, cela conduit à des questions intéressantes? Et si c'était le tout premier langage écrit pour votre matériel particulier? Un problème très réel pour les personnes qui travaillent sur des appareils embarqués. Comme déjà répondu "une langue sur un autre ordinateur". En fait, certains périphériques embarqués n'obtiendront jamais de compilateur, leurs programmes seront toujours compilés sur un autre ordinateur.

Mais vous pouvez le repousser encore plus loin. Qu'en est-il des premiers programmes jamais écrits?

Eh bien, les premiers compilateurs pour les "langages de haut niveau" auraient été écrits dans ce qu'on appelle le "langage d'assemblage". Le langage d'assemblage est un langage dans lequel chaque instruction de la langue correspond à une seule instruction adressée à la CPU. Son langage de très bas niveau et extrêmement verbeux et très laborieux à écrire.

Mais même l'écriture du langage assembleur nécessite un programme appelé assembleur pour convertir le langage assembleur en "langage machine". Nous remontons plus loin. Les tout premiers assembleurs ont été écrits en "code machine". Un programme composé entièrement de nombres binaires qui sont une correspondance directe un à un avec la langue brute de l'ordinateur lui-même.

Mais cela ne s'arrête toujours pas. Même un fichier ne contenant que des nombres bruts a encore besoin d'être traduit. Vous devez toujours obtenir ces nombres bruts dans un fichier dans l'ordinateur.

Eh bien, croyez-le ou non, les premiers ordinateurs avaient une rangée d'interrupteurs à l'avant. Vous avez inversé les commutateurs jusqu'à ce qu'ils représentent un nombre binaire, puis vous avez actionné un autre commutateur et cela a chargé ce numéro unique dans la mémoire de l'ordinateur. Ensuite, vous avez continué à basculer jusqu'à ce que vous ayez chargé un programme informatique minimal capable de lire des programmes à partir de fichiers disque ou de cartes perforées. Vous avez appuyé sur un autre commutateur et il a lancé le programme en cours d'exécution. Quand je suis allé à l'université dans les années 80, j'ai vu des ordinateurs qui avaient cette capacité mais qui n'avaient jamais été chargés de charger un programme avec les commutateurs.

Et même avant cela, les programmes informatiques devaient être câblés avec des cartes enfichables !


20
+1, je pense que cette réponse correspond vraiment à l'esprit de la question.
stderr

30
Une fois, j'ai suivi un cours d'assembleur II et le prof a demandé pourquoi nous avions choisi le cours facultatif. J'ai opté pour la réponse amusante: "parce que je voulais un A. facile". Je pensais avoir la meilleure réponse, mais nous avions une usine Honeywell en ville et le type suivant a dit: "J'écris des microcodes toute la journée et je voulais apprendre un langage de haut niveau."
T.Rob

3
Je recommande vivement Code: The Hidden Language of Computer Hardware and Software . Il couvre essentiellement le même matériau que cette réponse, des tubes à vide jusqu'aux compilateurs pour les langages de haut niveau.
MatrixFrog

Les ordinateurs ont évolué tout comme les êtres humains, bien que dans un laps de temps relativement infinitésimal.
Gaurav Ojha

Maintenant, ce sera un commentaire non constructif, mais il doit être écrit ... c'est une réponse brillante sous toutes les formes, formes et informations :-)
Lukáš Řádek

23

La réponse la plus courante est C. La plupart des langages sont implémentés en C ou dans un hybride de C avec des callbacks et un "lexer" comme Flex et un générateur d'analyseur comme YACC . Ce sont des langues qui sont utilisées dans un seul but - pour décrire la syntaxe d'une autre langue. Parfois, quand il s'agit de langages compilés, ils sont d'abord implémentés en C. Ensuite, la première version du langage est utilisée pour créer une nouvelle version, et ainsi de suite. (Comme Haskell .)


1
Certains langages sont écrits en assembleur, comme picolisp. ( blog.kowalczyk.info/article/picoLisp-Arc-before-Arc.html )
Prof. Falken

1
Qu'en est-il des programmes lex / yacc (flex / bison)? Sont-ils considérés comme des compléments pour créer des langages en C?
Dave

1
Avez-vous quelque chose pour prouver que la réponse la plus courante est C?
RichardOD

J'ai commencé à parcourir la liste ici: google.com/Top/Computers/Programming/Languages/Open_Source Ensuite, j'ai accidentellement fermé ma fenêtre d'éditeur à propos de la langue 10, et j'ai perdu la motivation de passer. Quoi qu'il en soit, environ la moitié jusqu'à présent ont été implémentées en C et les autres se sont principalement amorcés.
Prof. Falken

3
Je pense que vous devez mentionner Lex / Yacc (ou des alternatives). On ne commence généralement pas à écrire un langage en C, mais plutôt avec un lexer et un analyseur qui sont ensuite supportés avec du code C.
Steve Rowe

14

De nombreux langages sont bootstrapés, c'est-à-dire écrits en eux-mêmes . Quant à savoir pourquoi vous voudriez faire cela, c'est souvent une bonne idée de manger votre propre dogfood .

L'article de wikipedia auquel je me réfère traite de la question de la poule et de l'œuf . Je pense que vous le trouverez assez intéressant.


5
Ce qui n'est pas possible lorsque vous débutez.
Michael Borgwardt

1
Oui évidemment. Mais beaucoup de langues sont écrites de cette façon une fois que c'est possible. Je voulais le souligner comme personne d'autre ne l'avait fait, et je pense que c'est un point important.
RichardOD

+1 pour l'utilisation du terme bootstrap. Il est intéressant que vous deviez compiler votre compilateur deux fois. La première fois est évidemment avec le compilateur simple que vous avez et la deuxième fois avec le compilateur que vous venez de construire. Supposons que vous ayez ajouté une optimisation à votre compilateur. Le compilateur que vous avez créé peut produire du code avec ces optimisations, mais il n'exécute pas lui-même le code optimisé tant que vous ne le compilez pas à nouveau avec le compilateur d'optimisation.
Les

@ Les- Oui, le bootstrapping est un concept intéressant.
RichardOD

2
Commentaire aléatoire ici. La réponse à la question séculaire de savoir qui est venu en premier (la poule ou l'œuf) est que le poulet est venu en premier. La raison en est que pour reproduire / répliquer quelque chose, vous devez d'abord avoir le reproducteur / réplicateur déjà en place pour effectuer la reproduction / réplication.
SpicyWeenie

10

À peu près n'importe quel langage, bien que l'utilisation d'un langage adapté au travail avec des graphiques et d'autres structures de données complexes facilitera beaucoup de choses. Les compilateurs de production sont souvent écrits en C ou C ++ pour des raisons de performances, mais des langages tels que OCaml, SML, Prolog et Lisp sont sans doute meilleurs pour le prototypage du langage.

Il existe également plusieurs «petits langages» utilisés dans la conception des langages. Lex et yacc sont utilisés pour spécifier la syntaxe et les grammaires, par exemple, et ils se compilent en C. (Il existe des ports pour d'autres langages, tels que ocamllex / ocamlyacc, et de nombreux autres outils similaires.)

En tant que cas particulier, les nouveaux dialectes Lisp sont souvent construits sur des implémentations Lisp existantes, car ils peuvent se greffer sur la plupart de la même infrastructure. L'écriture d'un interpréteur de schéma peut être effectuée dans Scheme sous une page de code, à quel point on peut facilement ajouter de nouvelles fonctionnalités.

Fondamentalement, les compilateurs ne sont que des programmes qui lisent quelque chose et le traduisent en autre chose - la conversion de la source LaTeX en DVI, la conversion du code C en assemblage puis en langage machine, la conversion d'une spécification de grammaire en code C pour un analyseur, etc. la structure du format source (analyse syntaxique), ce que signifient ces structures, comment simplifier les données (optimisation) et le type de sortie à générer. Les interprètes lisent la source et l'exécutent directement. (Les interprètes sont généralement plus simples à écrire, mais beaucoup plus lents.)


4

En fait, vous pouvez écrire dans presque toutes les langues que vous aimez. Il n'y a rien qui vous empêche d'écrire un compilateur C dans Ruby. "Tout" vous avez à faire est d'analyser le programme et d'émettre le code machine correspondant. Si vous pouvez lire / écrire des fichiers, votre langage de programmation suffira probablement.

Si vous partez de zéro sur une nouvelle plate-forme, vous pouvez effectuer une compilation croisée: écrivez un compilateur pour votre nouvelle plate-forme, qui s'exécute en Java ou en natif sur x86. Développez sur votre PC, puis transférez le programme sur votre nouvelle plate-forme cible.

Les compilateurs les plus basiques sont probablement Assembler et C.


Ce langage «tout» devrait cependant prendre en charge les appels récursifs. Sinon, implémenter un analyseur de syntaxe et un analyseur sera un véritable défi.

2
Si vous sélectionnez une langue inappropriée pour une tâche, c'est de votre faute. Cela peut arriver pour n'importe quel projet, pas seulement pour les compilateurs / interprètes.
ziggystar

4

"Ecrire un nouveau langage de programmation" n'implique techniquement aucun code. Il s'agit simplement de proposer une spécification de ce à quoi ressemble votre langue et de son fonctionnement. Une fois que vous avez une idée de ce à quoi ressemble votre langue, vous pouvez écrire des traducteurs et des interprètes pour que votre langue "fonctionne".

Un traducteur entre un programme dans une langue et produit un programme équivalent dans une autre langue. Un interprète entre un programme dans une langue et l'exécute.

Par exemple, un compilateur C traduit généralement le code source C (le langage d'entrée) en un programme en langage assembleur (le langage de sortie). L'assembleur prend ensuite le programme en langage assembleur et produit le langage machine. Une fois que vous avez votre sortie, vous n'avez pas besoin des traducteurs pour exécuter votre programme. Puisque vous disposez désormais d'un programme en langage machine, la CPU fait office d'interprète.

De nombreuses langues sont implémentées différemment. Par exemple, javacest un traducteur qui convertit le code source Java en bytecode JVM. La JVM est un interpréteur [1] qui exécute le bytecode Java. Après avoir exécuté javacet obtenu le bytecode, vous n'en avez plus besoin javac. Cependant, chaque fois que vous souhaitez exécuter votre programme, vous aurez besoin de la JVM.

Le fait que les traducteurs n'aient pas besoin d'être gardés pour exécuter un programme est ce qui permet de "bootstrap" votre langue sans qu'elle finisse par s'exécuter "au-dessus" des couches et des couches d'autres langues.

[1] La plupart des JVM font de la traduction dans les coulisses, mais ce ne sont pas vraiment des traducteurs dans la mesure où l'interface avec la JVM n'est pas "langue d'entrée -> langue de sortie".


3

En règle générale, vous pouvez utiliser à peu près n'importe quelle langue que vous aimez. PHP a été écrit en C, par exemple. Si vous n'avez accès à aucun compilateur, vous devrez recourir à l'écriture du langage d'assemblage et le compiler manuellement en code machine.


2
Vous n'avez pas à compiler le code machine. c'est la langue native du CPU par définition.
Stu Thompson

1
Vrai. Ce que je voulais dire, c'était "compiler le code machine à partir du langage d'assemblage ou quelque chose de similaire à la main". Je peux me tromper, mais je suppose que peu de gens saisissent tout de suite le code en binaire / hexadécimal.
Kaivosukeltaja

2

De nombreux langages ont d'abord été écrits dans un autre langage disponible, puis réimplémentés en eux-mêmes et amorcés de cette façon (ou ont simplement conservé l'implémentation dans le langage étranger, comme PHP et perl), mais certains langages, comme le premier assembleur, ont été compilés à la main en code machine comme le premier compilateur C a été compilé à la main en assemblage.

Je m'intéresse au bootstrap depuis que j'en ai lu. Pour en savoir plus, j'ai essayé de le faire moi-même en écrivant mon propre sur-ensemble de BF, que j'ai appelé EBF , en lui-même. la première version d'EBF avait 3 primitives supplémentaires et j'ai compilé le premier binaire à la main. J'ai trouvé un rythme en deux étapes en le faisant. J'ai implémenté une fonctionnalité dans la langue actuelle dans une version et j'ai eu une version douce où j'ai réécrit le code pour utiliser la fonctionnalité implémentée. Le langage était suffisamment expressif pour être utilisé pour créer un interprète LISP .

J'ai la version compilée à la main avec la source dans la première balise de publication et le code est assez petit. La dernière version est 12 fois plus grande en taille et en code et permet un code plus compact donc la compilation manuelle de la version actuelle serait difficile à obtenir correctement.

Edmund Grimley Evans a fait quelque chose de similaire avec son langage HEX

L'une des choses intéressantes à faire vous-même est que vous comprenez pourquoi certaines choses sont telles qu'elles sont. Mon code était un produit avec de petits ajustements incrémentiels et il semble plus avoir évolué que conçu à partir de zéro. Je garde cela à l'esprit en lisant le code aujourd'hui, ce qui, à mon avis, semble un peu décevant.


1

Habituellement avec un langage de programmation polyvalent adapté au développement de systèmes, par exemple C, Haskell, ML, Lisp, etc., mais la liste des options est longue. Aussi, généralement avec des langages spécifiques au domaine pour l'implémentation du langage, c'est-à-dire des générateurs d'analyseurs et d'analyseurs lexicaux, des langages intermédiaires comme LLVM , etc. Et probablement des scripts shell, des frameworks de test et un système de configuration de construction, par exemple autoconf.


1

La plupart des compilateurs étaient écrits en C ou ac comme un programme sinon c alors le langage d'assembly est la voie à suivre Cependant, lorsque vous écrivez un nouveau langage à partir de zéro et que vous n'avez pas de macro lib ou de code source à partir d'un langage prototype, vous devez définir vos propres fonctions Maintenant dans quelle langue? Vous pouvez simplement écrire un formulaire "de code source appelé psedocode sur la machine. Il ressemble à une grammaire bnf de la spécification de lang structurée orientée objet comme Fortran basic algo lisp. Donc, l'image écrivant un code croisé ressemblant à l'une de ces syntaxe de langage C'est le code psedo


1
Je ne pense pas que le code psedo soit censé être lisible par machine
Richard Tingle

0

Même les opérations binaires ou d'assemblage supplémentaires doivent être traduites en fonctions, c'est le travail des assembleurs / compilateurs, puis en objet, à partir de données et de fonctions, si vous n'avez pas de fichier source pour voir "comment ces objets doivent être représentés dans votre l'implémentation du langage, Ensuite, vous devez reconnaître "voir" implémenter, ou définir vos propres fonctions, procédures et structures de données, ce qui nécessite beaucoup de connaissances, vous devez vous demander ce qu'est une fonction. Votre esprit devient alors la simulation du langage. Cela sépare un programmeur principal du reste.


0

J'ai moi aussi eu cette question il y a quelques mois. Et j'ai lu quelques articles et regardé des vidéos qui m'ont aidé à commencer à écrire mon propre langage appelé soft. Ce n'est pas encore terminé, mais j'ai appris beaucoup de choses de ce voyage.

Ce que vous devez savoir de base, c'est comment fonctionne le compilateur lorsqu'il doit exécuter un extrait de code. Le compilateur a beaucoup de phases comme l'analyse lexicale, l'analyseur sémantique, AST (Abstract Syntax Tree) etc.

Ce que j'ai fait dans ma nouvelle langue peut être trouvé ici - http://www.singhajit.com/writing-a-new-programming-language/

Si vous écrivez une langue pour la première fois, tout le meilleur et vous avez un long chemin à parcourir.


0

Quels sont les langages de programmation en général?

les langages de programmation ne sont qu'un moyen de parler aux ordinateurs. grosso modo au début parce que les ordinateurs ne pouvaient comprendre que les zéros et les uns (du fait que les ordinateurs sont faits de transistors comme des commutateurs qui ne pouvaient prendre que deux états, nous appelons ces deux états 0 et 1) et travailler avec 0,1 était difficile pour en tant qu'êtres humains, les informaticiens ont donc décidé de faire un mappage un à un de chaque instruction en binaire (0,1) vers une forme plus lisible par l'homme qu'ils ont appelée langage d'assemblage.

par exemple si nous avions une instruction comme:

11001101

en assemblage, il s'appellerait:

LOAD_A 15

ce qui signifie que charger le contenu du registre a dans l'emplacement mémoire 15. comme je l'ai dit, c'était juste une convention comme choisir 0 et 1 pour deux états des transistors ou quoi que ce soit d'autre dans l'ordinateur. de cette manière avoir un programme avec 50 instructions, se souvenir du langage d'assemblage serait plus facile. donc l'utilisateur écrirait le code d'assemblage et un programme (l'assembleur dans ce cas) traduirait les codes en instructions binaires ou en langage machine comme ils l'appellent.

mais avec les ordinateurs améliorés chaque jour, il y avait de la place pour des programmes plus compliqués avec plus d'instructions, disons 10000.

dans ce cas, un mappage un à un comme l'assembly ne fonctionnerait pas, donc d'autres langages de programmation de haut niveau ont été créés. ils ont dit par exemple si pour une relation avec des périphériques d'E / S pour imprimer quelque chose sur l'écran créé par l'utilisateur prend environ 80 instructions, faisons quelque chose ici et nous pourrions regrouper tout ce code dans une bibliothèque et l'appeler par exemple printf et aussi créer un autre programme qui pourrait traduire ce printf ici en code d'assembly associé et à partir de là, l'assembly ferait le reste. donc ils l'appellent compilateur.

donc maintenant, chaque utilisateur qui veut simplement imprimer quelque chose à l'écran, il n'aurait pas à écrire toutes les instructions en binaire ou en assemblage, il tape juste printf ("quelque chose") et tous les programmes comme le compilateur et l'assembleur feraient le reste. maintenant, plus tard, d'autres codes plus longs seraient emballés de la même manière pour simplement faciliter le travail d'autres personnes, car vous voyez que vous pouvez simplement simplifier des milliers de lignes de code en un code en python et le conditionner pour l'utilisation d'autres personnes.

alors disons que vous avez emballé beaucoup de codes différents en python et créé un module (libray, package ou tout ce que vous voulez appeler) et que vous appelez ce module mgh (juste mon nom). maintenant, disons que nous avons créé ce mgh en quelque sorte que quiconque dit:

import mgh
mgh.connect(ip,port.data)...

pourrait facilement se connecter à un serveur distant avec l'IP et le numéro de port spécifiés et envoyer les données par la suite (ou quelque chose comme ça). maintenant, les gens peuvent tout faire en utilisant une seule ligne, mais ce qui se passe, c'est que beaucoup de codes sont exécutés qui ont été récupérés à partir du fichier mgh. et l'empaquetage n'a pas été pour accélérer le processus d'exécution mais plutôt pour faciliter les travaux d'autres programmeurs. donc ici, si quelqu'un veut d'abord utiliser votre code, il doit importer le fichier, puis l'interpréteur python reconnaîtra tout le code qu'il contient et pourrait ainsi interpréter le code.

maintenant si vous voulez créer un langage de programmation et que vous voulez l'exécuter, il faut d'abord une traduction, par exemple disons que vous créez un programme qui pourrait comprendre la syntaxe et le convertir en c, dans ce cas après qu'il a été traduit en c, le reste serait pris en charge par le compilateur c, puis l'assembleur, l'éditeur de liens, .... même si vous devrez payer le prix d'être plus lent puisqu'il faut d'abord le convertir en c.

maintenant une autre chose que vous pourriez faire est de créer un programme qui pourrait traduire tout le code dans le langage d'assemblage équivalent, tout comme ce qui se passe avec c, mais dans ce cas, le programme pourrait le faire directement et à partir de là, le reste serait fait par le éditeur de liens. nous savons que ce programme s'appelle compilateur.

donc ce dont je parle, c'est que, le seul code que le système comprend est 0,1, donc vous devriez d'une manière ou d'une autre convertir votre syntaxe en cela, maintenant dans nos systèmes d'exploitation, de nombreux programmes différents comme assembleur, éditeur de liens et ... ont a été créé pour vous dire que si vous pouviez convertir votre code en assemblage, ils pourraient s'occuper du reste ou, comme je l'ai dit, vous pourriez même utiliser d'autres compilateurs de langages de programmation en convertissant votre code dans ce langage.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.